Chaste Release::3.1
FineCoarseMeshPair.cpp
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>;