107 EXCEPTION(
"This cuboid construction is only valid in 3D");
110 assert(numElemX > 0);
111 assert(numElemY > 0);
115 this->mMeshIsLinear=
false;
118 std::map<std::pair<unsigned, unsigned>,
unsigned> edge_to_internal_map;
120 unsigned node_index = this->GetNumNodes();
121 c_vector<double, DIM> top;
124 c_vector<double, DIM> node_pos;
126 for (
unsigned j=0; j<numElemY+1; j++)
130 for (
unsigned i=0; i<numElemX; i++)
132 unsigned left_index = j*(numElemX+1) + i;
133 std::pair<unsigned,unsigned> edge(left_index, left_index+1 );
134 edge_to_internal_map[edge] = node_index;
136 MakeNewInternalNode(node_index, node_pos, top);
141 for (
unsigned i=0; i<numElemX+1; i++)
144 unsigned left_index = j*(numElemX+1) + i;
145 std::pair<unsigned,unsigned> edge(left_index, left_index+(numElemX+1) );
146 edge_to_internal_map[edge] = node_index;
147 MakeNewInternalNode(node_index, node_pos, top);
148 unsigned parity=(i+(numElemY-j))%2;
149 if (stagger==
false || parity==1)
152 std::pair<unsigned,unsigned> back_edge(left_index+1, left_index+(numElemX+1) );
153 edge_to_internal_map[back_edge] = node_index;
158 std::pair<unsigned,unsigned> forward_edge(left_index, left_index+(numElemX+1)+1 );
159 edge_to_internal_map[forward_edge] = node_index;
162 MakeNewInternalNode(node_index, node_pos, top);
169 iter != this->GetElementIteratorEnd();
172 unsigned local_index1=0;
173 for (
unsigned index=0; index<=DIM; index++)
175 local_index1 = (local_index1+1)%(DIM+1);
176 unsigned local_index2 = (local_index1+1)%(DIM+1);
177 unsigned global_index1 = iter->GetNodeGlobalIndex(local_index1);
178 unsigned global_index2 = iter->GetNodeGlobalIndex(local_index2);
179 unsigned new_node_index = LookupInternalNode(global_index1, global_index2, edge_to_internal_map);
180 iter->AddNode(this->mNodes[new_node_index]);
181 this->mNodes[new_node_index]->AddElement(iter->GetIndex());
186 iter != this->GetBoundaryElementIteratorEnd();
189 unsigned global_index1 = (*iter)->GetNodeGlobalIndex(0);
190 unsigned global_index2 = (*iter)->GetNodeGlobalIndex(1);
191 unsigned new_node_index = LookupInternalNode(global_index1, global_index2, edge_to_internal_map);
192 (*iter)->AddNode(this->mNodes[new_node_index]);
193 this->mNodes[new_node_index]->AddBoundaryElement((*iter)->GetIndex());
251 EXCEPTION(
"This cuboid construction is only valid in 3D");
254 assert(numElemX > 0);
255 assert(numElemY > 0);
256 assert(numElemZ > 0);
259 c_vector<double, DIM> top;
263 c_vector<double, DIM> node_pos;
264 this->mMeshIsLinear=
false;
267 std::map<std::pair<unsigned, unsigned>,
unsigned> edge_to_internal_map;
268 unsigned node_index = this->GetNumNodes();
269 for (
unsigned k=0; k<numElemZ+1; k++)
273 for (
unsigned j=0; j<numElemY+1; j++)
275 unsigned lo_z_lo_y = (numElemX+1)*((numElemY+1)*k + j);
276 unsigned lo_z_hi_y = (numElemX+1)*((numElemY+1)*k + j + 1);
281 for (
unsigned i=0; i<numElemX+1; i++)
284 std::pair<unsigned,unsigned> edge(lo_z_lo_y+i, lo_z_lo_y+i+1);
285 edge_to_internal_map[edge] = node_index;
287 MakeNewInternalNode(node_index, node_pos, top);
291 for (
unsigned i=0; i<numElemX+1; i++)
294 std::pair<unsigned,unsigned> edge(lo_z_lo_y+i, lo_z_hi_y+i);
295 edge_to_internal_map[edge] = node_index;
297 MakeNewInternalNode(node_index, node_pos, top);
300 std::pair<unsigned,unsigned> edge2(lo_z_lo_y+i, lo_z_hi_y+i+1);
301 edge_to_internal_map[edge2] = node_index;
303 MakeNewInternalNode(node_index, node_pos, top);
308 for (
unsigned j=0; j<numElemY+1; j++)
311 unsigned lo_z_lo_y = (numElemX+1)*((numElemY+1)*k + j);
312 unsigned hi_z_lo_y = (numElemX+1)*((numElemY+1)*(k+1) + j);
313 unsigned hi_z_hi_y = (numElemX+1)*((numElemY+1)*(k+1) + j + 1);
316 for (
unsigned i=0; i<numElemX+1; i++)
319 std::pair<unsigned,unsigned> edge(lo_z_lo_y+i, hi_z_lo_y+i);
320 edge_to_internal_map[edge] = node_index;
322 MakeNewInternalNode(node_index, node_pos, top);
326 std::pair<unsigned,unsigned> edge2(lo_z_lo_y+i, hi_z_lo_y+i+1);
327 edge_to_internal_map[edge2] = node_index;
328 MakeNewInternalNode(node_index, node_pos, top);
332 for (
unsigned i=0; i<numElemX+1; i++)
335 std::pair<unsigned,unsigned> edge(lo_z_lo_y+i, hi_z_hi_y+i);
336 edge_to_internal_map[edge] = node_index;
338 MakeNewInternalNode(node_index, node_pos, top);
341 std::pair<unsigned,unsigned> edge2(lo_z_lo_y+i, hi_z_hi_y+i+1);
342 edge_to_internal_map[edge2] = node_index;
344 MakeNewInternalNode(node_index, node_pos, top);
350 iter != this->GetElementIteratorEnd();
359 unsigned v0 = iter->GetNodeGlobalIndex(0);
360 unsigned v1 = iter->GetNodeGlobalIndex(1);
361 unsigned v2 = iter->GetNodeGlobalIndex(2);
362 unsigned v3 = iter->GetNodeGlobalIndex(3);
363 unsigned internal_index;
366 internal_index=LookupInternalNode(v0, v1, edge_to_internal_map);
367 iter->AddNode(this->mNodes[internal_index]);
368 this->mNodes[internal_index]->AddElement(iter->GetIndex());
370 internal_index=LookupInternalNode(v1, v2, edge_to_internal_map);
371 iter->AddNode(this->mNodes[internal_index]);
372 this->mNodes[internal_index]->AddElement(iter->GetIndex());
374 internal_index=LookupInternalNode(v0, v2, edge_to_internal_map);
375 iter->AddNode(this->mNodes[internal_index]);
376 this->mNodes[internal_index]->AddElement(iter->GetIndex());
378 internal_index=LookupInternalNode(v0, v3, edge_to_internal_map);
379 iter->AddNode(this->mNodes[internal_index]);
380 this->mNodes[internal_index]->AddElement(iter->GetIndex());
382 internal_index=LookupInternalNode(v1, v3, edge_to_internal_map);
383 iter->AddNode(this->mNodes[internal_index]);
384 this->mNodes[internal_index]->AddElement(iter->GetIndex());
386 internal_index=LookupInternalNode(v2, v3, edge_to_internal_map);
387 iter->AddNode(this->mNodes[internal_index]);
388 this->mNodes[internal_index]->AddElement(iter->GetIndex());
392 iter != this->GetBoundaryElementIteratorEnd();
395 unsigned local_index1=0;
396 for (
unsigned index=0; index<DIM; index++)
398 local_index1 = (local_index1+1)%(DIM);
399 unsigned local_index2 = (local_index1+1)%(DIM);
400 unsigned global_index1 = (*iter)->GetNodeGlobalIndex(local_index1);
401 unsigned global_index2 = (*iter)->GetNodeGlobalIndex(local_index2);
402 unsigned new_node_index = LookupInternalNode(global_index1, global_index2, edge_to_internal_map);
403 (*iter)->AddNode(this->mNodes[new_node_index]);
404 this->mNodes[new_node_index]->AddBoundaryElement((*iter)->GetIndex());
424 NodeMap unused_map(this->GetNumNodes());
428 struct triangulateio mesher_input, mesher_output;
429 this->InitialiseTriangulateIo(mesher_input);
430 this->InitialiseTriangulateIo(mesher_output);
432 mesher_input.numberoftriangles = this->GetNumElements();
433 mesher_input.trianglelist = (
int *) malloc(this->GetNumElements() * (DIM+1) *
sizeof(
int));
434 this->ExportToMesher(unused_map, mesher_input, mesher_input.trianglelist);
437 triangulate((
char*)
"Qzero2", &mesher_input, &mesher_output,
nullptr);
439 this->ImportFromMesher(mesher_output, mesher_output.numberoftriangles, mesher_output.trianglelist, mesher_output.numberofedges, mesher_output.edgelist, mesher_output.edgemarkerlist);
444 this->FreeTriangulateIo(mesher_input);
445 this->FreeTriangulateIo(mesher_output);
450 class tetgen::tetgenio mesher_input, mesher_output;
452 mesher_input.numberoftetrahedra = this->GetNumElements();
453 mesher_input.tetrahedronlist =
new int[this->GetNumElements() * (DIM+1)];
454 this->ExportToMesher(unused_map, mesher_input, mesher_input.tetrahedronlist);
457 tetgen::tetrahedralize((
char*)
"Qzro2", &mesher_input, &mesher_output);
459 this->ImportFromMesher(mesher_output, mesher_output.numberoftetrahedra, mesher_output.tetrahedronlist, mesher_output.numberoftrifaces, mesher_output.trifacelist,
nullptr);