Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 #include "FineCoarseMeshPair.hpp" 00037 00038 template<unsigned DIM> 00039 FineCoarseMeshPair<DIM>::FineCoarseMeshPair(TetrahedralMesh<DIM,DIM>& rFineMesh, TetrahedralMesh<DIM,DIM>& rCoarseMesh) 00040 : mrFineMesh(rFineMesh), 00041 mrCoarseMesh(rCoarseMesh) 00042 { 00043 mpFineMeshBoxCollection = NULL; 00044 mpCoarseMeshBoxCollection = NULL; 00045 ResetStatisticsVariables(); 00046 } 00047 00048 template<unsigned DIM> 00049 const TetrahedralMesh<DIM,DIM>& FineCoarseMeshPair<DIM>::GetFineMesh() const 00050 { 00051 return mrFineMesh; 00052 } 00053 00054 template<unsigned DIM> 00055 const TetrahedralMesh<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 // Setting up boxes methods 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(TetrahedralMesh<DIM,DIM>& rMesh, 00105 double boxWidth, 00106 BoxCollection<DIM>*& rpBoxCollection) 00107 { 00108 if (rpBoxCollection) 00109 { 00110 delete rpBoxCollection; 00111 rpBoxCollection = NULL; 00112 } 00113 00114 // Compute min and max values for the fine mesh nodes 00115 ChasteCuboid<DIM> bounding_box = rMesh.CalculateBoundingBox(); 00116 00117 // Set up the boxes using a domain that is slightly larger than the fine mesh 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 // Subtract from the minima 00124 extended_min_and_max(2*i) = bounding_box.rGetLowerCorner()[i] - 0.05*width; 00125 00126 // Add to the maxima 00127 extended_min_and_max(2*i+1) = bounding_box.rGetUpperCorner()[i] + 0.05*width; 00128 } 00129 00130 if (boxWidth < 0) 00131 { 00132 /* 00133 * Use default value = max(max_edge_length, w20), where w20 is the width 00134 * corresponding to 20 boxes in the x-direction. 00135 * 00136 * BoxCollection creates an extra box so divide by 19 not 20. Add a little 00137 * bit on to ensure minor numerical fluctuations don't change the answer. 00138 */ 00139 boxWidth = (extended_min_and_max(1) - extended_min_and_max(0))/19.000000001; 00140 00141 // Determine the maximum edge length 00142 double max_edge_length = -1; 00143 00144 for (typename TetrahedralMesh<DIM,DIM>::EdgeIterator edge_iterator = rMesh.EdgesBegin(); 00145 edge_iterator!=rMesh.EdgesEnd(); 00146 ++edge_iterator) 00147 { 00148 c_vector<double, 3> location1 = edge_iterator.GetNodeA()->rGetLocation(); 00149 c_vector<double, 3> location2 = edge_iterator.GetNodeB()->rGetLocation(); 00150 double edge_length = norm_2(location1-location2); 00151 00152 if (edge_length>max_edge_length) 00153 { 00154 max_edge_length = edge_length; 00155 } 00156 } 00157 00158 if (boxWidth < max_edge_length) 00159 { 00160 boxWidth = 1.1*max_edge_length; 00161 } 00162 } 00163 00164 rpBoxCollection = new BoxCollection<DIM>(boxWidth, extended_min_and_max); 00165 rpBoxCollection->SetupAllLocalBoxes(); 00166 00167 // For each element, if ANY of its nodes are physically in a box, put that element in that box 00168 for (unsigned i=0; i<rMesh.GetNumElements(); i++) 00169 { 00170 Element<DIM,DIM>* p_element = rMesh.GetElement(i); 00171 00172 std::set<unsigned> box_indices_each_node_this_elem; 00173 for (unsigned j=0; j<DIM+1; j++) // num vertices per element 00174 { 00175 Node<DIM>* p_node = p_element->GetNode(j); 00176 unsigned box_index = rpBoxCollection->CalculateContainingBox(p_node); 00177 box_indices_each_node_this_elem.insert(box_index); 00178 } 00179 00180 for (std::set<unsigned>::iterator iter = box_indices_each_node_this_elem.begin(); 00181 iter != box_indices_each_node_this_elem.end(); 00182 ++iter) 00183 { 00184 rpBoxCollection->rGetBox( *iter ).AddElement(p_element); 00185 } 00186 } 00187 } 00188 00190 // ComputeFineElementsAndWeightsForCoarseQuadPoints() 00191 // and 00192 // ComputeFineElementsAndWeightsForCoarseNodes() 00193 // and 00194 // common method 00196 00197 template<unsigned DIM> 00198 void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseQuadPoints(GaussianQuadratureRule<DIM>& rQuadRule, 00199 bool safeMode) 00200 { 00201 if (mpFineMeshBoxCollection == NULL) 00202 { 00203 EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseQuadPoints()"); 00204 } 00205 00206 // Get the quad point (physical) positions 00207 QuadraturePointsGroup<DIM> quad_point_posns(mrCoarseMesh, rQuadRule); 00208 00209 // Resize the elements and weights vector. 00210 mFineMeshElementsAndWeights.resize(quad_point_posns.Size()); 00211 00212 #define COVERAGE_IGNORE 00213 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00214 { 00215 std::cout << "\nComputing fine elements and weights for coarse quad points\n"; 00216 } 00217 #undef COVERAGE_IGNORE 00218 00219 00220 ResetStatisticsVariables(); 00221 for (unsigned i=0; i<quad_point_posns.Size(); i++) 00222 { 00223 #define COVERAGE_IGNORE 00224 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00225 { 00226 std::cout << "\r " << i << " of " << quad_point_posns.Size() << std::flush; 00227 } 00228 #undef COVERAGE_IGNORE 00229 00230 // Get the box this point is in 00231 unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( quad_point_posns.Get(i) ); 00232 00233 // A chaste point version of the c-vector is needed for the GetContainingElement call. 00234 ChastePoint<DIM> point(quad_point_posns.Get(i)); 00235 00236 ComputeFineElementAndWeightForGivenPoint(point, safeMode, box_for_this_point, i); 00237 } 00238 00239 if (mStatisticsCounters[1] > 0) 00240 { 00241 WARNING(mStatisticsCounters[1] << " of " << quad_point_posns.Size() << " coarse-mesh quadrature points were outside the fine mesh"); 00242 } 00243 } 00244 00245 template<unsigned DIM> 00246 void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseNodes(bool safeMode) 00247 { 00248 if (mpFineMeshBoxCollection==NULL) 00249 { 00250 EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseNodes()"); 00251 } 00252 00253 // Resize the elements and weights vector. 00254 mFineMeshElementsAndWeights.resize(mrCoarseMesh.GetNumNodes()); 00255 00256 #define COVERAGE_IGNORE 00257 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00258 { 00259 std::cout << "\nComputing fine elements and weights for coarse nodes\n"; 00260 } 00261 #undef COVERAGE_IGNORE 00262 00263 00264 ResetStatisticsVariables(); 00265 for (unsigned i=0; i<mrCoarseMesh.GetNumNodes(); i++) 00266 { 00267 #define COVERAGE_IGNORE 00268 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00269 { 00270 std::cout << "\r " << i << " of " << mrCoarseMesh.GetNumNodes() << std::flush; 00271 } 00272 #undef COVERAGE_IGNORE 00273 00274 Node<DIM>* p_node = mrCoarseMesh.GetNode(i); 00275 00276 // Get the box this point is in 00277 unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( p_node->rGetModifiableLocation() ); 00278 00279 // A chaste point version of the c-vector is needed for the GetContainingElement call 00280 ChastePoint<DIM> point(p_node->rGetLocation()); 00281 00282 ComputeFineElementAndWeightForGivenPoint(point, safeMode, box_for_this_point, i); 00283 } 00284 } 00285 00292 template<unsigned DIM> 00293 void FineCoarseMeshPair<DIM>::ComputeFineElementAndWeightForGivenPoint(ChastePoint<DIM>& rPoint, 00294 bool safeMode, 00295 unsigned boxForThisPoint, 00296 unsigned index) 00297 { 00298 std::set<unsigned> test_element_indices; 00299 00300 /* 00301 * The elements to try (initially) are those contained in the box the point is in. 00302 * 00303 * Note: it is possible the point to be in an element not 'in' this box, as it is 00304 * possible for all element nodes to be in different boxes. 00305 */ 00306 CollectElementsInContainingBox(mpFineMeshBoxCollection, boxForThisPoint, test_element_indices); 00307 00308 unsigned elem_index; 00309 c_vector<double,DIM+1> weight; 00310 00311 try 00312 { 00313 //std::cout << "\n" << "# test elements initially " << test_element_indices.size() << "\n"; 00314 // Try these elements only, initially 00315 elem_index = mrFineMesh.GetContainingElementIndex(rPoint, 00316 false, 00317 test_element_indices, 00318 true /* quit if not in test_elements */); 00319 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint); 00320 00321 mStatisticsCounters[0]++; 00322 } 00323 catch(Exception& e) 00324 { 00325 // Now try all elements, trying the elements contained in the boxes local to this element first 00326 std::set<unsigned> test_element_indices; 00327 00328 CollectElementsInLocalBoxes(mpFineMeshBoxCollection, boxForThisPoint, test_element_indices); 00329 00330 try 00331 { 00332 elem_index = mrFineMesh.GetContainingElementIndex(rPoint, false, test_element_indices, true); 00333 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint); 00334 mStatisticsCounters[0]++; 00335 } 00336 catch(Exception& e) 00337 { 00338 if (safeMode) 00339 { 00340 // Try the remaining elements 00341 try 00342 { 00343 elem_index = mrFineMesh.GetContainingElementIndex(rPoint, false); 00344 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint); 00345 mStatisticsCounters[0]++; 00346 00347 } 00348 catch (Exception& e) 00349 { 00350 // The point is not in ANY element, so store the nearest element and corresponding weights 00351 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices); 00352 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint); 00353 00354 mNotInMesh.push_back(index); 00355 mNotInMeshNearestElementWeights.push_back(weight); 00356 mStatisticsCounters[1]++; 00357 } 00358 } 00359 else 00360 { 00361 assert(test_element_indices.size() > 0); // boxes probably too small if this fails 00362 00363 /* 00364 * Immediately assume it isn't in the rest of the mesh - this should be the 00365 * case assuming the box width was chosen suitably. Store the nearest element 00366 * and corresponding weights. 00367 */ 00368 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices); 00369 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(rPoint); 00370 00371 mNotInMesh.push_back(index); 00372 mNotInMeshNearestElementWeights.push_back(weight); 00373 mStatisticsCounters[1]++; 00374 } 00375 } 00376 } 00377 00378 mFineMeshElementsAndWeights[index].ElementNum = elem_index; 00379 mFineMeshElementsAndWeights[index].Weights = weight; 00380 } 00381 00383 // ComputeCoarseElementsForFineNodes 00384 // and 00385 // ComputeCoarseElementsForFineElementCentroids 00386 // and 00387 // common method 00389 00390 template<unsigned DIM> 00391 void FineCoarseMeshPair<DIM>::ComputeCoarseElementsForFineNodes(bool safeMode) 00392 { 00393 if (mpCoarseMeshBoxCollection==NULL) 00394 { 00395 EXCEPTION("Call SetUpBoxesOnCoarseMesh() before ComputeCoarseElementsForFineNodes()"); 00396 } 00397 00398 #define COVERAGE_IGNORE 00399 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00400 { 00401 std::cout << "\nComputing coarse elements for fine nodes\n"; 00402 } 00403 #undef COVERAGE_IGNORE 00404 00405 mCoarseElementsForFineNodes.resize(mrFineMesh.GetNumNodes()); 00406 00407 ResetStatisticsVariables(); 00408 for (unsigned i=0; i<mCoarseElementsForFineNodes.size(); i++) 00409 { 00410 #define COVERAGE_IGNORE 00411 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00412 { 00413 std::cout << "\r " << i << " of " << mCoarseElementsForFineNodes.size() << std::flush; 00414 } 00415 #undef COVERAGE_IGNORE 00416 00417 ChastePoint<DIM> point = mrFineMesh.GetNode(i)->GetPoint(); 00418 00419 // Get the box this point is in 00420 unsigned box_for_this_point = mpCoarseMeshBoxCollection->CalculateContainingBox(mrFineMesh.GetNode(i)->rGetModifiableLocation()); 00421 00422 mCoarseElementsForFineNodes[i] = ComputeCoarseElementForGivenPoint(point, safeMode, box_for_this_point); 00423 } 00424 } 00425 00426 template<unsigned DIM> 00427 void FineCoarseMeshPair<DIM>::ComputeCoarseElementsForFineElementCentroids(bool safeMode) 00428 { 00429 if (mpCoarseMeshBoxCollection==NULL) 00430 { 00431 EXCEPTION("Call SetUpBoxesOnCoarseMesh() before ComputeCoarseElementsForFineElementCentroids()"); 00432 } 00433 00434 #define COVERAGE_IGNORE 00435 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00436 { 00437 std::cout << "\nComputing coarse elements for fine element centroids\n"; 00438 } 00439 #undef COVERAGE_IGNORE 00440 00441 mCoarseElementsForFineElementCentroids.resize(mrFineMesh.GetNumElements()); 00442 00443 ResetStatisticsVariables(); 00444 for (unsigned i=0; i<mrFineMesh.GetNumElements(); i++) 00445 { 00446 #define COVERAGE_IGNORE 00447 if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) 00448 { 00449 std::cout << "\r " << i << " of " << mrFineMesh.GetNumElements() << std::flush; 00450 } 00451 #undef COVERAGE_IGNORE 00452 00453 c_vector<double,DIM> point_cvec = mrFineMesh.GetElement(i)->CalculateCentroid(); 00454 ChastePoint<DIM> point(point_cvec); 00455 00456 // Get the box this point is in 00457 unsigned box_for_this_point = mpCoarseMeshBoxCollection->CalculateContainingBox( point_cvec ); 00458 00459 mCoarseElementsForFineElementCentroids[i] = ComputeCoarseElementForGivenPoint(point, safeMode, box_for_this_point); 00460 } 00461 } 00462 00469 template<unsigned DIM> 00470 unsigned FineCoarseMeshPair<DIM>::ComputeCoarseElementForGivenPoint(ChastePoint<DIM>& rPoint, 00471 bool safeMode, 00472 unsigned boxForThisPoint) 00473 { 00474 std::set<unsigned> test_element_indices; 00475 CollectElementsInContainingBox(mpCoarseMeshBoxCollection, boxForThisPoint, test_element_indices); 00476 00477 unsigned elem_index; 00478 00479 try 00480 { 00481 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint, 00482 false, 00483 test_element_indices, 00484 true /* quit if not in test_elements */); 00485 00486 mStatisticsCounters[0]++; 00487 } 00488 catch(Exception& e) 00489 { 00490 // Now try all elements, trying the elements contained in the boxes local to this element first 00491 std::set<unsigned> test_element_indices; 00492 CollectElementsInLocalBoxes(mpCoarseMeshBoxCollection, boxForThisPoint, test_element_indices); 00493 00494 try 00495 { 00496 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint, false, test_element_indices, true); 00497 mStatisticsCounters[0]++; 00498 } 00499 catch(Exception& e) 00500 { 00501 if (safeMode) 00502 { 00503 // Try the remaining elements 00504 try 00505 { 00506 elem_index = mrCoarseMesh.GetContainingElementIndex(rPoint, false); 00507 00508 mStatisticsCounters[0]++; 00509 } 00510 catch (Exception& e) 00511 { 00512 // The point is not in ANY element, so store the nearest element and corresponding weights 00513 elem_index = mrCoarseMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices); 00514 mStatisticsCounters[1]++; 00515 } 00516 } 00517 else 00518 { 00519 assert(test_element_indices.size() > 0); // boxes probably too small if this fails 00520 00521 /* 00522 * Immediately assume it isn't in the rest of the mesh - this should be the 00523 * case assuming the box width was chosen suitably. Store the nearest element 00524 * and corresponding weights. 00525 */ 00526 elem_index = mrCoarseMesh.GetNearestElementIndexFromTestElements(rPoint,test_element_indices); 00527 mStatisticsCounters[1]++; 00528 } 00529 } 00530 } 00531 00532 return elem_index; 00533 } 00534 00536 // Helper methods for code 00538 00539 template<unsigned DIM> 00540 void FineCoarseMeshPair<DIM>::CollectElementsInContainingBox(BoxCollection<DIM>*& rpBoxCollection, 00541 unsigned boxIndex, 00542 std::set<unsigned>& rElementIndices) 00543 { 00544 for (typename std::set<Element<DIM,DIM>*>::iterator elem_iter = rpBoxCollection->rGetBox(boxIndex).rGetElementsContained().begin(); 00545 elem_iter != rpBoxCollection->rGetBox(boxIndex).rGetElementsContained().end(); 00546 ++elem_iter) 00547 { 00548 rElementIndices.insert((*elem_iter)->GetIndex()); 00549 } 00550 } 00551 00552 template<unsigned DIM> 00553 void FineCoarseMeshPair<DIM>::CollectElementsInLocalBoxes(BoxCollection<DIM>*& rpBoxCollection, 00554 unsigned boxIndex, 00555 std::set<unsigned>& rElementIndices) 00556 { 00557 std::set<unsigned> local_boxes = rpBoxCollection->GetLocalBoxes(boxIndex); 00558 for (std::set<unsigned>::iterator local_box_iter = local_boxes.begin(); 00559 local_box_iter != local_boxes.end(); 00560 ++local_box_iter) 00561 { 00562 for (typename std::set<Element<DIM,DIM>*>::iterator elem_iter = rpBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().begin(); 00563 elem_iter != rpBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().end(); 00564 ++elem_iter) 00565 { 00566 rElementIndices.insert((*elem_iter)->GetIndex()); 00567 } 00568 } 00569 } 00570 00572 // Statistics related methods 00574 00575 template<unsigned DIM> 00576 void FineCoarseMeshPair<DIM>::ResetStatisticsVariables() 00577 { 00578 mNotInMesh.clear(); 00579 mNotInMeshNearestElementWeights.clear(); 00580 mStatisticsCounters.resize(2, 0u); 00581 } 00582 00583 template<unsigned DIM> 00584 void FineCoarseMeshPair<DIM>::PrintStatistics() 00585 { 00586 std::cout << "\nFineCoarseMeshPair statistics for the last-called method:\n"; 00587 00588 // std::cout << "\tNum points for which containing element was found, using box containing that point = " << mStatisticsCounters[0] << "\n"; 00589 // std::cout << "\tNum points for which containing element was in local box = " << mStatisticsCounters[1] << "\n"; 00590 // std::cout << "\tNum points for which containing element was in an element in a non-local box = " << mStatisticsCounters[2] << "\n"; 00591 // std::cout << "\tNum points for which no containing element was found = " << mStatisticsCounters[3] << "\n"; 00592 00593 std::cout << "\tNum points for which containing element was found: " << mStatisticsCounters[0] << "\n"; 00594 std::cout << "\tNum points for which no containing element was found = " << mStatisticsCounters[1] << "\n"; 00595 00596 if (mNotInMesh.size() > 0) 00597 { 00598 std::cout << "\tIndices and weights for points (nodes/quad points) for which no containing element was found:\n"; 00599 for (unsigned i=0; i<mNotInMesh.size(); i++) 00600 { 00601 std::cout << "\t\t" << mNotInMesh[i] << ", " << mNotInMeshNearestElementWeights[i] << "\n"; 00602 } 00603 } 00604 } 00605 00607 // Explicit instantiation 00609 00610 template class FineCoarseMeshPair<1>; 00611 template class FineCoarseMeshPair<2>; 00612 template class FineCoarseMeshPair<3>;