Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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