void
AdvDiffPredictorCorrectorHierarchyIntegrator::initializeHierarchyIntegrator(
    Pointer<PatchHierarchy<NDIM> > hierarchy,
    Pointer<GriddingAlgorithm<NDIM> > gridding_alg)
{
    if (d_integrator_is_initialized) return;

    d_hierarchy = hierarchy;
    d_gridding_alg = gridding_alg;
    Pointer<CartesianGridGeometry<NDIM> > grid_geom = d_hierarchy->getGridGeometry();

    // Initialize the HyperbolicPatchStrategy and HyperbolicLevelIntegrator
    // objects that provide numerical routines for explicitly integrating the
    // advective terms.
    d_hyp_patch_ops = new AdvDiffPredictorCorrectorHyperbolicPatchOps(
        d_object_name+"::AdvDiffPredictorCorrectorHyperbolicPatchOps",
        d_hyp_patch_ops_db,
        d_explicit_predictor,
        grid_geom,
        d_registered_for_restart);
    d_hyp_level_integrator = new HyperbolicLevelIntegrator<NDIM>(
        d_object_name+"::HyperbolicLevelIntegrator",
        d_hyp_level_integrator_db,
        d_hyp_patch_ops,
        d_registered_for_restart,
        /*using_time_refinement*/ false);

    // Setup variable contexts.
    d_current_context = d_hyp_level_integrator->getCurrentContext();
    d_new_context     = d_hyp_level_integrator->getNewContext();

    // Register the VisIt data writer with the patch strategy object, which is
    // the object that actually registers variables for plotting.
    if (d_visit_writer)
    {
        d_hyp_patch_ops->registerVisItDataWriter(d_visit_writer);
    }

    // Register variables with the hyperbolic level integrator.
    for (std::vector<Pointer<FaceVariable<NDIM,double> > >::const_iterator cit = d_u_var.begin(); cit != d_u_var.end(); ++cit)
    {
        Pointer<FaceVariable<NDIM,double> > u_var = *cit;
        d_hyp_patch_ops->registerAdvectionVelocity(u_var);
        d_hyp_patch_ops->setAdvectionVelocityIsDivergenceFree(u_var,d_u_is_div_free[u_var]);
        if (d_u_fcn[u_var]) d_hyp_patch_ops->setAdvectionVelocityFunction(u_var,d_u_fcn[u_var]);
    }

    const IntVector<NDIM> cell_ghosts = CELLG;
    for (std::vector<Pointer<CellVariable<NDIM,double> > >::const_iterator cit = d_F_var.begin(); cit != d_F_var.end(); ++cit)
    {
        Pointer<CellVariable<NDIM,double> > F_var = *cit;
        d_hyp_level_integrator->registerVariable(
            F_var, cell_ghosts,
            HyperbolicLevelIntegrator<NDIM>::TIME_DEP,
            d_hierarchy->getGridGeometry(),
            "CONSERVATIVE_COARSEN",
            "CONSERVATIVE_LINEAR_REFINE");
    }

    for (std::vector<Pointer<SideVariable<NDIM,double> > >::const_iterator cit = d_diffusion_coef_var.begin(); cit != d_diffusion_coef_var.end(); ++cit)
    {
        Pointer<SideVariable<NDIM,double> > D_var = *cit;
        d_hyp_level_integrator->registerVariable(
            D_var, cell_ghosts,
            HyperbolicLevelIntegrator<NDIM>::TIME_DEP,
            d_hierarchy->getGridGeometry(),
            "CONSERVATIVE_COARSEN",
            "CONSERVATIVE_LINEAR_REFINE");
        int D_scratch_idx;
        registerVariable(D_scratch_idx, D_var, cell_ghosts, getScratchContext());
    }

    for (std::vector<Pointer<SideVariable<NDIM,double> > >::const_iterator cit = d_diffusion_coef_rhs_var.begin(); cit != d_diffusion_coef_rhs_var.end(); ++cit)
    {
        Pointer<SideVariable<NDIM,double> > D_rhs_var = *cit;
        int D_rhs_scratch_idx;
        registerVariable(D_rhs_scratch_idx, D_rhs_var, cell_ghosts, getScratchContext());
    }

    for (std::vector<Pointer<CellVariable<NDIM,double> > >::const_iterator cit = d_Q_rhs_var.begin(); cit != d_Q_rhs_var.end(); ++cit)
    {
        Pointer<CellVariable<NDIM,double> > Q_rhs_var = *cit;
        int Q_rhs_scratch_idx;
        registerVariable(Q_rhs_scratch_idx, Q_rhs_var, cell_ghosts, getScratchContext());
        d_hyp_patch_ops->registerSourceTerm(Q_rhs_var);
    }

    for (std::vector<Pointer<CellVariable<NDIM,double> > >::const_iterator cit = d_Q_var.begin(); cit != d_Q_var.end(); ++cit)
    {
        Pointer<CellVariable<NDIM,double> > Q_var = *cit;
        int Q_scratch_idx;
        registerVariable(Q_scratch_idx, Q_var, cell_ghosts, getScratchContext());
        d_hyp_patch_ops->registerTransportedQuantity(Q_var);
        if (d_Q_u_map[Q_var]) d_hyp_patch_ops->setAdvectionVelocity(Q_var,d_Q_u_map[Q_var]);
        d_hyp_patch_ops->setSourceTerm(Q_var,d_Q_Q_rhs_map[Q_var]);
        d_hyp_patch_ops->setConvectiveDifferencingType(Q_var,d_Q_difference_form[Q_var]);
        if (d_Q_init[Q_var]) d_hyp_patch_ops->setInitialConditions(Q_var,d_Q_init[Q_var]);
        if (!d_Q_bc_coef[Q_var].empty()) d_hyp_patch_ops->setPhysicalBcCoefs(Q_var,d_Q_bc_coef[Q_var]);
    }

    // Initialize the HyperbolicLevelIntegrator.
    //
    // WARNING: This must be done AFTER all variables have been registered with
    // the level integrator.
    d_hyp_level_integrator->initializeLevelIntegrator(d_gridding_alg);

    // Perform hierarchy initialization operations common to all implementations
    // of AdvDiffHierarchyIntegrator.
    AdvDiffHierarchyIntegrator::initializeHierarchyIntegrator(hierarchy, gridding_alg);

    // Indicate that the integrator has been initialized.
    d_integrator_is_initialized = true;
    return;
}// initializeHierarchyIntegrator
void IBHierarchyIntegrator::initializeHierarchyIntegrator(
    Pointer<PatchHierarchy<NDIM> > hierarchy,
    Pointer<GriddingAlgorithm<NDIM> > gridding_alg)
{
    if (d_integrator_is_initialized) return;

    d_hierarchy = hierarchy;
    d_gridding_alg = gridding_alg;

    // Obtain the Hierarchy data operations objects.
    HierarchyDataOpsManager<NDIM>* hier_ops_manager =
        HierarchyDataOpsManager<NDIM>::getManager();
    d_hier_velocity_data_ops = hier_ops_manager->getOperationsDouble(d_u_var, hierarchy, true);
    d_hier_pressure_data_ops = hier_ops_manager->getOperationsDouble(d_p_var, hierarchy, true);
    d_hier_cc_data_ops = hier_ops_manager->getOperationsDouble(
        new CellVariable<NDIM, double>("cc_var"), hierarchy, true);

    // Initialize all variables.
    VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase();

    const IntVector<NDIM> ib_ghosts = d_ib_method_ops->getMinimumGhostCellWidth();
    const IntVector<NDIM> ghosts = 1;

    d_u_idx = var_db->registerVariableAndContext(d_u_var, d_ib_context, ib_ghosts);
    d_f_idx = var_db->registerVariableAndContext(d_f_var, d_ib_context, ghosts);
    if (d_time_stepping_type == TRAPEZOIDAL_RULE)
    {
        d_f_current_idx = var_db->registerClonedPatchDataIndex(d_f_var, d_f_idx);
    }
    else
    {
        d_f_current_idx = -1;
    }

    if (d_ib_method_ops->hasFluidSources())
    {
        d_p_idx = var_db->registerVariableAndContext(d_p_var, d_ib_context, ib_ghosts);
        d_q_idx = var_db->registerVariableAndContext(d_q_var, d_ib_context, ghosts);
    }
    else
    {
        d_q_var = NULL;
        d_q_idx = -1;
    }

    if (!d_mark_file_name.empty())
    {
        d_mark_var = new LMarkerSetVariable(d_object_name + "::markers");
        registerVariable(
            d_mark_current_idx, d_mark_new_idx, d_mark_scratch_idx, d_mark_var, ghosts);
    }

    // Initialize the fluid solver.
    if (d_ib_method_ops->hasFluidSources())
    {
        d_ins_hier_integrator->registerFluidSourceFunction(new IBEulerianSourceFunction(this));
    }
    d_ins_hier_integrator->initializeHierarchyIntegrator(hierarchy, gridding_alg);

    // Have the IB method ops object register any additional Eulerian variables
    // and communications algorithms that it requires.
    d_ib_method_ops->registerEulerianVariables();
    d_ib_method_ops->registerEulerianCommunicationAlgorithms();

    // Create several communications algorithms, used in filling ghost cell data
    // and synchronizing data on the patch hierarchy.
    Pointer<Geometry<NDIM> > grid_geom = d_hierarchy->getGridGeometry();

    const int u_new_idx = var_db->mapVariableAndContextToIndex(d_u_var, getNewContext());
    const int u_scratch_idx =
        var_db->mapVariableAndContextToIndex(d_u_var, getScratchContext());
    const int p_new_idx = var_db->mapVariableAndContextToIndex(d_p_var, getNewContext());
    const int p_scratch_idx =
        var_db->mapVariableAndContextToIndex(d_p_var, getScratchContext());

    Pointer<CellVariable<NDIM, double> > u_cc_var = d_u_var;
    Pointer<SideVariable<NDIM, double> > u_sc_var = d_u_var;
    if (u_cc_var)
    {
        d_u_phys_bdry_op =
            new CartCellRobinPhysBdryOp(u_scratch_idx,
                                        d_ins_hier_integrator->getVelocityBoundaryConditions(),
                                        /*homogeneous_bc*/ false);
    }
    else if (u_sc_var)
    {
        d_u_phys_bdry_op =
            new CartSideRobinPhysBdryOp(u_scratch_idx,
                                        d_ins_hier_integrator->getVelocityBoundaryConditions(),
                                        /*homogeneous_bc*/ false);
    }
    else
    {
        TBOX_ERROR(
            "IBHierarchyIntegrator::initializeHierarchy(): unsupported velocity data "
            "centering\n");
    }

    d_u_ghostfill_alg = new RefineAlgorithm<NDIM>();
    d_u_ghostfill_op = NULL;
    d_u_ghostfill_alg->registerRefine(d_u_idx, d_u_idx, d_u_idx, d_u_ghostfill_op);
    registerGhostfillRefineAlgorithm(
        d_object_name + "::u", d_u_ghostfill_alg, d_u_phys_bdry_op);

    d_u_coarsen_alg = new CoarsenAlgorithm<NDIM>();
    d_u_coarsen_op = grid_geom->lookupCoarsenOperator(d_u_var, "CONSERVATIVE_COARSEN");
    d_u_coarsen_alg->registerCoarsen(d_u_idx, d_u_idx, d_u_coarsen_op);
    registerCoarsenAlgorithm(d_object_name + "::u::CONSERVATIVE_COARSEN", d_u_coarsen_alg);

    d_f_prolong_alg = new RefineAlgorithm<NDIM>();
    d_f_prolong_op = grid_geom->lookupRefineOperator(d_f_var, "CONSERVATIVE_LINEAR_REFINE");
    d_f_prolong_alg->registerRefine(d_f_idx, d_f_idx, d_f_idx, d_f_prolong_op);
    registerProlongRefineAlgorithm(d_object_name + "::f", d_f_prolong_alg);

    if (d_ib_method_ops->hasFluidSources())
    {
        Pointer<CellVariable<NDIM, double> > p_cc_var = d_p_var;
        if (p_cc_var)
        {
            d_p_phys_bdry_op = new CartCellRobinPhysBdryOp(
                p_scratch_idx,
                d_ins_hier_integrator->getPressureBoundaryConditions(),
                /*homogeneous_bc*/ false);
        }
        else
        {
            TBOX_ERROR(
                "IBHierarchyIntegrator::initializeHierarchy(): unsupported pressure data "
                "centering\n");
        }

        d_p_ghostfill_alg = new RefineAlgorithm<NDIM>();
        d_p_ghostfill_op = NULL;
        d_p_ghostfill_alg->registerRefine(d_p_idx, d_p_idx, d_p_idx, d_p_ghostfill_op);
        registerGhostfillRefineAlgorithm(
            d_object_name + "::p", d_p_ghostfill_alg, d_p_phys_bdry_op);

        d_p_coarsen_alg = new CoarsenAlgorithm<NDIM>();
        d_p_coarsen_op = grid_geom->lookupCoarsenOperator(d_p_var, "CONSERVATIVE_COARSEN");
        d_p_coarsen_alg->registerCoarsen(d_p_idx, d_p_idx, d_p_coarsen_op);
        registerCoarsenAlgorithm(d_object_name + "::p::CONSERVATIVE_COARSEN", d_p_coarsen_alg);

        d_q_prolong_alg = new RefineAlgorithm<NDIM>();
        d_q_prolong_op =
            grid_geom->lookupRefineOperator(d_q_var, "CONSERVATIVE_LINEAR_REFINE");
        d_q_prolong_alg->registerRefine(d_q_idx, d_q_idx, d_q_idx, d_q_prolong_op);
        registerProlongRefineAlgorithm(d_object_name + "::q", d_q_prolong_alg);
    }

    Pointer<RefineAlgorithm<NDIM> > refine_alg = new RefineAlgorithm<NDIM>();
    Pointer<RefineOperator<NDIM> > refine_op;
    refine_op = grid_geom->lookupRefineOperator(d_u_var, "CONSERVATIVE_LINEAR_REFINE");
    refine_alg->registerRefine(u_scratch_idx, u_new_idx, u_scratch_idx, refine_op);
    refine_op = grid_geom->lookupRefineOperator(d_p_var, "LINEAR_REFINE");
    refine_alg->registerRefine(p_scratch_idx, p_new_idx, p_scratch_idx, refine_op);
    ComponentSelector instrumentation_data_fill_bc_idxs;
    instrumentation_data_fill_bc_idxs.setFlag(u_scratch_idx);
    instrumentation_data_fill_bc_idxs.setFlag(p_scratch_idx);
    RefinePatchStrategy<NDIM>* refine_patch_bdry_op =
        new CartExtrapPhysBdryOp(instrumentation_data_fill_bc_idxs, "LINEAR");
    registerGhostfillRefineAlgorithm(
        d_object_name + "::INSTRUMENTATION_DATA_FILL", refine_alg, refine_patch_bdry_op);

    // Read in initial marker positions.
    if (!d_mark_file_name.empty())
    {
        LMarkerUtilities::readMarkerPositions(
            d_mark_init_posns, d_mark_file_name, hierarchy->getGridGeometry());
    }

    // Setup the tag buffer.
    const int finest_hier_ln = gridding_alg->getMaxLevels() - 1;
    const int tsize = d_tag_buffer.size();
    d_tag_buffer.resizeArray(finest_hier_ln);
    for (int i = tsize; i < finest_hier_ln; ++i) d_tag_buffer[i] = 0;
    for (int i = std::max(tsize, 1); i < d_tag_buffer.size(); ++i)
    {
        d_tag_buffer[i] = d_tag_buffer[i - 1];
    }
    d_ib_method_ops->setupTagBuffer(d_tag_buffer, d_gridding_alg);

    // Indicate that the integrator has been initialized.
    d_integrator_is_initialized = true;
    return;
} // initializeHierarchyIntegrator