FineCoarseMeshPair.cpp
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 #include "FineCoarseMeshPair.hpp"
00031
00032
00033 template<unsigned DIM>
00034 FineCoarseMeshPair<DIM>::FineCoarseMeshPair(TetrahedralMesh<DIM,DIM>& rFineMesh, QuadraticMesh<DIM>& rCoarseMesh)
00035 : mrFineMesh(rFineMesh),
00036 mrCoarseMesh(rCoarseMesh)
00037 {
00038
00039 for(unsigned j=0; j<DIM; j++)
00040 {
00041 double min = 1e200;
00042 double max = -1e200;
00043
00044 for(unsigned i=0; i<mrFineMesh.GetNumNodes(); i++)
00045 {
00046 if( mrFineMesh.GetNode(i)->rGetLocation()[j] < min)
00047 {
00048 min = mrFineMesh.GetNode(i)->rGetLocation()[j];
00049 }
00050
00051 if( mrFineMesh.GetNode(i)->rGetLocation()[j] > max)
00052 {
00053 max = mrFineMesh.GetNode(i)->rGetLocation()[j];
00054 }
00055 }
00056
00057 mMinValuesFine(j) = min;
00058 mMaxValuesFine(j) = max;
00059 }
00060
00061 mpFineMeshBoxCollection = NULL;
00062 mCounters.resize(4,0);
00063
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 }
00085
00086
00087 template<unsigned DIM>
00088 FineCoarseMeshPair<DIM>::~FineCoarseMeshPair()
00089 {
00090 DeleteBoxCollection();
00091 }
00092
00093 template<unsigned DIM>
00094 void FineCoarseMeshPair<DIM>::SetUpBoxesOnFineMesh(double boxWidth)
00095 {
00096
00097 c_vector<double,2*DIM> min_and_max;
00098 for(unsigned i=0; i<DIM; i++)
00099 {
00100 min_and_max(2*i) = mMinValuesFine(i) - 0.05*fabs(mMinValuesFine(i));
00101 min_and_max(2*i+1) = mMaxValuesFine(i) + 0.05*fabs(mMaxValuesFine(i));
00102 }
00103
00104 if(boxWidth < 0)
00105 {
00106
00107
00108
00109
00110
00111 boxWidth = (min_and_max(1) - min_and_max(0))/19.000000001;
00112
00113
00114 double max_edge_length = -1;
00115
00116 for (typename TetrahedralMesh<DIM,DIM>::EdgeIterator edge_iterator=mrFineMesh.EdgesBegin();
00117 edge_iterator!=mrFineMesh.EdgesEnd();
00118 ++edge_iterator)
00119 {
00120 c_vector<double, 3> location1 = edge_iterator.GetNodeA()->rGetLocation();
00121 c_vector<double, 3> location2 = edge_iterator.GetNodeB()->rGetLocation();
00122 double edge_length = norm_2(location1-location2);
00123
00124 if(edge_length>max_edge_length)
00125 {
00126 max_edge_length = edge_length;
00127 }
00128 }
00129
00130 if(boxWidth < max_edge_length)
00131 {
00132 boxWidth = 1.1*max_edge_length;
00133 }
00134 }
00135
00136 mpFineMeshBoxCollection = new BoxCollection<DIM>(boxWidth, min_and_max);
00137 mpFineMeshBoxCollection->SetupAllLocalBoxes();
00138
00139
00140
00141 for(unsigned i=0; i<mrFineMesh.GetNumElements(); i++)
00142 {
00143 Element<DIM,DIM>* p_element = mrFineMesh.GetElement(i);
00144
00145 std::set<unsigned> box_indices_each_node_this_elem;
00146 for(unsigned j=0; j<DIM+1; j++)
00147 {
00148 Node<DIM>* p_node = p_element->GetNode(j);
00149 unsigned box_index = mpFineMeshBoxCollection->CalculateContainingBox(p_node);
00150 box_indices_each_node_this_elem.insert(box_index);
00151 }
00152
00153 for(std::set<unsigned>::iterator iter = box_indices_each_node_this_elem.begin();
00154 iter != box_indices_each_node_this_elem.end();
00155 ++iter)
00156 {
00157 mpFineMeshBoxCollection->rGetBox( *iter ).AddElement(p_element);
00158 }
00159 }
00160 }
00161
00162
00163 template<unsigned DIM>
00164 void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseQuadPoints(GaussianQuadratureRule<DIM>& rQuadRule,
00165 bool safeMode)
00166 {
00167 if(mpFineMeshBoxCollection==NULL)
00168 {
00169 EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseQuadPoints()");
00170 }
00171
00172
00173 QuadraturePointsGroup<DIM> quad_point_posns(mrCoarseMesh, rQuadRule);
00174
00175
00176 mElementsAndWeights.resize(quad_point_posns.Size());
00177
00178
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 for(unsigned i=0; i<quad_point_posns.Size(); i++)
00212 {
00213
00214
00215
00216 unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( quad_point_posns.Get(i) );
00217
00218
00219 ChastePoint<DIM> point;
00220 for(unsigned j=0; j<DIM; j++)
00221 {
00222 point.rGetLocation()[j]=quad_point_posns.Get(i)[j];
00223 }
00224
00225 std::set<unsigned> test_element_indices;
00226
00227
00228
00229
00230 for(typename std::set<Element<DIM,DIM>*>::iterator elem_iter = mpFineMeshBoxCollection->rGetBox(box_for_this_point).rGetElementsContained().begin();
00231 elem_iter != mpFineMeshBoxCollection->rGetBox(box_for_this_point).rGetElementsContained().end();
00232 ++elem_iter)
00233 {
00234 test_element_indices.insert((*elem_iter)->GetIndex());
00235 }
00236
00237 unsigned elem_index;
00238 c_vector<double,DIM+1> weight;
00239
00240 try
00241 {
00242
00243
00244 elem_index = mrFineMesh.GetContainingElementIndex(point,
00245 false,
00246 test_element_indices,
00247 true );
00248 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(point);
00249
00250 mCounters[0]++;
00251 }
00252 catch(Exception& e)
00253 {
00254
00255
00256 std::set<unsigned> test_element_indices;
00257
00258 std::set<unsigned> local_boxes = mpFineMeshBoxCollection->GetLocalBoxes(box_for_this_point);
00259 for(std::set<unsigned>::iterator local_box_iter = local_boxes.begin();
00260 local_box_iter != local_boxes.end();
00261 ++local_box_iter)
00262 {
00263 for(typename std::set<Element<DIM,DIM>*>::iterator elem_iter = mpFineMeshBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().begin();
00264 elem_iter != mpFineMeshBoxCollection->rGetBox(*local_box_iter).rGetElementsContained().end();
00265 ++elem_iter)
00266 {
00267 test_element_indices.insert((*elem_iter)->GetIndex());
00268 }
00269 }
00270
00271 try
00272 {
00273 elem_index = mrFineMesh.GetContainingElementIndex(point,
00274 false,
00275 test_element_indices,
00276 true);
00277 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(point);
00278
00279 mCounters[1]++;
00280
00281 }
00282 catch(Exception& e)
00283 {
00284 if(safeMode)
00285 {
00286
00287 try
00288 {
00289 elem_index = mrFineMesh.GetContainingElementIndex(point,
00290 false);
00291 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(point);
00292 mCounters[2]++;
00293
00294 }
00295 catch (Exception& e)
00296 {
00297
00298 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(point,test_element_indices);
00299 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(point);
00300
00301 mNotInMesh.push_back(i);
00302 mNotInMeshNearestElementWeights.push_back(weight);
00303 mCounters[3]++;
00304 }
00305 }
00306 else
00307 {
00308 assert(test_element_indices.size()>0);
00309
00310
00311
00312
00313 elem_index = mrFineMesh.GetNearestElementIndexFromTestElements(point,test_element_indices);
00314 weight = mrFineMesh.GetElement(elem_index)->CalculateInterpolationWeights(point);
00315
00316 mNotInMesh.push_back(i);
00317 mNotInMeshNearestElementWeights.push_back(weight);
00318 mCounters[3]++;
00319 }
00320 }
00321 }
00322
00323 mElementsAndWeights[i].ElementNum = elem_index;
00324 mElementsAndWeights[i].Weights = weight;
00325 }
00326
00327 }
00328
00329 template<unsigned DIM>
00330 void FineCoarseMeshPair<DIM>::PrintStatistics()
00331 {
00332 assert(mNotInMesh.size()==mCounters[3]);
00333 assert(mNotInMesh.size()==mNotInMeshNearestElementWeights.size());
00334 std::cout << "\nFineCoarseMeshPair statistics:\n";
00335 std::cout << "\tNum points for which containing (fine) element was found, using box containing that point = " << mCounters[0] << "\n";
00336 std::cout << "\tNum points for which containing (fine) element was in local box = " << mCounters[1] << "\n";
00337 std::cout << "\tNum points for which containing (fine) element was in non-local element = " << mCounters[2] << "\n";
00338 std::cout << "\tNum points for which no containing element was found in fine mesh = " << mCounters[3] << "\n";
00339 if(mCounters[3]>0)
00340 {
00341 std::cout << "\tIndices and weights for points for which no containing element was found:\n";
00342 for(unsigned i=0; i<mNotInMesh.size(); i++)
00343 {
00344 std::cout << "\t\t" << mNotInMesh[i] << ", " << mNotInMeshNearestElementWeights[i] << "\n";
00345 }
00346 }
00347 }
00348
00349
00350 template<unsigned DIM>
00351 void FineCoarseMeshPair<DIM>::DeleteBoxCollection()
00352 {
00353 if(mpFineMeshBoxCollection != NULL)
00354 {
00355 delete mpFineMeshBoxCollection;
00356 mpFineMeshBoxCollection = NULL;
00357 }
00358 }
00359
00360
00362
00364
00365
00366 template class FineCoarseMeshPair<1>;
00367 template class FineCoarseMeshPair<2>;
00368 template class FineCoarseMeshPair<3>;