KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
refine_elements_on_size_mesher_process.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosDelaunayMeshingApplication $
3 // Created by: $Author: JMCarbonell $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: April 2018 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined( KRATOS_REFINE_ELEMENTS_ON_SIZE_MESHER_PROCESS_H_INCLUDED )
11 #define KRATOS_REFINE_ELEMENTS_ON_SIZE_MESHER_PROCESS_H_INCLUDED
12 
13 
14 // External includes
15 
16 // System includes
17 
18 // Project includes
21 
22 #include "includes/model_part.h"
25 
27 //Data:
28 //StepData: NODAL_H, CONTACT_FORCE
29 //Flags: (checked) TO_REFOME, BOUNDARY, NEW_ENTITY
30 // (set)
31 // (modified)
32 // (reset)
33 //(set):=(set in this process)
34 
35 namespace Kratos
36 {
37 
40 
42 
47  : public MesherProcess
48 {
49 public:
52 
55 
59 
63 
66  MesherUtilities::MeshingParameters& rRemeshingParameters,
67  int EchoLevel)
68  : mrModelPart(rModelPart),
69  mrRemesh(rRemeshingParameters)
70  {
71  mEchoLevel = EchoLevel;
72  }
73 
74 
77 
78 
82 
84  void operator()()
85  {
86  Execute();
87  }
88 
89 
93 
94 
96  void Execute() override
97  {
99 
100  if( mEchoLevel > 0 ){
101  std::cout<<" [ SELECT ELEMENTS TO REFINE : "<<std::endl;
102  //std::cout<<" refine selection "<<std::endl;
103  }
104 
105 
106  //***SIZES :::: parameters do define the tolerance in mesh size:
107  double size_for_inside_elements = 0.75 * mrRemesh.Refine->CriticalRadius;
108  double size_for_boundary_elements = 1.50 * mrRemesh.Refine->CriticalRadius;
109 
110  double nodal_h_refining_factor = 0.75;
111  double nodal_h_non_refining_factor = 2.00;
112 
113  ProcessInfo& CurrentProcessInfo = mrModelPart.GetProcessInfo();
114 
115  unsigned int refine_on_size = 0;
116  unsigned int refine_on_threshold = 0;
117 
118  int id = 0;
119  if(mrRemesh.Refine->RefiningOptions.Is(MesherUtilities::REFINE_ELEMENTS)
120  && mrRemesh.Refine->RefiningOptions.Is(MesherUtilities::REFINE_ADD_NODES) )
121  {
122 
123  ModelPart::ElementsContainerType::iterator element_begin = mrModelPart.ElementsBegin();
124 
125  unsigned int nds = (*element_begin).GetGeometry().size();
126 
127  MesherUtilities::MeshContainer& InMesh = mrRemesh.InMesh;
128 
129  InMesh.CreateElementList(mrRemesh.Info->NumberOfElements, nds); //number of preserved elements
130  InMesh.CreateElementSizeList(mrRemesh.Info->NumberOfElements);
131 
132  int& OutNumberOfElements = mrRemesh.OutMesh.GetNumberOfElements();
133 
134  int* InElementList = mrRemesh.InMesh.GetElementList();
135  double* InElementSizeList = mrRemesh.InMesh.GetElementSizeList();
136 
137  int* OutElementList = mrRemesh.OutMesh.GetElementList();
138 
139  ModelPart::NodesContainerType::iterator nodes_begin = mrModelPart.NodesBegin();
140 
141  //PREPARE THE NODAL_H as a variable to control the automatic point insertion
142  //**************************************************************************
143 
144  if(mrRemesh.Refine->RefiningOptions.IsNot(MesherUtilities::REFINE_BOUNDARY)){
145 
146  for(unsigned int i = 0; i<mrModelPart.Nodes().size(); i++)
147  {
149  // if ( (nodes_begin + i)->Is(FREE_SURFACE))
150  // {
151  // double & nodal_h=(nodes_begin + i)->FastGetSolutionStepValue(NODAL_H);
152  // nodal_h*=nodal_h_non_refining_factor;
153  // }
154 
155  //Assign a huge NODAL_H to the Boundary nodes, so that there no nodes will be added
156  if ( (nodes_begin + i)->Is(BOUNDARY))
157  {
158  double & nodal_h=(nodes_begin + i)->FastGetSolutionStepValue(NODAL_H);
159  nodal_h*=nodal_h_non_refining_factor;
160  }
161 
162 
163  }
164 
165  }
166 
167  //SET THE REFINED ELEMENTS AND THE AREA (NODAL_H)
168  //*********************************************************************
169  mrRemesh.Info->CriticalElements = 0;
170 
171  for(int el = 0; el< OutNumberOfElements; el++)
172  {
173  if(mrRemesh.PreservedElements[el])
174  {
175 
176  double prescribed_h = 0;
177  bool dissipative = false; //dissipative means reference threshold is overwhelmed
178  bool refine_size = false;
179 
180  unsigned int count_dissipative = 0;
181  unsigned int count_boundary_inserted = 0;
182  unsigned int count_boundary = 0;
183  unsigned int count_contact_boundary = 0;
184 
185  Geometry<Node > vertices;
186 
187  for(unsigned int pn=0; pn<nds; pn++)
188  {
189 
190  InElementList[id*nds+pn]= OutElementList[el*nds+pn];
191 
192  vertices.push_back(*(nodes_begin + OutElementList[el*nds+pn]-1).base());
193 
194  prescribed_h += (nodes_begin + OutElementList[el*nds+pn]-1)->FastGetSolutionStepValue(NODAL_H);
195 
196  if((nodes_begin + OutElementList[el*nds+pn]-1)->Is(TO_REFINE))
197  count_dissipative+=1;
198 
199  if((nodes_begin + OutElementList[el*nds+pn]-1)->Is(BOUNDARY)){
200 
201  count_boundary+=1;
202 
203  if((nodes_begin + OutElementList[el*nds+pn]-1)->Is(NEW_ENTITY))
204  count_boundary_inserted+=1;
205 
206 
207  if( (nodes_begin + OutElementList[el*nds+pn]-1)->SolutionStepsDataHas(CONTACT_FORCE) ){
208  array_1d<double, 3 > & ContactForceNormal = (nodes_begin + OutElementList[el*nds+pn]-1)->FastGetSolutionStepValue(CONTACT_FORCE);
209  if( norm_2(ContactForceNormal) )
210  count_contact_boundary+=1;
211  }
212 
213  }
214 
215  }
216 
217  // if(count_dissipative>0)
218  // std::cout<<" Count REFINE nodes "<<count_dissipative<<std::endl;
219  // std::cout<<" prescribed_h (el:"<<el<<") = "<<prescribed_h<<std::endl;
220 
221  bool refine_candidate = true;
222  if (mrRemesh.Refine->RefiningBoxSetFlag == true ){
223  refine_candidate = mMesherUtilities.CheckVerticesInBox(vertices,*(mrRemesh.Refine->RefiningBox),CurrentProcessInfo);
224  }
225 
226 
227 
228  double element_size = 0;
229  double element_radius = mMesherUtilities.CalculateElementRadius(vertices, element_size);
230 
231 
232  //calculate the prescribed h
233  prescribed_h *= 0.3333;
234 
235  double h = mrRemesh.AlphaParameter * prescribed_h;
236  double element_ideal_radius = 0;
237  if( nds == 3 ){ //if h is the height of a equilateral triangle, the area is sqrt(3)*h*h/4
238  element_ideal_radius = sqrt(3.0) * 0.25 * ( h * h );
239  }
240 
241  if( nds == 4 ){//if h is the height of a regular tetrahedron, the volume is h*h*h/(6*sqrt(2))
242  //element_ideal_radius = (27.0/16.0)* sqrt(1.0/108.0) * ( h * h* h );
243  element_ideal_radius = ( h * h * h )/( 6.0 * sqrt(2.0) );
244  }
245 
246 
247  //std::cout<<" prescribed_h (el:"<<el<<") = "<<prescribed_h<<std::endl;
248 
249  if( refine_candidate ){
250 
251 
252  //********* PLASTIC POWER ENERGY REFINEMENT CRITERION (A)
253  if(count_dissipative>=nds-1){
254  dissipative = true;
255  //Set Critical Elements
256  mrRemesh.Info->CriticalElements += 1;
257  //std::cout<<" Dissipative True "<<std::endl;
258  }
259 
260 
261  //********* SIZE REFINEMENT CRITERION (B)
262 
263  // if(dissipative)
264  // std::cout<<" element_radius "<<element_radius<<" CriticalRadius "<<size_for_inside_elements<<std::endl;
265 
266  double critical_size = size_for_inside_elements;
267  if(count_boundary>=nds-1)
268  critical_size = size_for_boundary_elements;
269 
270 
271  if( element_radius > critical_size ){
272  refine_size = true;
273  }
274 
275 
276  //Also a criteria for the CriticalDissipation (set in nodes)
277  if(mrRemesh.Refine->RefiningOptions.Is(MesherUtilities::REFINE_ELEMENTS_ON_THRESHOLD)
278  && mrRemesh.Refine->RefiningOptions.Is(MesherUtilities::REFINE_ELEMENTS_ON_DISTANCE))
279  {
280  // if( dissipative )
281  // std::cout<<" [ Refine Criteria ["<<id<<"] : (dissipative: "<<dissipative<<"; size: "<<refine_size<<"; prescribed h: "<<prescribed_h<<") ]"<<std::endl;
282 
283 
284  //********* THRESHOLD REFINEMENT CRITERION (A)
285  if( (dissipative == true && refine_size == true) )
286  {
287  InElementSizeList[id] = nodal_h_refining_factor * element_size;
288 
289  refine_on_threshold += 1;
290  //std::cout<<" Area Factor Refine DISSIPATIVE :"<<InElementSizeList[id]<<std::endl;
291  }
292  else if (refine_size == true)
293  {
294 
295 
296  InElementSizeList[id] = element_ideal_radius;
297 
298  if( count_boundary_inserted && count_contact_boundary){
299 
300  InElementSizeList[id] = nodal_h_refining_factor * element_ideal_radius;
301 
302  std::cout<<" count boundary inserted-contact on "<<std::endl;
303  }
304 
305  refine_on_size +=1;
306  //std::cout<<" Area Factor Refine SIZE :"<<InElementSizeList[id]<<std::endl;
307 
308  }
309  else{
310 
311  InElementSizeList[id] = nodal_h_non_refining_factor * element_size;
312  //std::cout<<" Area Factor Refine NO :"<<InElementSizeList[id]<<std::endl;
313  }
314 
315 
316  //std::cout<<" [ AREA: "<<Area<<"; NEW AREA: "<<InElementSizeList[id]<<" ]"<<std::endl;
317  }
318  else if(mrRemesh.Refine->RefiningOptions.Is(MesherUtilities::REFINE_ELEMENTS_ON_DISTANCE))
319  {
320 
321  //********* SIZE REFINEMENT CRITERION (B)
322  if( refine_size == true ){
323 
324  InElementSizeList[id] = nodal_h_refining_factor * element_ideal_radius;
325  }
326  else{
327 
328  //InElementSizeList[id] = element_size;
329  InElementSizeList[id] = element_ideal_radius;
330  }
331 
332  }
333  else{
334 
335  //InElementSizeList[id] = element_ideal_radius;
336  InElementSizeList[id] = nodal_h_non_refining_factor * element_size;
337 
338  }
339 
340 
341  //std::cout<<" mod_prescribed_h (el:"<<el<<") = "<<prescribed_h<<" [ Triangle Area: "<<InElementSizeList[id]<<" ]"<<std::endl;
342 
343  }
344  else{
345 
346  //InElementSizeList[id] = element_ideal_radius;
347  InElementSizeList[id] = nodal_h_non_refining_factor * element_size;
348 
349  }
350 
351 
352  id += 1;
353 
354  }
355 
356 
357 
358  }
359 
360 
361 
362  //RESTORE THE NODAL_H ON BOUNDARY
363  //*********************************************************************
364  if(mrRemesh.Refine->RefiningOptions.IsNot(MesherUtilities::REFINE_BOUNDARY)){
365 
366  for(unsigned int i = 0; i<mrModelPart.Nodes().size(); i++)
367  {
368  // //Unassign the NODAL_H of the free surface nodes
369  // if ( (nodes_begin + i)->Is(FREE_SURFACE))
370  // {
371  // double & nodal_h=(nodes_begin + i)->FastGetSolutionStepValue(NODAL_H);
372  // nodal_h/=nodal_h_non_refining_factor;
373  // }
374 
375  //Unassign the NODAL_H of the Boundary nodes
376  if ( (nodes_begin + i)->Is(BOUNDARY))
377  {
378  double & nodal_h=(nodes_begin + i)->FastGetSolutionStepValue(NODAL_H);
379  nodal_h/=nodal_h_non_refining_factor;
380  }
381 
382 
383  }
384  }
385  }
386  else{
387 
388  ModelPart::ElementsContainerType::iterator element_begin = mrModelPart.ElementsBegin();
389 
390  unsigned int nds = (*element_begin).GetGeometry().size();
391 
392  MesherUtilities::MeshContainer& InMesh = mrRemesh.InMesh;
393 
394  InMesh.CreateElementList(mrRemesh.Info->NumberOfElements, nds); //number of preserved elements
395  InMesh.CreateElementSizeList(mrRemesh.Info->NumberOfElements);
396 
397  int& OutNumberOfElements = mrRemesh.OutMesh.GetNumberOfElements();
398 
399  int* InElementList = mrRemesh.InMesh.GetElementList();
400  double* InElementSizeList = mrRemesh.InMesh.GetElementSizeList();
401 
402  int* OutElementList = mrRemesh.OutMesh.GetElementList();
403 
404 
405  ModelPart::NodesContainerType::iterator nodes_begin = mrModelPart.NodesBegin();
406 
407  for(int el = 0; el< OutNumberOfElements; el++)
408  {
409  if(mrRemesh.PreservedElements[el])
410  {
411  Geometry<Node > vertices;
412  for(unsigned int pn=0; pn<nds; pn++)
413  {
414 
415  InElementList[id*nds+pn]= OutElementList[el*nds+pn];
416  vertices.push_back(*(nodes_begin + OutElementList[el*nds+pn]-1).base());
417  }
418 
419  double element_size = 0;
420  mMesherUtilities.CalculateElementRadius(vertices, element_size);
421 
422  InElementSizeList[id] = nodal_h_non_refining_factor * element_size;
423 
424  id++;
425  }
426 
427  }
428 
429  }
430 
431 
432  if( mEchoLevel > 0 ){
433  std::cout<<" Visited Elements: "<<id<<" [threshold:"<<refine_on_threshold<<"/size:"<<refine_on_size<<"]"<<std::endl;
434  std::cout<<" SELECT ELEMENTS TO REFINE ]; "<<std::endl;
435  }
436 
437 
438  KRATOS_CATCH(" ")
439  }
440 
441 
445 
446 
450 
451 
455 
457  std::string Info() const override
458  {
459  return "RefineElementsOnSizeMesherProcess";
460  }
461 
463  void PrintInfo(std::ostream& rOStream) const override
464  {
465  rOStream << "RefineElementsOnSizeMesherProcess";
466  }
467 
469  void PrintData(std::ostream& rOStream) const override
470  {
471  }
472 
473 
477 
479 
480 
481 private:
484 
488  ModelPart& mrModelPart;
489 
491 
492  MesherUtilities mMesherUtilities;
493 
494  int mEchoLevel;
495 
499 
501 
502 
503 
506 
507 
509 
510 
512  //Process(Process const& rOther);
513 
514 
516 
517 }; // Class Process
518 
520 
523 
524 
528 
529 
531 inline std::istream& operator >> (std::istream& rIStream,
533 
535 inline std::ostream& operator << (std::ostream& rOStream,
537 {
538  rThis.PrintInfo(rOStream);
539  rOStream << std::endl;
540  rThis.PrintData(rOStream);
541 
542  return rOStream;
543 }
545 
546 
547 } // namespace Kratos.
548 
549 #endif // KRATOS_REFINE_ELEMENTS_ON_SIZE_MEHSER_PROCESS_H_INCLUDED defined
550 
Base class for all Conditions.
Definition: condition.h:59
bool Is(Flags const &rOther) const
Definition: flags.h:274
Geometry base class.
Definition: geometry.h:71
void push_back(PointPointerType x)
Definition: geometry.h:548
The base class for processes passed to the solution scheme.
Definition: mesher_process.hpp:37
Short class definition.
Definition: mesher_utilities.hpp:49
static double CalculateElementRadius(Geometry< Node > &rGeometry)
Definition: mesher_utilities.hpp:1142
bool CheckVerticesInBox(Geometry< Node > &rGeometry, SpatialBoundingBox &rRefiningBox, ProcessInfo &rCurrentProcessInfo)
Definition: mesher_utilities.cpp:1615
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
Refine Mesh Elements Process 2D and 3D.
Definition: refine_elements_on_size_mesher_process.hpp:48
RefineElementsOnSizeMesherProcess(ModelPart &rModelPart, MesherUtilities::MeshingParameters &rRemeshingParameters, int EchoLevel)
Default constructor.
Definition: refine_elements_on_size_mesher_process.hpp:65
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: refine_elements_on_size_mesher_process.hpp:96
ModelPart::PropertiesType PropertiesType
Definition: refine_elements_on_size_mesher_process.hpp:57
std::string Info() const override
Turn back information as a string.
Definition: refine_elements_on_size_mesher_process.hpp:457
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: refine_elements_on_size_mesher_process.hpp:463
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: refine_elements_on_size_mesher_process.hpp:469
ConditionType::GeometryType GeometryType
Definition: refine_elements_on_size_mesher_process.hpp:58
ModelPart::ConditionType ConditionType
Definition: refine_elements_on_size_mesher_process.hpp:56
KRATOS_CLASS_POINTER_DEFINITION(RefineElementsOnSizeMesherProcess)
Pointer definition of Process.
void operator()()
This operator is provided to call the process as a function and simply calls the Execute method.
Definition: refine_elements_on_size_mesher_process.hpp:84
virtual ~RefineElementsOnSizeMesherProcess()
Destructor.
Definition: refine_elements_on_size_mesher_process.hpp:76
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
h
Definition: generate_droplet_dynamics.py:91
pn
Definition: generate_droplet_dynamics.py:65
el
Definition: read_stl.py:25
integer i
Definition: TensorModule.f:17
Definition: mesher_utilities.hpp:149
void CreateElementSizeList(const unsigned int NumberOfElements)
Definition: mesher_utilities.hpp:207
int * GetElementList()
Definition: mesher_utilities.hpp:178
void CreateElementList(const unsigned int NumberOfElements, const unsigned int NumberOfVertices)
Definition: mesher_utilities.hpp:196
int & GetNumberOfElements()
Definition: mesher_utilities.hpp:183
double * GetElementSizeList()
Definition: mesher_utilities.hpp:179
Definition: mesher_utilities.hpp:631
MeshingInfoParameters::Pointer Info
Definition: mesher_utilities.hpp:681
std::vector< int > PreservedElements
Definition: mesher_utilities.hpp:669
RefiningParameters::Pointer Refine
Definition: mesher_utilities.hpp:684
MeshContainer InMesh
Definition: mesher_utilities.hpp:674
MeshContainer OutMesh
Definition: mesher_utilities.hpp:675
double AlphaParameter
Definition: mesher_utilities.hpp:651