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.
trilinos_refine_mesh.h
Go to the documentation of this file.
1 
4 
5 // Project Name: Kratos
6 // Last Modified by: $Author: Nelson $
7 // Date: $Date: 2010-05-12 $
8 // Revision: $Revision: 1.0 $
9 //
10 //
11 
12 #if !defined(KRATOS_TRILINOS_LOCAL_REFINE_SIMPLEX_MESH)
13 #define KRATOS_TRILINOS_LOCAL_REFINE_SIMPLEX_MESH
14 
15 // System includes
16 
17 /* Project includes */
19 #include "utilities/math_utils.h"
26 #include "Epetra_Vector.h"
27 #include "Epetra_Map.h"
28 #include "Epetra_SerialDenseMatrix.h"
29 #include "Epetra_MpiComm.h"
30 #include "Epetra_FECrsGraph.h"
31 #include "Epetra_FECrsMatrix.h"
32 #include "Epetra_Import.h"
33 #include "Epetra_MpiComm.h"
34 
35 
36 
37 namespace Kratos
38 {
42 
44 {
45 public:
46 
50  typedef vector<Matrix> Matrix_Order_Tensor;
51  typedef vector<Vector> Vector_Order_Tensor;
52  typedef vector<Vector_Order_Tensor> Node_Vector_Order_Tensor;
53  typedef Node PointType;
54  typedef Node ::Pointer PointPointerType;
55  typedef std::vector<PointType::Pointer> PointVector;
56  typedef PointVector::iterator PointIterator;
57 
64  {
65  }
66 
68  {
69  }
70 
71 
74 
92  void Local_Refine_Mesh(bool refine_on_reference, bool interpolate_internal_variables, int domain_size)
93  {
95 
96  if (refine_on_reference == true)
97  if (!(mr_model_part.NodesBegin()->SolutionStepsDataHas(DISPLACEMENT)))
98  KRATOS_ERROR << "DISPLACEMENT Variable is not in the model part -- needed if refine_on_reference = true" << std::endl;
99 
100  if (!(mr_model_part.NodesBegin()->SolutionStepsDataHas(PARTITION_INDEX)))
101  KRATOS_ERROR << "PARTITION_INDEX Variable is not in the model part -- mpi not possible" << std::endl;
102 
103  Kratos::shared_ptr<Epetra_FECrsMatrix> p_edge_ids; //helper matrix to assign ids to the edges to be refined
104  Kratos::shared_ptr<Epetra_FECrsMatrix> p_partition_ids; //helper matrix to assign a partition to the edges
105  vector<int> List_New_Nodes;
106  vector<int> partition_new_nodes;
107  vector<array_1d<int, 2 > > father_node_ids;
108  vector< array_1d<double, 3 > > Coordinate_New_Node;
109 
110  PointerVector< Element > New_Elements;
111  PointerVector< Condition > New_Conditions;
112  if (refine_on_reference == true)
113  {
114  for (ModelPart::NodesContainerType::iterator it = mr_model_part.NodesBegin(); it != mr_model_part.NodesEnd(); it++)
115  {
116  it->X() = it->X0();
117  it->Y() = it->Y0();
118  it->Z() = it->Z0();
119  }
120  }
121 
122  if (mrComm.MyPID() == 0) std::cout << "beginning the refinement" << std::endl;
123 
124  CSR_Row_Matrix(mr_model_part, p_edge_ids);
125  if (mrComm.MyPID() == 0) std::cout << "index matrix constructed" << std::endl;
126 
127  Search_Edge_To_Be_Refined(mr_model_part, p_edge_ids, p_partition_ids);
128  if (mrComm.MyPID() == 0) std::cout << "Search_Edge_To_Be_Refined completed" << std::endl;
129 
130  Create_List_Of_New_Nodes(mr_model_part, p_edge_ids, p_partition_ids, List_New_Nodes, partition_new_nodes, father_node_ids);
131  if (mrComm.MyPID() == 0) std::cout << "Create_List_Of_New_Nodes completed" << std::endl;
132 
133  Calculate_Coordinate_And_Insert_New_Nodes(mr_model_part, father_node_ids, List_New_Nodes, partition_new_nodes);
134  if (mrComm.MyPID() == 0) std::cout << "Calculate_Coordinate_And_Insert_New_Nodes completed" << std::endl;
135 
136  if (domain_size == 2)
137  Erase_Old_Element_And_Create_New_Triangle_Element(mr_model_part, p_edge_ids, New_Elements, interpolate_internal_variables);
138  else if (domain_size == 3)
139  {
140  Erase_Old_Element_And_Create_New_Tetra_Element(mr_model_part, p_edge_ids, New_Elements, interpolate_internal_variables);
141  Erase_Old_Condition_And_Create_New_Triangle_Conditions(mr_model_part, p_edge_ids, New_Conditions, interpolate_internal_variables);
142  }
143  else
144  KRATOS_THROW_ERROR(std::logic_error, "domain size can be either 2 or 3!", "");
145 
146 
147  if (mrComm.MyPID() == 0) std::cout << "Erase_Old_Element_And_Create_New completed" << std::endl;
148 
149 
150  Renumbering_Elements(mr_model_part, New_Elements);
151  Renumbering_Conditions(mr_model_part, New_Conditions);
152  if (mrComm.MyPID() == 0) std::cout << "Renumbering completed" << std::endl;
153 
154 
155 
156 
157 
158 
159  if (refine_on_reference == true)
160  {
161  for (ModelPart::NodesContainerType::iterator it = mr_model_part.NodesBegin(); it != mr_model_part.NodesEnd(); it++)
162  {
163  const array_1d<double, 3 > & disp = it->FastGetSolutionStepValue(DISPLACEMENT);
164  it->X() = it->X0() + disp[0];
165  it->Y() = it->Y0() + disp[1];
166  it->Z() = it->Z0() + disp[2];
167  }
168  }
169 
170  //fill the communicator
172  if (mrComm.MyPID() == 0) std::cout << "recalculation of communication plan completed" << std::endl;
173 
174  //clean up the data
175  Clear();
176 
177  KRATOS_CATCH("")
178  }
183 
185  {
186  KRATOS_TRY
187 
188  //print ghost mesh
189  std::cout << "proc = " << mrComm.MyPID() << "ghost mesh nodes" << std::endl;
190  for (ModelPart::NodesContainerType::iterator it = mr_model_part.GetCommunicator().GhostMesh().NodesBegin();
192  it++)
193  std::cout << it->Id() << " " << it->Coordinates() << std::endl;
194 
195  KRATOS_CATCH("");
196 
197  }
198 
200  void Clear()
201  {
202  KRATOS_TRY
204  empty_map.swap(mp_non_overlapping_map);
205 
207 
209  mp_non_overlapping_graph.swap(empty1);
210 
212  mp_overlapping_graph.swap(empty2);
213 
214 
215  KRATOS_CATCH("");
216  }
217 
218 
219 
224 
226  ModelPart& this_model_part,
228  {
229  KRATOS_TRY
230 
231  //generate a map with the ids of the nodes
232  int nlocal_nodes = this_model_part.GetCommunicator().LocalMesh().Nodes().size();
233  int *local_ids = new int[nlocal_nodes];
234  int k = 0;
235  for (ModelPart::NodesContainerType::iterator it = this_model_part.GetCommunicator().LocalMesh().NodesBegin(); it != this_model_part.GetCommunicator().LocalMesh().NodesEnd(); it++)
236  {
237  local_ids[k++] = it->Id() - 1;
238  }
239 
240  Kratos::shared_ptr<Epetra_Map> pmy_map = Kratos::make_shared<Epetra_Map>(-1, nlocal_nodes, local_ids, 0, mrComm);
241  mp_non_overlapping_map.swap(pmy_map);
242  delete [] local_ids;
243 
244  //now create a matrix that has overlapping elements ... that is both local and ghosts
245  //generate a map with the ids of the nodes
246  int nnodes = this_model_part.Nodes().size();
247  int *ids = new int[nnodes];
248  k = 0;
249  for (ModelPart::NodesContainerType::iterator it = this_model_part.NodesBegin(); it != this_model_part.NodesEnd(); it++)
250  {
251  ids[k++] = it->Id() - 1;
252  }
253 
254  Kratos::shared_ptr<Epetra_Map> pmy_ov_map = Kratos::make_shared<Epetra_Map>(-1, nnodes, ids, 0, mrComm);
255  mp_overlapping_map.swap(pmy_ov_map);
256  delete [] ids;
257 
258  //generate the graph
259  int guess_row_size = 20;
260  Kratos::shared_ptr<Epetra_FECrsGraph > aux_non_overlapping_graph = Kratos::make_shared<Epetra_FECrsGraph>(Copy, *mp_non_overlapping_map, guess_row_size);
261  aux_non_overlapping_graph.swap(mp_non_overlapping_graph);
262  // Epetra_FECrsGraph Agraph(Copy, *mp_non_overlapping_map, guess_row_size);
263 
264  int aux_ids[4]; //this works both for 2d and 3d
265  for (ModelPart::ElementsContainerType::iterator it = this_model_part.ElementsBegin(); it != this_model_part.ElementsEnd(); it++)
266  {
267  Geometry<Node >& geom = it->GetGeometry();
268  for (unsigned int i = 0; i < geom.size(); i++)
269  aux_ids[i] = geom[i].Id() - 1;
270 
271  int ierr = mp_non_overlapping_graph->InsertGlobalIndices(geom.size(), aux_ids, geom.size(), aux_ids);
272  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
273  }
274  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.ConditionsBegin(); it != this_model_part.ConditionsEnd(); it++)
275  {
276  Geometry<Node >& geom = it->GetGeometry();
277  for (unsigned int i = 0; i < geom.size(); i++)
278  aux_ids[i] = geom[i].Id() - 1;
279 
280  int ierr = mp_non_overlapping_graph->InsertGlobalIndices(geom.size(), aux_ids, geom.size(), aux_ids);
281  if (ierr < 0) KRATOS_THROW_ERROR(std::logic_error, "epetra failure ->ln 183", "");
282  }
283  mp_non_overlapping_graph->GlobalAssemble();
284 
285 
286 
287  //fill the edge_matrix
288  Kratos::shared_ptr<Epetra_FECrsMatrix> pA = Kratos::make_shared<Epetra_FECrsMatrix>(Copy, *mp_non_overlapping_graph);
289  pA->PutScalar(-1.0);
290 
291  pA.swap(p_edge_ids);
292 
293 
294  KRATOS_CATCH("")
295 
296  }
297 
302 
304  ModelPart& this_model_part,
307  {
308  KRATOS_TRY
309  ElementsArrayType& rElements = this_model_part.Elements();
310 
311  Kratos::shared_ptr<Epetra_FECrsMatrix> p_nonoverlapping_partitions
312  = Kratos::make_shared<Epetra_FECrsMatrix>(Copy, *mp_non_overlapping_graph);
313  p_nonoverlapping_partitions->PutScalar(-1.0);
314 
315  double this_partition_index = double(mrComm.MyPID());
316  // KRATOS_THROW_ERROR(std::logic_error,"aaaaaaaaaaa","")
317 
318  //first of all create a matrix with no overlap
319  ElementsArrayType::iterator it_begin = rElements.ptr_begin(); //+element_partition[k];
320  ElementsArrayType::iterator it_end = rElements.ptr_end(); //+element_partition[k+1];
321  for (ElementsArrayType::iterator it = it_begin; it != it_end; ++it)
322  {
323  //unsigned int level = it->GetValue(REFINEMENT_LEVEL);
324  if (it->GetValue(SPLIT_ELEMENT) == true)
325  {
326  Element::GeometryType& geom = it->GetGeometry(); // Nodos del elemento
327  for (unsigned int i = 0; i < geom.size(); i++)
328  {
329  int index_i = geom[i].Id() - 1;
330  for (unsigned int j = 0; j < geom.size(); j++)
331  {
332  int index_j = geom[j].Id() - 1;
333  double value = -1.0;
334  if (index_j > index_i)
335  {
336  int ierr = p_edge_ids->SumIntoGlobalValues(1, &index_i, 1, &index_j, &value);
337  if (ierr < 0) KRATOS_THROW_ERROR(std::logic_error, "epetra failure --> ln 235", "");
338  ierr = p_nonoverlapping_partitions->ReplaceGlobalValues(1, &index_i, 1, &index_j, &this_partition_index);
339  if (ierr < 0) KRATOS_THROW_ERROR(std::logic_error, "epetra failure --> ln 237", "");
340  // Coord(index_i, index_j) = -2;
341  }
342  }
343  }
344  }
345  }
346  int ierr = -1;
347  ierr = p_edge_ids->GlobalAssemble(true, Add);
348  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
349 
350  ierr = p_nonoverlapping_partitions->GlobalAssemble(true, Insert);
351  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
352 
353  //import the non overlapping matrix into the overlapping one
354  int MaxNumEntries = p_edge_ids->MaxNumEntries() + 5;
355  Epetra_Import importer(*mp_overlapping_map, *mp_non_overlapping_map);
356 
357  Kratos::shared_ptr<Epetra_FECrsMatrix> pAoverlap = Kratos::make_shared<Epetra_FECrsMatrix>(Copy, *mp_overlapping_map, MaxNumEntries);
358  Kratos::shared_ptr<Epetra_FECrsMatrix> paux = Kratos::make_shared<Epetra_FECrsMatrix>(Copy, *mp_overlapping_map, MaxNumEntries);
359 
360  ierr = pAoverlap->Import(*p_edge_ids, importer, Insert);
361  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
362  ierr = pAoverlap->FillComplete();
363  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
364 
365  ierr = paux->Import(*p_nonoverlapping_partitions, importer, Insert);
366  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
367  ierr = paux->FillComplete();
368  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
369 
370  //perform a pointer swap - after this we have overlapping matrices with the values syncronized
371  pAoverlap.swap(p_edge_ids);
372  paux.swap(p_partition_ids);
373 
374  //sace the overlapping graph
375  Kratos::shared_ptr<Epetra_CrsGraph > pg = Kratos::make_shared<Epetra_CrsGraph>(p_edge_ids->Graph());
376  mp_overlapping_graph.swap(pg);
377 
378  KRATOS_CATCH("")
379  }
380 
385 
386  void Create_List_Of_New_Nodes(ModelPart& this_model_part,
389  vector<int> &List_New_Nodes,
390  vector<int> &partition_new_nodes,
391  vector<array_1d<int, 2 > >& father_node_ids)
392  {
393  KRATOS_TRY
394  //here we count the new nodes on the local mesh
395  int NumMyRows = p_edge_ids->NumMyRows();
396  int Row; // iterator on rows
397  int Col; // iterator on cols
398  int MaxNumEntries = p_edge_ids->MaxNumEntries();
399  double * id_values = new double[MaxNumEntries];
400  double * partition_values = new double[MaxNumEntries];
401  int * Indices = new int[MaxNumEntries];
402  int NumEntries;
403  int GlobalRow;
404 
405  int n_owned_nonzeros = 0;
406  int n_new_nonzeros = 0; //this are the nonzeros owned or not, but that must be known
407  double this_partition_index = mrComm.MyPID();
408 
409  for (Row = 0; Row < NumMyRows; ++Row)
410  {
411  GlobalRow = p_edge_ids->GRID(Row);
412  int ierr = p_edge_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, NumEntries, id_values, Indices);
413  if (ierr < 0) KRATOS_THROW_ERROR(std::logic_error, "epetra failure", "");
414 
415  ierr = p_partition_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, NumEntries, partition_values, Indices);
416  if (ierr < 0) KRATOS_THROW_ERROR(std::logic_error, "epetra failure", "");
417 
418  for (Col = 0; Col != NumEntries; Col++)
419  {
420  if (Indices[Col] > Row)
421  if (id_values[Col] < -1.5 && mp_overlapping_map->MyGID(Indices[Col]) == true)
422  {
423  n_new_nonzeros = n_new_nonzeros + 1;
424  if (partition_values[Col] == this_partition_index)
425  n_owned_nonzeros = n_owned_nonzeros + 1;
426  }
427 
428  }
429  }
430  //use the scan sum
431  int nodes_before = -1;
432  mrComm.ScanSum(&n_owned_nonzeros, &nodes_before, 1);
433  nodes_before = nodes_before - n_owned_nonzeros;
434  if (nodes_before < 0)
435  KRATOS_THROW_ERROR(std::logic_error, "problem with scan sum ... giving a negative number of nodes before", "")
436 
437  //find our the total number of nodes
438  int number_of_local_nodes = this_model_part.GetCommunicator().LocalMesh().Nodes().size();
439  int total_number_of_nodes = -1;
440  mrComm.SumAll(&number_of_local_nodes, &total_number_of_nodes, 1);
441 
442 // int counter=0;
443 // for(ModelPart::NodesContainerType::iterator iii=this_model_part.NodesBegin(); iii!=this_model_part.NodesEnd(); iii++)
444 // if(iii->FastGetSolutionStepValue(PARTITION_INDEX)==mrComm.MyPID())
445 // counter++;
446 //
447 // if(counter!=number_of_local_nodes )
448 // KRATOS_THROW_ERROR(std::logic_error,"local mesh is not up to date!","");
449 
450  mtotal_number_of_existing_nodes = total_number_of_nodes;
451 
452 //for(ModelPart::NodesContainerType::iterator iii=this_model_part.NodesBegin(); iii!=this_model_part.NodesEnd(); iii++)
453 // if(iii->Id() > mtotal_number_of_existing_nodes)
454 // KRATOS_THROW_ERROR(std::logic_error,"node ids are not contiguous","");
455 
456 
457  //the ids of the new nodes we will create AND OWN will be between
458  //start_id and end_id;
459  //non local nodes may have ids out of this limits
460  int start_id = total_number_of_nodes + nodes_before + 1;
461  int end_id = start_id + n_owned_nonzeros;
462 
463  //now distribute the ids of the new nodes so that they will be the same over all of the processors.
464  Kratos::shared_ptr<Epetra_FECrsMatrix> plocal_ids = Kratos::make_shared<Epetra_FECrsMatrix>(Copy, *mp_non_overlapping_graph);
465  plocal_ids->PutScalar(-1);
466 
467  int id = start_id;
468  // Epetra_FECrsGraph Agraph(Copy, *mp_non_overlapping_map, MaxNumEntries);
469  for (Row = 0; Row < NumMyRows; ++Row)
470  {
471  GlobalRow = p_edge_ids->GRID(Row);
472 
473  int ierr = p_edge_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, NumEntries, id_values, Indices);
474  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
475 
476  ierr = p_partition_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, NumEntries, partition_values, Indices);
477  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
478 
479  for (Col = 0; Col < NumEntries; ++Col)
480  {
481  if (Indices[Col] > Row)
482  if (id_values[Col] < -1.5 &&
483  partition_values[Col] == this_partition_index &&
484  mp_overlapping_map->MyGID(Indices[Col]) == true)
485  {
486  double did = double(id);
487  plocal_ids->ReplaceGlobalValues(1, &GlobalRow, 1, &(Indices[Col]), &did);
488  id++;
489  }
490  }
491  }
492  plocal_ids->GlobalAssemble(true, Insert);
493 
494  KRATOS_ERROR_IF(id != end_id) << "the own node count is not verified...some error occurred" << std::endl;
495  //now import the non local elements
496  Epetra_Import importer(*mp_overlapping_map, *mp_non_overlapping_map);
497 
498  int ierr = p_edge_ids->Import(*plocal_ids, importer, Insert);
499  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
500  p_edge_ids->FillComplete();
501 
502 
504  List_New_Nodes.resize(n_new_nonzeros);
505  partition_new_nodes.resize(n_new_nonzeros);
506  father_node_ids.resize(n_new_nonzeros);
507 
508 
509 
510  int k = 0;
511  for (Row = 0; Row < NumMyRows; ++Row)
512  {
513  GlobalRow = p_edge_ids->GRID(Row);
514  int num_id_entries = -1;
515  int ierr = p_edge_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, num_id_entries, id_values, Indices);
516  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
517 
518  ierr = p_partition_ids->ExtractGlobalRowCopy(GlobalRow, MaxNumEntries, NumEntries, partition_values, Indices);
519  KRATOS_ERROR_IF(ierr < 0) << "epetra failure in line" << __LINE__ << std::endl;
520 
521  KRATOS_ERROR_IF(NumEntries != num_id_entries) << "we should have the same number of new_ids and of partition_values" << std::endl;
522  for (Col = 0; Col < NumEntries; ++Col)
523  {
524  if (Indices[Col] > Row)
525  {
526  //nodes are to be created only if they are identified by a positive ID
527  //AND if they both appear in the overlapping map for the current processor
528  if (id_values[Col] >= 0 && mp_overlapping_map->MyGID(Indices[Col]) == true)
529  {
530 //if(this_model_part.Nodes().find(id_values[Col])!=this_model_part.Nodes().end())
531 // KRATOS_THROW_ERROR(std::logic_error,"node already existing","");
532 
533  List_New_Nodes[k] = id_values[Col];
534  partition_new_nodes[k] = partition_values[Col];
535 
536  father_node_ids[k][0] = GlobalRow + 1;
537  father_node_ids[k][1] = Indices[Col] + 1; //+1;
538 
539  k++;
540  }
541  if (id_values[Col] < -1.5) //at this point every edge to be refined should have an Id!!
542  KRATOS_ERROR << "edge to be refined without id assigned" << std::endl;
543  }
544  }
545  }
546  KRATOS_ERROR_IF(k != int(n_new_nonzeros)) << "number of new nodes check failed" << std::endl;
547 
548 
549  delete [] Indices;
550  delete [] id_values;
551  delete [] partition_values;
552 
553  KRATOS_CATCH("")
554 
555  }
556 
559  // insert the news nodes in the model part and interopolate the variables
560 
562  const vector<array_1d<int, 2 > >& father_node_ids,
563  const vector<int> &List_New_Nodes,
564  const vector<int> &partition_new_nodes)
565  {
566  KRATOS_TRY
567  array_1d<double, 3 > Coord_Node_1;
568  array_1d<double, 3 > Coord_Node_2;
569  vector< array_1d<double, 3 > > Coordinate_New_Node;
570  Coordinate_New_Node.resize(father_node_ids.size());
571  unsigned int step_data_size = this_model_part.GetNodalSolutionStepDataSize();
572  Node ::DofsContainerType& reference_dofs = (this_model_part.NodesBegin())->GetDofs();
573 
574  //check that all of the nodes have the same number of dofs
575  for (ModelPart::NodesContainerType::iterator it = this_model_part.NodesBegin(); it != this_model_part.NodesEnd(); it++)
576  if ((it->GetDofs()).size() != reference_dofs.size())
577  {
578  std::cout << "reference_dof_list" << *(this_model_part.NodesBegin()) << std::endl;
579  std::cout << "inconsistent dof list found" << *it << std::endl;
580  KRATOS_THROW_ERROR(std::logic_error, "list of dofs is not the same on all of the nodes!", "")
581  }
582 
583  PointerVector< Node > new_nodes;
584 
585  for (unsigned int i = 0; i < father_node_ids.size(); i++)
586  {
588 
589  //getting father node 1
590  const int& node_i = father_node_ids[i][0];
591  const int& node_j = father_node_ids[i][1];
592  ModelPart::NodesContainerType::iterator it_node1 = this_model_part.Nodes().find(node_i);
593  if (it_node1 == this_model_part.NodesEnd())
594  {
595  std::cout << "- father node 1 - looking for Id " << node_i << " " << node_j << std::endl;
596  KRATOS_THROW_ERROR(std::logic_error, "error inexisting node", "")
597  }
598  std::size_t pos1 = it_node1 - this_model_part.NodesBegin();
599  noalias(Coord_Node_1) = it_node1->Coordinates();
600 
601  //getting father node 2
602  ModelPart::NodesContainerType::iterator it_node2 = this_model_part.Nodes().find(node_j);
603  if (it_node2 == this_model_part.NodesEnd())
604  {
605  std::cout << "- father node 2 - looking for Id " << node_i << " " << node_j << std::endl;
606  KRATOS_THROW_ERROR(std::logic_error, "error inexisting node", "")
607  }
608  std::size_t pos2 = it_node2 - this_model_part.NodesBegin();
609  noalias(Coord_Node_2) = it_node2->Coordinates();
610 
611 
612  noalias(Coordinate_New_Node[i]) = 0.50 * (Coord_Node_1 + Coord_Node_2);
614 
615 // if(this_model_part.Nodes().find(List_New_Nodes[i]) != this_model_part.Nodes().end())
616 // {
617 // cout << this_model_part.Nodes().find(List_New_Nodes[i])->Id() << " " << this_model_part.Nodes().find(List_New_Nodes[i])->Coordinates() << "new coords " << Coordinate_New_Node[i] ;
618 // cout << "position_found = " << this_model_part.Nodes().find(List_New_Nodes[i]) - this_model_part.Nodes().begin() << " number of existing nodes " << this_model_part.Nodes().size();
619 // cout << "last id in model_part = " << (this_model_part.Nodes().end()-1)->Id() << "problematic Id() = " << List_New_Nodes[i] << endl;
620 // KRATOS_THROW_ERROR(std::logic_error,"attempting to create a duplicated node","")
621 // }
622 
623 
624  // Node ::Pointer pnode = this_model_part.CreateNewNode(List_New_Nodes[i], Coordinate_New_Node[i][0], Coordinate_New_Node[i][1], Coordinate_New_Node[i][2]);
625  Node ::Pointer pnode = AuxCreateNewNode(this_model_part, List_New_Nodes[i], Coordinate_New_Node[i][0], Coordinate_New_Node[i][1], Coordinate_New_Node[i][2]);
626  new_nodes.push_back(pnode);
627 
628 
629 
630  it_node1 = this_model_part.NodesBegin() + pos1;
631  it_node2 = this_model_part.NodesBegin() + pos2;
632 
633  pnode->GetValue(FATHER_NODES).resize(0);
634  pnode->GetValue(FATHER_NODES).push_back(Node ::WeakPointer(*it_node1.base()));
635  pnode->GetValue(FATHER_NODES).push_back(Node ::WeakPointer(*it_node2.base()));
636 
637  pnode->X0() = 0.5 * (it_node1->X0() + it_node2->X0());
638  pnode->Y0() = 0.5 * (it_node1->Y0() + it_node2->Y0());
639  pnode->Z0() = 0.5 * (it_node1->Z0() + it_node2->Z0());
640 
641 
642  for (Node ::DofsContainerType::iterator iii = reference_dofs.begin(); iii != reference_dofs.end(); iii++)
643  {
644  Node ::DofType& rDof = **iii;
645  Node ::DofType::Pointer p_new_dof = pnode->pAddDof(rDof);
646  if (it_node1->IsFixed(rDof.GetVariable()) == true && it_node2->IsFixed(rDof.GetVariable()) == true)
647  (p_new_dof)->FixDof();
648  else
649  {
650  (p_new_dof)->FreeDof();
651  }
652 
653  }
654 
656  unsigned int buffer_size = pnode->GetBufferSize();
657  for (unsigned int step = 0; step < buffer_size; step++)
658  {
659  double* new_step_data = pnode->SolutionStepData().Data(step);
660  double* step_data1 = it_node1->SolutionStepData().Data(step);
661  double* step_data2 = it_node2->SolutionStepData().Data(step);
663  for (unsigned int j = 0; j < step_data_size; j++)
664  {
665  new_step_data[j] = 0.5 * (step_data1[j] + step_data2[j]);
666  }
667  }
668 
669  pnode->FastGetSolutionStepValue(PARTITION_INDEX) = partition_new_nodes[i];
670 
671 
673  // const double zero = 0.00;
674  // for (Node ::DofsContainerType::iterator iii = pnode->GetDofs().begin(); iii != pnode->GetDofs().end(); iii++)
675  // {
676  // if (pnode->IsFixed(iii->GetVariable()) == false)
677  // {
678  //
679  // iii->GetSolutionStepReactionValue() = zero;
680  //
681  // }
682  // }
683 
684  }
685 
686  for (PointerVector<Node >::iterator it = new_nodes.begin(); it != new_nodes.end(); it++)
687  {
688 // cout << (*it.base())->Id() << endl;
689 
690 // here soemthing wrong
691  this_model_part.GetMesh(0).Nodes().push_back(*it.base());
692  }
693 
694  unsigned int current_size = this_model_part.Nodes().size();
695 
696  this_model_part.Nodes().Unique();
697 
698  KRATOS_ERROR_IF(current_size != this_model_part.Nodes().size()) << "some node was duplicated! error" << std::endl;
699 
700  KRATOS_CATCH("")
701  }
702 
703 
707 
709  ModelPart& this_model_part,
711  PointerVector< Element >& New_Elements,
712  bool interpolate_internal_variables
713  )
714  {
715  KRATOS_TRY
716  DenseMatrix<int> new_conectivity;
717 
718  int total_existing_elements = -1;
719  int local_existing_elements = this_model_part.Elements().size();
720  mrComm.SumAll(&local_existing_elements, &total_existing_elements, 1);
721 
722  Element const rReferenceElement;
723  unsigned int to_be_deleted = 0;
724  unsigned int large_id = total_existing_elements * 15;
725  bool create_element = false;
726  int edge_ids[3];
727  int t[12];
728  int nel = 0;
729  int splitted_edges = 0;
730  int nint = 0;
731  int aux[6];
732 
733  const ProcessInfo& rCurrentProcessInfo = this_model_part.GetProcessInfo();
734  PointerVector< Element > Old_Elements;
735 
736  unsigned int current_id = (this_model_part.Elements().end() - 1)->Id() + 1;
737  for (ModelPart::ElementsContainerType::iterator it = this_model_part.Elements().begin();
738  it != this_model_part.Elements().end(); ++it)
739  {
740  for (unsigned int i = 0; i < 12; i++)
741  {
742  t[i] = -1;
743  }
744  Element::GeometryType& geom = it->GetGeometry();
745  Calculate_Triangle_Edges(geom, p_edge_ids, edge_ids, aux);
746 
748  create_element = TriangleSplit::Split_Triangle(edge_ids, t, &nel, &splitted_edges, &nint);
749 
751  if (create_element == true)
752  {
753  to_be_deleted++;
754  for (int i = 0; i < nel; i++)
755  {
756  int i0, i1, i2;
757  TriangleSplit::TriangleGetNewConnectivityGID(i, t, aux, &i0, &i1, &i2);
758 
759  Triangle2D3<Node > geom(
760  this_model_part.Nodes()(i0),
761  this_model_part.Nodes()(i1),
762  this_model_part.Nodes()(i2)
763  );
764 
765 
766  Element::Pointer p_element;
767  p_element = it->Create(current_id, geom, it->pGetProperties());
768  p_element->SetFlags(*it);
769  p_element->Initialize(rCurrentProcessInfo);
770  p_element->InitializeSolutionStep(rCurrentProcessInfo);
771  p_element->FinalizeSolutionStep(rCurrentProcessInfo);
772 
774  if (interpolate_internal_variables == true)
775  InterpolateInternalVariables(nel, *it.base(), p_element, rCurrentProcessInfo);
776 
777  // Transfer elemental variables
778  p_element->GetData() = it->GetData();
779  //const unsigned int& level = it->GetValue(REFINEMENT_LEVEL);
780  p_element->GetValue(SPLIT_ELEMENT) = false;
781  //p_element->SetValue(REFINEMENT_LEVEL, 1);
782  New_Elements.push_back(p_element);
783  current_id++;
784 
785  }
786  it->SetId(large_id);
787  large_id++;
788  }
789 
790  }
791 
793  for (PointerVector< Element >::iterator it_new = New_Elements.begin(); it_new != New_Elements.end(); it_new++)
794  {
795  this_model_part.Elements().push_back(*(it_new.base()));
796  }
797 
799  this_model_part.Elements().Sort();
800 
802  this_model_part.Elements().erase(this_model_part.Elements().end() - to_be_deleted, this_model_part.Elements().end());
803 
804  int number_of_elements_before = -1;
805  int number_of_own_elements = this_model_part.Elements().size();
806  mrComm.ScanSum(&number_of_own_elements, &number_of_elements_before, 1);
807  number_of_elements_before = number_of_elements_before - number_of_own_elements;
808  if (number_of_elements_before < 0)
809  KRATOS_THROW_ERROR(std::logic_error, "problem with scan sum ... giving a negative number of nodes before", "");
810 
811  int start_elem_id = number_of_elements_before + 1;
812  // int end_elem_id = number_of_elements_before + number_of_own_elements;
813 
814  int id_counter = start_elem_id;
815  for (ModelPart::ElementsContainerType::iterator it = this_model_part.Elements().begin();
816  it != this_model_part.Elements().end(); ++it)
817  {
818  it->SetId(id_counter++);
819  }
820 
821  // //find our the total number of nodes
822  // int number_of_local_nodes = this_model_part.GetCommunicator().LocalMesh().Nodes().size();
823  // int total_number_of_nodes = -1;
824  // mrComm.SumAll(&number_of_local_nodes, &total_number_of_nodes, 1);
825 
826 
827  KRATOS_CATCH("")
828  }
829 
832 
835  int* edge_ids,
836  int aux[6]
837  )
838  {
839  KRATOS_TRY
840  int index_0 = geom[0].Id() - 1;
841  int index_1 = geom[1].Id() - 1;
842  int index_2 = geom[2].Id() - 1;
843 
844  aux[0] = geom[0].Id();
845  aux[1] = geom[1].Id();
846  aux[2] = geom[2].Id();
847 
848  //here we count the new nodes on the local mesh
849  int MaxNumEntries = p_edge_ids->MaxNumEntries();
850  double * id_values = new double[MaxNumEntries];
851  int * Indices = new int[MaxNumEntries];
852  int NumEntries;
853 
854  aux[3] = GetUpperTriangularMatrixValue(p_edge_ids, index_0, index_1, MaxNumEntries, NumEntries, Indices, id_values);
855  aux[4] = GetUpperTriangularMatrixValue(p_edge_ids, index_1, index_2, MaxNumEntries, NumEntries, Indices, id_values);
856  aux[5] = GetUpperTriangularMatrixValue(p_edge_ids, index_2, index_0, MaxNumEntries, NumEntries, Indices, id_values);
857 
858  TriangleSplit::TriangleSplitMode(aux, edge_ids);
859 
860 
861  KRATOS_CATCH("")
862  }
863 
864 
868 
869  void Renumbering_Elements(ModelPart& this_model_part,
870  PointerVector< Element >& New_Elements
871  )
872  {
873  KRATOS_TRY
874  //compute element ids
875  int nel = this_model_part.Elements().size();
876  int el_before = -1;
877  mrComm.ScanSum(&nel, &el_before, 1);
878  // int el_end_id = el_before + 1;
879  int el_start_id = el_before - nel + 1;
880  if (el_start_id < 0) KRATOS_THROW_ERROR(std::logic_error, "wrong id in renumbering of the elements", "")
881 
882  unsigned int id_elem = el_start_id;
883  for (ModelPart::ElementsContainerType::iterator it = this_model_part.ElementsBegin();
884  it != this_model_part.ElementsEnd(); ++it)
885  {
886  if (it->Id() != id_elem)
887  {
888  it->SetId(id_elem);
889  }
890  id_elem++;
891  }
892 
893  //verify that the nodes are numbered consecutively
894  int local_max_id = (mr_model_part.GetCommunicator().LocalMesh().NodesEnd() - 1)->Id();
895  int local_number_of_nodes = mr_model_part.GetCommunicator().LocalMesh().Nodes().size();
896  int max_id = -1;
897  int tot_nnodes = -1;
898  mrComm.MaxAll(&local_max_id, &max_id, 1);
899  mrComm.SumAll(&local_number_of_nodes, &tot_nnodes, 1);
900  if (max_id != tot_nnodes)
901  KRATOS_THROW_ERROR(std::logic_error, "node ids are not consecutive", "");
902 
903  int tot_elements;
904  int local_max_elem_id = (mr_model_part.Elements().end() - 1)->Id();
905  int local_number_of_elem = mr_model_part.Elements().size();
906  mrComm.MaxAll(&local_max_elem_id, &max_id, 1);
907  mrComm.SumAll(&local_number_of_elem, &tot_elements, 1);
908  if (max_id != tot_elements)
909  KRATOS_THROW_ERROR(std::logic_error, "element ids are not consecutive", "");
910 
911  KRATOS_CATCH("")
912 
913  }
914 
918 
919  void Renumbering_Conditions(ModelPart& this_model_part,
920  PointerVector< Condition >& New_Conditions
921  )
922  {
923  KRATOS_TRY
924 
925 
926  //compute Condition ids
927  int nel = this_model_part.Conditions().size();
928 
929  int el_before = -1;
930  mrComm.ScanSum(&nel, &el_before, 1);
931  // int el_end_id = el_before + 1;
932  int el_start_id = el_before - nel + 1;
933  if (el_start_id <= 0) KRATOS_THROW_ERROR(std::logic_error, "wrong id in renumbering of the Conditions", "")
934 
935  unsigned int id_elem = el_start_id;
936  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.ConditionsBegin();
937  it != this_model_part.ConditionsEnd(); ++it)
938  {
939  if (it->Id() != id_elem)
940  {
941  it->SetId(id_elem);
942  }
943  id_elem++;
944  }
945 
946  //verify that the nodes are numbered consecutively
947  int local_max_id = (mr_model_part.GetCommunicator().LocalMesh().NodesEnd() - 1)->Id();
948  int local_number_of_nodes = mr_model_part.GetCommunicator().LocalMesh().Nodes().size();
949  int max_id = -1;
950  int tot_nnodes = -1;
951  mrComm.MaxAll(&local_max_id, &max_id, 1);
952  mrComm.SumAll(&local_number_of_nodes, &tot_nnodes, 1);
953  if (max_id != tot_nnodes)
954  KRATOS_THROW_ERROR(std::logic_error, "node ids are not consecutive", "");
955 
956  int tot_Conditions;
957 
958  int local_max_elem_id = 0;
959  if (nel != 0) local_max_elem_id = (mr_model_part.Conditions().end() - 1)->Id();
960  int local_number_of_elem = mr_model_part.Conditions().size();
961 
962  mrComm.MaxAll(&local_max_elem_id, &max_id, 1);
963  mrComm.SumAll(&local_number_of_elem, &tot_Conditions, 1);
964  KRATOS_ERROR_IF (max_id != tot_Conditions) << "Condition ids are not consecutive" << std::endl;
965 
966  KRATOS_CATCH("")
967 
968  }
969 
970 
971 protected:
973  Epetra_MpiComm& mrComm;
977 
980 
984 
985  void InterpolateInternalVariables(const int& nel,
986  const Element::Pointer father_elem,
987  Element::Pointer child_elem,
988  const ProcessInfo& rCurrentProcessInfo)
989  {
990  std::vector<Vector> values;
991  father_elem->CalculateOnIntegrationPoints(INTERNAL_VARIABLES, values, rCurrentProcessInfo);
992  /* /// WARNING = Calculando la longitud ponderada de fractura del elemento. Solo valido para isotropic_damage
993  Element::GeometryType& geom_father = father_elem->GetGeometry();
994  Element::GeometryType& geom_child = child_elem->GetGeometry();
995  double area_father = geom_father.Area();
996  double area_child = geom_child.Area();
997  values[0][4] = (area_child/area_father) * values[0][4];
998  */
999  child_elem->SetValuesOnIntegrationPoints(INTERNAL_VARIABLES, values, rCurrentProcessInfo);
1000 
1001  }
1002 
1003  double GetValueFromRow(int row, int j, int row_size, int* indices, double* values)
1004  {
1005  for (int i = 0; i < row_size; i++)
1006  {
1007  if (indices[i] == j)
1008  {
1009  return values[i];
1010  }
1011  }
1012 
1013  KRATOS_THROW_ERROR(std::logic_error, "expected index not found", "")
1014  }
1015 
1016  double GetUpperTriangularMatrixValue(const Kratos::shared_ptr<Epetra_FECrsMatrix>& p_edge_ids, int index_0, int index_1, int& MaxNumEntries, int& NumEntries, int* Indices, double* values)
1017  {
1018  double value;
1019  if (index_0 > index_1)
1020  {
1021  p_edge_ids->ExtractGlobalRowCopy(index_1, MaxNumEntries, NumEntries, values, Indices); //Coord(index_1, index_0);
1022  value = this->GetValueFromRow(index_1, index_0, NumEntries, Indices, values);
1023  }
1024  else
1025  {
1026  p_edge_ids->ExtractGlobalRowCopy(index_0, MaxNumEntries, NumEntries, values, Indices);
1027  value = this->GetValueFromRow(index_0, index_1, NumEntries, Indices, values);
1028  }
1029  return value;
1030 
1031  }
1032 
1034  ModelPart& this_model_part,
1035  const Kratos::shared_ptr<Epetra_FECrsMatrix> p_edge_ids,
1036  PointerVector< Element >& New_Elements,
1037  bool interpolate_internal_variables
1038  )
1039  {
1040  if (this_model_part.Elements().size() > 0)
1041  {
1042  // Element const rReferenceElement;
1043  unsigned int to_be_deleted = 0;
1044 
1045  int total_existing_elements = -1;
1046  int local_existing_elements = this_model_part.Elements().size();
1047  mrComm.SumAll(&local_existing_elements, &total_existing_elements, 1);
1048 
1049  unsigned int large_id = total_existing_elements * 15;
1050  unsigned int current_id = local_existing_elements + 1;
1051  bool create_element = false;
1052 
1053  const ProcessInfo& rCurrentProcessInfo = this_model_part.GetProcessInfo();
1054  int edge_ids[6];
1055  int t[56];
1056  for (unsigned int i = 0; i < 56; i++)
1057  {
1058  t[i] = -1;
1059  }
1060  int nel = 0;
1061  int splitted_edges = 0;
1062  int internal_node = 0;
1063 
1064  ModelPart::NodesContainerType center_nodes;
1065 
1066  for (ModelPart::ElementsContainerType::iterator it = this_model_part.ElementsBegin(); it != this_model_part.ElementsEnd(); ++it)
1067  {
1068  //KRATOS_WATCH(it->Id())
1069  Element::GeometryType& geom = it->GetGeometry();
1070 
1071  int index_0 = geom[0].Id() - 1;
1072  int index_1 = geom[1].Id() - 1;
1073  int index_2 = geom[2].Id() - 1;
1074  int index_3 = geom[3].Id() - 1;
1075 
1076  //put the global ids in aux
1077  int aux[11];
1078  aux[0] = geom[0].Id();
1079  aux[1] = geom[1].Id();
1080  aux[2] = geom[2].Id();
1081  aux[3] = geom[3].Id();
1082 
1083  //here we count the new nodes on the local mesh
1084  int MaxNumEntries = p_edge_ids->MaxNumEntries();
1085  double * id_values = new double[MaxNumEntries];
1086  int * Indices = new int[MaxNumEntries];
1087  int NumEntries;
1088 
1089  aux[4] = GetUpperTriangularMatrixValue(p_edge_ids, index_0, index_1, MaxNumEntries, NumEntries, Indices, id_values);
1090  aux[5] = GetUpperTriangularMatrixValue(p_edge_ids, index_0, index_2, MaxNumEntries, NumEntries, Indices, id_values);
1091  aux[6] = GetUpperTriangularMatrixValue(p_edge_ids, index_0, index_3, MaxNumEntries, NumEntries, Indices, id_values);
1092  aux[7] = GetUpperTriangularMatrixValue(p_edge_ids, index_1, index_2, MaxNumEntries, NumEntries, Indices, id_values);
1093  aux[8] = GetUpperTriangularMatrixValue(p_edge_ids, index_1, index_3, MaxNumEntries, NumEntries, Indices, id_values);
1094  aux[9] = GetUpperTriangularMatrixValue(p_edge_ids, index_2, index_3, MaxNumEntries, NumEntries, Indices, id_values);
1095 
1096  TetrahedraSplit::TetrahedraSplitMode(aux, edge_ids);
1097 
1098  create_element = TetrahedraSplit::Split_Tetrahedra(edge_ids, t, &nel, &splitted_edges, &internal_node);
1099 
1100 
1101 
1102  if (create_element == true)
1103  {
1104  if (internal_node == 1)
1105  {
1106  aux[10] = CreateCenterNode(geom, this_model_part, center_nodes);
1107  }
1108 
1109  to_be_deleted++;
1110  //create the new connectivity
1111  for (int i = 0; i < nel; i++)
1112  {
1113 
1114  unsigned int base = i * 4;
1115  unsigned int i0 = aux[t[base]];
1116  unsigned int i1 = aux[t[base + 1]];
1117  unsigned int i2 = aux[t[base + 2]];
1118  unsigned int i3 = aux[t[base + 3]];
1119  // KRATOS_WATCH(i0)
1120  // KRATOS_WATCH(i1)
1121  // KRATOS_WATCH(i2)
1122  // KRATOS_WATCH(i3)
1123  // KRATOS_WATCH("-------------------------------------------" )
1124 
1125 
1126  Tetrahedra3D4<Node > geom(
1127  this_model_part.Nodes()(i0),
1128  this_model_part.Nodes()(i1),
1129  this_model_part.Nodes()(i2),
1130  this_model_part.Nodes()(i3)
1131  );
1132 
1133  //generate new element by cloning the base one
1134  Element::Pointer p_element = it->Create(current_id, geom, it->pGetProperties());
1135  p_element->Initialize(rCurrentProcessInfo);
1136  p_element->InitializeSolutionStep(rCurrentProcessInfo);
1137  p_element->FinalizeSolutionStep(rCurrentProcessInfo);
1138  New_Elements.push_back(p_element);
1139 
1141  if (interpolate_internal_variables == true)
1142  InterpolateInternalVariables(nel, *it.base(), p_element, rCurrentProcessInfo);
1143 
1144  // Transfer elemental variables
1145  p_element->GetData() = it->GetData();
1146  p_element->GetValue(SPLIT_ELEMENT) = false;
1147 
1148  current_id++;
1149 
1150  }
1151  it->SetId(large_id);
1152  large_id++;
1153  }
1154 
1155  // for (unsigned int i = 0; i < 32; i++)
1156  // {
1157  // t[i] = -1;
1158  // }
1159  }
1160 
1161  this_model_part.Nodes().Sort();
1162 
1164  this_model_part.Elements().Sort();
1165 
1167  this_model_part.Elements().erase(this_model_part.Elements().end() - to_be_deleted, this_model_part.Elements().end());
1168 
1169  unsigned int total_size = this_model_part.Elements().size() + New_Elements.size();
1170  this_model_part.Elements().reserve(total_size);
1171 
1173  for (PointerVector< Element >::iterator it_new = New_Elements.begin(); it_new != New_Elements.end(); it_new++)
1174  {
1175 
1176  this_model_part.Elements().push_back(*(it_new.base()));
1177  }
1178 
1179  int number_of_elements_before = -1;
1180  int number_of_own_elements = this_model_part.Elements().size();
1181  mrComm.ScanSum(&number_of_own_elements, &number_of_elements_before, 1);
1182  number_of_elements_before = number_of_elements_before - number_of_own_elements;
1183  if (number_of_elements_before < 0)
1184  KRATOS_THROW_ERROR(std::logic_error, "problem with scan sum ... giving a negative number of nodes before", "");
1185 
1186  int start_elem_id = number_of_elements_before + 1;
1187 
1188  int id_counter = start_elem_id;
1189  for (ModelPart::ElementsContainerType::iterator it = this_model_part.Elements().begin();
1190  it != this_model_part.Elements().end(); ++it)
1191  {
1192  it->SetId(id_counter++);
1193  }
1194 
1195  AssignIdToCenterNode(center_nodes);
1196 
1197 
1198 
1199 
1200 
1201  }
1202 
1203 
1204 
1205  }
1206 
1208  {
1209  //determine a new unique id
1210  unsigned int new_id = (model_part.NodesEnd() - 1)->Id() + 1;
1211 
1212  if (model_part.Nodes().find(new_id) != model_part.NodesEnd())
1213  KRATOS_THROW_ERROR(std::logic_error, "id is already being used", "");
1214 
1215 
1216  //determine the coordinates of the new node
1217  double X = (geom[0].X() + geom[1].X() + geom[2].X() + geom[3].X()) / 4.0;
1218  double Y = (geom[0].Y() + geom[1].Y() + geom[2].Y() + geom[3].Y()) / 4.0;
1219  double Z = (geom[0].Z() + geom[1].Z() + geom[2].Z() + geom[3].Z()) / 4.0;
1220 
1221  double X0 = (geom[0].X0() + geom[1].X0() + geom[2].X0() + geom[3].X0()) / 4.0;
1222  double Y0 = (geom[0].Y0() + geom[1].Y0() + geom[2].Y0() + geom[3].Y0()) / 4.0;
1223  double Z0 = (geom[0].Z0() + geom[1].Z0() + geom[2].Z0() + geom[3].Z0()) / 4.0;
1224 
1225  //generate the new node
1226  Node::Pointer pnode = AuxCreateNewNode(model_part,new_id,X,Y,Z);
1227 
1228  pnode->X0() = X0;
1229  pnode->Y0() = Y0;
1230  pnode->Z0() = Z0;
1231 
1232  //add the dofs
1233  Node ::DofsContainerType& reference_dofs = (model_part.NodesBegin())->GetDofs();
1234  unsigned int step_data_size = model_part.GetNodalSolutionStepDataSize();
1235 
1236  for (Node ::DofsContainerType::iterator iii = reference_dofs.begin(); iii != reference_dofs.end(); iii++)
1237  {
1238  Node ::DofType& rDof = **iii;
1239  Node ::DofType::Pointer p_new_dof = pnode->pAddDof(rDof);
1240 
1241  //the variables are left as free for the internal node
1242  (p_new_dof)->FreeDof();
1243 
1244  /* if(it_node1->IsFixed(iii->GetVariable()) == true && it_node2->IsFixed(iii->GetVariable()) == true)
1245  (p_new_dof)->FixDof();
1246  else
1247  { (p_new_dof)->FreeDof();} */
1248 
1249  }
1250 
1252  unsigned int buffer_size = model_part.NodesBegin()->GetBufferSize();
1253 
1254  for (unsigned int step = 0; step < buffer_size; step++)
1255  {
1256  double* new_step_data = pnode->SolutionStepData().Data(step);
1257  double* step_data1 = geom[0].SolutionStepData().Data(step);
1258  double* step_data2 = geom[1].SolutionStepData().Data(step);
1259  double* step_data3 = geom[2].SolutionStepData().Data(step);
1260  double* step_data4 = geom[3].SolutionStepData().Data(step);
1262  for (unsigned int j = 0; j < step_data_size; j++)
1263  {
1264  new_step_data[j] = 0.25 * (step_data1[j] + step_data2[j] + step_data3[j] + step_data4[j]);
1265  }
1266  }
1267 
1268  pnode->FastGetSolutionStepValue(PARTITION_INDEX) = mrComm.MyPID();
1269 
1270  center_nodes.push_back(pnode);
1271 
1272  return new_id;
1273  }
1274 
1276  {
1277  int total_number_of_nodes_nocenter = 1;
1278  int local_number_of_center_nodes = center_nodes.size();
1279 
1280  int rank = mrComm.MyPID();
1281 
1282  int number_of_nodes_before = -1;
1283  mrComm.ScanSum(&local_number_of_center_nodes, &number_of_nodes_before, 1);
1284  number_of_nodes_before = number_of_nodes_before - local_number_of_center_nodes;
1285  if (number_of_nodes_before < 0)
1286  KRATOS_THROW_ERROR(std::logic_error, "problem with scan sum ... giving a negative number of nodes before", "");
1287 
1288  //find our the total number of nodes (excluding center nodes)
1289  int number_of_own_nodes_nocenter = 0;
1290  for (ModelPart::NodesContainerType::iterator it = mr_model_part.NodesBegin(); it != mr_model_part.NodesEnd(); it++)
1291  if (it->FastGetSolutionStepValue(PARTITION_INDEX) == rank)
1292  number_of_own_nodes_nocenter++;
1293  number_of_own_nodes_nocenter -= local_number_of_center_nodes;
1294  mrComm.SumAll(&number_of_own_nodes_nocenter, &total_number_of_nodes_nocenter, 1);
1295 
1296  int counter = total_number_of_nodes_nocenter + number_of_nodes_before + 1;
1297  for (ModelPart::NodesContainerType::iterator it = center_nodes.begin(); it != center_nodes.end(); it++)
1298  it->SetId(counter++);
1299 
1300  }
1301 
1302 
1306 
1308  ModelPart& this_model_part,
1309  const Kratos::shared_ptr<Epetra_FECrsMatrix> p_edge_ids,
1310  PointerVector< Condition >& New_Conditions,
1311  bool interpolate_internal_variables
1312  )
1313  {
1314  KRATOS_TRY
1315 
1316  DenseMatrix<int> new_conectivity;
1317 
1318  int total_existing_Conditions = -1;
1319  int local_existing_Conditions = this_model_part.Conditions().size();
1320  mrComm.SumAll(&local_existing_Conditions, &total_existing_Conditions, 1);
1321 
1322  if (this_model_part.Conditions().size() != 0)
1323  {
1324  unsigned int to_be_deleted = 0;
1325  unsigned int large_id = total_existing_Conditions * 4;
1326  bool create_Condition = false;
1327  int edge_ids[3];
1328  int t[12];
1329  int nel = 0;
1330  int splitted_edges = 0;
1331  int nint = 0;
1332  int aux[6];
1333 
1334  const ProcessInfo& rCurrentProcessInfo = this_model_part.GetProcessInfo();
1335  PointerVector< Condition > Old_Conditions;
1336 
1337  unsigned int current_id = (this_model_part.Conditions().end() - 1)->Id() + 1;
1338  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.Conditions().begin();
1339  it != this_model_part.Conditions().end(); ++it)
1340  {
1341  for (unsigned int i = 0; i < 12; i++)
1342  {
1343  t[i] = -1;
1344  }
1345  Condition::GeometryType& geom = it->GetGeometry();
1346  Calculate_Triangle_Edges(geom, p_edge_ids, edge_ids, aux);
1347 
1349  create_Condition = TriangleSplit::Split_Triangle(edge_ids, t, &nel, &splitted_edges, &nint);
1350 
1352  if (create_Condition == true)
1353  {
1354  to_be_deleted++;
1355  for (int i = 0; i < nel; i++)
1356  {
1357  int i0, i1, i2;
1358  TriangleSplit::TriangleGetNewConnectivityGID(i, t, aux, &i0, &i1, &i2);
1359 
1360 // cout << i0 << " " << i1 << " " << i2 << endl;
1361 
1362  Triangle3D3<Node > geom(
1363  this_model_part.Nodes()(i0),
1364  this_model_part.Nodes()(i1),
1365  this_model_part.Nodes()(i2)
1366  );
1367  //KRATOS_WATCH("ln1304");
1368 
1369  Condition::Pointer p_Condition;
1370  p_Condition = it->Create(current_id, geom, it->pGetProperties());
1371  p_Condition->SetFlags(*it);
1372  p_Condition->Initialize(rCurrentProcessInfo);
1373  p_Condition->InitializeSolutionStep(rCurrentProcessInfo);
1374  p_Condition->FinalizeSolutionStep(rCurrentProcessInfo);
1375 
1377  // if (interpolate_internal_variables == true)
1378  // InterpolateInternalVariables(nel, *it.base(), p_Condition, rCurrentProcessInfo);
1379 
1380  // Transfer Conditional variables
1381  p_Condition->GetData() = it->GetData();
1382  //p_Condition->SetValue(REFINEMENT_LEVEL, 1);
1383  New_Conditions.push_back(p_Condition);
1384  current_id++;
1385 
1386  }
1387  it->SetId(large_id);
1388  large_id++;
1389  }
1390 
1391  }
1392 
1393 
1394 
1396  this_model_part.Conditions().Sort();
1397 
1399  this_model_part.Conditions().erase(this_model_part.Conditions().end() - to_be_deleted, this_model_part.Conditions().end());
1400 
1401  this_model_part.Conditions().reserve(this_model_part.Conditions().size() + New_Conditions.size());
1403  for (PointerVector< Condition >::iterator it_new = New_Conditions.begin(); it_new != New_Conditions.end(); it_new++)
1404  {
1405  this_model_part.Conditions().push_back(*(it_new.base()));
1406  }
1407  }
1408 
1409  int number_of_Conditions_before = -1;
1410  int number_of_own_Conditions = this_model_part.Conditions().size();
1411  mrComm.ScanSum(&number_of_own_Conditions, &number_of_Conditions_before, 1);
1412  number_of_Conditions_before = number_of_Conditions_before - number_of_own_Conditions;
1413  if (number_of_Conditions_before < 0)
1414  KRATOS_THROW_ERROR(std::logic_error, "problem with scan sum ... giving a negative number of nodes before", "");
1415 
1416  if (this_model_part.Conditions().size() != 0)
1417  {
1418  int start_elem_id = number_of_Conditions_before + 1;
1419  // int end_elem_id = number_of_Conditions_before + number_of_own_Conditions;
1420 
1421  int id_counter = start_elem_id;
1422  for (ModelPart::ConditionsContainerType::iterator it = this_model_part.Conditions().begin();
1423  it != this_model_part.Conditions().end(); ++it)
1424  {
1425  it->SetId(id_counter++);
1426  }
1427 
1428  // //find our the total number of nodes
1429  // int number_of_local_nodes = this_model_part.GetCommunicator().LocalMesh().Nodes().size();
1430  // int total_number_of_nodes = -1;
1431  // mrComm.SumAll(&number_of_local_nodes, &total_number_of_nodes, 1);
1432 
1433  }
1434 
1435  KRATOS_CATCH("")
1436  }
1437 
1438  Node::Pointer AuxCreateNewNode(ModelPart& r_model_part, int Id, double x, double y, double z)
1439  {
1440  //create a new node
1441  Node::Pointer p_new_node = Node::Pointer(new Node(Id, x, y, z));
1442 
1443  // Giving model part's variables list to the node
1444  p_new_node->SetSolutionStepVariablesList(&(r_model_part.GetNodalSolutionStepVariablesList()));
1445 
1446  p_new_node->SetBufferSize(r_model_part.NodesBegin()->GetBufferSize());
1447 
1448  return p_new_node;
1449  }
1450 
1451 
1452 
1453 };
1454 
1455 
1456 
1457 
1458 
1459 
1460 
1461 
1462 } // namespace Kratos.
1463 
1464 #endif // KRATOS_TRILINOS_LOCAL_REFINE_SIMPLEX_MESH defined
1465 
1466 
MeshType & GhostMesh()
Returns the reference to the mesh storing all ghost entities.
Definition: communicator.cpp:251
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
Base class for all Elements.
Definition: element.h:60
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
Definition: amatrix_interface.h:41
NodesContainerType & Nodes()
Definition: mesh.h:346
NodeIterator NodesEnd()
Definition: mesh.h:336
NodeIterator NodesBegin()
Definition: mesh.h:326
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
MeshType::ConditionsContainerType ConditionsContainerType
Condintions container. A vector set of Conditions with their Id's as key.
Definition: model_part.h:183
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
SizeType GetNodalSolutionStepDataSize()
Definition: model_part.h:571
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
Communicator & GetCommunicator()
Definition: model_part.h:1821
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
MeshType & GetMesh(IndexType ThisIndex=0)
Definition: model_part.h:1791
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
VariablesList & GetNodalSolutionStepVariablesList()
Definition: model_part.h:549
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
This class defines the node.
Definition: node.h:65
Dof< double > DofType
Dof type.
Definition: node.h:83
std::vector< std::unique_ptr< Dof< double > >> DofsContainerType
The DoF container type definition.
Definition: node.h:92
This function recomputes the communication plan for MPI.
Definition: parallel_fill_communicator.h:56
void Execute() override
Execute the communicator fill.
Definition: parallel_fill_communicator.cpp:39
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
size_type size() const
Definition: pointer_vector.h:255
iterator end()
Definition: pointer_vector.h:177
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector.h:89
iterator begin()
Definition: pointer_vector.h:169
void push_back(const TPointerType &x)
Definition: pointer_vector.h:270
size_type size() const
Returns the number of elements in the container.
Definition: pointer_vector_set.h:502
void push_back(TPointerType x)
Adds a pointer to the end of the set.
Definition: pointer_vector_set.h:544
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
A four node tetrahedra geometry with linear shape functions.
Definition: tetrahedra_3d_4.h:59
static int Split_Tetrahedra(const int edges[6], int t[56], int *nel, int *splitted_edges, int *nint)
Function to split a tetrahedron For a given edges splitting pattern, this function computes the inter...
Definition: split_tetrahedra.h:177
static void TetrahedraSplitMode(int aux_ids[11], int edge_ids[6])
Returns the edges vector filled with the splitting pattern. Provided the array of nodal ids,...
Definition: split_tetrahedra.h:91
A three node 2D triangle geometry with linear shape functions.
Definition: triangle_2d_3.h:74
A three node 3D triangle geometry with linear shape functions.
Definition: triangle_3d_3.h:77
static void TriangleSplitMode(const int aux_ids[6], int edge_ids[3])
Definition: split_triangle.h:64
static int Split_Triangle(const int edges[3], int t[12], int *nel, int *splitted_edges, int *nint)
Utility to split triangles.
Definition: split_triangle.h:117
static void TriangleGetNewConnectivityGID(const int triangle_index, const int t[12], const int aux_ids[6], int *id0, int *id1, int *id2)
Definition: split_triangle.h:96
Definition: trilinos_refine_mesh.h:44
void CSR_Row_Matrix(ModelPart &this_model_part, Kratos::shared_ptr< Epetra_FECrsMatrix > &p_edge_ids)
Definition: trilinos_refine_mesh.h:225
Node PointType
Definition: trilinos_refine_mesh.h:53
ModelPart::NodesContainerType NodesArrayType
Definition: trilinos_refine_mesh.h:47
Kratos::shared_ptr< Epetra_CrsGraph > mp_overlapping_graph
Definition: trilinos_refine_mesh.h:979
ModelPart & mr_model_part
Definition: trilinos_refine_mesh.h:972
void Local_Refine_Mesh(bool refine_on_reference, bool interpolate_internal_variables, int domain_size)
Definition: trilinos_refine_mesh.h:92
ModelPart::ElementsContainerType ElementsArrayType
Definition: trilinos_refine_mesh.h:48
Kratos::shared_ptr< Epetra_Map > mp_overlapping_map
Definition: trilinos_refine_mesh.h:974
void Clear()
This function frees all of the memory used.
Definition: trilinos_refine_mesh.h:200
Node ::Pointer PointPointerType
Definition: trilinos_refine_mesh.h:54
Kratos::shared_ptr< Epetra_Map > mp_non_overlapping_map
Definition: trilinos_refine_mesh.h:975
void Erase_Old_Element_And_Create_New_Triangle_Element(ModelPart &this_model_part, const Kratos::shared_ptr< Epetra_FECrsMatrix > p_edge_ids, PointerVector< Element > &New_Elements, bool interpolate_internal_variables)
Definition: trilinos_refine_mesh.h:708
ModelPart::ConditionsContainerType ConditionsArrayType
Definition: trilinos_refine_mesh.h:49
Kratos::shared_ptr< Epetra_FECrsGraph > mp_non_overlapping_graph
Definition: trilinos_refine_mesh.h:978
double GetUpperTriangularMatrixValue(const Kratos::shared_ptr< Epetra_FECrsMatrix > &p_edge_ids, int index_0, int index_1, int &MaxNumEntries, int &NumEntries, int *Indices, double *values)
Definition: trilinos_refine_mesh.h:1016
Epetra_MpiComm & mrComm
Definition: trilinos_refine_mesh.h:973
~TrilinosRefineMesh()
Definition: trilinos_refine_mesh.h:67
void Erase_Old_Element_And_Create_New_Tetra_Element(ModelPart &this_model_part, const Kratos::shared_ptr< Epetra_FECrsMatrix > p_edge_ids, PointerVector< Element > &New_Elements, bool interpolate_internal_variables)
Definition: trilinos_refine_mesh.h:1033
unsigned int CreateCenterNode(Geometry< Node > &geom, ModelPart &model_part, ModelPart::NodesContainerType &center_nodes)
Definition: trilinos_refine_mesh.h:1207
int mtotal_number_of_existing_nodes
Definition: trilinos_refine_mesh.h:976
Node::Pointer AuxCreateNewNode(ModelPart &r_model_part, int Id, double x, double y, double z)
Definition: trilinos_refine_mesh.h:1438
void PrintDebugInfo()
Definition: trilinos_refine_mesh.h:184
PointVector::iterator PointIterator
Definition: trilinos_refine_mesh.h:56
TrilinosRefineMesh(ModelPart &model_part, Epetra_MpiComm &Comm)
Definition: trilinos_refine_mesh.h:63
void AssignIdToCenterNode(ModelPart::NodesContainerType &center_nodes)
Definition: trilinos_refine_mesh.h:1275
void Erase_Old_Condition_And_Create_New_Triangle_Conditions(ModelPart &this_model_part, const Kratos::shared_ptr< Epetra_FECrsMatrix > p_edge_ids, PointerVector< Condition > &New_Conditions, bool interpolate_internal_variables)
Definition: trilinos_refine_mesh.h:1307
double GetValueFromRow(int row, int j, int row_size, int *indices, double *values)
Definition: trilinos_refine_mesh.h:1003
void Calculate_Coordinate_And_Insert_New_Nodes(ModelPart &this_model_part, const vector< array_1d< int, 2 > > &father_node_ids, const vector< int > &List_New_Nodes, const vector< int > &partition_new_nodes)
Definition: trilinos_refine_mesh.h:561
void Create_List_Of_New_Nodes(ModelPart &this_model_part, Kratos::shared_ptr< Epetra_FECrsMatrix > &p_edge_ids, Kratos::shared_ptr< Epetra_FECrsMatrix > &p_partition_ids, vector< int > &List_New_Nodes, vector< int > &partition_new_nodes, vector< array_1d< int, 2 > > &father_node_ids)
Definition: trilinos_refine_mesh.h:386
void Renumbering_Conditions(ModelPart &this_model_part, PointerVector< Condition > &New_Conditions)
Definition: trilinos_refine_mesh.h:919
vector< Vector > Vector_Order_Tensor
Definition: trilinos_refine_mesh.h:51
void Search_Edge_To_Be_Refined(ModelPart &this_model_part, Kratos::shared_ptr< Epetra_FECrsMatrix > &p_edge_ids, Kratos::shared_ptr< Epetra_FECrsMatrix > &p_partition_ids)
Definition: trilinos_refine_mesh.h:303
void InterpolateInternalVariables(const int &nel, const Element::Pointer father_elem, Element::Pointer child_elem, const ProcessInfo &rCurrentProcessInfo)
Definition: trilinos_refine_mesh.h:985
vector< Vector_Order_Tensor > Node_Vector_Order_Tensor
Definition: trilinos_refine_mesh.h:52
void Calculate_Triangle_Edges(Element::GeometryType &geom, const Kratos::shared_ptr< Epetra_FECrsMatrix > p_edge_ids, int *edge_ids, int aux[6])
Definition: trilinos_refine_mesh.h:833
void Renumbering_Elements(ModelPart &this_model_part, PointerVector< Element > &New_Elements)
Definition: trilinos_refine_mesh.h:869
vector< Matrix > Matrix_Order_Tensor
Definition: trilinos_refine_mesh.h:50
std::vector< PointType::Pointer > PointVector
Definition: trilinos_refine_mesh.h:55
BOOST_UBLAS_INLINE void resize(size_type array_size, bool preserve=true)
Definition: array_1d.h:242
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
z
Definition: GenerateWind.py:163
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
std::shared_ptr< T > shared_ptr
Definition: smart_pointers.h:27
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
list values
Definition: bombardelli_test.py:42
int domain_size
Definition: face_heat.py:4
int step
Definition: face_heat.py:88
model_part
Definition: face_heat.py:14
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
int t
Definition: ode_solve.py:392
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int counter
Definition: script_THERMAL_CORRECT.py:218
int current_id
Output settings end ####.
Definition: script.py:194
x
Definition: sensitivityMatrix.py:49
int nnodes
Definition: sensitivityMatrix.py:24
integer i
Definition: TensorModule.f:17