Salome HOME
23586: [EDF] HYDRO: Copy mesh to new geometry
[plugins/netgenplugin.git] / src / NETGENPlugin / NETGENPlugin_Hypothesis.cxx
1 // Copyright (C) 2007-2016  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,
44                                                   SMESH_Gen * gen)
45
46   : SMESH_Hypothesis(hypId, gen),
47     _maxSize            (GetDefaultMaxSize()),
48     _minSize            (0),
49     _growthRate         (GetDefaultGrowthRate()),
50     _nbSegPerEdge       (GetDefaultNbSegPerEdge()),
51     _nbSegPerRadius     (GetDefaultNbSegPerRadius()),
52     _fineness           (GetDefaultFineness()),
53     _chordalErrorEnabled(GetDefaultChordalError() > 0),
54     _chordalError       (GetDefaultChordalError() ),
55     _secondOrder        (GetDefaultSecondOrder()),
56     _optimize           (GetDefaultOptimize()),
57     _quadAllowed        (GetDefaultQuadAllowed()),
58     _surfaceCurvature   (GetDefaultSurfaceCurvature()),
59     _fuseEdges          (GetDefaultFuseEdges())
60 {
61   _name = "NETGEN_Parameters";
62   _param_algo_dim = 3;
63   _localSize.clear();
64 }
65
66 //=============================================================================
67 /*!
68  *  
69  */
70 //=============================================================================
71 void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
72 {
73   if (theSize != _maxSize)
74   {
75     _maxSize = theSize;
76     NotifySubMeshesHypothesisModification();
77   }
78 }
79
80 //=============================================================================
81 /*!
82  *  
83  */
84 //=============================================================================
85 void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
86 {
87   if (theSize != _minSize)
88   {
89     _minSize = theSize;
90     NotifySubMeshesHypothesisModification();
91   }
92 }
93
94 //=============================================================================
95 /*!
96  *  
97  */
98 //=============================================================================
99 void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal)
100 {
101   if (theVal != _secondOrder)
102   {
103     _secondOrder = theVal;
104     NotifySubMeshesHypothesisModification();
105   }
106 }
107
108 //=============================================================================
109 /*!
110  *  
111  */
112 //=============================================================================
113 void NETGENPlugin_Hypothesis::SetOptimize(bool theVal)
114 {
115   if (theVal != _optimize)
116   {
117     _optimize = theVal;
118     NotifySubMeshesHypothesisModification();
119   }
120 }
121
122 //=============================================================================
123 /*!
124  *  
125  */
126 //=============================================================================
127 void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness)
128 {
129   if (theFineness != _fineness)
130   {
131     _fineness = theFineness;
132     // the predefined values are taken from NETGEN 4.5 sources
133     switch (_fineness)
134     {
135     case VeryCoarse:
136       _growthRate = 0.7;
137       _nbSegPerEdge = 0.3;
138       _nbSegPerRadius = 1;
139       break;
140     case Coarse:
141       _growthRate = 0.5;
142       _nbSegPerEdge = 0.5;
143       _nbSegPerRadius = 1.5;
144       break;
145     case Fine:
146       _growthRate = 0.2;
147       _nbSegPerEdge = 2;
148       _nbSegPerRadius = 3;
149       break;
150     case VeryFine:
151       _growthRate = 0.1;
152       _nbSegPerEdge = 3;
153       _nbSegPerRadius = 5;
154       break;
155     case UserDefined:
156       break;
157     case Moderate:
158     default:
159       _growthRate = 0.3;
160       _nbSegPerEdge = 1;
161       _nbSegPerRadius = 2;
162       break;
163     }
164     NotifySubMeshesHypothesisModification();
165   }
166 }
167
168 //=============================================================================
169 /*!
170  *  
171  */
172 //=============================================================================
173 void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate)
174 {
175   if (theRate != _growthRate)
176   {
177     _growthRate = theRate;
178     _fineness = UserDefined;
179     NotifySubMeshesHypothesisModification();
180   }
181 }
182
183 //=============================================================================
184 /*!
185  *  
186  */
187 //=============================================================================
188 void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal)
189 {
190   if (theVal != _nbSegPerEdge)
191   {
192     _nbSegPerEdge = theVal;
193     _fineness = UserDefined;
194     NotifySubMeshesHypothesisModification();
195   }
196 }
197
198 //=============================================================================
199 /*!
200  *  
201  */
202 //=============================================================================
203 void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
204 {
205   if (theVal != _nbSegPerRadius)
206   {
207     _nbSegPerRadius = theVal;
208     _fineness = UserDefined;
209     NotifySubMeshesHypothesisModification();
210   }
211 }
212
213 //=============================================================================
214 /*!
215  *  
216  */
217 //=============================================================================
218 void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal)
219 {
220   if (theVal != _chordalErrorEnabled)
221   {
222     _chordalErrorEnabled = theVal;
223     NotifySubMeshesHypothesisModification();
224   }
225 }
226
227 //=============================================================================
228 /*!
229  *  
230  */
231 //=============================================================================
232 void NETGENPlugin_Hypothesis::SetChordalError(double theVal)
233 {
234   if (theVal != _chordalError)
235   {
236     _chordalError = theVal;
237     NotifySubMeshesHypothesisModification();
238   }
239 }
240
241 //=============================================================================
242 /*!
243  *  
244  */
245 //=============================================================================
246 void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize)
247 {
248   if(_localSize[entry] != localSize)
249   {
250     _localSize[entry] = localSize;
251     NotifySubMeshesHypothesisModification();
252   }
253 }
254
255 //=============================================================================
256 /*!
257  *
258  */
259 //=============================================================================
260 double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry)
261 {
262   TLocalSize::iterator it  = _localSize.find( entry );
263   if ( it != _localSize.end() )
264     return it->second;
265   else
266     return -1.0;
267 }
268
269 //=============================================================================
270 /*!
271  *  
272  */
273 //=============================================================================
274 void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry)
275 {
276   _localSize.erase(entry);
277   NotifySubMeshesHypothesisModification();
278 }
279
280 //=============================================================================
281 /*!
282  *  
283  */
284 //=============================================================================
285 void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName)
286 {
287   if ( fileName != _meshSizeFile )
288   {
289     _meshSizeFile = fileName;
290     NotifySubMeshesHypothesisModification();
291   }
292 }
293
294 //=============================================================================
295 /*!
296  *  
297  */
298 //=============================================================================
299 void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal)
300 {
301   if (theVal != _quadAllowed)
302   {
303     _quadAllowed = theVal;
304     NotifySubMeshesHypothesisModification();
305   }
306 }
307
308 //=============================================================================
309 /*!
310  *  
311  */
312 //=============================================================================
313 bool NETGENPlugin_Hypothesis::GetDefaultQuadAllowed()
314 {
315   return false;
316 }
317
318 //=============================================================================
319 /*!
320  *  
321  */
322 //=============================================================================
323 void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal)
324 {
325   if (theVal != _surfaceCurvature)
326   {
327     _surfaceCurvature = theVal;
328     NotifySubMeshesHypothesisModification();
329   }
330 }
331
332 //=============================================================================
333 /*!
334  *
335  */
336 //=============================================================================
337 bool NETGENPlugin_Hypothesis::GetDefaultSurfaceCurvature()
338 {
339   return true;
340 }
341
342 //=============================================================================
343 /*!
344  *
345  */
346 //=============================================================================
347 void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal)
348 {
349   if (theVal != _fuseEdges)
350   {
351     _fuseEdges = theVal;
352     NotifySubMeshesHypothesisModification();
353   }
354 }
355
356 //=============================================================================
357 /*!
358  *
359  */
360 //=============================================================================
361 bool NETGENPlugin_Hypothesis::GetDefaultFuseEdges()
362 {
363   return true; // false; -- for SALOME_TESTS/Grids/smesh/3D_mesh_NETGEN_05/F6
364 }
365
366 //=============================================================================
367 /*!
368  *
369  */
370 //=============================================================================
371 ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
372 {
373   save << _maxSize << " " << _fineness;
374
375   if (_fineness == UserDefined)
376     save << " " << _growthRate << " " << _nbSegPerEdge << " " << _nbSegPerRadius;
377
378   save << " " << (int)_secondOrder << " " << (int)_optimize;
379
380   TLocalSize::iterator it_sm  = _localSize.begin();
381   if (it_sm != _localSize.end()) {
382     save << " " << "__LOCALSIZE_BEGIN__";
383     for ( ; it_sm != _localSize.end(); ++it_sm ) {
384       save << " " << it_sm->first
385            << " " << it_sm->second << "%#"; // "%#" is a mark of value end
386     }
387     save << " " << "__LOCALSIZE_END__";
388   }
389   save << " " << _minSize;
390   save << " " << _quadAllowed;
391   save << " " << _surfaceCurvature;
392   save << " " << _fuseEdges;
393
394   save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
395
396   save << " " << ( _chordalErrorEnabled ? _chordalError : 0. );
397
398   return save;
399 }
400
401 //=============================================================================
402 /*!
403  *  
404  */
405 //=============================================================================
406 istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
407 {
408   bool isOK = true;
409   int is;
410   double val;
411
412   isOK = static_cast<bool>(load >> val);
413   if (isOK)
414     _maxSize = val;
415   else
416     load.clear(ios::badbit | load.rdstate());
417
418   isOK = static_cast<bool>(load >> is);
419   if (isOK)
420     SetFineness((Fineness) is);
421   else
422     load.clear(ios::badbit | load.rdstate());
423
424   if (_fineness == UserDefined)
425   {
426     isOK = static_cast<bool>(load >> val);
427     if (isOK)
428       _growthRate = val;
429     else
430       load.clear(ios::badbit | load.rdstate());
431
432     isOK = static_cast<bool>(load >> val);
433     if (isOK)
434       _nbSegPerEdge = val;
435     else
436       load.clear(ios::badbit | load.rdstate());
437
438     isOK = static_cast<bool>(load >> val);
439     if (isOK)
440       _nbSegPerRadius = val;
441     else
442       load.clear(ios::badbit | load.rdstate());
443   }
444
445   isOK = static_cast<bool>(load >> is);
446   if (isOK)
447     _secondOrder = (bool) is;
448   else
449     load.clear(ios::badbit | load.rdstate());
450
451   isOK = static_cast<bool>(load >> is);
452   if (isOK)
453     _optimize = (bool) is;
454   else
455     load.clear(ios::badbit | load.rdstate());
456
457   std::string option_or_sm;
458   bool hasLocalSize = false;
459
460   isOK = static_cast<bool>(load >> option_or_sm);
461   if (isOK)
462     if (option_or_sm == "__LOCALSIZE_BEGIN__")
463       hasLocalSize = true;
464
465   std::string smEntry, smValue;
466   while (isOK && hasLocalSize) {
467     isOK = static_cast<bool>(load >> smEntry);
468     if (isOK) {
469       if (smEntry == "__LOCALSIZE_END__")
470         break;
471       isOK = static_cast<bool>(load >> smValue);
472     }
473     if (isOK) {
474       std::istringstream tmp(smValue);
475       double val;
476       tmp >> val;
477       _localSize[ smEntry ] = val;
478     }
479   }
480
481   if ( !hasLocalSize && !option_or_sm.empty() )
482     _minSize = atof( option_or_sm.c_str() );
483   else
484     load >> _minSize;
485
486   isOK = static_cast<bool>( load >> is );
487   if ( isOK )
488     _quadAllowed = (bool) is;
489   else
490     _quadAllowed = GetDefaultQuadAllowed();
491
492   isOK = static_cast<bool>( load >> is );
493   if ( isOK )
494     _surfaceCurvature = (bool) is;
495   else
496     _surfaceCurvature = GetDefaultSurfaceCurvature();
497
498   isOK = static_cast<bool>( load >> is );
499   if ( isOK )
500     _fuseEdges = (bool) is;
501   else
502     _fuseEdges = GetDefaultFuseEdges();
503
504   isOK = static_cast<bool>( load >> is >> std::ws ); // size of meshSizeFile
505   if ( isOK && is > 0 )
506   {
507     _meshSizeFile.resize( is );
508     load.get( &_meshSizeFile[0], is+1 );
509   }
510
511   isOK = static_cast<bool>(load >> val);
512   if (isOK)
513     _chordalError = val;
514   else
515     load.clear(ios::badbit | load.rdstate());
516   _chordalErrorEnabled = ( _chordalError > 0 );
517
518   return load;
519 }
520
521 //=============================================================================
522 /*!
523  *
524  */
525 //=============================================================================
526 ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
527 {
528   return hyp.SaveTo( save );
529 }
530
531 //=============================================================================
532 /*!
533  *
534  */
535 //=============================================================================
536 istream & operator >>(istream & load, NETGENPlugin_Hypothesis & hyp)
537 {
538   return hyp.LoadFrom( load );
539 }
540
541
542 //================================================================================
543 /*!
544  * \brief Does nothing
545  * \param theMesh - the built mesh
546  * \param theShape - the geometry of interest
547  * \retval bool - always false
548  */
549 //================================================================================
550 bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh*   theMesh,
551                                                   const TopoDS_Shape& theShape)
552 {
553   return false;
554 }
555
556 //================================================================================
557 /*!
558  * \brief Initialize my parameter values by default parameters.
559  *  \retval bool - true if parameter values have been successfully defined
560  */
561 //================================================================================
562
563 bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  dflts,
564                                                       const SMESH_Mesh* theMesh)
565 {
566   _nbSegPerEdge = dflts._nbSegments;
567   _maxSize      = dflts._elemLength;
568
569   if ( dflts._shape && !dflts._shape->IsNull() )
570     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize );
571   else if ( theMesh && theMesh->HasShapeToMesh() )
572     _minSize    = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize );
573
574   return _nbSegPerEdge && _maxSize > 0;
575 }
576
577 //=============================================================================
578 /*!
579  *  
580  */
581 //=============================================================================
582 double NETGENPlugin_Hypothesis::GetDefaultMaxSize()
583 {
584   return 1000;
585 }
586
587 //=============================================================================
588 /*!
589  *  
590  */
591 //=============================================================================
592 NETGENPlugin_Hypothesis::Fineness NETGENPlugin_Hypothesis::GetDefaultFineness()
593 {
594   return Moderate;
595 }
596
597 //=============================================================================
598 /*!
599  *  
600  */
601 //=============================================================================
602 double NETGENPlugin_Hypothesis::GetDefaultGrowthRate()
603 {
604   return 0.3;
605 }
606
607 //=============================================================================
608 /*!
609  *  
610  */
611 //=============================================================================
612 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge()
613 {
614   return 1;
615 }
616
617 //=============================================================================
618 /*!
619  *  
620  */
621 //=============================================================================
622 double NETGENPlugin_Hypothesis::GetDefaultNbSegPerRadius()
623 {
624   return 2;
625 }
626 //=============================================================================
627 /*!
628  *  
629  */
630 //=============================================================================
631 double NETGENPlugin_Hypothesis::GetDefaultChordalError()
632 {
633   return -1; // disabled by default
634 }
635
636 //=============================================================================
637 /*!
638  *  
639  */
640 //=============================================================================
641 bool NETGENPlugin_Hypothesis::GetDefaultSecondOrder()
642 {
643   return false;
644 }
645
646 //=============================================================================
647 /*!
648  *  
649  */
650 //=============================================================================
651 bool NETGENPlugin_Hypothesis::GetDefaultOptimize()
652 {
653   return true;
654 }