 X_mark_current[k] + dt*U_mark_half[k];
            }

            // Prevent markers from leaving the computational domain through
            // physical boundaries (but *not* through periodic boundaries).
            preventMarkerEscape(X_mark_new, hierarchy->getGridGeometry());

            // Store the local marker velocities at at time n, and the marker
            // positions at time n+1.
            resetMarkerVelocitiesOnPatch(U_mark_new, mark_new_data);
            resetMarkerPositionsOnPatch(X_mark_new, mark_new_data);
        }
    }
    return;
}// trapezoidalStep

void
LMarkerUtilities::collectMarkersOnPatchHierarchy(
    const int mark_idx,
    Pointer<PatchHierarchy<NDIM> > hierarchy)
{
    const int coarsest_ln = 0;
    const int finest_ln = hierarchy->getFinestLevelNumber();

    const unsigned int num_marks_before_coarsening = countMarkers(mark_idx,hierarchy);
    const unsigned int num_marks_before_coarsening_level_0 = countMarkers(mark_idx,hierarchy,0,0);

    // Collect all marker data on the patch hierarchy.
    VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase();
    Pointer<Variable<NDIM> > var;
    var_db->mapIndexToVariable(mark_idx, var);
    int mark_scratch_idx = var_db->registerClonedPatchDataIndex(var, mark_idx);
    Pointer<CoarsenAlgorithm<NDIM> > mark_coarsen_alg = new CoarsenAlgorithm<NDIM>();
    mark_coarsen_alg->registerCoarsen(mark_scratch_idx, mark_idx, new LMarkerCoarsen());
    for (int ln = finest_ln; ln > coarsest_ln; --ln)
    {
        Pointer<PatchLevel<NDIM> > level = hierarchy->getPatchLevel(ln);
        Pointer<PatchLevel<NDIM> > coarser_level = hierarchy->getPatchLevel(ln-1);

        // Allocate scratch data.
        coarser_level->allocatePatchData(mark_scratch_idx);

        // Coarsen fine data onto coarser level.
        CoarsenPatchStrategy<NDIM>* mark_coarsen_op = NULL;
        mark_coarsen_alg->createSchedule(coarser_level, level, mark_coarsen_op)->coarsenData();

        // Merge the coarsened fine data with the coarse data.
        for (PatchLevel<NDIM>::Iterator p(coarser_level); p; p++)
        {
            Pointer<Patch<NDIM> > patch = coarser_level->getPatch(p());
            Pointer<LMarkerSetData> mark_current_data = patch->getPatchData(mark_idx);
            Pointer<LMarkerSetData> mark_scratch_data = patch->getPatchData(mark_scratch_idx);
            for (LMarkerSetData::Iterator it(*mark_scratch_data); it; it++)
            {
                const Index<NDIM>& i = it.getIndex();
                if (!mark_current_data->isElement(i))
                {
                    mark_current_data->appendItemPointer(i, new LMarkerSet());
                }
                LMarkerSet& dst_mark_set = *(mark_current_data->getItem(i));
                const LMarkerSet& src_mark_set = it();
                dst_mark_set.insert(dst_mark_set.end(), src_mark_set.begin(), src_mark_set.end());
            }
        }

        // Clear the fine data.
        for (PatchLevel<NDIM>::Iterator p(level); p; p++)
        {
            Pointer<Patch<NDIM> > patch = level->getPatch(p());
            Pointer<LMarkerSetData> mark_current_data = patch->getPatchData(mark_idx);
            mark_current_data->removeAllItems();
        }

        // Deallocate scratch data.
        coarser_level->deallocatePatchData(mark_scratch_idx);
    }
    var_db->removePatchDataIndex(mark_scratch_idx);
    mark_scratch_idx = -1;

    // Ensure that the total number of markers is correct.
    const unsigned int num_marks_after_coarsening = countMarkers(mark_idx,hierarchy);
    const unsigned int num_marks_after_coarsening_level_0 = countMarkers(mark_idx,hierarchy,0,0);
    if (num_marks_before_coarsening!= num_marks_after_coarsening || num_marks_before_coarsening!= num_marks_after_coarsening_level_0)
    {
        TBOX_ERROR("LMarkerUtilities::collectMarkersOnPatchHierarchy()\n"
                   << "  number of marker particles changed during collection to coarsest level\n"
                   << "  number of markers in hierarchy before collection to coarsest level = " << num_marks_before_coarsening << "\n"
                   << "  number of markers on level 0   before collection to coarsest level = " << num_marks_before_coarsening_level_0 << "\n"
                   << "  number of markers in hierarchy after  collection to coarsest level = " << num_marks_after_coarsening << "\n"
                   << "  number of markers on level 0   after  collection to coarsest level = " << num_marks_after_coarsening_level_0 << "\n");
    }

    // Reset the assignment of markers to Cartesian grid cells on the coarsest
    // level of the patch hierarchy.
    //
    // NOTE: It is important to do this only *after* collecting markers on the
    // patch hierarchy.  Otherwise, markers that have left a fine level through
    // the coarse-fine interface would be discarded by this procedure.
    Pointer<RefineAlgorithm<NDIM> > mark_level_fill_alg = new RefineAlgorithm<NDIM>();
    mark_level_fill_alg->registerRefine(mark_idx, mark_idx, mark_idx, NULL);
    Pointer<PatchLevel<NDIM> > level = hierarchy->getPatchLevel(coarsest_ln);
    mark_level_fill_alg->createSchedule(level,NULL)->fillData(0.0);
    for (PatchLevel<NDIM>::Iterator p(level); p; p++)
    {
        Pointer<Patch<NDIM> > patch = level->getPatch(p());
        const Box<NDIM>& patch_box = patch->getBox();

        const Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry();
        const Index<NDIM>& patch_lower = patch_box.lower();
        const Index<NDIM>& patch_upper = patch_box.upper();
        const double* const patchXLower = patch_geom->getXLower();
        const double* const patchXUpper = patch_geom->getXUpper();
        const double* const patchDx = patch_geom->getDx();

        Pointer<LMarkerSetData> mark_data = patch->getPatchData(mark_idx);
        Pointer<LMarkerSetData> mark_data_new = new LMarkerSetData(mark_data->getBox(), mark_data->getGhostCellWidth());
        for (LMarkerSetData::DataIterator it = mark_data->data_begin(mark_data->getGhostBox()); it!= mark_data->data_end(); ++it)
        {
            const LMarkerSet::value_type& mark = *it;
            const blitz::TinyVector<double,NDIM>& X = mark->getPosition();
            const IntVector<NDIM>& offset = mark->getPeriodicOffset();
            blitz::TinyVector<double,NDIM> X_shifted;
            for (unsigned int d = 0; d < NDIM; ++d)
            {
                X_shifted[d] = X[d] + static_cast<double>(offset(d))*patchDx[d];
            }
            const bool patch_owns_mark_at_new_loc =
                ((  patchXLower[0] <= X_shifted[0])&&(X_shifted[0] < patchXUpper[0]))
#if (NDIM > 1)
                &&((patchXLower[1] <= X_shifted[1])&&(X_shifted[1] < patchXUpper[1]))
#if (NDIM