void TestMeshGetWidth()
    {
        // Create mesh
        CylindricalHoneycombVertexMeshGenerator generator(4, 4);
        Cylindrical2dVertexMesh* p_mesh = generator.GetCylindricalMesh();

        // Test CalculateBoundingBox() method
        ChasteCuboid<2> bounds = p_mesh->CalculateBoundingBox();

        ///\todo this should really be 4 as mesh is periodic
        TS_ASSERT_DELTA(bounds.rGetUpperCorner()[0], 3.5, 1e-4);

        TS_ASSERT_DELTA(bounds.rGetUpperCorner()[1], 13.0*0.5/sqrt(3.0), 1e-4);
        TS_ASSERT_DELTA(bounds.rGetLowerCorner()[0], 0.0, 1e-4);
        TS_ASSERT_DELTA(bounds.rGetLowerCorner()[1], 0.0, 1e-4);

        // Test GetWidth() method
        double width = p_mesh->GetWidth(0);
        double height = p_mesh->GetWidth(1);

        TS_ASSERT_DELTA(width, 4, 1e-4);
        TS_ASSERT_DELTA(height, 13.0*0.5/sqrt(3.0), 1e-4);


        //Scale mesh and check its updated correctly
        p_mesh->Scale(0.5,1.0);
        TS_ASSERT_DELTA(p_mesh->GetWidth(0), 2, 1e-4);
    }
示例#2
0
void CellBasedPdeHandler<DIM>::OpenResultsFiles(std::string outputDirectory)
{
    // If appropriate, make a coarse mesh which exactly overlays the lattice sites of a PottsMesh (used for all OnLattice simulations)
    if ((dynamic_cast<MultipleCaBasedCellPopulation<DIM>*>(mpCellPopulation) != NULL) && mpCoarsePdeMesh==NULL)
    {
        assert(DIM ==2);
        ChasteCuboid<DIM> cuboid = mpCellPopulation->rGetMesh().CalculateBoundingBox();

        // Currently only works with square meshes
        assert(cuboid.GetWidth(0) == cuboid.GetWidth(1));

        UseCoarsePdeMesh(1, cuboid, false);
    }

    // If using a NodeBasedCellPopulation a VertexBasedCellPopulation, a MultipleCABasedCellPopulation or a PottsBasedCellPopulation, mpCoarsePdeMesh must be set up
    if (PdeSolveNeedsCoarseMesh() && mpCoarsePdeMesh==NULL)
    {
        EXCEPTION("Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh().");
    }

    if (mpCoarsePdeMesh != NULL)
    {
        InitialiseCellPdeElementMap();

        // Write mesh to file
        TrianglesMeshWriter<DIM,DIM> mesh_writer(outputDirectory+"/coarse_mesh_output", "coarse_mesh",false);
        mesh_writer.WriteFilesUsingMesh(*mpCoarsePdeMesh);
    }

    if (PetscTools::AmMaster())
    {
        OutputFileHandler output_file_handler(outputDirectory+"/", false);

        if (mpCoarsePdeMesh != NULL)
        {
            mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizcoarsepdesolution");
        }
        else
        {
            mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution");
        }

        if (mWriteAverageRadialPdeSolution)
        {
            mpAverageRadialPdeSolutionResultsFile = output_file_handler.OpenOutputFile("radial_dist.dat");
        }
    }

    mDirPath = outputDirectory; // caching the path to the output directory for VTK
    //double current_time = SimulationTime::Instance()->GetTime();
    //WritePdeSolution(current_time);
}
示例#3
0
void CellBasedPdeHandler<DIM>::UseCoarsePdeMesh(double stepSize, ChasteCuboid<DIM> meshCuboid, bool centreOnCellPopulation)
{
    if (mPdeAndBcCollection.empty())
    {
        EXCEPTION("mPdeAndBcCollection should be populated prior to calling UseCoarsePdeMesh().");
    }
    // If solving PDEs on a coarse mesh, each PDE must have an averaged source term
    for (unsigned pde_index=0; pde_index<mPdeAndBcCollection.size(); pde_index++)
    {
        if (mPdeAndBcCollection[pde_index]->HasAveragedSourcePde() == false && !dynamic_cast<MultipleCaBasedCellPopulation<DIM>*>(mpCellPopulation))
        {
            EXCEPTION("UseCoarsePdeMesh() should only be called if averaged-source PDEs are specified.");
        }
    }

    // Create a regular coarse tetrahedral mesh
    mpCoarsePdeMesh = new TetrahedralMesh<DIM,DIM>;
    switch (DIM)
    {
        case 1:
            mpCoarsePdeMesh->ConstructRegularSlabMesh(stepSize, meshCuboid.GetWidth(0));
            break;
        case 2:
            mpCoarsePdeMesh->ConstructRegularSlabMesh(stepSize, meshCuboid.GetWidth(0), meshCuboid.GetWidth(1));
            break;
        case 3:
            mpCoarsePdeMesh->ConstructRegularSlabMesh(stepSize, meshCuboid.GetWidth(0), meshCuboid.GetWidth(1), meshCuboid.GetWidth(2));
            break;
        default:
            NEVER_REACHED;
    }

    if (centreOnCellPopulation)
    {
        // Find the centre of the coarse PDE mesh
        c_vector<double,DIM> centre_of_coarse_mesh = zero_vector<double>(DIM);
        for (unsigned i=0; i<mpCoarsePdeMesh->GetNumNodes(); i++)
        {
            centre_of_coarse_mesh += mpCoarsePdeMesh->GetNode(i)->rGetLocation();
        }
        centre_of_coarse_mesh /= mpCoarsePdeMesh->GetNumNodes();

        // Translate the centre of coarse PDE mesh to the centre of the cell population
        c_vector<double,DIM> centre_of_cell_population = mpCellPopulation->GetCentroidOfCellPopulation();
        mpCoarsePdeMesh->Translate(centre_of_cell_population - centre_of_coarse_mesh);
    }
    else
    {
        // Get centroid of meshCuboid
        ChastePoint<DIM> upper = meshCuboid.rGetUpperCorner();
        ChastePoint<DIM> lower = meshCuboid.rGetLowerCorner();
        c_vector<double,DIM> centre_of_cuboid = 0.5*(upper.rGetLocation() + lower.rGetLocation());

        // Find the centre of the coarse PDE mesh
        c_vector<double,DIM> centre_of_coarse_mesh = zero_vector<double>(DIM);
        for (unsigned i=0; i<mpCoarsePdeMesh->GetNumNodes(); i++)
        {
            centre_of_coarse_mesh += mpCoarsePdeMesh->GetNode(i)->rGetLocation();
        }
        centre_of_coarse_mesh /= mpCoarsePdeMesh->GetNumNodes();

        mpCoarsePdeMesh->Translate(centre_of_cuboid - centre_of_coarse_mesh);
    }
}