Salome HOME
Adding new algo for parallel meshing
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  NETGENPlugin : C++ implementation
24 // File      : NETGENPlugin_Hypothesis.cxx
25 // Author    : Michael Sazonov (OCN)
26 // Date      : 28/03/2006
27 // Project   : SALOME
28 //
29 #include "NETGENPlugin_Hypothesis.hxx"
30
31 #include "NETGENPlugin_Mesher.hxx"
32 #include "SMESH_Mesh.hxx"
33
34 #include <utilities.h>
35
36 using namespace std;
37
38 //=============================================================================
39 /*!
40  *
41  */
42 //=============================================================================
43 NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, SMESH_Gen * gen)
44
45   : SMESH_Hypothesis(hypId, gen),
46     _fineness           (GetDefaultFineness()),
47     _secondOrder        (GetDefaultSecondOrder()),
48     _quadAllowed        (GetDefaultQuadAllowed()),
49     _maxSize            (GetDefaultMaxSize()),
50     _minSize            (0),
51     _growthRate         (GetDefaultGrowthRate()),
52     _nbSegPerRadius     (GetDefaultNbSegPerRadius()),
53     _nbSegPerEdge       (GetDefaultNbSegPerEdge()),
54     _chordalErrorEnabled(GetDefaultChordalError() > 0),
55     _chordalError       (GetDefaultChordalError() ),
56     _optimize           (GetDefaultOptimize()),
57     _nbSurfOptSteps     (GetDefaultNbSurfOptSteps()),
58     _nbVolOptSteps      (GetDefaultNbVolOptSteps()),
59     _elemSizeWeight     (GetDefaultElemSizeWeight()),
60     _worstElemMeasure   (GetDefaultWorstElemMeasure()),
61     _nbThreads          (GetDefaultNbThreads()),
62     _surfaceCurvature   (GetDefaultSurfaceCurvature()),
63     _useDelauney        (GetDefaultUseDelauney()),
64     _checkOverlapping   (GetDefaultCheckOverlapping()),
65     _checkChartBoundary (GetDefaultCheckChartBoundary()),
66     _fuseEdges          (GetDefaultFuseEdges())
67 {
68   _name = "NETGEN_Parameters";
69   _param_algo_dim = 3;
70 }
71
72 //=============================================================================
73 /*!
74  *
75  */
76 //=============================================================================
77 void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
78 {
79   if (theSize != _maxSize)
80   {
81     _maxSize = theSize;
82     NotifySubMeshesHypothesisModification();
83   }
84 }
85
86 //=============================================================================
87 /*!
88  *
89  */
90 //=============================================================================
91 void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
92 {
93   if (theSize != _minSize)
94   {
95     _minSize = theSize;
96     NotifySubMeshesHypothesisModification();
97   }
98 }
99
100 //=============================================================================
101 /*!
102  *
103  */
104 //=============================================================================
105 void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal)
106 {
107   if (theVal != _secondOrder)
108   {
109     _secondOrder = theVal;
110     NotifySubMeshesHypothesisModification();
111   }
112 }
113
114 //=============================================================================
115 /*!
116  *
117  */
118 //=============================================================================
119 void NETGENPlugin_Hypothesis::SetOptimize(bool theVal)
120 {
121   if (theVal != _optimize)
122   {
123     _optimize = theVal;
124     NotifySubMeshesHypothesisModification();
125   }
126 }
127
128 //=============================================================================
129 /*!
130  *
131  */
132 //=============================================================================
133 void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness)
134 {
135   if (theFineness != _fineness)
136   {
137     _fineness = theFineness;
138     // the predefined values are taken from NETGEN 4.5 sources
139     switch (_fineness)
140     {
141     case VeryCoarse:
142       _growthRate = 0.7;
143       _nbSegPerEdge = 0.3;
144       _nbSegPerRadius = 1;
145       break;
146     case Coarse:
147       _growthRate = 0.5;
148       _nbSegPerEdge = 0.5;
149       _nbSegPerRadius = 1.5;
150       break;
151     case Fine:
152       _growthRate = 0.2;
153       _nbSegPerEdge = 2;
154       _nbSegPerRadius = 3;
155       break;
156     case VeryFine:
157       _growthRate = 0.1;
158       _nbSegPerEdge = 3;
159       _nbSegPerRadius = 5;
160       break;
161     case UserDefined:
162       break;
163     case Moderate:
164     default:
165       _growthRate = 0.3;
166       _nbSegPerEdge = 1;
167       _nbSegPerRadius = 2;
168       break;
169     }
170     NotifySubMeshesHypothesisModification();
171   }
172 }
173
174 //=============================================================================
175 /*!
176  *
177  */
178 //=============================================================================
179 void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate)
180 {
181   if (theRate != _growthRate)
182   {
183     _growthRate = theRate;
184     _fineness = UserDefined;
185     NotifySubMeshesHypothesisModification();
186   }
187 }
188
189 //=============================================================================
190 /*!
191  *
192  */
193 //=============================================================================
194 void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal)
195 {
196   if (theVal != _nbSegPerEdge)
197   {
198     _nbSegPerEdge = theVal;
199     _fineness = UserDefined;
200     NotifySubMeshesHypothesisModification();
201   }
202 }
203
204 //=============================================================================
205 /*!
206  *
207  */
208 //=============================================================================
209 void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
210 {
211   if (theVal != _nbSegPerRadius)
212   {
213     _nbSegPerRadius = theVal;
214     _fineness = UserDefined;
215     NotifySubMeshesHypothesisModification();
216   }
217 }
218
219 //=============================================================================
220 /*!
221  *
222  */
223 //=============================================================================
224 void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal)
225 {
226   if (theVal != _chordalErrorEnabled)
227   {
228     _chordalErrorEnabled = theVal;
229     NotifySubMeshesHypothesisModification();
230   }
231 }
232
233 //=============================================================================
234 /*!
235  *
236  */
237 //=============================================================================
238 void NETGENPlugin_Hypothesis::SetChordalError(double theVal)
239 {
240   if (theVal != _chordalError)
241   {
242     _chordalError = theVal;
243     NotifySubMeshesHypothesisModification();
244   }
245 }
246
247 //=============================================================================
248 /*!
249  *
250  */
251 //=============================================================================
252 void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize)
253 {
254   if(_localSize[entry] != localSize)
255   {
256     _localSize[entry] = localSize;
257     NotifySubMeshesHypothesisModification();
258   }
259 }
260
261 //=============================================================================
262 /*!
263  *
264  */
265 //=============================================================================
266 double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry)
267 {
268   TLocalSize::iterator it  = _localSize.find( entry );
269   if ( it != _localSize.end() )
270     return it->second;
271   else
272     return -1.0;
273 }
274
275 //=============================================================================
276 /*!
277  *
278  */
279 //=============================================================================
280 void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry)
281 {
282   _localSize.erase(entry);
283   NotifySubMeshesHypothesisModification();
284 }
285
286 //=============================================================================
287 /*!
288  *
289  */
290 //=============================================================================
291 void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName)
292 {
293   if ( fileName != _meshSizeFile )
294   {
295     _meshSizeFile = fileName;
296     NotifySubMeshesHypothesisModification();
297   }
298 }
299
300 //=============================================================================
301 /*!
302  *
303  */
304 //=============================================================================
305 void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal)
306 {
307   if (theVal != _quadAllowed)
308   {
309     _quadAllowed = theVal;
310     NotifySubMeshesHypothesisModification();
311   }
312 }
313
314 //=============================================================================
315 /*!
316  *
317  */
318 //=============================================================================
319 void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal)
320 {
321   if (theVal != _surfaceCurvature)
322   {
323     _surfaceCurvature = theVal;
324     NotifySubMeshesHypothesisModification();
325   }
326 }
327
328 //=============================================================================
329 /*!
330  *
331  */
332 //=============================================================================
333 void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal)
334 {
335   if (theVal != _fuseEdges)
336   {
337     _fuseEdges = theVal;
338     NotifySubMeshesHypothesisModification();
339   }
340 }
341
342 //=======================================================================
343 //function : SetNbSurfOptSteps
344 //purpose  :
345 //=======================================================================
346
347 void NETGENPlugin_Hypothesis::SetNbSurfOptSteps( int theVal )
348 {
349   if (theVal != _nbSurfOptSteps)
350   {
351     _nbSurfOptSteps = theVal;
352     NotifySubMeshesHypothesisModification();
353   }
354 }
355
356 //=======================================================================
357 //function : SetNbVolOptSteps
358 //purpose  :
359 //=======================================================================
360
361 void NETGENPlugin_Hypothesis::SetNbVolOptSteps( int theVal )
362 {
363   if (theVal != _nbVolOptSteps)
364   {
365     _nbVolOptSteps = theVal;
366     NotifySubMeshesHypothesisModification();
367   }
368 }
369
370 //=======================================================================
371 //function : SetElemSizeWeight
372 //purpose  :
373 //=======================================================================
374
375 void NETGENPlugin_Hypothesis::SetElemSizeWeight( double theVal )
376 {
377   if (theVal != _elemSizeWeight)
378   {
379     _elemSizeWeight = theVal;
380     NotifySubMeshesHypothesisModification();
381   }
382 }
383
384 //=======================================================================
385 //function : SetWorstElemMeasure
386 //purpose  :
387 //=======================================================================
388
389 void NETGENPlugin_Hypothesis::SetWorstElemMeasure( int theVal )
390 {
391   if (theVal != _worstElemMeasure)
392   {
393     _worstElemMeasure = theVal;
394     NotifySubMeshesHypothesisModification();
395   }
396 }
397
398 //=======================================================================
399 //function : SetUseDelauney
400 //purpose  :
401 //=======================================================================
402
403 void NETGENPlugin_Hypothesis::SetUseDelauney( bool theVal )
404 {
405   if (theVal != _useDelauney )
406   {
407     _useDelauney = theVal;
408     NotifySubMeshesHypothesisModification();
409   }
410 }
411
412 //=======================================================================
413 //function : SetCheckOverlapping
414 //purpose  :
415 //=======================================================================
416
417 void NETGENPlugin_Hypothesis::SetCheckOverlapping( bool theVal )
418 {
419   if (theVal != _checkOverlapping )
420   {
421     _checkOverlapping = theVal;
422     NotifySubMeshesHypothesisModification();
423   }
424 }
425
426 //=======================================================================
427 //function : SetCheckChartBoundary
428 //purpose  :
429 //=======================================================================
430
431 void NETGENPlugin_Hypothesis::SetCheckChartBoundary( bool theVal )
432 {
433   if (theVal != _checkChartBoundary)
434   {
435     _checkChartBoundary = theVal;
436     NotifySubMeshesHypothesisModification();
437   }
438 }
439
440 //=======================================================================
441 //function : SetNbThreads
442 //purpose  :
443 //=======================================================================
444
445 void NETGENPlugin_Hypothesis::SetNbThreads( int theVal )
446 {
447   if (theVal != _nbThreads)
448   {
449     _nbThreads = theVal;
450     NotifySubMeshesHypothesisModification();
451   }
452 }
453
454 //=============================================================================
455 /*!
456  *
457  */
458 //=============================================================================
459 ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
460 {
461   save << _maxSize << " " << _fineness;
462
463   if (_fineness == UserDefined)
464     save << " " << _growthRate << " " << _nbSegPerEdge << " " << _nbSegPerRadius;
465
466   save << " " << (int)_secondOrder << " " << (int)_optimize;
467
468   TLocalSize::iterator it_sm  = _localSize.begin();
469   if (it_sm != _localSize.end()) {
470     save << " " << "__LOCALSIZE_BEGIN__";
471     for ( ; it_sm != _localSize.end(); ++it_sm ) {
472       save << " " << it_sm->first
473            << " " << it_sm->second << "%#"; // "%#" is a mark of value end
474     }
475     save << " " << "__LOCALSIZE_END__";
476   }
477   save << " " << _minSize;
478   save << " " << _quadAllowed;
479   save << " " << _surfaceCurvature;
480   save << " " << _fuseEdges;
481
482   save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
483
484   save << " " << ( _chordalErrorEnabled ? _chordalError : 0. );
485
486
487   // added for option set completion
488
489   save << " " << _nbSurfOptSteps;
490   save << " " << _nbVolOptSteps;
491   save << " " << _elemSizeWeight;
492   save << " " << _worstElemMeasure;
493
494   save << " " << _useDelauney;
495   save << " " << _checkOverlapping;
496   save << " " << _checkChartBoundary;
497
498   return save;
499 }
500
501 //=============================================================================
502 /*!
503  *
504  */
505 //=============================================================================
506 istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
507 {
508   bool isOK = true;
509   int is;
510   double val;
511
512   isOK = static_cast<bool>(load >> val);
513   if (isOK)
514     _maxSize = val;
515   else
516     load.clear(ios::badbit | load.rdstate());
517
518   isOK = static_cast<bool>(load >> is);
519   if (isOK)
520     SetFineness((Fineness) is);
521   else
522     load.clear(ios::badbit | load.rdstate());
523
524   if (_fineness == UserDefined)
525   {
526     isOK = static_cast<bool>(load >> val);
527     if (isOK)
528       _growthRate = val;
529     else
530       load.clear(ios::badbit | load.rdstate());
531
532     isOK = static_cast<bool>(load >> val);
533     if (isOK)
534       _nbSegPerEdge = val;
535     else
536       load.clear(ios::badbit | load.rdstate());
537
538     isOK = static_cast<bool>(load >> val);
539     if (isOK)
540       _nbSegPerRadius = val;
541     else
542       load.clear(ios::badbit | load.rdstate());
543   }
544
545   isOK = static_cast<bool>(load >> is);
546   if (isOK)
547     _secondOrder = (bool) is;
548   else
549     load.clear(ios::badbit | load.rdstate());
550
551   isOK = static_cast<bool>(load >> is);
552   if (isOK)
553     _optimize = (bool) is;
554   else
555     load.clear(ios::badbit | load.rdstate());
556
557   std::string option_or_sm;
558   bool hasLocalSize = false;
559
560   isOK = static_cast<bool>(load >> option_or_sm);
561   if (isOK)
562     if (option_or_sm == "__LOCALSIZE_BEGIN__")
563       hasLocalSize = true;
564
565   std::string smEntry, smValue;
566   while (isOK && hasLocalSize) {
567     isOK = static_cast<bool>(load >> smEntry);
568     if (isOK) {
569       if (smEntry == "__LOCALSIZE_END__")
570         break;
571       isOK = static_cast<bool>(load >> smValue);
572     }
573     if (isOK) {
574       std::istringstream tmp(smValue);
575       double val;
576       tmp >> val;
577       _localSize[ smEntry ] = val;
578     }
579   }
580
581   if ( !hasLocalSize && !option_or_sm.empty() )
582     _minSize = atof( option_or_sm.c_str() );
583   else
584     load >> _minSize;
585
586   isOK = static_cast<bool>( load >> is );
587   if ( isOK )
588     _quadAllowed = (bool) is;
589   else
590     _quadAllowed = GetDefaultQuadAllowed();
591
592   isOK = static_cast<bool>( load >> is );
593   if ( isOK )
594     _surfaceCurvature = (bool) is;
595   else
596     _surfaceCurvature = GetDefaultSurfaceCurvature();
597
598   isOK = static_cast<bool>( load >> is );
599   if ( isOK )
600     _fuseEdges = (bool) is;
601   else
602     _fuseEdges = GetDefaultFuseEdges();
603
604   isOK = static_cast<bool>( load >> is >> std::ws ); // size of meshSizeFile
605   if ( isOK && is > 0 )
606   {
607     _meshSizeFile.resize( is );
608     load.get( &_meshSizeFile[0], is+1 );
609   }
610
611   isOK = static_cast<bool>(load >> val);
612   if (isOK)
613     _chordalError = val;
614   else
615     load.clear(ios::badbit | load.rdstate());
616   _chordalErrorEnabled = ( _chordalError > 0 );
617
618
619   // added for option set completion
620
621   isOK = static_cast<bool>( load >> is );
622   if ( isOK )
623     _nbSurfOptSteps = is;
624
625   isOK = static_cast<bool>( load >> is );
626   if ( isOK )
627     _nbVolOptSteps = is;
628
629   isOK = static_cast<bool>( load >> val );
630   if ( isOK )
631     _elemSizeWeight =  val;
632
633   isOK = static_cast<bool>( load >> is );
634   if ( isOK )
635     _worstElemMeasure = is;
636
637   isOK = static_cast<bool>( load >> is );
638   if ( isOK )
639     _useDelauney = (bool) is;
640
641   isOK = static_cast<bool>( load >> is );
642   if ( isOK )
643     _checkOverlapping = (bool) is;
644
645   isOK = static_cast<bool>( load >> is );
646   if ( isOK )
647     _checkChartBoundary = (bool) is;
648
649   return load;
650 }
651
652 //================================================================================
653 /*!
654  * \brief Does nothing
655  * \param theMesh - the built mesh
656  * \param theShape - the geometry of interest
657  * \retval bool - always false
658  */
659 //================================================================================
660 bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh*   /*theMesh*/,
661                                                   const TopoDS_Shape& /*theShape*/)
662 {
663   return false;
664 }
665
666 //================================================================================
667 /*!
668  * \brief Initialize my parameter values by default parameters.
669  *  \retval bool - true if parameter values have been successfully defined
670  */
671 //================================================================================
672
673 bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
674                                                       const SMESH_Mesh* theMesh)
675 {
676   _nbSegPerEdge = dflts._nbSegments;
677   _maxSize      = dflts._elemLength;
678
679   if ( dflts._shape && !dflts._shape->IsNull() )
680     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize );
681   else if ( theMesh && theMesh->HasShapeToMesh() )
682     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize );
683
684   if ( dflts._way == SMESH_Hypothesis::BY_AVERAGE_LENGTH )
685   {
686     _minSize      = dflts._elemLength / 100.;
687     _nbSegPerEdge = 1;
688     _chordalError = dflts._elemLength / 2.;
689     _chordalErrorEnabled = true;
690     _quadAllowed  = dflts._quadDominated;
691   }
692
693   return _nbSegPerEdge && _maxSize > 0;
694 }