void IMPInitializer::tagCellsForInitialRefinement( const Pointer<PatchHierarchy<NDIM> > hierarchy, const int level_number, const double /*error_data_time*/, const int tag_index) { // Loop over all patches in the specified level of the patch level and tag // cells for refinement wherever there are vertices assigned to a finer // level of the Cartesian grid. Pointer<PatchLevel<NDIM> > level = hierarchy->getPatchLevel(level_number); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry(); const Box<NDIM>& patch_box = patch->getBox(); const CellIndex<NDIM>& patch_lower = patch_box.lower(); const CellIndex<NDIM>& patch_upper = patch_box.upper(); const double* const patch_x_lower = patch_geom->getXLower(); const double* const patch_x_upper = patch_geom->getXUpper(); const double* const patch_dx = patch_geom->getDx(); Pointer<CellData<NDIM,int> > tag_data = patch->getPatchData(tag_index); // Tag cells for refinement whenever there are vertices whose initial // locations will be within the index space of the given patch, but on // the finer levels of the AMR patch hierarchy. const int max_levels = d_gridding_alg->getMaxLevels(); const bool can_be_refined = level_number+2 < max_levels; for (int ln = level_number+1; ln < max_levels; ++ln) { std::vector<std::pair<int,int> > patch_vertices; getPatchVertices(patch_vertices, patch, ln, can_be_refined); for (std::vector<std::pair<int,int> >::const_iterator it = patch_vertices.begin(); it != patch_vertices.end(); ++it) { const std::pair<int,int>& point_idx = (*it); const Point& X = getVertexPosn(point_idx, ln); const CellIndex<NDIM> i = IndexUtilities::getCellIndex(&X(0), patch_x_lower, patch_x_upper, patch_dx, patch_lower, patch_upper); if (patch_box.contains(i)) (*tag_data)(i) = 1; } } } return; }// tagCellsForInitialRefinement
unsigned int IMPInitializer::computeLocalNodeCountOnPatchLevel(const Pointer<PatchHierarchy<NDIM> > hierarchy, const int level_number, const double /*init_data_time*/, const bool can_be_refined, const bool /*initial_time*/) { // Loop over all patches in the specified level of the patch level and count // the number of local vertices. int local_node_count = 0; Pointer<PatchLevel<NDIM> > level = hierarchy->getPatchLevel(level_number); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); // Count the number of vertices whose initial locations will be within // the given patch. std::vector<std::pair<int, int> > patch_vertices; getPatchVertices(patch_vertices, patch, level_number, can_be_refined); local_node_count += patch_vertices.size(); } return local_node_count; } // computeLocalNodeCountOnPatchLevel
unsigned int IMPInitializer::initializeDataOnPatchLevel(const int lag_node_index_idx, const unsigned int global_index_offset, const unsigned int local_index_offset, Pointer<LData> X_data, Pointer<LData> U_data, const Pointer<PatchHierarchy<NDIM> > hierarchy, const int level_number, const double /*init_data_time*/, const bool can_be_refined, const bool /*initial_time*/, LDataManager* const /*l_data_manager*/) { // Determine the extents of the physical domain. Pointer<CartesianGridGeometry<NDIM> > grid_geom = hierarchy->getGridGeometry(); const double* const grid_x_lower = grid_geom->getXLower(); const double* const grid_x_upper = grid_geom->getXUpper(); // Loop over all patches in the specified level of the patch level and // initialize the local vertices. boost::multi_array_ref<double, 2>& X_array = *X_data->getLocalFormVecArray(); boost::multi_array_ref<double, 2>& U_array = *U_data->getLocalFormVecArray(); int local_idx = -1; int local_node_count = 0; Pointer<PatchLevel<NDIM> > level = hierarchy->getPatchLevel(level_number); const IntVector<NDIM>& ratio = level->getRatio(); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry(); Pointer<LNodeSetData> index_data = patch->getPatchData(lag_node_index_idx); // Initialize the vertices whose initial locations will be within the // given patch. std::vector<std::pair<int, int> > patch_vertices; getPatchVertices(patch_vertices, patch, level_number, can_be_refined); local_node_count += patch_vertices.size(); for (std::vector<std::pair<int, int> >::const_iterator it = patch_vertices.begin(); it != patch_vertices.end(); ++it) { const std::pair<int, int>& point_idx = (*it); const int lagrangian_idx = getCanonicalLagrangianIndex(point_idx, level_number) + global_index_offset; const int local_petsc_idx = ++local_idx + local_index_offset; const int global_petsc_idx = local_petsc_idx + global_index_offset; // Get the coordinates of the present vertex. const libMesh::Point& X = getVertexPosn(point_idx, level_number); const CellIndex<NDIM> idx = IndexUtilities::getCellIndex(&X(0), grid_geom, ratio); for (int d = 0; d < NDIM; ++d) { X_array[local_petsc_idx][d] = X(d); if (X(d) <= grid_x_lower[d]) { TBOX_ERROR(d_object_name << "::initializeDataOnPatchLevel():\n" << " encountered node below lower physical boundary\n" << " please ensure that all nodes are within the " "computational domain." << std::endl); } if (X(d) >= grid_x_upper[d]) { TBOX_ERROR(d_object_name << "::initializeDataOnPatchLevel():\n" << " encountered node above upper physical boundary\n" << " please ensure that all nodes are within the " "computational domain." << std::endl); } } // Create or retrieve a pointer to the LNodeSet associated with the // current Cartesian grid cell. if (!index_data->isElement(idx)) { index_data->appendItemPointer(idx, new LNodeSet()); } LNodeSet* const node_set = index_data->getItem(idx); static const IntVector<NDIM> periodic_offset(0); static const IBTK::Point periodic_displacement(IBTK::Point::Zero()); Pointer<MaterialPointSpec> point_spec = new MaterialPointSpec(lagrangian_idx, d_vertex_wgt[level_number][point_idx.first][point_idx.second], d_vertex_subdomain_id[level_number][point_idx.first][point_idx.second]); std::vector<Pointer<Streamable> > node_data(1, point_spec); node_set->push_back(new LNode(lagrangian_idx, global_petsc_idx, local_petsc_idx, /*initial*/ periodic_offset, /*current*/ periodic_offset, /*initial*/ periodic_displacement, /*current*/ periodic_displacement, node_data)); // Initialize the velocity of the present vertex. std::fill(&U_array[local_petsc_idx][0], &U_array[local_petsc_idx][0] + NDIM, 0.0); } } X_data->restoreArrays(); U_data->restoreArrays(); d_level_is_initialized[level_number] = true; // If a Lagrangian Silo data writer is registered with the initializer, // setup the visualization data corresponding to the present level of the // locally refined grid. if (d_silo_writer) initializeLSiloDataWriter(level_number); return local_node_count; } // initializeDataOnPatchLevel