00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "AbstractTetrahedralMesh.hpp"
00030
00032
00034
00035
00036 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00037 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::SetElementOwnerships(unsigned lo, unsigned hi)
00038 {
00039 assert(hi >= lo);
00040 for (unsigned element_index=0; element_index<mElements.size(); element_index++)
00041 {
00042 Element<ELEMENT_DIM, SPACE_DIM>* p_element = mElements[element_index];
00043 p_element->SetOwnership(false);
00044 for (unsigned local_node_index=0; local_node_index< p_element->GetNumNodes(); local_node_index++)
00045 {
00046 unsigned global_node_index = p_element->GetNodeGlobalIndex(local_node_index);
00047 if (lo<=global_node_index && global_node_index<hi)
00048 {
00049 p_element->SetOwnership(true);
00050 break;
00051 }
00052 }
00053 }
00054 }
00055
00056 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00057 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::AbstractTetrahedralMesh()
00058 : mMeshIsLinear(true)
00059 {
00060 }
00061
00062 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00063 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::~AbstractTetrahedralMesh()
00064 {
00065
00066 for (unsigned i=0; i<mElements.size(); i++)
00067 {
00068 delete mElements[i];
00069 }
00070
00071 for (unsigned i=0; i<mBoundaryElements.size(); i++)
00072 {
00073 delete mBoundaryElements[i];
00074 }
00075 }
00076
00077 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00078 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00079 {
00080 return mElements.size();
00081 }
00082
00083 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00084 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumLocalElements() const
00085 {
00086 return GetNumElements();
00087 }
00088
00089 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00090 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllElements() const
00091 {
00092 return mElements.size();
00093 }
00094
00095 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00096 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllBoundaryElements() const
00097 {
00098 return mBoundaryElements.size();
00099 }
00100
00101 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00102 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryElements() const
00103 {
00104 return mBoundaryElements.size();
00105 }
00106
00107
00108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00109 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElement(unsigned index) const
00110 {
00111 unsigned local_index = SolveElementMapping(index);
00112 return mElements[local_index];
00113 }
00114
00115 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00116 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElement(unsigned index) const
00117 {
00118 unsigned local_index = SolveBoundaryElementMapping(index);
00119 return mBoundaryElements[local_index];
00120 }
00121
00122 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorBegin() const
00124 {
00125 return mBoundaryElements.begin();
00126 }
00127
00128 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00129 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorEnd() const
00130 {
00131 return mBoundaryElements.end();
00132 }
00133
00134 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00135 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetInverseJacobianForElement(
00136 unsigned elementIndex,
00137 c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00138 double& rJacobianDeterminant,
00139 c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const
00140 {
00141 mElements[SolveElementMapping(elementIndex)]->CalculateInverseJacobian(rJacobian, rJacobianDeterminant, rInverseJacobian);
00142 }
00143
00144 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00145 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetWeightedDirectionForBoundaryElement(
00146 unsigned elementIndex,
00147 c_vector<double, SPACE_DIM>& rWeightedDirection,
00148 double& rJacobianDeterminant) const
00149 {
00150 mBoundaryElements[SolveBoundaryElementMapping(elementIndex)]->CalculateWeightedDirection(rWeightedDirection, rJacobianDeterminant );
00151 }
00152
00153
00154 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00155 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructLinearMesh(unsigned width)
00156 {
00157 assert(ELEMENT_DIM == 1);
00158
00159 for (unsigned node_index=0; node_index<=width; node_index++)
00160 {
00161 Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index, node_index==0 || node_index==width, node_index);
00162 this->mNodes.push_back(p_node);
00163 if (node_index==0)
00164 {
00165 this->mBoundaryNodes.push_back(p_node);
00166 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(0, p_node) );
00167 }
00168 if (node_index==width)
00169 {
00170 this->mBoundaryNodes.push_back(p_node);
00171 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(1, p_node) );
00172 }
00173 if (node_index>0)
00174 {
00175 std::vector<Node<SPACE_DIM>*> nodes;
00176 nodes.push_back(this->mNodes[node_index-1]);
00177 nodes.push_back(this->mNodes[node_index]);
00178 this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(node_index-1, nodes) );
00179 }
00180 }
00181
00182 this->RefreshMesh();
00183 }
00184
00185
00186 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00187 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructRectangularMesh(unsigned width, unsigned height, bool stagger)
00188 {
00189 assert(SPACE_DIM == 2);
00190 assert(ELEMENT_DIM == 2);
00191
00192
00193 unsigned node_index=0;
00194 for (unsigned j=0; j<height+1; j++)
00195 {
00196 for (unsigned i=0; i<width+1; i++)
00197 {
00198 bool is_boundary=false;
00199 if (i==0 || j==0 || i==width || j==height)
00200 {
00201 is_boundary=true;
00202 }
00203
00204 assert(node_index==(width+1)*(j) + i);
00205 Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index++, is_boundary, i, j);
00206 this->mNodes.push_back(p_node);
00207 if (is_boundary)
00208 {
00209 this->mBoundaryNodes.push_back(p_node);
00210 }
00211 }
00212 }
00213
00214
00215 unsigned belem_index=0;
00216
00217 for (unsigned i=0; i<width; i++)
00218 {
00219 std::vector<Node<SPACE_DIM>*> nodes;
00220 nodes.push_back(this->mNodes[height*(width+1)+i]);
00221 nodes.push_back(this->mNodes[height*(width+1)+i+1]);
00222 assert(belem_index==i);
00223 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00224 }
00225
00226 for (unsigned j=1; j<=height; j++)
00227 {
00228 std::vector<Node<SPACE_DIM>*> nodes;
00229 nodes.push_back(this->mNodes[(width+1)*(j+1)-1]);
00230 nodes.push_back(this->mNodes[(width+1)*j-1]);
00231 assert(belem_index==width+j-1);
00232 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00233 }
00234
00235 for (unsigned i=0; i<width; i++)
00236 {
00237 std::vector<Node<SPACE_DIM>*> nodes;
00238 nodes.push_back(this->mNodes[i+1]);
00239 nodes.push_back(this->mNodes[i]);
00240 assert(belem_index==width+height+i);
00241 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00242 }
00243
00244 for (unsigned j=0; j<height; j++)
00245 {
00246 std::vector<Node<SPACE_DIM>*> nodes;
00247 nodes.push_back(this->mNodes[(width+1)*(j+1)]);
00248 nodes.push_back(this->mNodes[(width+1)*(j)]);
00249 assert(belem_index==2*width+height+j);
00250 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00251 }
00252
00253
00254 unsigned elem_index = 0;
00255 for (unsigned j=0; j<height; j++)
00256 {
00257 for (unsigned i=0; i<width; i++)
00258 {
00259 unsigned parity=(i+(height-j))%2;
00260 unsigned nw=(j+1)*(width+1)+i;
00261 unsigned sw=(j)*(width+1)+i;
00262 std::vector<Node<SPACE_DIM>*> upper_nodes;
00263 upper_nodes.push_back(this->mNodes[nw]);
00264 upper_nodes.push_back(this->mNodes[nw+1]);
00265 if (stagger==false || parity == 1)
00266 {
00267 upper_nodes.push_back(this->mNodes[sw+1]);
00268 }
00269 else
00270 {
00271 upper_nodes.push_back(this->mNodes[sw]);
00272 }
00273 assert(elem_index==2*(j*width+i));
00274 this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++,upper_nodes));
00275 std::vector<Node<SPACE_DIM>*> lower_nodes;
00276 lower_nodes.push_back(this->mNodes[sw+1]);
00277 lower_nodes.push_back(this->mNodes[sw]);
00278 if (stagger==false ||parity == 1)
00279 {
00280 lower_nodes.push_back(this->mNodes[nw]);
00281 }
00282 else
00283 {
00284 lower_nodes.push_back(this->mNodes[nw+1]);
00285 }
00286 this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++,lower_nodes));
00287 }
00288 }
00289
00290 this->RefreshMesh();
00291 }
00292
00293
00294
00295
00296 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00297 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructCuboid(unsigned width,
00298 unsigned height,
00299 unsigned depth)
00300 {
00301 assert(SPACE_DIM == 3);
00302 assert(ELEMENT_DIM == 3);
00303
00304
00305 unsigned node_index = 0;
00306 for (unsigned k=0; k<depth+1; k++)
00307 {
00308 for (unsigned j=0; j<height+1; j++)
00309 {
00310 for (unsigned i=0; i<width+1; i++)
00311 {
00312 bool is_boundary = false;
00313 if (i==0 || j==0 || k==0 || i==width || j==height || k==depth)
00314 {
00315 is_boundary = true;
00316 }
00317 assert(node_index == (k*(height+1)+j)*(width+1)+i);
00318 Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index++, is_boundary, i, j, k);
00319
00320 this->mNodes.push_back(p_node);
00321 if (is_boundary)
00322 {
00323 this->mBoundaryNodes.push_back(p_node);
00324 }
00325 }
00326 }
00327 }
00328
00329
00330
00331 unsigned elem_index = 0;
00332 unsigned belem_index = 0;
00333 unsigned element_nodes[6][4] = {{0, 1, 5, 7}, {0, 1, 3, 7},
00334 {0, 2, 3, 7}, {0, 2, 6, 7},
00335 {0, 4, 6, 7}, {0, 4, 5, 7}};
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 std::vector<Node<SPACE_DIM>*> tetrahedra_nodes;
00349
00350 for (unsigned k=0; k<depth; k++)
00351 {
00352 if (k!=0)
00353 {
00354
00355 assert(belem_index == 2*(height*width+k*2*(height+width)) );
00356 }
00357 for (unsigned j=0; j<height; j++)
00358 {
00359 for (unsigned i=0; i<width; i++)
00360 {
00361
00362 unsigned global_node_indices[8];
00363 unsigned local_node_index = 0;
00364
00365 for (unsigned z = 0; z < 2; z++)
00366 {
00367 for (unsigned y = 0; y < 2; y++)
00368 {
00369 for (unsigned x = 0; x < 2; x++)
00370 {
00371 global_node_indices[local_node_index] = i+x+(width+1)*(j+y+(height+1)*(k+z));
00372
00373 local_node_index++;
00374 }
00375 }
00376 }
00377
00378 for (unsigned m = 0; m < 6; m++)
00379 {
00380
00381
00382 tetrahedra_nodes.clear();
00383
00384 for (unsigned n = 0; n < 4; n++)
00385 {
00386 tetrahedra_nodes.push_back(this->mNodes[global_node_indices[element_nodes[m][n]]]);
00387 }
00388
00389 assert(elem_index == 6 * ((k*height+j)*width+i)+m );
00390 this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++, tetrahedra_nodes));
00391 }
00392
00393
00394 std::vector<Node<SPACE_DIM>*> triangle_nodes;
00395
00396 if (i == 0)
00397 {
00398 triangle_nodes.clear();
00399 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00400 triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00401 triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00402 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00403 triangle_nodes.clear();
00404 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00405 triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00406 triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00407 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00408 }
00409 if (i == width-1)
00410 {
00411 triangle_nodes.clear();
00412 triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00413 triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00414 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00415 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00416 triangle_nodes.clear();
00417 triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00418 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00419 triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00420 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00421 }
00422 if (j == 0)
00423 {
00424 triangle_nodes.clear();
00425 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00426 triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00427 triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00428 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00429 triangle_nodes.clear();
00430 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00431 triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00432 triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00433 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00434 }
00435 if (j == height-1)
00436 {
00437 triangle_nodes.clear();
00438 triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00439 triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00440 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00441 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00442 triangle_nodes.clear();
00443 triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00444 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00445 triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00446 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00447 }
00448 if (k == 0)
00449 {
00450 triangle_nodes.clear();
00451 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00452 triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00453 triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00454 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00455 triangle_nodes.clear();
00456 triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00457 triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00458 triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00459 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00460 }
00461 if (k == depth-1)
00462 {
00463 triangle_nodes.clear();
00464 triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00465 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00466 triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00467 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00468 triangle_nodes.clear();
00469 triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00470 triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00471 triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00472 this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00473 }
00474 }
00475 }
00476 }
00477
00478 this->RefreshMesh();
00479 }
00480
00481 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00482 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructRegularSlabMesh(double spaceStep, double width, double height, double depth)
00483 {
00484 assert(spaceStep>0);
00485 assert(width>0);
00486 if (ELEMENT_DIM > 1)
00487 {
00488 assert(height>0);
00489 }
00490 if (ELEMENT_DIM > 2)
00491 {
00492 assert(depth>0);
00493 }
00494 unsigned num_elem_x=(unsigned)((width+0.5*spaceStep)/spaceStep);
00495 unsigned num_elem_y=(unsigned)((height+0.5*spaceStep)/spaceStep);
00496 unsigned num_elem_z=(unsigned)((depth+0.5*spaceStep)/spaceStep);
00497
00498 double actual_width_x=num_elem_x*spaceStep;
00499 double actual_width_y=num_elem_y*spaceStep;
00500 double actual_width_z=num_elem_z*spaceStep;
00501
00502 if ( fabs (actual_width_x - width) > DBL_EPSILON
00503 ||fabs (actual_width_y - height) > DBL_EPSILON
00504 ||fabs (actual_width_z - depth) > DBL_EPSILON )
00505 {
00506 EXCEPTION("Space step does not divide the size of the mesh");
00507 }
00508
00509 switch (ELEMENT_DIM)
00510 {
00511 case 1:
00512 this->ConstructLinearMesh(num_elem_x);
00513 break;
00514 case 2:
00515 this->ConstructRectangularMesh(num_elem_x, num_elem_y, true);
00516 break;
00517 default:
00518 case 3:
00519 this->ConstructCuboid(num_elem_x, num_elem_y, num_elem_z);
00520 }
00521 this->Scale(spaceStep, spaceStep, spaceStep);
00522 }
00523
00524 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00525 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex )
00526 {
00527
00528 unsigned tie_break_index = this->GetBoundaryElement(faceIndex)->GetNodeGlobalIndex(0);
00529
00530
00531 if (this->GetDistributedVectorFactory()->IsGlobalIndexLocal(tie_break_index))
00532 {
00533 return true;
00534 }
00535 else
00536 {
00537 return false;
00538 }
00539 }
00540
00541 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00542 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::CalculateDesignatedOwnershipOfElement( unsigned elementIndex )
00543 {
00544
00545 unsigned tie_break_index = this->GetElement(elementIndex)->GetNodeGlobalIndex(0);
00546
00547
00548 if (this->GetDistributedVectorFactory()->IsGlobalIndexLocal(tie_break_index))
00549 {
00550 return true;
00551 }
00552 else
00553 {
00554 return false;
00555 }
00556 }
00557
00558 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00559 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::CalculateMaximumNodeConnectivityPerProcess() const
00560 {
00561 unsigned max_num=0u;
00562 unsigned connected_node_index=0u;
00563 for (unsigned local_node_index=0; local_node_index<this->mNodes.size(); local_node_index++)
00564 {
00565 unsigned num=this->mNodes[local_node_index]->GetNumContainingElements();
00566 if (num>max_num)
00567 {
00568 max_num=num;
00569 connected_node_index=local_node_index;
00570 }
00571 }
00572 if (max_num == 0u)
00573 {
00574 #define COVERAGE_IGNORE
00575
00576
00577
00578
00579
00580 assert(this->mNodes.size() == 0u);
00581 return(1u);
00582
00583
00584
00585 #undef COVERAGE_IGNORE
00586 }
00587
00588 std::set<unsigned> forward_star_nodes;
00589 unsigned nodes_per_element = this->mElements[0]->GetNumNodes();
00590 for (typename Node<SPACE_DIM>::ContainingElementIterator it = this->mNodes[connected_node_index]->ContainingElementsBegin();
00591 it != this->mNodes[connected_node_index]->ContainingElementsEnd();
00592 ++it)
00593 {
00594 Element<ELEMENT_DIM, SPACE_DIM>* p_elem=this->GetElement(*it);
00595 for (unsigned i=0; i<nodes_per_element; i++)
00596 {
00597 forward_star_nodes.insert(p_elem->GetNodeGlobalIndex(i));
00598 }
00599 }
00600 return forward_star_nodes.size();
00601 }
00602
00603 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00604 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetHaloNodeIndices(std::vector<unsigned>& rHaloIndices) const
00605 {
00606
00607 rHaloIndices.clear();
00608 }
00609
00610 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00611 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructFromMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rOtherMesh)
00612 {
00613 for (unsigned i=0; i<rOtherMesh.GetNumNodes(); i++)
00614 {
00615 Node<SPACE_DIM>* p_node = rOtherMesh.GetNode(i);
00616 assert(!p_node->IsDeleted());
00617 c_vector<double, SPACE_DIM> location=p_node->rGetLocation();
00618 bool is_boundary=p_node->IsBoundaryNode();
00619
00620 Node<SPACE_DIM>* p_node_copy = new Node<SPACE_DIM>(i, location, is_boundary);
00621 this->mNodes.push_back( p_node_copy );
00622 if (is_boundary)
00623 {
00624 this->mBoundaryNodes.push_back( p_node_copy );
00625 }
00626 }
00627
00628 for (unsigned i=0; i<rOtherMesh.GetNumElements(); i++)
00629 {
00630 Element<ELEMENT_DIM, SPACE_DIM>* p_elem = rOtherMesh.GetElement(i);
00631 assert(!p_elem->IsDeleted());
00632 std::vector<Node<SPACE_DIM>*> nodes_for_element;
00633 for (unsigned j=0; j<p_elem->GetNumNodes(); j++)
00634 {
00635 nodes_for_element.push_back(this->mNodes[ p_elem->GetNodeGlobalIndex(j) ]);
00636 }
00637 Element<ELEMENT_DIM, SPACE_DIM>* p_elem_copy=new Element<ELEMENT_DIM, SPACE_DIM>(i, nodes_for_element);
00638 p_elem_copy->RegisterWithNodes();
00639 this->mElements.push_back(p_elem_copy);
00640 }
00641
00642 for (unsigned i=0; i<rOtherMesh.GetNumBoundaryElements(); i++)
00643 {
00644 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_b_elem = rOtherMesh.GetBoundaryElement(i);
00645 assert(!p_b_elem->IsDeleted());
00646 std::vector<Node<SPACE_DIM>*> nodes_for_element;
00647 for (unsigned j=0; j<p_b_elem->GetNumNodes(); j++)
00648 {
00649 nodes_for_element.push_back(this->mNodes[ p_b_elem->GetNodeGlobalIndex(j) ]);
00650 }
00651 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_b_elem_copy=new BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>(i, nodes_for_element);
00652 p_b_elem_copy->RegisterWithNodes();
00653 this->mBoundaryElements.push_back(p_b_elem_copy);
00654 }
00655 this->RefreshMesh();
00656
00657 }
00658
00659
00661
00663
00664 template class AbstractTetrahedralMesh<1,1>;
00665 template class AbstractTetrahedralMesh<1,2>;
00666 template class AbstractTetrahedralMesh<1,3>;
00667 template class AbstractTetrahedralMesh<2,2>;
00668 template class AbstractTetrahedralMesh<2,3>;
00669 template class AbstractTetrahedralMesh<3,3>;