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); }
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); } }