void TestWithCoarseSlightlyOutsideFine() throw(Exception) { // Fine mesh is has h=0.1, on unit cube (so 6000 elements) TetrahedralMesh<3,3> fine_mesh; fine_mesh.ConstructRegularSlabMesh(0.1, 1.0,1.0,1.0); // Coarse mesh is slightly bigger than in previous test QuadraticMesh<3> coarse_mesh(1.0, 1.0, 1.0, 1.0); // xmax > 1.0 coarse_mesh.Scale(1.03, 1.0, 1.0); FineCoarseMeshPair<3> mesh_pair(fine_mesh,coarse_mesh); GaussianQuadratureRule<3> quad_rule(3); // Need to call SetUpBoxesOnFineMesh first TS_ASSERT_THROWS_CONTAINS(mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true), "Call"); mesh_pair.SetUpBoxesOnFineMesh(0.3); TS_ASSERT_EQUALS(mesh_pair.mpFineMeshBoxCollection->GetNumBoxes(), 4*4*4u); mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true); TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 2u); // hardcoded TS_ASSERT_EQUALS(mesh_pair.mNotInMeshNearestElementWeights.size(), 2u); TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights().size(), 6*8u); for (unsigned i=0; i<mesh_pair.rGetElementsAndWeights().size(); i++) { TS_ASSERT_LESS_THAN(mesh_pair.rGetElementsAndWeights()[i].ElementNum, fine_mesh.GetNumElements()); // comment out this test as now some of the weights are negative/greater than one //for (unsigned j=0; j<4; j++) //{ // TS_ASSERT_LESS_THAN(-1e14, mesh_pair.rGetElementsAndWeights()[i].Weights(j)); // TS_ASSERT_LESS_THAN(mesh_pair.rGetElementsAndWeights()[i].Weights(j), 1.0+1e-14); //} } /* * For each quadrature point that was not found in the fine mesh, check * that its x-value is greater than one - this is the only way it could * be outside the fine mesh. */ QuadraturePointsGroup<3> quad_point_posns(coarse_mesh, quad_rule); for (unsigned i=0; i<mesh_pair.mNotInMesh.size(); i++) { double x = quad_point_posns.rGet(mesh_pair.mNotInMesh[i])(0); TS_ASSERT_LESS_THAN(1.0, x); } mesh_pair.PrintStatistics(); TS_ASSERT_EQUALS( Warnings::Instance()->GetNumWarnings(), 1u); Warnings::Instance()->QuietDestroy(); }
void FineCoarseMeshPair<DIM>::ComputeFineElementsAndWeightsForCoarseQuadPoints(GaussianQuadratureRule<DIM>& rQuadRule, bool safeMode) { if (mpFineMeshBoxCollection == NULL) { EXCEPTION("Call SetUpBoxesOnFineMesh() before ComputeFineElementsAndWeightsForCoarseQuadPoints()"); } // Get the quad point (physical) positions QuadraturePointsGroup<DIM> quad_point_posns(mrCoarseMesh, rQuadRule); // Resize the elements and weights vector. mFineMeshElementsAndWeights.resize(quad_point_posns.Size()); #define COVERAGE_IGNORE if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) { std::cout << "\nComputing fine elements and weights for coarse quad points\n"; } #undef COVERAGE_IGNORE ResetStatisticsVariables(); for (unsigned i=0; i<quad_point_posns.Size(); i++) { #define COVERAGE_IGNORE if(CommandLineArguments::Instance()->OptionExists("-mesh_pair_verbose")) { std::cout << "\t" << i << " of " << quad_point_posns.Size() << std::flush; } #undef COVERAGE_IGNORE // Get the box this point is in unsigned box_for_this_point = mpFineMeshBoxCollection->CalculateContainingBox( quad_point_posns.rGet(i) ); if (mpFineMeshBoxCollection->IsBoxOwned(box_for_this_point)) { // A chaste point version of the c-vector is needed for the GetContainingElement call. ChastePoint<DIM> point(quad_point_posns.rGet(i)); ComputeFineElementAndWeightForGivenPoint(point, safeMode, box_for_this_point, i); } else { assert(mFineMeshElementsAndWeights[i].ElementNum == 0u); // and the weight is zero too... } } ShareFineElementData(); if (mStatisticsCounters[1] > 0) { WARNING(mStatisticsCounters[1] << " of " << quad_point_posns.Size() << " coarse-mesh quadrature points were outside the fine mesh"); } }
/* * Test when calling ComputeFineElementsAndWeightsForCoarseQuadPoints() * in non-safe mode, but using the default value of box width. It is * difficult to get the class to run incorrectly (ie fail without an * assertion failing) in non-safe mode (ie we can't just specify boxes * that are too small), so we just test we get the same results as in * safe mode. */ void TestNonSafeMode() throw(Exception) { // Fine mesh is has h=0.1, on unit cube (so 6000 elements) TetrahedralMesh<3,3> fine_mesh; fine_mesh.ConstructRegularSlabMesh(0.1, 1.0, 1.0, 1.0); QuadraticMesh<3> coarse_mesh(1.0, 1.0, 1.0, 1.0); // xmax > 1.0 coarse_mesh.Scale(1.03, 1.0, 1.0); FineCoarseMeshPair<3> mesh_pair(fine_mesh,coarse_mesh); GaussianQuadratureRule<3> quad_rule(3); // Call SetUpBoxesOnFineMesh() without providing a width mesh_pair.SetUpBoxesOnFineMesh(); /* * Whereas before 4 by 4 by 4 boxes were explicitly chosen, here it * has been determined that 6 by 6 by 6 are needed. */ TS_ASSERT_EQUALS(mesh_pair.mpFineMeshBoxCollection->GetNumBoxes(), 6*6*6u); mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, false /* non-safe mode*/); TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 2u); // hardcoded TS_ASSERT_EQUALS(mesh_pair.mNotInMeshNearestElementWeights.size(), 2u); TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights().size(), 6*8u); for (unsigned i=0; i<mesh_pair.rGetElementsAndWeights().size(); i++) { TS_ASSERT_LESS_THAN(mesh_pair.rGetElementsAndWeights()[i].ElementNum, fine_mesh.GetNumElements()); } /* * For each quadrature point that was not found in the fine mesh, check * that its x-value is greater than one - this is the only way it could * be outside the fine mesh. */ QuadraturePointsGroup<3> quad_point_posns(coarse_mesh, quad_rule); for (unsigned i=0; i<mesh_pair.mNotInMesh.size(); i++) { double x = quad_point_posns.rGet(mesh_pair.mNotInMesh[i])(0); TS_ASSERT_LESS_THAN(1.0, x); } mesh_pair.PrintStatistics(); TS_ASSERT_EQUALS( Warnings::Instance()->GetNumWarnings(), 1u); Warnings::Instance()->QuietDestroy(); }