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
00030
00031
00032
00033
00034
00035
00036 #include "FineCoarseMeshPair.hpp"
00037
00038 template<unsigned DIM>
00039 FineCoarseMeshPair<DIM>::FineCoarseMeshPair(AbstractTetrahedralMesh<DIM,DIM>& rFineMesh, AbstractTetrahedralMesh<DIM,DIM>& rCoarseMesh)
00040 : mrFineMesh(rFineMesh),
00041 mrCoarseMesh(rCoarseMesh),
00042 mpFineMeshBoxCollection(NULL),
00043 mpCoarseMeshBoxCollection(NULL)
00044 {
00045 ResetStatisticsVariables();
00046 }
00047
00048 template<unsigned DIM>
00049 const AbstractTetrahedralMesh<DIM,DIM>& FineCoarseMeshPair<DIM>::GetFineMesh() const
00050 {
00051 return mrFineMesh;
00052 }
00053
00054 template<unsigned DIM>
00055 const AbstractTetrahedralMesh<DIM,DIM>& FineCoarseMeshPair<DIM>::GetCoarseMesh() const
00056 {
00057 return mrCoarseMesh;
00058 }
00059
00060 template<unsigned DIM>
00061 FineCoarseMeshPair<DIM>::~FineCoarseMeshPair()
00062 {
00063 DeleteFineBoxCollection();
00064 DeleteCoarseBoxCollection();
00065 }
00066
00067 template<unsigned DIM>
00068 void FineCoarseMeshPair<DIM>::DeleteFineBoxCollection()
00069 {
00070 if (mpFineMeshBoxCollection != NULL)
00071 {
00072 delete mpFineMeshBoxCollection;
00073 mpFineMeshBoxCollection = NULL;
00074 }
00075 }
00076
00077 template<unsigned DIM>
00078 void FineCoarseMeshPair<DIM>::DeleteCoarseBoxCollection()
00079 {
00080 if (mpCoarseMeshBoxCollection != NULL)
00081 {
00082 delete mpCoarseMeshBoxCollection;
00083 mpCoarseMeshBoxCollection = NULL;
00084 }
00085 }
00086
00088
00090
00091 template<unsigned DIM>
00092 void FineCoarseMeshPair<DIM>::SetUpBoxesOnFineMesh(double boxWidth)
00093 {
00094 SetUpBoxes(mrFineMesh, boxWidth, mpFineMeshBoxCollection);
00095 }
00096
00097 template<unsigned DIM>
00098 void FineCoarseMeshPair<DIM>::SetUpBoxesOnCoarseMesh(double boxWidth)
00099 {
00100 SetUpBoxes(mrCoarseMesh, boxWidth, mpCoarseMeshBoxCollection);
00101 }
00102
00103 template<unsigned DIM>
00104 void FineCoarseMeshPair<DIM>::SetUpBoxes(AbstractTetrahedralMesh<DIM, DIM>& rMesh,
00105 double boxWidth,
00106 BoxCollection<DIM>*& rpBoxCollection)
00107 {
00108 if (rpBoxCollection)
00109 {
00110 delete rpBoxCollection;
00111 rpBoxCollection = NULL;
00112 }
00113
00114
00115 ChasteCuboid<DIM> bounding_box = rMesh.CalculateBoundingBox();
00116
00117
00118 c_vector<double,2*DIM> extended_min_and_max;
00119 for (unsigned i=0; i<DIM; i++)
00120 {
00121 double width = bounding_box.GetWidth(i);
00122
00123
00124 extended_min_and_max(2*i) = bounding_box.rGetLowerCorner()[i] - 0.05*width;
00125
00126
00127 extended_min_and_max(2*i+1) = bounding_box.rGetUpperCorner()[i] + 0.05*width;
00128 }
00129
00130 if (boxWidth < 0)
00131 {
00132
00133
00134
00135
00136
00137
00138
00139 boxWidth = (extended_min_and_max(1) - extended_min_and_max(0))/19.000000001;
00140
00141
00142 c_vector<double, 2> min_max_edge_length = rMesh.CalculateMinMaxEdgeLengths();
00143
00144 if (boxWidth < min_max_edge_length[1])
00145 {
00146 boxWidth = 1.1*min_max_edge_length[1];
00147 }
00148 }
00149
00150 rpBoxCollection = new BoxCollection<DIM>(boxWidth, extended_min_and_max);
00151 rpBoxCollection->SetupAllLocalBoxes();
00152
00153
00154 for (unsigned i=0; i<rMesh.GetNumElements(); i++)
00155 {
00156 Element<DIM,DIM>* p_element = rMesh.GetElement(i);
00157
00158 std::set<unsigned> box_indices_each_node_this_elem;
00159 for (unsigned j=0; j<DIM+1; j++)
00160 {
00161 Node<DIM>* p_node = p_element->GetNode(j);
00162 unsigned box_index = rpBoxCollection->CalculateContainingBox(p_node);
00163 box_indices_each_node_this_elem.insert(box_index);
00164 }
00165
00166 for (std::set<unsigned>::iterator iter = box_indices_each_node_this_elem.begin();
00167 iter != box_indices_each_node_this_elem.end();
00168 ++iter)
00169 {
00170 rpBoxCollection->rGetBox( *iter ).AddElement(p_element);
00171 }
00172 }
00173 }
00174
00176
00177
00178
00179
00180
00182
00183 template<unsigned DIM>
00184 void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseQuadPoints(GaussianQuadratureRule<DIM>& rQuadRule,
00185 bool safeMode)
00186 {
00187 if (mpFineMeshBoxCollection == NULL)
00188 {
00189 EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseQuadPoints()");
00190 }
00191
00192
00193 QuadraturePointsGroup<DIM> quad_point_posns(mrCoarseMesh, rQuadRule);
00194
00195
00196 mFineMeshElementsAndWeights.resize(quad_point_posns.Size());
00197
00198 #define COVERAGE_IGNORE
00199 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00200 {
00201 std::cout << "\nComputing fine elements and weights for coarse quad points\n";
00202 }
00203 #undef COVERAGE_IGNORE
00204
00205
00206 ResetStatisticsVariables();
00207 for (unsigned i=0; i<quad_point_posns.Size(); i++)
00208 {
00209 #define COVERAGE_IGNORE
00210 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00211 {
00212 std::cout << "\t" << i << " of " << quad_point_posns.Size() << std::flush;
00213 }
00214 #undef COVERAGE_IGNORE
00215
00216
00217 unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( quad_point_posns.rGet(i) );
00218
00219
00220 ChastePoint<DIM> point(quad_point_posns.rGet(i));
00221
00222 ComputeFineElementAndWeightForGivenPoint(point, safeMode, box_for_this_point, i);
00223 }
00224
00225 if (mStatisticsCounters[1] > 0)
00226 {
00227 WARNING(mStatisticsCounters[1] << " of " << quad_point_posns.Size() << " coarse-mesh quadrature points were outside the fine mesh");
00228 }
00229 }
00230
00231 template<unsigned DIM>
00232 void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseNodes(bool safeMode)
00233 {
00234 if (mpFineMeshBoxCollection==NULL)
00235 {
00236 EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseNodes()");
00237 }
00238
00239
00240 mFineMeshElementsAndWeights.resize(mrCoarseMesh.GetNumNodes());
00241
00242 #define COVERAGE_IGNORE
00243 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00244 {
00245 std::cout << "\nComputing fine elements and weights for coarse nodes\n";
00246 }
00247 #undef COVERAGE_IGNORE
00248
00249
00250 ResetStatisticsVariables();
00251 for (unsigned i=0; i<mrCoarseMesh.GetNumNodes(); i++)
00252 {
00253 #define COVERAGE_IGNORE
00254 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00255 {
00256 std::cout << "\t" << i << " of " << mrCoarseMesh.GetNumNodes() << std::flush;
00257 }
00258 #undef COVERAGE_IGNORE
00259
00260 Node<DIM>* p_node = mrCoarseMesh.GetNode(i);
00261
00262
00263 unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( p_node->rGetModifiableLocation() );
00264
00265
00266 ChastePoint<DIM> point(p_node->rGetLocation());
00267
00268 ComputeFineElementAndWeightForGivenPoint(point, safeMode, box_for_this_point, i);
00269 }
00270 }
00271
00278 template<unsigned DIM>
00279 void FineCoarseMeshPair<DIM>::ComputeFineElementAndWeightForGivenPoint(ChastePoint<DIM>& rPoint,
00280 bool safeMode,
00281 unsigned boxForThisPoint,
00282 unsigned index)
00283 {
00284 std::set<unsigned> test_element_indices;
00285
00286
00287
00288
00289
00290
00291
00292 CollectElementsInContainingBox(mpFineMeshBoxCollection, boxForThisPoint, test_element_indices);
00293
00294 unsigned elem_index;
00295 c_vector<double,DIM+1> weight;
00296
00297 try
00298 {
00299
00300
00301 elem_index = mrFineMesh.GetContainingElementIndex(rPoint,
00302 false,
00303 test_element_indices,
00304 true );
00305 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint);
00306
00307 mStatisticsCounters[0]++;
00308 }
00309 catch(Exception&)
00310 {
00311
00312 test_element_indices.clear();
00313
00314 CollectElementsInLocalBoxes(mpFineMeshBoxCollection, boxForThisPoint, test_element_indices);
00315
00316 try
00317 {
00318 elem_index = mrFineMesh.GetContainingElementIndex(rPoint, false, test_element_indices, true);
00319 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint);
00320 mStatisticsCounters[0]++;
00321 }
00322 catch(Exception&)
00323 {
00324 if (safeMode)
00325 {
00326
00327 try
00328 {
00329 elem_index = mrFineMesh.GetContainingElementIndex(rPoint, false);
00330 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint);
00331 mStatisticsCounters[0]++;
00332
00333 }
00334 catch (Exception&)
00335 {
00336
00337 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices);
00338 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint);
00339
00340 mNotInMesh.push_back(index);
00341 mNotInMeshNearestElementWeights.push_back(weight);
00342 mStatisticsCounters[1]++;
00343 }
00344 }
00345 else
00346 {
00347 assert(test_element_indices.size() > 0);
00348
00349
00350
00351
00352
00353
00354 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices);
00355 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint);
00356
00357 mNotInMesh.push_back(index);
00358 mNotInMeshNearestElementWeights.push_back(weight);
00359 mStatisticsCounters[1]++;
00360 }
00361 }
00362 }
00363
00364 mFineMeshElementsAndWeights[index].ElementNum = elem_index;
00365 mFineMeshElementsAndWeights[index].Weights = weight;
00366 }
00367
00369
00370
00371
00372
00373
00375
00376 template<unsigned DIM>
00377 void FineCoarseMeshPair<DIM>::ComputeCoarseElementsForFineNodes(bool safeMode)
00378 {
00379 if (mpCoarseMeshBoxCollection==NULL)
00380 {
00381 EXCEPTION("Call SetUpBoxesOnCoarseMesh() before ComputeCoarseElementsForFineNodes()");
00382 }
00383
00384 #define COVERAGE_IGNORE
00385 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00386 {
00387 std::cout << "\nComputing coarse elements for fine nodes\n";
00388 }
00389 #undef COVERAGE_IGNORE
00390
00391 mCoarseElementsForFineNodes.resize(mrFineMesh.GetNumNodes());
00392
00393 ResetStatisticsVariables();
00394 for (unsigned i=0; i<mCoarseElementsForFineNodes.size(); i++)
00395 {
00396 #define COVERAGE_IGNORE
00397 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00398 {
00399 std::cout << "\t" << i << " of " << mCoarseElementsForFineNodes.size() << std::flush;
00400 }
00401 #undef COVERAGE_IGNORE
00402
00403 ChastePoint<DIM> point = mrFineMesh.GetNode(i)->GetPoint();
00404
00405
00406 unsigned box_for_this_point = mpCoarseMeshBoxCollection->CalculateContainingBox(mrFineMesh.GetNode(i)->rGetModifiableLocation());
00407
00408 mCoarseElementsForFineNodes[i] = ComputeCoarseElementForGivenPoint(point, safeMode, box_for_this_point);
00409 }
00410 }
00411
00412 template<unsigned DIM>
00413 void FineCoarseMeshPair<DIM>::ComputeCoarseElementsForFineElementCentroids(bool safeMode)
00414 {
00415 if (mpCoarseMeshBoxCollection==NULL)
00416 {
00417 EXCEPTION("Call SetUpBoxesOnCoarseMesh() before ComputeCoarseElementsForFineElementCentroids()");
00418 }
00419
00420 #define COVERAGE_IGNORE
00421 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00422 {
00423 std::cout << "\nComputing coarse elements for fine element centroids\n";
00424 }
00425 #undef COVERAGE_IGNORE
00426
00427 mCoarseElementsForFineElementCentroids.resize(mrFineMesh.GetNumElements());
00428
00429 ResetStatisticsVariables();
00430 for (unsigned i=0; i<mrFineMesh.GetNumElements(); i++)
00431 {
00432 #define COVERAGE_IGNORE
00433 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose"))
00434 {
00435 std::cout << "\t" << i << " of " << mrFineMesh.GetNumElements() << std::flush;
00436 }
00437 #undef COVERAGE_IGNORE
00438
00439 c_vector<double,DIM> point_cvec = mrFineMesh.GetElement(i)->CalculateCentroid();
00440 ChastePoint<DIM> point(point_cvec);
00441
00442
00443 unsigned box_for_this_point = mpCoarseMeshBoxCollection->CalculateContainingBox( point_cvec );
00444
00445 mCoarseElementsForFineElementCentroids[i] = ComputeCoarseElementForGivenPoint(point, safeMode, box_for_this_point);
00446 }
00447 }
00448
00449 template<unsigned DIM>
00450 unsigned FineCoarseMeshPair<DIM>::ComputeCoarseElementForGivenPoint(ChastePoint<DIM>& rPoint,
00451 bool safeMode,
00452 unsigned boxForThisPoint)
00453 {
00460 std::set<unsigned> test_element_indices;
00461 CollectElementsInContainingBox(mpCoarseMeshBoxCollection, boxForThisPoint, test_element_indices);
00462
00463 unsigned elem_index;
00464
00465 try
00466 {
00467 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint,
00468 false,
00469 test_element_indices,
00470 true );
00471
00472 mStatisticsCounters[0]++;
00473 }
00474 catch(Exception&)
00475 {
00476
00477 test_element_indices.clear();
00478 CollectElementsInLocalBoxes(mpCoarseMeshBoxCollection, boxForThisPoint, test_element_indices);
00479
00480 try
00481 {
00482 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint, false, test_element_indices, true);
00483 mStatisticsCounters[0]++;
00484 }
00485 catch(Exception&)
00486 {
00487 if (safeMode)
00488 {
00489
00490 try
00491 {
00492 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint, false);
00493
00494 mStatisticsCounters[0]++;
00495 }
00496 catch (Exception&)
00497 {
00498
00499 elem_index = mrCoarseMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices);
00500 mStatisticsCounters[1]++;
00501 }
00502 }
00503 else
00504 {
00505 assert(test_element_indices.size() > 0);
00506
00507
00508
00509
00510
00511
00512 elem_index = mrCoarseMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices);
00513 mStatisticsCounters[1]++;
00514 }
00515 }
00516 }
00517
00518 return elem_index;
00519 }
00520
00522
00524
00525 template<unsigned DIM>
00526 void FineCoarseMeshPair<DIM>::CollectElementsInContainingBox(BoxCollection<DIM>*& rpBoxCollection,
00527 unsigned boxIndex,
00528 std::set<unsigned>& rElementIndices)
00529 {
00530 for (typename std::set<Element<DIM,DIM>*>::iterator elem_iter = rpBoxCollection->rGetBox(boxIndex).rGetElementsContained().begin();
00531 elem_iter != rpBoxCollection->rGetBox(boxIndex).rGetElementsContained().end();
00532 ++elem_iter)
00533 {
00534 rElementIndices.insert((*elem_iter)->GetIndex());
00535 }
00536 }
00537
00538 template<unsigned DIM>
00539 void FineCoarseMeshPair<DIM>::CollectElementsInLocalBoxes(BoxCollection<DIM>*& rpBoxCollection,
00540 unsigned boxIndex,
00541 std::set<unsigned>& rElementIndices)
00542 {
00543 std::set<unsigned> local_boxes = rpBoxCollection->GetLocalBoxes(boxIndex);
00544 for (std::set<unsigned>::iterator local_box_iter = local_boxes.begin();
00545 local_box_iter != local_boxes.end();
00546 ++local_box_iter)
00547 {
00548 for (typename std::set<Element<DIM,DIM>*>::iterator elem_iter = rpBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().begin();
00549 elem_iter != rpBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().end();
00550 ++elem_iter)
00551 {
00552 rElementIndices.insert((*elem_iter)->GetIndex());
00553 }
00554 }
00555 }
00556
00558
00560
00561 template<unsigned DIM>
00562 void FineCoarseMeshPair<DIM>::ResetStatisticsVariables()
00563 {
00564 mNotInMesh.clear();
00565 mNotInMeshNearestElementWeights.clear();
00566 mStatisticsCounters.resize(2, 0u);
00567 }
00568
00569 template<unsigned DIM>
00570 void FineCoarseMeshPair<DIM>::PrintStatistics()
00571 {
00572 std::cout << "\nFineCoarseMeshPair statistics for the last-called method:\n";
00573
00574
00575
00576
00577
00578
00579 std::cout << "\tNum points for which containing element was found: " << mStatisticsCounters[0] << "\n";
00580 std::cout << "\tNum points for which no containing element was found = " << mStatisticsCounters[1] << "\n";
00581
00582 if (mNotInMesh.size() > 0)
00583 {
00584 std::cout << "\tIndices and weights for points (nodes/quad points) for which no containing element was found:\n";
00585 for (unsigned i=0; i<mNotInMesh.size(); i++)
00586 {
00587 std::cout << "\t\t" << mNotInMesh[i] << ", " << mNotInMeshNearestElementWeights[i] << "\n";
00588 }
00589 }
00590 }
00591
00593
00595
00596 template class FineCoarseMeshPair<1>;
00597 template class FineCoarseMeshPair<2>;
00598 template class FineCoarseMeshPair<3>;