[cig-commits] commit: Move everything into Elastic namespace

Mercurial hg at geodynamics.org
Thu Jun 7 13:36:09 PDT 2012


changeset:   281:dc04c13db402
user:        Walter Landry <wlandry at caltech.edu>
date:        Wed Jun 06 15:05:55 2012 -0700
files:       input/fault.input input/fault3D.input src/Elastic/FAC.h src/Elastic/FAC/FAC.C src/Elastic/FAC/applyGradientDetector.C src/Elastic/FAC/fix_moduli.C src/Elastic/FAC/initializeLevelData.C src/Elastic/FAC/packDerivedDataIntoDoubleBuffer.C src/Elastic/FAC/resetHierarchyConfiguration.C src/Elastic/FAC/setupPlotter.C src/Elastic/FAC/solve.C src/Elastic/FACOps.I src/Elastic/FACOps.h src/Elastic/FACOps/FACOps.C src/Elastic/FACOps/computeCompositeResidualOnLevel.C src/Elastic/FACOps/computeResidualNorm.C src/Elastic/FACOps/computeVectorWeights.C src/Elastic/FACOps/deallocateOperatorState.C src/Elastic/FACOps/finalizeCallback.C src/Elastic/FACOps/initializeOperatorState.C src/Elastic/FACOps/postprocessOneCycle.C src/Elastic/FACOps/prolongErrorAndCorrect.C src/Elastic/FACOps/residual_2D.C src/Elastic/FACOps/residual_3D.C src/Elastic/FACOps/restrictResidual.C src/Elastic/FACOps/restrictSolution.C src/Elastic/FACOps/set_boundaries.C src/Elastic/FACOps/smoothError.C src/Elastic/FACOps/smooth_Tackley_2D.C src/Elastic/FACOps/smooth_Tackley_3D.C src/Elastic/FACOps/smooth_V_2D.C src/Elastic/FACOps/smooth_V_3D.C src/Elastic/FACOps/solveCoarsestLevel.C src/Elastic/FACOps/solveCoarsestLevel_HYPRE.C src/Elastic/FACOps/xeqScheduleGhostFill.C src/Elastic/FACOps/xeqScheduleGhostFillNoCoarse.C src/Elastic/FACOps/xeqScheduleProlongation.C src/Elastic/FACOps/xeqScheduleRRestriction.C src/Elastic/FACOps/xeqScheduleURestriction.C src/Elastic/FACSolver.I src/Elastic/FACSolver.h src/Elastic/FACSolver/FACSolver.C src/Elastic/FACSolver/FACSolver_Destructor.C src/Elastic/FACSolver/createVectorWrappers.C src/Elastic/FACSolver/deallocateSolverState.C src/Elastic/FACSolver/destroyVectorWrappers.C src/Elastic/FACSolver/enableLogging.C src/Elastic/FACSolver/getFromInput.C src/Elastic/FACSolver/initializeSolverState.C src/Elastic/FACSolver/initializeStatics.C src/Elastic/FACSolver/setBcObject.C src/Elastic/FACSolver/setBoundaries.C src/Elastic/FACSolver/solveSystem.C src/Elastic/HypreSolver.C src/Elastic/HypreSolver.I src/Elastic/HypreSolver.h src/Elastic/P_Boundary_Refine.h src/Elastic/P_Boundary_Refine/Update_P_2D.C src/Elastic/P_Boundary_Refine/Update_P_3D.C src/Elastic/P_Boundary_Refine/refine.C src/Elastic/P_Refine.C src/Elastic/P_Refine.h src/Elastic/P_Refine_Patch_Strategy.h src/Elastic/Resid_Coarsen.C src/Elastic/Resid_Coarsen.h src/Elastic/V_Boundary_Refine.h src/Elastic/V_Boundary_Refine/Update_V_2D.C src/Elastic/V_Boundary_Refine/Update_V_3D.C src/Elastic/V_Boundary_Refine/refine.C src/Elastic/V_Coarsen.h src/Elastic/V_Coarsen/coarsen_2D.C src/Elastic/V_Coarsen/coarsen_3D.C src/Elastic/V_Coarsen_Patch_Strategy.h src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C src/Elastic/V_Refine.h src/Elastic/V_Refine/refine.C src/Elastic/V_Refine/refine_along_line.C src/Elastic/V_Refine_Patch_Strategy.h src/Elastic/dRc_dp.h src/Elastic/dRm_dv.h src/Elastic/set_boundary.C src/Elastic/set_boundary.h src/ElasticFACOps.I src/ElasticFACOps.h src/ElasticFACOps/ElasticFACOps.C src/ElasticFACOps/computeCompositeResidualOnLevel.C src/ElasticFACOps/computeResidualNorm.C src/ElasticFACOps/computeVectorWeights.C src/ElasticFACOps/deallocateOperatorState.C src/ElasticFACOps/finalizeCallback.C src/ElasticFACOps/initializeOperatorState.C src/ElasticFACOps/postprocessOneCycle.C src/ElasticFACOps/prolongErrorAndCorrect.C src/ElasticFACOps/residual_2D.C src/ElasticFACOps/residual_3D.C src/ElasticFACOps/restrictResidual.C src/ElasticFACOps/restrictSolution.C src/ElasticFACOps/set_boundaries.C src/ElasticFACOps/smoothError.C src/ElasticFACOps/smooth_Tackley_2D.C src/ElasticFACOps/smooth_Tackley_3D.C src/ElasticFACOps/smooth_V_2D.C src/ElasticFACOps/smooth_V_3D.C src/ElasticFACOps/solveCoarsestLevel.C src/ElasticFACOps/solveCoarsestLevel_HYPRE.C src/ElasticFACOps/xeqScheduleGhostFill.C src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C src/ElasticFACOps/xeqScheduleProlongation.C src/ElasticFACOps/xeqScheduleRRestriction.C src/ElasticFACOps/xeqScheduleURestriction.C src/ElasticFACSolver.I src/ElasticFACSolver.h src/ElasticFACSolver/ElasticFACSolver.C src/ElasticFACSolver/ElasticFACSolver_Destructor.C src/ElasticFACSolver/createVectorWrappers.C src/ElasticFACSolver/deallocateSolverState.C src/ElasticFACSolver/destroyVectorWrappers.C src/ElasticFACSolver/enableLogging.C src/ElasticFACSolver/getFromInput.C src/ElasticFACSolver/initializeSolverState.C src/ElasticFACSolver/initializeStatics.C src/ElasticFACSolver/setBcObject.C src/ElasticFACSolver/setBoundaries.C src/ElasticFACSolver/solveSystem.C src/ElasticHypreSolver.C src/ElasticHypreSolver.I src/ElasticHypreSolver.h src/FACElastic.h src/FACElastic/FACElastic.C src/FACElastic/applyGradientDetector.C src/FACElastic/fix_moduli.C src/FACElastic/initializeLevelData.C src/FACElastic/packDerivedDataIntoDoubleBuffer.C src/FACElastic/resetHierarchyConfiguration.C src/FACElastic/setupPlotter.C src/FACElastic/solveElastic.C src/P_Boundary_Refine.h src/P_Boundary_Refine/Update_P_2D.C src/P_Boundary_Refine/Update_P_3D.C src/P_Boundary_Refine/refine.C src/P_Refine.C src/P_Refine.h src/P_Refine_Patch_Strategy.h src/Resid_Coarsen.C src/Resid_Coarsen.h src/V_Boundary_Refine.h src/V_Boundary_Refine/Update_V_2D.C src/V_Boundary_Refine/Update_V_3D.C src/V_Boundary_Refine/refine.C src/V_Coarsen.h src/V_Coarsen/coarsen_2D.C src/V_Coarsen/coarsen_3D.C src/V_Coarsen_Patch_Strategy.h src/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C src/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C src/V_Refine.h src/V_Refine/refine.C src/V_Refine/refine_along_line.C src/V_Refine_Patch_Strategy.h src/dRc_dp.h src/dRm_dv.h src/main.C src/set_boundary.C src/set_boundary.h wscript
description:
Move everything into Elastic namespace


diff -r daa8bb8aed75 -r dc04c13db402 input/fault.input
--- a/input/fault.input	Tue Jun 05 15:28:40 2012 -0700
+++ b/input/fault.input	Wed Jun 06 15:05:55 2012 -0700
@@ -23,7 +23,7 @@ Main {
     vis_writer = "Vizamrai", "VisIt"
 }
 
-FACElastic {
+Elastic {
     // The FACStokes class is the "user class" in this example.
     // It owns the solver and contains the code to set up the solver.
     // The inputs for FACStokes is simply the inputs for the individual
diff -r daa8bb8aed75 -r dc04c13db402 input/fault3D.input
--- a/input/fault3D.input	Tue Jun 05 15:28:40 2012 -0700
+++ b/input/fault3D.input	Wed Jun 06 15:05:55 2012 -0700
@@ -23,7 +23,7 @@ Main {
     vis_writer = "Vizamrai", "VisIt"
 }
 
-FACStokes {
+Elastic {
     // The FACStokes class is the "user class" in this example.
     // It owns the solver and contains the code to set up the solver.
     // The inputs for FACStokes is simply the inputs for the individual
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#ifndef included_FACElastic
+#define included_FACElastic
+
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/tbox/Database.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/solv/LocationIndexRobinBcCoefs.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/hier/PatchHierarchy.h"
+#include "SAMRAI/hier/PatchLevel.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/mesh/StandardTagAndInitStrategy.h"
+#include "SAMRAI/hier/VariableContext.h"
+#include "SAMRAI/appu/VisDerivedDataStrategy.h"
+#include "SAMRAI/appu/VisItDataWriter.h"
+
+namespace SAMRAI {
+namespace Elastic {
+  /*!
+   * @brief Class to solve a sample Elastic equation on a SAMR grid.
+   */
+  class FAC:
+    public mesh::StandardTagAndInitStrategy,
+    public appu::VisDerivedDataStrategy
+  {
+
+  public:
+    /*!
+     * @brief Constructor.
+     *
+     * If you want standard output and logging,
+     * pass in valid pointers for those streams.
+     *
+     * @param object_name Ojbect name
+     * @param database Input database (may be NULL)
+     */
+    FAC(const std::string& object_name,
+        const tbox::Dimension& dim,
+        tbox::Pointer<tbox::Database> database =
+        tbox::Pointer<tbox::Database>(NULL));
+
+    virtual ~FAC() {}
+
+    //@{ @name mesh::StandardTagAndInitStrategy virtuals
+
+    /*!
+     * @brief Allocate and initialize data for a new level
+     * in the patch hierarchy.
+     *
+     * This is where you implement the code for initialize data on
+     * the grid.  All the information needed to initialize the grid
+     * are in the arguments.
+     *
+     * @see mesh::StandardTagAndInitStrategy::initializeLevelData()
+     */
+    virtual void
+    initializeLevelData(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy,
+                        const int level_number,
+                        const double init_data_time,
+                        const bool can_be_refined,
+                        const bool initial_time,
+                        const tbox::Pointer<hier::BasePatchLevel> old_level,
+                        const bool allocate_data);
+
+    /*!
+     * @brief Reset any internal hierarchy-dependent information.
+     */
+    virtual void
+    resetHierarchyConfiguration(tbox::Pointer<hier::BasePatchHierarchy> new_hierarchy,
+                                int coarsest_level,
+                                int finest_level);
+
+    //@}
+
+    virtual void
+    applyGradientDetector(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy,
+                          const int level_number,
+                          const double error_data_time,
+                          const int tag_index,
+                          const bool initial_time,
+                          const bool uses_richardson_extrapolation);
+
+    void computeAdaptionEstimate(pdat::CellData<double>& estimate_data,
+                                 const pdat::CellData<double>& soln_cell_data)
+      const;
+
+    //@{ @name appu::VisDerivedDataStrategy virtuals
+
+    virtual bool
+    packDerivedDataIntoDoubleBuffer(double* buffer,
+                                    const hier::Patch& patch,
+                                    const hier::Box& region,
+                                    const std::string& variable_name,
+                                    int depth_id) const;
+
+    //@}
+
+    /*!
+     * @brief Solve using HYPRE Elastic solver
+     *
+     * Set up the linear algebra problem and use a
+     * solv::Elastic::FACSolver object to solve it.
+     * -# Set initial guess
+     * -# Set boundary conditions
+     * -# Specify Elastic equation parameters
+     * -# Call solver
+     */
+    int
+    solve();
+
+#ifdef HAVE_HDF5
+    /*!
+     * @brief Set up external plotter to plot internal
+     * data from this class.
+     *
+     * After calling this function, the external
+     * data writer may be used to write the
+     * viz file for this object.
+     *
+     * The internal hierarchy is used and must be
+     * established before calling this function.
+     * (This is commonly done by building a hierarchy
+     * with the mesh::StandardTagAndInitStrategy virtual
+     * functions implemented by this class.)
+     *
+     * @param viz_writer VisIt writer
+     */
+    int
+    setupPlotter(appu::VisItDataWriter& plotter) const;
+#endif
+
+  private:
+    void fix_moduli();
+    std::string d_object_name;
+
+    const tbox::Dimension d_dim;
+
+    tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
+
+    //@{
+    /*!
+     * @name Major algorithm objects.
+     */
+
+    /*!
+     * @brief FAC Elastic solver.
+     */
+    solv::Elastic::FACSolver d_elastic_fac_solver;
+
+    /*!
+     * @brief Boundary condition coefficient implementation.
+     */
+    solv::LocationIndexRobinBcCoefs d_bc_coefs;
+
+    //@}
+
+    //@{
+
+    /*!
+     * @name Private state variables for solution.
+     */
+
+    /*!
+     * @brief Context owned by this object.
+     */
+    tbox::Pointer<hier::VariableContext> d_context;
+  
+    /*!
+     * @brief Descriptor indices of internal data.
+     *
+     * These are initialized in the constructor and never change.
+     */
+
+    double d_adaption_threshold;
+    int min_full_refinement_level;
+  public:
+    int p_id, cell_moduli_id, edge_moduli_id, dp_id, p_exact_id,
+      p_rhs_id, v_id, v_rhs_id;
+
+    tbox::Array<double> lambda, lambda_xyz_max, lambda_xyz_min;
+    tbox::Array<int> lambda_ijk;
+
+    tbox::Array<double> mu, mu_xyz_max, mu_xyz_min;
+    tbox::Array<int> mu_ijk;
+
+    tbox::Array<double> v_rhs, v_rhs_xyz_max, v_rhs_xyz_min;
+    tbox::Array<int> v_rhs_ijk;
+
+    tbox::Array<double> p_initial, p_initial_xyz_max, p_initial_xyz_min;
+    tbox::Array<int> p_initial_ijk;
+    //@}
+
+  };
+
+}
+}
+
+#endif  // included_FACElastic
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/FAC.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/FAC.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+
+namespace SAMRAI {
+
+  /* A little utility routine to validate the sizes of input arrays */
+  void check_array_sizes(const tbox::Array<int> ijk,
+                         const tbox::Array<double> min,
+                         const tbox::Array<double> max,
+                         const tbox::Array<double> data,
+                         const int dim, const std::string &name,
+                         const int num_components=1)
+  {
+    if(ijk.size()!=dim)
+      TBOX_ERROR("Bad number of elements in " << name << "_ijk.  Expected "
+                 << dim << " but got " << ijk.size());
+    if(min.size()!=dim)
+      TBOX_ERROR("Bad number of elements in "
+                 << name << "_coord_min.  Expected "
+                 << dim << " but got " << min.size());
+    if(max.size()!=dim)
+      TBOX_ERROR("Bad number of elements in "
+                 << name << "_coord_max.  Expected "
+                 << dim << " but got " << max.size());
+    int data_size(1);
+    for(int d=0; d<dim; ++d)
+      data_size*=ijk[d];
+    if(data.size()!=data_size*num_components)
+      TBOX_ERROR("Bad number of elements in "
+                 << name << "_data.  Expected "
+                 << data_size << " but got " << data.size());
+  }
+  /*
+*************************************************************************
+* Constructor creates a unique context for the object and register      *
+* all its internal variables with the variable database.                *
+*************************************************************************
+*/
+  Elastic::FAC::FAC(const std::string& object_name,
+                    const tbox::Dimension& dimension,
+                    tbox::Pointer<tbox::Database> database):
+    d_object_name(object_name),
+    d_dim(dimension),
+    d_hierarchy(NULL),
+    d_elastic_fac_solver((d_dim),
+                         object_name + "::elastic_hypre",
+                         (!database.isNull() &&
+                          database->isDatabase("fac_solver")) ?
+                         database->getDatabase("fac_solver"):
+                         tbox::Pointer<tbox::Database>(NULL)),
+    d_bc_coefs(d_dim,
+               object_name + "::bc_coefs",
+               (!database.isNull() &&
+                database->isDatabase("bc_coefs")) ?
+               database->getDatabase("bc_coefs"):
+               tbox::Pointer<tbox::Database>(NULL)),
+    d_context()
+  {
+    const int dim(d_dim.getValue());
+    hier::VariableDatabase* vdb =
+      hier::VariableDatabase::getDatabase();
+
+    /*
+     * Get a unique context for variables owned by this object.
+     */
+    d_context = vdb->getContext(d_object_name + ":Context");
+
+    /*
+     * Register variables with hier::VariableDatabase
+     * and get the descriptor indices for those variables.
+     */
+
+    tbox::Pointer<pdat::CellVariable<double> >
+      p_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":p", 1));
+    p_id = vdb->registerVariableAndContext(p_ptr, d_context,
+                                           hier::IntVector(d_dim, 1)
+                                           /* ghost cell width is 1 for
+                                              stencil widths */);
+
+	int depth=2;
+    tbox::Pointer<pdat::CellVariable<double> >
+      cell_moduli_ptr(new pdat::CellVariable<double>(d_dim,
+                                                        object_name
+                                                        + ":cell_moduli",depth));
+    cell_moduli_id = vdb->registerVariableAndContext(cell_moduli_ptr,
+                                                        d_context,
+                                                        hier::IntVector(d_dim, 1)
+                                                        /* ghost cell width is
+                                                           1 in case needed */);
+
+    if(dim==2)
+      {
+        tbox::Pointer<pdat::NodeVariable<double> >
+          edge_moduli_ptr(new pdat::NodeVariable<double>(d_dim,
+                                                            object_name
+                                                            + ":edge_moduli",depth));
+        edge_moduli_id =
+          vdb->registerVariableAndContext(edge_moduli_ptr,d_context,
+                                          hier::IntVector(d_dim,1)
+                                          /* ghost cell width is 1 in
+                                             case needed */);
+      }
+    else if(dim==3)
+      {
+        tbox::Pointer<pdat::EdgeVariable<double> >
+          edge_moduli_ptr(new pdat::EdgeVariable<double>(d_dim,
+                                                            object_name
+                                                            + ":edge_moduli",depth));
+        edge_moduli_id =
+          vdb->registerVariableAndContext(edge_moduli_ptr,d_context,
+                                          hier::IntVector(d_dim,1)
+                                          /* ghost cell width is 1 in
+                                             case needed */);
+      }
+
+    tbox::Pointer<pdat::CellVariable<double> >
+      dp_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":dp"));
+    dp_id = vdb->registerVariableAndContext(dp_ptr,d_context,
+                                            hier::IntVector(d_dim, 1)
+                                            /* ghost cell width is
+                                                    1 in case needed */);
+
+    tbox::Pointer<pdat::CellVariable<double> >
+      p_exact_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":p exact"));
+    p_exact_id = vdb->registerVariableAndContext(p_exact_ptr,d_context,
+                                                 hier::IntVector(d_dim, 1)
+                                                 /* ghost cell width is
+                                                    1 in case needed */);
+
+    tbox::Pointer<pdat::CellVariable<double> >
+      p_rhs_ptr(new pdat::CellVariable<double>(d_dim,object_name
+                                               + ":p right hand side"));
+    p_rhs_id = vdb->registerVariableAndContext(p_rhs_ptr,d_context,
+                                               hier::IntVector(d_dim, 1));
+
+    tbox::Pointer<pdat::SideVariable<double> >
+      v_ptr(new pdat::SideVariable<double>(d_dim, object_name + ":v", 1));
+    v_id = vdb->registerVariableAndContext(v_ptr, d_context,
+                                           hier::IntVector(d_dim, 1)
+                                           /* ghost cell width is 1 for
+                                              stencil widths */);
+
+    tbox::Pointer<pdat::SideVariable<double> >
+      v_rhs_ptr(new pdat::SideVariable<double>(d_dim,object_name
+                                               + ":v right hand side"));
+    v_rhs_id = vdb->registerVariableAndContext(v_rhs_ptr,d_context,
+                                               hier::IntVector(d_dim, 1)
+                                               /* ghost cell width is
+                                                  1 for coarsening
+                                                  operator */);
+
+    d_adaption_threshold=database->getDoubleWithDefault("adaption_threshold",
+                                                        1.0e-15);
+    min_full_refinement_level
+      =database->getIntegerWithDefault("min_full_refinement_level",0);
+
+    if(database->keyExists("lambda_data"))
+      {
+        lambda_ijk=database->getIntegerArray("lambda_ijk");
+        lambda_xyz_min=database->getDoubleArray("lambda_coord_min");
+        lambda_xyz_max=database->getDoubleArray("lambda_coord_max");
+        lambda=database->getDoubleArray("lambda_data");
+        check_array_sizes(lambda_ijk,lambda_xyz_min,lambda_xyz_max,
+                          lambda,dim,"lambda");
+      }
+
+    if(database->keyExists("mu_data"))
+      {
+        mu_ijk=database->getIntegerArray("mu_ijk");
+        mu_xyz_min=database->getDoubleArray("mu_coord_min");
+        mu_xyz_max=database->getDoubleArray("mu_coord_max");
+        mu=database->getDoubleArray("mu_data");
+        check_array_sizes(mu_ijk,mu_xyz_min,mu_xyz_max,
+                          mu,dim,"mu");
+      }
+
+    if(database->keyExists("v_rhs_data"))
+      {
+        v_rhs_ijk=database->getIntegerArray("v_rhs_ijk");
+        v_rhs_xyz_min=database->getDoubleArray("v_rhs_coord_min");
+        v_rhs_xyz_max=database->getDoubleArray("v_rhs_coord_max");
+        v_rhs=database->getDoubleArray("v_rhs_data");
+        check_array_sizes(v_rhs_ijk,v_rhs_xyz_min,v_rhs_xyz_max,
+                          v_rhs,dim,"v_rhs",dim);
+      }
+
+    if(database->keyExists("p_initial_data"))
+      {
+        p_initial_ijk=database->getIntegerArray("p_initial_ijk");
+        p_initial_xyz_min=database->getDoubleArray("p_initial_coord_min");
+        p_initial_xyz_max=database->getDoubleArray("p_initial_coord_max");
+        p_initial=database->getDoubleArray("p_initial_data");
+        check_array_sizes(p_initial_ijk,p_initial_xyz_min,p_initial_xyz_max,
+                          p_initial,dim,"p_initial");
+      }
+
+    /*
+     * Specify an implementation of solv::RobinBcCoefStrategy for the
+     * solver to use.  We use the implementation
+     * solv::LocationIndexRobinBcCoefs, but other implementations are
+     * possible, including user-implemented.
+     */
+    d_elastic_fac_solver.setBcObject(&d_bc_coefs);
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/applyGradientDetector.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/applyGradientDetector.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,113 @@
+#include "Elastic/FAC.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/pdat/MDA_Access.h"
+#include "SAMRAI/pdat/ArrayDataAccess.h"
+
+void SAMRAI::Elastic::FAC::applyGradientDetector
+(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy_,
+ const int ln,
+ const double ,
+ const int tag_index,
+ const bool ,
+ const bool )
+{
+  const tbox::Pointer<hier::PatchHierarchy> hierarchy__ = hierarchy_;
+  hier::PatchHierarchy& hierarchy = *hierarchy__;
+  hier::PatchLevel& level =
+    (hier::PatchLevel &) * hierarchy.getPatchLevel(ln);
+  
+  int ntag = 0, ntotal = 0;
+  double maxestimate = 0;
+  for(hier::PatchLevel::Iterator pi(level); pi; pi++)
+    {
+      hier::Patch& patch = **pi;
+      tbox::Pointer<hier::PatchData>
+        tag_data = patch.getPatchData(tag_index);
+      ntotal += patch.getBox().numberCells().getProduct();
+      if (tag_data.isNull())
+        {
+          TBOX_ERROR("Data index "
+                     << tag_index << " does not exist for patch.\n");
+        }
+      tbox::Pointer<pdat::CellData<int> > tag_cell_data_ = tag_data;
+      if (tag_cell_data_.isNull())
+        {
+          TBOX_ERROR("Data index " << tag_index << " is not cell int data.\n");
+        }
+      tbox::Pointer<hier::PatchData> soln_data = patch.getPatchData(v_id);
+      if (soln_data.isNull())
+        {
+          TBOX_ERROR("Data index " << v_id << " does not exist for patch.\n");
+        }
+      tbox::Pointer<pdat::SideData<double> > soln_side_data_ = soln_data;
+      if (soln_side_data_.isNull())
+        {
+          TBOX_ERROR("Data index " << v_id << " is not side data.\n");
+        }
+      pdat::SideData<double>& v = *soln_side_data_;
+      pdat::CellData<int>& tag_cell_data = *tag_cell_data_;
+                              
+      tbox::Pointer<geom::CartesianPatchGeometry> geom = patch.getPatchGeometry();
+
+      tag_cell_data.fill(0);
+      for (pdat::CellIterator ci(patch.getBox()); ci; ci++)
+        {
+          const pdat::CellIndex cell_index(*ci);
+
+	  double curve(0.);
+	  for (int ix=0; ix<d_dim.getValue(); ++ix)
+	  {
+            const pdat::SideIndex x(cell_index,ix,pdat::SideIndex::Lower);
+	    for (int d=0; d<d_dim.getValue(); ++d){
+		    hier::Index ip(d_dim,0),
+			        jp(d_dim,0),
+			        kp(d_dim,0);
+		    ip(0)=1;
+		    jp(1)=1;
+		    if (3==d_dim.getValue())
+		    {
+			kp(2)=1;
+		    }
+              const hier::Index pp[]={ip,jp,kp};
+
+              if(cell_index[ix]==patch.getBox().lower(ix)
+                 && geom->getTouchesRegularBoundary(ix,0))
+	      {
+	      curve=std::max(curve,std::abs(v(x+pp[ix]+pp[ix])-2*v(x+pp[ix])+v(x)));
+	      } else if(cell_index[ix]==patch.getBox().upper(ix)
+                 && geom->getTouchesRegularBoundary(ix,1))
+	      {
+	      curve=std::max(curve,std::abs(v(x+pp[ix])-2*v(x)+v(x-pp[ix])));
+	      }
+	      else
+	      {
+	      curve=std::max(curve,std::abs(v(x+pp[ix]+pp[ix])-v(x+pp[ix])-v(x)+v(x-pp[ix])));
+	      }
+	    }
+	  }
+          /*
+	   * tbox::plog << "estimate "
+                     << cell_index << " "
+                     << d_adaption_threshold << " "
+                     << curve << " "
+                     << std::boolalpha
+                     << (curve > d_adaption_threshold)
+                     << " "
+                     << "\n";
+		     */
+
+          if (maxestimate < curve)
+               maxestimate=curve;
+          if (curve > d_adaption_threshold || ln<min_full_refinement_level)
+            {
+              tag_cell_data(cell_index) = 1;
+              ++ntag;
+            }
+        }
+    }
+  tbox::plog << "Adaption threshold is " << d_adaption_threshold << "\n";
+  tbox::plog << "Number of cells tagged on level " << ln << " is "
+             << ntag << "/" << ntotal << "\n";
+  tbox::plog << "Max estimate is " << maxestimate << "\n";
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/fix_moduli.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/fix_moduli.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,141 @@
+#include "Elastic/FAC.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+
+/* Fix the moduli on the coarse grids by coarsening from the finer
+   grids. */
+
+void SAMRAI::Elastic::FAC::fix_moduli()
+{
+  const int ln_max(d_hierarchy->getFinestLevelNumber());
+
+  tbox::Pointer<xfer::CoarsenOperator> cell_moduli_coarsen_operator;
+  tbox::Pointer<xfer::CoarsenAlgorithm> cell_moduli_coarsen_algorithm;
+  tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
+    cell_moduli_coarsen_schedules;
+
+  hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
+  tbox::Pointer<geom::CartesianGridGeometry> geometry =
+    d_hierarchy->getGridGeometry();
+  tbox::Pointer<hier::Variable> variable;
+  vdb->mapIndexToVariable(cell_moduli_id, variable);
+  cell_moduli_coarsen_operator =
+    geometry->lookupCoarsenOperator(variable,
+                                    "CONSERVATIVE_COARSEN");
+                                    // "CELL_VISCOSITY_COARSEN");
+
+  if (!cell_moduli_coarsen_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find cell moduli coarsening operator");
+  }
+
+  cell_moduli_coarsen_schedules.resizeArray(ln_max + 1);
+  cell_moduli_coarsen_algorithm = new xfer::CoarsenAlgorithm(d_dim);
+  cell_moduli_coarsen_algorithm->
+    registerCoarsen(cell_moduli_id,cell_moduli_id,
+                    cell_moduli_coarsen_operator);
+
+  for (int dest_ln = 0; dest_ln < ln_max; ++dest_ln) {
+    cell_moduli_coarsen_schedules[dest_ln] =
+      cell_moduli_coarsen_algorithm->
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     d_hierarchy->getPatchLevel(dest_ln + 1));
+    if (!cell_moduli_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a coarsen schedule for cell moduli restriction!\n");
+    }
+  }
+
+  for(int dest_ln=ln_max-1; dest_ln>=0; --dest_ln)
+    {
+      xfer::CoarsenAlgorithm coarsener(d_dim);
+      coarsener.registerCoarsen(cell_moduli_id, cell_moduli_id,
+                                cell_moduli_coarsen_operator);
+      coarsener.resetSchedule(cell_moduli_coarsen_schedules[dest_ln]);
+      cell_moduli_coarsen_schedules[dest_ln]->coarsenData();
+      cell_moduli_coarsen_algorithm->
+        resetSchedule(cell_moduli_coarsen_schedules[dest_ln]);
+    }
+
+  cell_moduli_coarsen_algorithm.setNull();
+  cell_moduli_coarsen_schedules.setNull();
+
+  /* Compute edge_moduli by averaging the cell moduli. */
+
+  hier::Index ip(hier::Index::getZeroIndex(d_dim)), jp(ip), kp(ip);
+  ip[0]=1;
+  jp[1]=1;
+  if(d_dim.getValue()>2)
+    kp[2]=1;
+  hier::Index pp[]={ip,jp,kp};
+
+  for (int ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln)
+    {
+      tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
+      hier::PatchLevel::Iterator i_p(*level);
+      for ( ; i_p; i_p++)
+        {
+          tbox::Pointer<hier::Patch> patch = *i_p;
+          tbox::Pointer<pdat::CellData<double> >
+            cell_moduli_ptr = patch->getPatchData(cell_moduli_id);
+          pdat::CellData<double> &cell_moduli(*cell_moduli_ptr);
+          if(2==d_dim.getValue())
+            {
+              tbox::Pointer<pdat::NodeData<double> >
+                edge_moduli_ptr = patch->getPatchData(edge_moduli_id);
+              pdat::NodeData<double> &edge_moduli(*edge_moduli_ptr);
+
+              for(pdat::NodeIterator ni(edge_moduli.getBox()); ni; ni++)
+                {
+                  for (int m=0;m<2;++m)
+                    {
+                      pdat::NodeIndex e=ni();
+                      pdat::CellIndex c(e);
+                      cell_moduli(c,m);
+                      cell_moduli(c-ip,m);
+                      cell_moduli(c-jp,m);
+                      cell_moduli(c-ip-jp,m);
+                      edge_moduli(e,m)=
+                        pow(cell_moduli(c,m)*cell_moduli(c-ip,m)
+                            *cell_moduli(c-jp,m)*cell_moduli(c-ip-jp,m),0.25);
+                    }
+		}
+            }
+          else
+            {
+              tbox::Pointer<pdat::EdgeData<double> >
+                edge_moduli_ptr = patch->getPatchData(edge_moduli_id);
+              pdat::EdgeData<double> &edge_moduli(*edge_moduli_ptr);
+              for(int axis=0;axis<3;++axis)
+                {
+                  const int axis2((axis+1)%3), axis3((axis+2)%3);
+                  hier::Box pbox=patch->getBox();
+                  pbox.grow(axis,edge_moduli.getGhostCellWidth()[axis]);
+
+                  for(pdat::EdgeIterator ni(pbox,axis); ni; ni++)
+                    {
+                      pdat::EdgeIndex e=ni();
+                      pdat::CellIndex c(e);
+		      for (int m=0;m<2;++m)
+                        {
+                          edge_moduli(e,m)=
+                            pow(cell_moduli(c,m)*cell_moduli(c-pp[axis2],m)
+                                *cell_moduli(c-pp[axis3],m)
+                                *cell_moduli(c-pp[axis2]-pp[axis3],m),0.25);
+                        }
+                    }
+                }
+            }
+        }
+
+      /* Ghost fill */
+      xfer::RefineAlgorithm refiner(d_dim);
+      refiner.registerRefine(edge_moduli_id,edge_moduli_id,
+                             edge_moduli_id,
+                             tbox::Pointer<xfer::RefineOperator>(0));
+
+      tbox::Pointer<xfer::RefineSchedule> schedule=
+        refiner.createSchedule(d_hierarchy->getPatchLevel(ln));
+        
+      schedule->fillData(0.0,false);
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/initializeLevelData.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/initializeLevelData.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,477 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "FTensor.hpp"
+
+bool intersect_fault(const int &dim,
+                     const FTensor::Tensor1<double,3> &c0,
+                     const FTensor::Tensor1<double,3> &c1,
+                     const double fault[])
+{
+  bool result(true);
+  for(int d=1;d<dim;++d)
+    {
+      double y((c1(d)*c0(0) -  c1(0)*c0(d))/(c1(0) - c0(0)));
+      result=result && (y<=fault[d-1]/2 && y>-fault[d-1]/2);
+    }
+  return result;
+}
+
+void rotate(double cstrike, double sstrike, double cdip, double sdip, 
+            double x1, double x2, double x3, 
+            double * x1s, double * x1i, double * x2s, double * x3s, double * x3i)
+{
+
+  double x2r(cstrike*x1-sstrike*x2);
+
+  (*x1s)= cdip*x2r-sdip*x3;
+  (*x1i)= cdip*x2r+sdip*x3;
+  (*x2s)= sstrike*x1+cstrike*x2;
+  (*x3s)= sdip*x2r+cdip*x3;
+  (*x3i)=-sdip*x2r+cdip*x3;
+
+}
+
+double gauss(double x, double sigma)
+{
+  const double pi2 = atan(1.0)*8;
+  return exp(-0.5*(x/sigma)*(x/sigma))/sqrt(pi2)/sigma;
+}
+
+double omega(double x, double beta)
+{
+  const double pi=4*atan(1);
+
+  if (fabs(x) <= (1-2*beta)/(1-beta)/2)
+    {
+      return 1;
+    }
+  else
+    {
+      if (fabs(x) < 1./(2.*(1.-beta)))
+        {
+          return pow(cos(pi*((1.-beta)*fabs(x)-0.5+beta)/(2.*beta)),2.);
+        }
+      else
+        {
+          return 0;
+        }
+    }
+}
+
+/*
+*************************************************************************
+* Initialize data on a level.                                           *
+*                                                                       *
+* Allocate the solution, exact solution and rhs memory.                 *
+* Fill the rhs and exact solution.                                      *
+*************************************************************************
+*/
+void SAMRAI::Elastic::FAC::initializeLevelData
+(const tbox::Pointer<hier::BasePatchHierarchy> patch_hierarchy,
+ const int level_number,
+ const double ,
+ const bool ,
+ const bool ,
+ const tbox::Pointer<hier::BasePatchLevel> ,
+ const bool allocate_data)
+{
+  tbox::Pointer<hier::PatchHierarchy> hierarchy = patch_hierarchy;
+  tbox::Pointer<geom::CartesianGridGeometry> grid_geom =
+    hierarchy->getGridGeometry();
+
+  tbox::Pointer<hier::PatchLevel> level =
+    hierarchy->getPatchLevel(level_number);
+  const int dim=d_dim.getValue();
+
+  if (allocate_data) {
+    level->allocatePatchData(p_id);
+    level->allocatePatchData(cell_moduli_id);
+    level->allocatePatchData(edge_moduli_id);
+    level->allocatePatchData(dp_id);
+    level->allocatePatchData(p_rhs_id);
+    level->allocatePatchData(p_exact_id);
+    level->allocatePatchData(v_id);
+    level->allocatePatchData(v_rhs_id);
+  }
+
+  /*
+   * Initialize data in all patches in the level.
+   */
+  hier::PatchLevel::Iterator p_i(*level);
+  for (p_i.initialize(*level); p_i; p_i++) {
+
+    tbox::Pointer<hier::Patch> patch = *p_i;
+    if (patch.isNull()) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot find patch.  Null patch pointer.");
+    }
+    tbox::Pointer<geom::CartesianPatchGeometry>
+      geom = patch->getPatchGeometry();
+    const double *dx=geom->getDx();
+
+    /* Initialize cell moduli */
+    tbox::Pointer<pdat::CellData<double> > cell_moduli =
+      patch->getPatchData(cell_moduli_id);
+
+    hier::Box cell_moduli_box = cell_moduli->getBox();
+
+    for(pdat::CellIterator ci(cell_moduli->getGhostBox()); ci; ci++)
+      {
+        pdat::CellIndex c=ci();
+        double xyz[dim];
+        for(int d=0;d<dim;++d)
+          xyz[d]=geom->getXLower()[d]
+            + dx[d]*(c[d]-cell_moduli_box.lower()[d] + 0.5);
+
+        int ijk(0), factor(1);
+        for(int d=0;d<dim;++d)
+          {
+            int i=static_cast<int>(xyz[d]*(lambda_ijk[d]-1)
+                                   /(lambda_xyz_max[d]-lambda_xyz_min[d]));
+            i=std::max(0,std::min(lambda_ijk[d]-1,i));
+            ijk+=i*factor;
+            factor*=lambda_ijk[d];
+          }
+        (*cell_moduli)(c,0)=lambda[ijk];
+      }
+
+    for(pdat::CellIterator ci(cell_moduli->getGhostBox()); ci; ci++)
+      {
+        pdat::CellIndex c=ci();
+        double xyz[dim];
+        for(int d=0;d<dim;++d)
+          xyz[d]=geom->getXLower()[d]
+            + dx[d]*(c[d]-cell_moduli_box.lower()[d] + 0.5);
+
+        int ijk(0), factor(1);
+        for(int d=0;d<dim;++d)
+          {
+            int i=static_cast<int>(xyz[d]*(mu_ijk[d]-1)
+                                   /(mu_xyz_max[d]-mu_xyz_min[d]));
+            i=std::max(0,std::min(mu_ijk[d]-1,i));
+            ijk+=i*factor;
+            factor*=mu_ijk[d];
+          }
+        (*cell_moduli)(c,1)=mu[ijk];
+      }
+
+    /* I do not think this is actually necessary. */
+    tbox::Pointer<pdat::CellData<double> > dp_data =
+      patch->getPatchData(dp_id);
+    dp_data->fill(0.0);
+
+    tbox::Pointer<pdat::CellData<double> > p_rhs_data =
+      patch->getPatchData(p_rhs_id);
+    p_rhs_data->fill(0.0);
+
+    /* v_rhs */
+    tbox::Pointer<pdat::SideData<double> > v_rhs_data =
+      patch->getPatchData(v_rhs_id);
+
+    if(v_rhs.empty())
+      {
+        v_rhs_data->fill(0,0);
+      }
+    else
+      {
+        double L(0.2),W(0.25);
+        double cdip(0.707107),sdip(0.707107);
+        //double cdip(0.),sdip(1.);
+        double cstrike(0.),sstrike(1.);
+        double cr(0.),sr(1.);
+        double delta(0.003);
+        double x(0.500001),y(0.5),z(0.5);
+        double beta(0.2);
+	double scale(-10.);
+
+        const double pi=4*atan(1);
+        const double theta(0);
+        // const double theta(pi/4);
+        const FTensor::Tensor1<double,3> center(x,y,z);
+        const FTensor::Tensor2<double,3,3> rot(std::cos(theta),std::sin(theta),0,
+                                               -std::sin(theta),cos(theta),0,
+                                               0,0,1);
+        FTensor::Tensor1<double,3> Dx[dim];
+        for(int d0=0;d0<dim;++d0)
+          {
+            for(int d1=0;d1<dim;++d1)
+              Dx[d0](d1)=0;
+            
+            Dx[d0](d0)=dx[d0];
+          }
+        FTensor::Tensor1<double,3> slip(0,scale,0);
+        FTensor::Index<'a',3> a;
+        FTensor::Index<'b',3> b;
+        FTensor::Tensor1<double,3> jump;
+        jump(a)=slip(b)*rot(b,a);
+
+        double fault[]={L,W};
+
+        hier::Box pbox = v_rhs_data->getBox();
+        for(int ix=0;ix<dim;++ix)
+          {
+            double offset[]={0.5,0.5,0.5};
+            offset[ix]=0;
+
+            for(pdat::SideIterator si(pbox,ix); si; si++)
+              {
+                pdat::SideIndex s=si();
+                (*v_rhs_data)(s)=0;
+
+                FTensor::Tensor1<double,3> xyz(0,0,0);
+                for(int d=0;d<dim;++d)
+                  xyz(d)=geom->getXLower()[d]
+                    + dx[d]*(s[d]-pbox.lower()[d]+offset[d]);
+
+                /* Rotate the coordinates into the coordinates of the
+                   fault.  So in those coordinates, if x<0, you are on
+                   the left, and if x>0, you are on the right. */
+                FTensor::Tensor1<double,3> ntt;
+                FTensor::Tensor1<double,3> ntt_dp[dim], ntt_dm[dim];
+                ntt(a)=rot(a,b)*(xyz(b)-center(b));
+                for(int d=0;d<dim;++d)
+                  {
+                    ntt_dp[d](a)=rot(a,b)*(xyz(b)+Dx[d](b)-center(b));
+                    ntt_dm[d](a)=rot(a,b)*(xyz(b)-Dx[d](b)-center(b));
+                  }
+
+                /* d/dx^2, d/dy^2, d/dz^2 */
+                for(int d=0;d<dim;++d)
+                  {
+                    int sign(0);
+                    if(ntt(0)<=0 && ntt_dp[d](0)>0
+                       && intersect_fault(dim,ntt,ntt_dp[d],fault))
+                      sign=1;
+                    else if(ntt(0)>0 && ntt_dp[d](0)<=0
+                            && intersect_fault(dim,ntt,ntt_dp[d],fault))
+                      sign=-1;
+                    else if(ntt(0)<=0 && ntt_dm[d](0)>0
+                            && intersect_fault(dim,ntt,ntt_dm[d],fault))
+                      sign=1;
+                    else if(ntt(0)>0 && ntt_dm[d](0)<=0
+                            && intersect_fault(dim,ntt,ntt_dm[d],fault))
+                      sign=-1;
+
+                    if(sign!=0)
+                      {
+                        const double lambda_here(1), mu_here(1);
+                        double factor(mu_here);
+                        if(ix==d)
+                          factor=lambda_here+2*mu_here;
+                        (*v_rhs_data)(s)+=sign*factor*jump(ix)/(dx[d]*dx[d]);
+                      }
+                  }
+
+                /* d/dxy */
+
+                for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
+                  {
+                    FTensor::Tensor1<double,3> ntt_dxy[2][2];
+                    ntt_dxy[0][0](a)=
+                      rot(a,b)*(xyz(b)+Dx[ix](b)/2+Dx[iy](b)/2-center(b));
+                    ntt_dxy[0][1](a)=
+                      rot(a,b)*(xyz(b)+Dx[ix](b)/2-Dx[iy](b)/2-center(b));
+                    ntt_dxy[1][0](a)=
+                      rot(a,b)*(xyz(b)-Dx[ix](b)/2+Dx[iy](b)/2-center(b));
+                    ntt_dxy[1][1](a)=
+                      rot(a,b)*(xyz(b)-Dx[ix](b)/2-Dx[iy](b)/2-center(b));
+
+                    const double lambda_here(1), mu_here(1);
+                    int l(0), m(0);
+                    double j(0);
+
+                    if(ntt_dxy[0][0](0)<=0 && ntt_dxy[1][0](0)>0
+                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[1][0],fault))
+                      m-=1;
+                    if(ntt_dxy[0][0](0)>0 && ntt_dxy[1][0](0)<=0
+                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[1][0],fault))
+                      m+=1;
+                    if(ntt_dxy[0][1](0)<=0 && ntt_dxy[1][1](0)>0
+                       && intersect_fault(dim,ntt_dxy[0][1],ntt_dxy[1][1],fault))
+                      m+=1;
+                    if(ntt_dxy[0][1](0)>0 && ntt_dxy[1][1](0)<=0
+                       && intersect_fault(dim,ntt_dxy[0][1],ntt_dxy[1][1],fault))
+                      m-=1;
+
+                    if(ntt_dxy[0][0](0)<=0 && ntt_dxy[0][1](0)>0
+                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[0][1],fault))
+                      l-=1;
+                    if(ntt_dxy[0][0](0)>0 && ntt_dxy[0][1](0)<=0
+                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[0][1],fault))
+                      l+=1;
+                    if(ntt_dxy[1][0](0)<=0 && ntt_dxy[1][1](0)>0
+                       && intersect_fault(dim,ntt_dxy[1][0],ntt_dxy[1][1],fault))
+                      l+=1;
+                    if(ntt_dxy[1][0](0)>0 && ntt_dxy[1][1](0)<=0
+                       && intersect_fault(dim,ntt_dxy[1][0],ntt_dxy[1][1],fault))
+                      l-=1;
+
+                    j=l*lambda_here + m*mu_here;
+
+                    if(j!=0)
+                      (*v_rhs_data)(s)+=j*jump(iy) / (dx[0]*dx[1]);
+                  }
+              }
+          }
+        // if(0)
+        //   {
+
+	// typedef struct {
+	// 	double x1s,x1i,x2s,x3s,x3i;
+	// } rpoint;
+
+	// rpoint xp00,xm00,x0p0,x0m0,x00p,x00m;
+	// double xr,yr,zr;
+        // double x2r;
+
+	// x2r= cstrike*x  -sstrike*y;
+	// xr = cdip   *x2r-sdip   *z;
+	// yr = sstrike*x  +cstrike*y;
+	// zr = sdip   *x2r+cdip   *z;
+
+        // hier::Box pbox = v_rhs_data->getBox();
+        // for(int ix=0;ix<dim;++ix)
+        //   {
+        //     double offset[]={0.5,0.5,0.5};
+        //     offset[ix]=0;
+
+        //     for(pdat::SideIterator si(pbox,ix); si; si++)
+        //       {
+        //         pdat::SideIndex s=si();
+        //         double xyz[dim];
+        //         for(int d=0;d<dim;++d)
+        //           xyz[d]=geom->getXLower()[d]
+        //             + dx[d]*(s[d]-pbox.lower()[d]+offset[d]);
+            
+	// 	double x1,x2,x3;
+	// 	double dx1,dx2,dx3;
+
+	// 	if (2==d_dim.getValue())
+	// 	{
+	// 		x1=0;
+	// 		x2=xyz[0];
+	// 		x3=xyz[1];
+	// 		dx1=dx[0];
+	// 		dx2=dx[0];
+	// 		dx3=dx[1];
+	// 	} else if (3==d_dim.getValue())
+	// 	{
+        //                 x1=xyz[0];
+	// 		x2=xyz[1];
+	// 		x3=xyz[2];
+	// 		dx1=dx[0];
+	// 		dx2=dx[1];
+	// 		dx3=dx[2];
+	// 	}
+
+	// 	double g0m0(1.),g0p0(1.),g00p(1.),g00m(1.),gm00(1.),gp00(1.);
+	// 	double x1s,x1i,x2s,x3s,x3i;
+
+        //         x2r= cstrike*x1-sstrike*x2;
+        //         x1s= cdip*x2r-sdip*x3;
+        //         x1i= cdip*x2r+sdip*x3;
+        //         x2s= sstrike*x1+cstrike*x2;
+        //         x3s= sdip*x2r+cdip*x3;
+        //         x3i=-sdip*x2r+cdip*x3;
+
+	// 	double n[]={cdip*cstrike,-cdip*sstrike,-sdip};
+	// 	double b[]={sstrike*cr+cstrike*sdip*sr,cstrike*cr-sstrike*sdip*sr,+cdip*sr};
+
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1+dx1/2.,x2,x3,&(xp00.x1s),&(xp00.x1i),&(xp00.x2s),&(xp00.x3s),&(xp00.x3i));
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1-dx1/2.,x2,x3,&(xm00.x1s),&(xm00.x1i),&(xm00.x2s),&(xm00.x3s),&(xm00.x3i));
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2+dx2/2.,x3,&(x0p0.x1s),&(x0p0.x1i),&(x0p0.x2s),&(x0p0.x3s),&(x0p0.x3i));
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2-dx2/2.,x3,&(x0m0.x1s),&(x0m0.x1i),&(x0m0.x2s),&(x0m0.x3s),&(x0m0.x3i));
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2,x3+dx3/2.,&(x00p.x1s),&(x00p.x1i),&(x00p.x2s),&(x00p.x3s),&(x00p.x3i));
+	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2,x3-dx3/2.,&(x00m.x1s),&(x00m.x1i),&(x00m.x2s),&(x00m.x3s),&(x00m.x3i));
+
+	// 	double temp1=gauss(x1s-xr,delta);
+	// 	double temp2(1.0);
+	// 	if (3==d_dim.getValue())
+	// 	{
+	// 		temp2=omega((x2s-yr)/L,beta);
+	// 	}
+	// 	double temp3=omega((x3s-zr)/W,beta);
+	// 	double sourc=(+(gp00*gauss(xp00.x1s-xr,delta)-gm00*gauss(xm00.x1s-xr,delta))*n[0]/dx1
+        //                       +(g0p0*gauss(x0p0.x1s-xr,delta)-g0m0*gauss(x0m0.x1s-xr,delta))*n[1]/dx2
+        //                       +(g00p*gauss(x00p.x1s-xr,delta)-g00m*gauss(x00m.x1s-xr,delta))*n[2]/dx3 )
+	// 		*temp2 
+	// 		*temp3;
+
+        //         double dblcp=temp1 
+        //                *( (gp00*omega((xp00.x2s-yr)/L,beta)-gm00*omega((xm00.x2s-yr)/L,beta))*b[0]/dx1
+        //                  +(g0p0*omega((x0p0.x2s-yr)/L,beta)-g0m0*omega((x0m0.x2s-yr)/L,beta))*b[1]/dx2
+        //                  +(g00p*omega((x00p.x2s-yr)/L,beta)-g00m*omega((x00m.x2s-yr)/L,beta))*b[2]/dx3 ) 
+        //                *temp3;
+
+	// 	double dipcs=temp1 
+	// 		*temp2 
+	// 		*(+(gp00*omega((xp00.x3s-zr)/W,beta)-gm00*omega((xm00.x3s-zr)/W,beta))*b[0]/dx1
+	// 		  +(g0p0*omega((x0p0.x3s-zr)/W,beta)-g0m0*omega((x0m0.x3s-zr)/W,beta))*b[1]/dx2
+	// 		  +(g00p*omega((x00p.x3s-zr)/W,beta)-g00m*omega((x00m.x3s-zr)/W,beta))*b[2]/dx3 );
+
+        //         temp1=gauss(x1i-xr,delta);
+        //         temp3=omega((x3i+zr)/W,beta);
+        //         // double image=( (gp00*gauss(xp00.x1i-xr,delta)-gm00*gauss(xm00.x1i-xr,delta))*n[0]/dx1
+        //         //               +(g0p0*gauss(x0p0.x1i-xr,delta)-g0m0*gauss(x0m0.x1i-xr,delta))*n[1]/dx2
+        //         //               +(g00p*gauss(x00p.x1i-xr,delta)-g00m*gauss(x00m.x1i-xr,delta))*n[2]/dx3 )
+        //         //      *temp2 
+        //         //      *temp3;
+        //         // double cplei=temp1 
+        //         //             *( (gp00*omega((xp00.x2s-yr)/L,beta)-gm00*omega((xp00.x2s-yr)/L,beta))*b[0]/dx1
+        //         //               +(g0p0*omega((x0p0.x2s-yr)/L,beta)-g0m0*omega((x0p0.x2s-yr)/L,beta))*b[1]/dx2
+        //         //               +(g00p*omega((x00p.x2s-yr)/L,beta)-g00m*omega((x00p.x2s-yr)/L,beta))*b[2]/dx3 ) 
+        //         //             *temp3;
+        //         // double dipci=temp1 
+        //         //             *temp2 
+        //         //             *( (gp00*omega((xp00.x3i+zr)/W,beta)-gm00*omega((xm00.x3i+zr)/W,beta))*b[0]/dx1
+        //         //               +(g0p0*omega((x0p0.x3i+zr)/W,beta)-g0m0*omega((x0m0.x3i+zr)/W,beta))*b[1]/dx2
+        //         //               +(g00p*omega((x00p.x3i+zr)/W,beta)-g00m*omega((x00m.x3i+zr)/W,beta))*b[2]/dx3 );
+ 
+       	// 	// force update
+	// 	switch (d_dim.getValue()-ix-1)
+	// 	{
+	// 		case 2:{
+	// 			// f_1
+	// 			double f1=+cr*sstrike*sourc
+	// 				  +cr*cdip*cstrike*dblcp
+	// 				  +sr*cdip*cstrike*dipcs
+	// 				  +sr*sdip*cstrike*sourc;
+        //         		(*v_rhs_data)(s)=-f1*scale;
+	// 			break;
+	// 		       }
+	// 		case 1:{
+	// 		       // f_2
+	// 			double f2=+cr*cstrike*sourc
+	// 				  -cr*cdip*sstrike*dblcp
+	// 				  -sr*cdip*sstrike*dipcs
+	// 				  -sr*sdip*sstrike*sourc;
+        //         		(*v_rhs_data)(s)=-f2*scale;
+	// 			break;
+	// 		       }
+	// 		case 0:{
+	// 			// f_3
+	// 			double f3=-cr*sdip*dblcp
+	// 				  +sr*cdip*sourc
+	// 				  -sr*sdip*dipcs;
+	// 			(*v_rhs_data)(s)=-f3*scale;
+	// 		       }
+	// 	}
+
+        //       }
+        //     int i=1;
+        //     for(int d=0;d<dim;++d)
+        //       i*=v_rhs_ijk[d];
+        //   }
+        //   }
+      }
+  }    // End patch loop.
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/packDerivedDataIntoDoubleBuffer.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/packDerivedDataIntoDoubleBuffer.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+
+namespace SAMRAI {
+
+  /*
+*************************************************************************
+* Write derived data to the given stream.                               *
+*************************************************************************
+*/
+  bool Elastic::FAC::packDerivedDataIntoDoubleBuffer(
+                                                     double* buffer,
+                                                     const hier::Patch& patch,
+                                                     const hier::Box& region,
+                                                     const std::string&
+                                                     variable_name,
+                                                     int depth_id) const
+  {
+    pdat::CellData<double>::Iterator icell(region);
+
+	tbox::Pointer<pdat::SideData<double> > v_ptr;
+	if (variable_name == "Displacement") {
+		v_ptr = patch.getPatchData(v_id);
+	}
+	else if ("Equivalent body force" == variable_name)
+	{
+		v_ptr = patch.getPatchData(v_rhs_id);
+	}
+	else
+	{
+		// Did not register this name.
+		TBOX_ERROR(
+		"Unregistered variable name '" << variable_name << "' in\n"
+		<<
+		"Elastic::FAC::packDerivedDataIntoDoubleBuffer");
+	}
+
+	pdat::SideData<double>& v = *v_ptr;
+        if(d_dim.getValue()==2)
+          {
+            const hier::Index ip(1,0), jp(0,1);
+            for ( ; icell; icell++) {
+
+              pdat::CellIndex center(*icell);
+              const pdat::SideIndex
+		x(center,0,pdat::SideIndex::Lower),
+		y(center,1,pdat::SideIndex::Lower);
+	
+              double vx=(v(x+ip) + v(x))/2.;
+              double vy=(v(y+jp) + v(y))/2.;
+
+              if (0==depth_id)
+		{
+                  *buffer = vx;
+		}
+              else
+		{
+                  *buffer = vy;
+		}
+              buffer = buffer + 1;
+            }
+          }
+        else
+          {
+            const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
+            for ( ; icell; icell++) {
+
+              pdat::CellIndex center(*icell);
+              const pdat::SideIndex
+		x(center,0,pdat::SideIndex::Lower),
+		y(center,1,pdat::SideIndex::Lower),
+		z(center,2,pdat::SideIndex::Lower);
+	
+              double vx=(v(x+ip) + v(x))/2.;
+              double vy=(v(y+jp) + v(y))/2.;
+              double vz=(v(z+kp) + v(z))/2.;
+
+              if (0==depth_id)
+		{
+                  *buffer = vx;
+		}
+              else if (1==depth_id)
+		{
+                  *buffer = vy;
+		}
+              else
+                {
+                  *buffer = vz;
+                }
+              buffer = buffer + 1;
+            }
+          }
+    // Return true if this patch has derived data on it.
+    // False otherwise.
+    return true;
+  }
+
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/resetHierarchyConfiguration.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/resetHierarchyConfiguration.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+
+namespace SAMRAI {
+
+  /*
+*************************************************************************
+* Reset the hierarchy-dependent internal information.                   *
+*************************************************************************
+*/
+  void Elastic::FAC::resetHierarchyConfiguration
+  (tbox::Pointer<hier::BasePatchHierarchy> new_hierarchy,
+   int coarsest_level,
+   int finest_level)
+  {
+    (void)coarsest_level;
+    (void)finest_level;
+
+    d_hierarchy = new_hierarchy;
+  }
+
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/setupPlotter.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/setupPlotter.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+
+namespace SAMRAI {
+
+#ifdef HAVE_HDF5
+  /*
+*************************************************************************
+* Set up external plotter to plot internal data from this class.        *
+* Register variables appropriate for plotting.                          *
+*************************************************************************
+*/
+  int Elastic::FAC::setupPlotter(appu::VisItDataWriter& plotter) const {
+    if (d_hierarchy.isNull()) {
+      TBOX_ERROR(d_object_name << ": No hierarchy in\n"
+                 << " Elastic::FAC::setupPlotter\n"
+                 << "The hierarchy must be set before calling\n"
+                 << "this function.\n");
+    }
+    plotter.registerPlotQuantity("Pressure",
+                                 "SCALAR",
+                                 p_id);
+    plotter.registerDerivedPlotQuantity("Displacement",
+                                        "VECTOR",
+                                        (appu::VisDerivedDataStrategy *)this);
+    plotter.registerDerivedPlotQuantity("Equivalent body force",
+                                        "VECTOR",
+                                        (appu::VisDerivedDataStrategy *)this);
+    plotter.registerPlotQuantity("Exact solution",
+                                 "SCALAR",
+                                 p_exact_id);
+    plotter.registerPlotQuantity("Cell lambda",
+                                 "SCALAR",
+                                 cell_moduli_id,0);
+		// this, below, doesn't seem to work.
+    plotter.registerPlotQuantity("Cell mu",
+                                 "SCALAR",
+                                 cell_moduli_id,1);
+    plotter.registerPlotQuantity("Elastic source",
+                                 "SCALAR",
+                                 p_rhs_id);
+
+    return 0;
+  }
+#endif
+
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FAC/solve.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FAC/solve.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Numerical routines for example FAC Elastic solver 
+ *
+ ************************************************************************/
+#include "Elastic/FAC.h"
+
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+
+/*
+*************************************************************************
+* Set up the initial guess and problem parameters                       *
+* and solve the Elastic problem.  We explicitly initialize and          *
+* deallocate the solver state in this example.                          *
+*************************************************************************
+*/
+int SAMRAI::Elastic::FAC::solve()
+{
+
+  if (d_hierarchy.isNull()) {
+    TBOX_ERROR(d_object_name
+               << "Cannot solve using an uninitialized object.\n");
+  }
+
+  int ln;
+  /*
+   * Fill in the initial guess.
+   */
+  for (ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln) {
+    tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
+    hier::PatchLevel::Iterator ip(*level);
+    for ( ; ip; ip++) {
+      tbox::Pointer<hier::Patch> patch = *ip;
+      tbox::Pointer<pdat::CellData<double> >
+        p = patch->getPatchData(p_id);
+
+      tbox::Pointer<geom::CartesianPatchGeometry>
+        geom = patch->getPatchGeometry();
+
+      if(p_initial.empty())
+        {
+          p->fill(0.0);
+        }
+      else
+        {
+          const int dim=d_dim.getValue();
+          const double *dx=geom->getDx();
+          double dx_p[dim];
+          for(int d=0;d<dim;++d)
+            dx_p[d]=(p_initial_xyz_max[d]
+                     - p_initial_xyz_min[d])/(p_initial_ijk[d]-1);
+          int di[dim];
+          di[0]=1;
+          for(int d=1;d<dim;++d)
+            di[d]=di[d-1]*p_initial_ijk[d-1];
+
+          hier::Box pbox = p->getBox();
+          for(pdat::CellIterator ci(p->getGhostBox()); ci; ci++)
+            {
+              pdat::CellIndex c=ci();
+              double xyz[dim], weight[dim][2];
+              for(int d=0;d<dim;++d)
+                xyz[d]=geom->getXLower()[d]
+                  + dx[d]*(c[d]-pbox.lower()[d] + 0.5);
+
+              int ijk(0);
+              int ddi[dim];
+              for(int d=0;d<dim;++d)
+                {
+                  int i=static_cast<int>(xyz[d]*(p_initial_ijk[d]-1)
+                                         /(p_initial_xyz_max[d]
+                                           - p_initial_xyz_min[d]));
+                  i=std::max(0,std::min(p_initial_ijk[d]-1,i));
+                  ijk+=i*di[d];
+
+                  if(i==p_initial_ijk[d]-1)
+                    {
+                      weight[d][0]=1;
+                      weight[d][1]=0;
+                      ddi[d]=0;
+                    }
+                  else
+                    {
+                      weight[d][1]=
+                        (xyz[d]-(i*dx_p[d] + p_initial_xyz_min[d]))/dx_p[d];
+                      weight[d][0]=1-weight[d][1];
+                      ddi[d]=di[d];
+                    }
+                }
+
+              if(dim==2)
+                {
+                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]
+                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]
+                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]
+                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1];
+                }
+              else
+                {
+                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]*weight[2][0]
+                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]*weight[2][0]
+                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]*weight[2][0]
+                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1]*weight[2][0]
+                    
+                    + p_initial[ijk+ddi[2]]*weight[0][0]*weight[1][0]*weight[2][1]
+                    + p_initial[ijk+ddi[0]+ddi[2]]*weight[0][1]*weight[1][0]*weight[2][1]
+                    + p_initial[ijk+ddi[1]+ddi[2]]*weight[0][0]*weight[1][1]*weight[2][1]
+                    + p_initial[ijk+ddi[0]+ddi[1]+ddi[2]]*weight[0][1]*weight[1][1]*weight[2][1];
+                }
+            }
+        }
+
+      tbox::Pointer<pdat::SideData<double> >
+        v = patch->getPatchData(v_id);
+      v->fill(0.0);
+    }
+    d_elastic_fac_solver.set_boundaries(p_id,v_id,level,false);
+  }
+
+  fix_moduli();
+
+  d_elastic_fac_solver.initializeSolverState
+    (p_id,cell_moduli_id,edge_moduli_id,dp_id,p_rhs_id,v_id,v_rhs_id,
+     d_hierarchy,0,d_hierarchy->getFinestLevelNumber());
+
+  tbox::plog << "solving..." << std::endl;
+  int solver_ret;
+  solver_ret = d_elastic_fac_solver.solveSystem(p_id,p_rhs_id,v_id,v_rhs_id);
+  /*
+   * Present data on the solve.
+   */
+  // double avg_factor, final_factor;
+  // d_elastic_fac_solver.getConvergenceFactors(avg_factor, final_factor);
+  // tbox::plog << "\t" << (solver_ret ? "" : "NOT ") << "converged " << "\n"
+  //            << "	iterations: "
+  //            << d_elastic_fac_solver.getNumberOfIterations() << "\n"
+  //            << "	residual: "<< d_elastic_fac_solver.getResidualNorm()
+  //            << "\n"
+  //            << "	average convergence: "<< avg_factor << "\n"
+  //            << "	final convergence: "<< final_factor << "\n"
+  //            << std::flush;
+
+  d_elastic_fac_solver.deallocateSolverState();
+
+  return 0;
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps.I
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps.I	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for solving scalar Elastic using FAC 
+ *
+ ************************************************************************/
+namespace SAMRAI {
+namespace solv {
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setPreconditioner(
+   const FACPreconditioner* preconditioner) {
+   d_preconditioner = preconditioner;
+}
+
+#ifdef HAVE_HYPRE
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setUseSMG(
+   bool use_smg)
+{
+   if (d_hierarchy) {
+      TBOX_ERROR(
+         d_object_name << ": setUseSMG(bool) may NOT be called\n"
+         <<
+         "while the solver state is initialized, as that\n"
+         << "would lead to a corrupted solver state.\n");
+   }
+   d_hypre_solver.setUseSMG(use_smg);
+}
+#endif
+
+/*
+ ********************************************************************
+ * Set the physical boundary condition object.                      *
+ ********************************************************************
+ */
+
+// SAMRAI_INLINE_KEYWORD
+// void Elastic::FACOps::setPhysicalBcCoefObject(
+//    const RobinBcCoefStrategy* physical_bc_coef)
+// {
+//    d_physical_bc_coef = physical_bc_coef;
+//    // d_bc_helper.setCoefImplementation(physical_bc_coef);
+// #ifdef HAVE_HYPRE
+//    d_hypre_solver.setPhysicalBcCoefObject(d_physical_bc_coef);
+// #endif
+// }
+
+/*
+ ********************************************************************
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::enableLogging(
+   bool enable_logging)
+{
+   d_enable_logging = enable_logging;
+}
+
+/*
+ ********************************************************************
+ * Set the choice for smoothing algorithm.                          *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setSmoothingChoice(
+   const std::string& smoothing_choice)
+{
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (smoothing_choice != "Tackley" && smoothing_choice != "Gerya") {
+      TBOX_ERROR(d_object_name << ": Bad smoothing choice '"
+                               << smoothing_choice
+                               << "' in Elastic::FACOps::setSmoothingChoice.");
+   }
+#endif
+   d_smoothing_choice = smoothing_choice;
+}
+
+/*
+ ********************************************************************
+ * Set the choice for the coarse level solver.                      *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setCoarsestLevelSolverChoice(
+   const std::string& choice) {
+#ifdef DEBUG_CHECK_ASSERTIONS
+#ifndef HAVE_HYPRE
+   if (choice == "hypre") {
+      TBOX_ERROR(d_object_name << ": HYPRe library is not available.\n");
+   }
+#endif
+#endif
+   if (choice == "Tackley"
+       || choice == "Gerya"
+       || choice == "hypre") {
+      d_coarse_solver_choice = choice;
+   } else {
+      TBOX_ERROR(
+         d_object_name << ": Bad coarse level solver choice '"
+         << choice
+         <<
+         "' in Elastic::FACOps::setCoarseLevelSolver.");
+   }
+}
+
+/*
+ ********************************************************************
+ * Set the tolerance for the coarse level solver.                   *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setCoarsestLevelSolverTolerance(
+   double tol) {
+   d_coarse_solver_tolerance = tol;
+}
+
+/*
+ ********************************************************************
+ * Set the tolerance for the coarse level solver.                   *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setCoarsestLevelSolverMaxIterations(
+   int max_iterations) {
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (max_iterations < 0) {
+      TBOX_ERROR(d_object_name << ": Invalid number of max iterations\n");
+   }
+#endif
+   d_coarse_solver_max_iterations = max_iterations;
+}
+
+/*
+ ********************************************************************
+ * Set the coarse-fine discretization method.                       *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::setCoarseFineDiscretization(
+   const std::string& coarsefine_method) {
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (d_hierarchy) {
+      TBOX_ERROR(
+         d_object_name << ": Cannot change coarse-fine\n"
+         <<
+         "discretization method while operator state\n"
+         << "is initialized because that causes a\n"
+         << "corruption in the state.\n");
+   }
+#endif
+   d_cf_discretization = coarsefine_method;
+}
+
+/*
+ ********************************************************************
+ * Set the prolongation method                                      *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::set_P_ProlongationMethod(
+   const std::string& prolongation_method) {
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (d_hierarchy) {
+      TBOX_ERROR(
+         d_object_name << ": Cannot change p prolongation method\n"
+         <<
+         "while operator state is initialized because that\n"
+         << "causes a corruption in the state.\n");
+   }
+#endif
+   p_prolongation_method = prolongation_method;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACOps::set_V_ProlongationMethod(
+   const std::string& prolongation_method) {
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (d_hierarchy) {
+      TBOX_ERROR(
+         d_object_name << ": Cannot change v prolongation method\n"
+         <<
+         "while operator state is initialized because that\n"
+         << "causes a corruption in the state.\n");
+   }
+#endif
+   v_prolongation_method = prolongation_method;
+}
+
+}
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,1079 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#ifndef included_solv_ElasticFACOps
+#define included_solv_ElasticFACOps
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "SAMRAI/solv/FACOperatorStrategy.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/solv/SAMRAIVectorReal.h"
+#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
+#include "SAMRAI/math/HierarchySideDataOpsReal.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/hier/CoarseFineBoundary.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/hier/PatchHierarchy.h"
+#include "SAMRAI/hier/PatchLevel.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/VariableContext.h"
+#include "SAMRAI/tbox/Database.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "P_Refine_Patch_Strategy.h"
+#include "V_Refine_Patch_Strategy.h"
+#include "V_Coarsen_Patch_Strategy.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace solv {
+namespace Elastic {
+
+/*!
+ * @brief FAC operator class to solve Elastic's equation on a SAMR grid,
+ * using cell-centered, second-order finite-volume method, with Robin
+ * boundary conditions.
+ *
+ * This class provides operators that are used by the FAC
+ * preconditioner FACPreconditioner.
+ * It is used to solve the scalar Elastic's equation using a cell-centered
+ * second-order finite-volume discretization.
+ * It is designed to provide all operations specific to
+ * the scalar Elastic's equation,
+ * @f[ \nabla \cdot D \nabla u + C u = f @f]
+ * (see Elastic::Specifications) where
+ * - C, D and f are indpendent of u
+ * - C is a cell-centered scalar field
+ * - D is the @em diffusion @em coefficients, stored on faces
+ * - f is a cell-centered scalar function
+ *
+ * You are left to provide the source function, initial guess, etc.,
+ * by specifying them in specific forms.
+ *
+ * This class provides:
+ * -# 5-point (second order), cell-centered stencil operations
+ *    for the discrete Laplacian.
+ * -# Red-black Gauss-Seidel smoothing.
+ * -# Provisions for working Robin boundary conditions
+ *    (see RobinBcCoefStrategy).
+ *
+ * This class is meant to provide the Elastic-specific operator
+ * used by the FAC preconditioner, FACPreconditioner.
+ * To use the preconditioner with this class, you will have to provide:
+ * -# The solution vector SAMRAIVectorReal,
+ *    with appropriate norm weighting for the cell-centered AMR mesh.
+ *    This class provides the function computeVectorWeights()
+ *    to help with computing the appropriate weights.
+ *    Since this is for a scalar equation, only the first depth
+ *    of the first component of the vectors are used.
+ *    All other parts are ignored.
+ * -# The source vector SAMRAIVectorReal for f.
+ * -# A Elastic::Specifications objects to specify
+ *    the cell-centered scalar field C and the side-centered
+ *    diffusion coefficients D
+ * -# The boundary condition specifications in terms of the coefficients
+ *    @f$ \alpha @f$, @f$ \beta @f$ and @f$ \gamma @f$ in the
+ *    Robin formula @f$  \alpha u + \beta u_n = \gamma @f$ applied on the
+ *    boundary faces.  See RobinBcCoefStrategy.
+ *
+ * This class allocates and deallocates only its own scratch data.
+ * Other data that it manipuates are passed in as function arguments.
+ * Hence, it owns none of the solution vectors, error vectors,
+ * diffusion coefficient data, or any such things.
+ *
+ * Input Examples
+ * @verbatim
+ * coarse_solver_choice = "hypre"    // see setCoarsestLevelSolverChoice()
+ * coarse_solver_tolerance = 1e-14   // see setCoarsestLevelSolverTolerance()
+ * coarse_solver_max_iterations = 10 // see setCoarsestLevelSolverMaxIterations()
+ * smoothing_choice = "Tackley"     // see setSmoothingChoice()
+ * cf_discretization = "Ewing"       // see setCoarseFineDiscretization()
+ * prolongation_method = "P_REFINE" // see setProlongationMethod()
+ * hypre_solver = { ... }            // tbox::Database for initializing Hypre solver
+ * @endverbatim
+ */
+class FACOps:
+   public FACOperatorStrategy
+{
+
+public:
+   /*!
+    * @brief Constructor.
+    *
+    * If you want standard output and logging,
+    * pass in valid pointers for those streams.
+    * @param object_name Ojbect name
+    * @param database Input database
+    */
+   FACOps(
+      const tbox::Dimension& dim,
+      const std::string& object_name = std::string(),
+      tbox::Pointer<tbox::Database> database =
+         tbox::Pointer<tbox::Database>(NULL));
+
+   /*!
+    * @brief Destructor.
+    *
+    * Deallocate internal data.
+    */
+   ~FACOps(void) {}
+
+   /*!
+    * @brief Enable logging.
+    *
+    * By default, logging is disabled.  The logging flag is
+    * propagated to the major components used by this class.
+    */
+   void
+   enableLogging(
+      bool enable_logging);
+
+   //@{
+   /*!
+    * @name Functions for setting solver mathematic algorithm controls
+    */
+
+   /*!
+    * @brief Set the choice of smoothing algorithms.
+    *
+    * Current smoothing choices are:
+    * - "Tackley"
+    * - "Gerya"
+    */
+   void
+   setSmoothingChoice(
+      const std::string& smoothing_choice);
+
+   /*!
+    * @brief Set coarse level solver.
+    *
+    * Select from these:
+    * - @c "Tackley" (red-black smoothing until convergence--very slow!)
+    * - @c "Gerya" (red-black smoothing until convergence--very slow!)
+    * - @c "hypre" (only if the HYPRE library is available).
+    */
+   void
+   setCoarsestLevelSolverChoice(
+      const std::string& choice);
+
+   /*!
+    * @brief Set tolerance for coarse level solve.
+    *
+    * If the coarse level solver requires a tolerance (currently, they all do),
+    * the specified value is used.
+    */
+   void
+   setCoarsestLevelSolverTolerance(
+      double tol);
+
+   /*!
+    * @brief Set max iterations for coarse level solve.
+    *
+    * If the coarse level solver requires a max iteration limit
+    * (currently, they all do), the specified value is used.
+    */
+   void
+   setCoarsestLevelSolverMaxIterations(
+      int max_iterations);
+
+   /*!
+    * @brief Set the coarse-fine boundary discretization method.
+    *
+    * Specify the @c op_name std::string which will be passed to
+    * xfer::Geometry::lookupRefineOperator() to get the operator
+    * for setting fine grid ghost cells from the coarse grid.
+    * Note that chosing this operator implicitly choses the
+    * discretization method at the coarse-fine boundary.
+    *
+    * There is one important instance where this std::string is
+    * @em not passed to xfer::Geometry::lookupRefineOperator.
+    * If this variable is set to "Ewing", Ewing's coarse-fine
+    * discretization is used (a constant refinement is performed,
+    * and the flux is later corrected to result in Ewing's scheme).
+    * For a reference to Ewing's discretization method, see
+    * "Local Refinement Techniques for Elliptic Problems on Cell-Centered
+    * Grids, I. Error Analysis", Mathematics of Computation, Vol. 56, No. 194,
+    * April 1991, pp. 437-461.
+    *
+    * @param coarsefine_method String selecting the coarse-fine discretization method.
+    */
+   void
+   setCoarseFineDiscretization(
+      const std::string& coarsefine_method);
+
+   /*!
+    * @brief Set the name of the prolongation method.
+    *
+    * Specify the @c op_name std::string which will be passed to
+    * xfer::Geometry::lookupRefineOperator() to get the operator
+    * for prolonging the coarse-grid correction.
+    *
+    * By default, "CONSTANT_REFINE" is used.  "LINEAR_REFINE" seems to
+    * to lead to faster convergence, but it does NOT satisfy the Galerkin
+    * condition.
+    *
+    * Prolonging using linear refinement requires a Robin bc
+    * coefficient implementation that is capable of delivering
+    * coefficients for non-hierarchy data, because linear refinement
+    * requires boundary conditions to be set on temporary levels.
+    *
+    * @param prolongation_method String selecting the coarse-fine
+    *        discretization method.
+    */
+   void
+   set_P_ProlongationMethod(
+      const std::string& prolongation_method);
+
+   void
+   set_V_ProlongationMethod(
+      const std::string& prolongation_method);
+
+#ifdef HAVE_HYPRE
+   /*!
+    * @brief Set whether to use Hypre's PFMG algorithm instead of the
+    * SMG algorithm.
+    *
+    * This flag affects the Hypre solver (used to solve the coarsest level).
+    * The flag is used to select which of HYPRE's linear solver algorithms
+    * to use if true, the semicoarsening multigrid algorithm is used, and if
+    * false, the ``PF'' multigrid algorithm is used.
+    * By default, the SMG algorithm is used.
+    *
+    * This setting has effect only when Hypre is chosen for the coarsest
+    * level solver.  See setCoarsestLevelSolverChoice().
+    *
+    * Changing the algorithm must be done before initializing the solver
+    * state and must NOT be done while the state is initialized
+    * (the program will exit), as that would corrupt the state.
+    */
+   void
+   setUseSMG(
+      bool use_smg);
+#endif
+
+   //@}
+
+   //@{
+   /*!
+    * @name Functions for setting patch data indices and coefficients
+    */
+
+   /*!
+    * @brief Set the scratch patch data index for the flux.
+    *
+    * The use of this function is optional.
+    * The patch data index should be a pdat::SideData<DIM> type of variable.
+    * If the flux id is -1 (the default initial value), scratch space
+    * for the flux is allocated as needed and immediately deallocated
+    * afterward, level by level.  If you have space preallocated for
+    * flux and you would like that to be used, set flux id to the
+    * patch data index of that space.
+    */
+  void set_moduli_id(const int &cell_moduli, const int &edge_moduli)
+  {
+    cell_moduli_id=cell_moduli;
+    edge_moduli_id=edge_moduli;
+  }
+   //@}
+
+   /*!
+    * @brief Provide an implementation for getting the
+    * physical bc coefficients
+    *
+    * If your solution is fixed at the physical boundary
+    * ghost cell centers AND those cells have the correct
+    * values before entering solveSystem(), you may use a
+    * GhostCellRobinBcCoefs object.
+    *
+    * If your solution is @b not fixed at the ghost cell centers,
+    * the ghost cell values will change as the interior
+    * cell values change.  In those cases, the flexible
+    * Robin boundary conditions are applied.  You must
+    * call this function to provide the implementation for
+    * determining the boundary condition coefficients.
+    *
+    * @param physical_bc_coef tbox::Pointer to an object that can
+    *        set the Robin bc coefficients.
+    */
+   // void
+   // setPhysicalBcCoefObject(
+   //    const RobinBcCoefStrategy* physical_bc_coef);
+
+   /*!
+    * @brief Set weight appropriate for computing vector norms.
+    *
+    * If you this function to set the weights used when you
+    * SAMRAIVectorReal::addComponent, you can use the
+    * vector norm functions of SAMRAIVectorReal, and
+    * the weights will be used to blank out coarse grid
+    * regions under fine grids.
+    *
+    * The weights computed are specific to the cell-centered
+    * discretization used by this class.  The weight is equal
+    * to the cell volume if the cell has not been refined,
+    * and zero if it has.
+    *
+    * This function is state-independent.  All inputs are in
+    * the argument list.
+    *
+    * @param hierarchy Hierarchy configuration to compute weights for
+    * @param weight_id hier::Patch data index of the weight
+    * @param coarsest_ln Coarsest level number.  Must be included
+    *        in hierarchy.  Must not be greater than @c finest_ln.
+    *        Default to 0.
+    * @param finest_ln Finest level number.  Must be included
+    *        in hierarchy.  Must not be less than @c coarsest_ln.
+    *        Default to finest level in @c hierarchy.
+    */
+   void
+   computeVectorWeights(
+      tbox::Pointer<hier::PatchHierarchy> hierarchy,
+      int weight_id,
+      int coarsest_ln = -1,
+      int finest_ln = -1) const;
+
+   /*!
+    * @brief Set the FAC preconditioner that will be using this object.
+    *
+    * The FAC preconditioner is accessed to get convergence data during
+    * the cycle postprocessing step.  It is optional.
+    */
+   void
+   setPreconditioner(
+      const FACPreconditioner* preconditioner);
+
+   //@{ @name FACOperatorStrategy virtuals
+
+   virtual void
+   restrictSolution(
+      const SAMRAIVectorReal<double>& source,
+      SAMRAIVectorReal<double>& dest,
+      int dest_ln);
+   virtual void
+   restrictResidual(
+      const SAMRAIVectorReal<double>& source,
+      SAMRAIVectorReal<double>& dest,
+      int dest_ln);
+
+   virtual void
+   prolongErrorAndCorrect(
+      const SAMRAIVectorReal<double>& source,
+      SAMRAIVectorReal<double>& dest,
+      int dest_ln);
+
+   virtual void
+   smoothError(
+      SAMRAIVectorReal<double>& error,
+      const SAMRAIVectorReal<double>& residual,
+      int ln,
+      int num_sweeps);
+
+   virtual int
+   solveCoarsestLevel(
+      SAMRAIVectorReal<double>& error,
+      const SAMRAIVectorReal<double>& residual,
+      int coarsest_ln);
+
+   virtual void
+   computeCompositeResidualOnLevel(
+      SAMRAIVectorReal<double>& residual,
+      const SAMRAIVectorReal<double>& solution,
+      const SAMRAIVectorReal<double>& rhs,
+      int ln,
+      bool error_equation_indicator);
+
+  void residual_2D
+  (pdat::CellData<double> &p,
+   pdat::SideData<double> &v,
+   pdat::CellData<double> &cell_moduli,
+   pdat::CellData<double> &p_rhs,
+   pdat::SideData<double> &v_rhs,
+   pdat::CellData<double> &p_resid,
+   pdat::SideData<double> &v_resid,
+   hier::Patch &patch,
+   const hier::Box &pbox,
+   const geom::CartesianPatchGeometry &geom);
+
+  void residual_3D
+  (pdat::CellData<double> &p,
+   pdat::SideData<double> &v,
+   pdat::CellData<double> &cell_moduli,
+   pdat::CellData<double> &p_rhs,
+   pdat::SideData<double> &v_rhs,
+   pdat::CellData<double> &p_resid,
+   pdat::SideData<double> &v_resid,
+   hier::Patch &patch,
+   const hier::Box &pbox,
+   const geom::CartesianPatchGeometry &geom);
+
+   virtual double
+   computeResidualNorm(
+      const SAMRAIVectorReal<double>& residual,
+      int fine_ln,
+      int coarse_ln);
+
+   virtual void
+   initializeOperatorState(
+      const SAMRAIVectorReal<double>& solution,
+      const SAMRAIVectorReal<double>& rhs);
+
+   virtual void
+   deallocateOperatorState();
+
+   virtual void
+   postprocessOneCycle(
+      int fac_cycle_num,
+      const SAMRAIVectorReal<double>& current_soln,
+      const SAMRAIVectorReal<double>& residual);
+
+  void set_boundaries(const int &p_id, const int &v_id, const int &l)
+  {
+    set_boundaries(p_id,v_id,l,true);
+  }
+  void set_boundaries(const int &p_id, const int &v_id, const int &l,
+                      const bool &rhs)
+  {
+    tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(l);
+    set_boundaries(p_id,v_id,level,rhs);
+  }
+  void set_boundaries(const int &p_id, const int &v_id,
+                      tbox::Pointer<hier::PatchLevel> &level)
+  {
+    set_boundaries(p_id,v_id,level,true);
+  }
+  void set_boundaries(const int &p_id, const int &v_id, 
+                      tbox::Pointer<hier::PatchLevel> &level,
+                      const bool &rhs);
+
+   //@}
+
+private:
+   //@{
+   /*!
+    * @name Private workhorse functions.
+    */
+
+   /*!
+    * @brief Red-black Gauss-Seidel error smoothing on a level.
+    *
+    * Smoothes on the residual equation @f$ Ae=r @f$ on a level.
+    *
+    * @param error error vector
+    * @param residual residual vector
+    * @param ln level number
+    * @param num_sweeps number of sweeps
+    * @param residual_tolerance the maximum residual considered to be
+    *        converged
+    */
+   void smooth_Tackley_2D(
+      SAMRAIVectorReal<double>& error,
+      const SAMRAIVectorReal<double>& residual,
+      int ln,
+      int num_sweeps,
+      double residual_tolerance = -1.0);
+
+   void smooth_Tackley_3D
+            (SAMRAIVectorReal<double>& solution,
+             const SAMRAIVectorReal<double>& residual,
+             int ln,
+             int num_sweeps,
+             double residual_tolerance = -1.0);
+
+void smooth_V_2D(const int &axis,
+	const hier::Box &pbox,
+	tbox::Pointer<geom::CartesianPatchGeometry> &geom,
+	const pdat::CellIndex &center,
+	const hier::Index &ip,
+	const hier::Index &jp,
+	pdat::SideData<double> &v,
+	pdat::SideData<double> &v_rhs,
+	double &maxres,
+	const double &dx,
+	const double &dy,
+	pdat::CellData<double> &cell_moduli,
+	pdat::NodeData<double> &edge_moduli,
+	const double &theta_momentum);
+
+void smooth_V_3D(const int &ix,
+  const hier::Box &pbox,
+  tbox::Pointer<geom::CartesianPatchGeometry> &geom,
+  pdat::SideData<double> &v,
+  pdat::SideData<double> &v_rhs,
+  pdat::CellData<double> &cell_moduli,
+  pdat::EdgeData<double> &edge_moduli,
+  const pdat::CellIndex &center,
+  const double Dx[3],
+  const double &theta_momentum,
+  const hier::Index pp[3],
+  double &maxres);
+
+  /* The mixed derivative of the stress.  We have to use a template
+     because 2D uses Node's for the edge moduli, while 3D uses
+     Edge's.  Written as if it is dtau_xy_dy. */
+
+  template<class E_data, class E_index>
+  double shear_noncell(const pdat::SideData<double> &v,
+                    const E_data &edge_moduli,
+                    const pdat::SideIndex &x,
+                    const pdat::SideIndex &y,
+                    const E_index &edge,
+                    const hier::Index &ip,
+                    const hier::Index &jp,
+                    const double &dx,
+                    const double &dy)
+  {
+    return 
+	     edge_moduli(edge+jp,1)*(v(x+jp)-v(x   ))/(dy*dy)
+            -edge_moduli(edge   ,1)*(v(x   )-v(x-jp))/(dy*dy)
+            +edge_moduli(edge+jp,1)*(v(y+jp)-v(y+jp-ip))/(dx*dy) 
+            -edge_moduli(edge   ,1)*(v(y   )-v(y-ip   ))/(dx*dy);
+  }
+
+  /* The action of the velocity operator. It is written from the
+     perspective of vx, but pass in different values for center_x
+     etc. to get vy. */
+
+  double aligned_terms(const pdat::SideData<double> &v,
+                       const pdat::CellData<double> &cell_moduli,
+                       const pdat::CellIndex &center,
+                       const pdat::SideIndex &x,
+                       const hier::Index &ip,
+                       const double &dx)
+  {
+    return ( (v(x+ip)-v(x   ))*(cell_moduli(center   ,0)+2*cell_moduli(center   ,1))
+            -(v(x   )-v(x-ip))*(cell_moduli(center-ip,0)+2*cell_moduli(center-ip,1)))/(dx*dx);
+  }
+
+  double lame_mixed(const pdat::SideData<double> &v,
+                       const pdat::CellData<double> &cell_moduli,
+                       const pdat::CellIndex &center,
+                       const pdat::SideIndex &y,
+                       const hier::Index &ip,
+                       const hier::Index &jp,
+                       const double &dx,
+                       const double &dy)
+  {
+    return (+ cell_moduli(center   ,0)*(v(y+jp   )-v(y   ))/dy
+            - cell_moduli(center-ip,0)*(v(y+jp-ip)-v(y-ip))/dy)/dx;
+  }
+
+  double v_operator_2D(const pdat::SideData<double> &v,
+                       const pdat::CellData<double> &cell_moduli,
+                       const pdat::NodeData<double> &edge_moduli,
+                       const pdat::CellIndex &center,
+                       const pdat::NodeIndex &edge,
+                       const pdat::SideIndex &x,
+                       const pdat::SideIndex &y,
+                       const hier::Index &ip,
+                       const hier::Index &jp,
+                       const double &dx,
+                       const double &dy)
+ {
+    return aligned_terms(v,cell_moduli,center,x,ip,dx)
+	  +lame_mixed(v,cell_moduli,center,y,ip,jp,dx,dy)
+	  +shear_noncell(v,edge_moduli,x,y,edge,ip,jp,dx,dy);
+  }
+
+  double v_operator_3D(const pdat::SideData<double> &v,
+                       const pdat::CellData<double> &cell_moduli,
+                       const pdat::EdgeData<double> &edge_moduli,
+                       const pdat::CellIndex &center,
+                       const pdat::EdgeIndex &edge_y,
+                       const pdat::EdgeIndex &edge_z,
+                       const pdat::SideIndex &x,
+                       const pdat::SideIndex &y,
+                       const pdat::SideIndex &z,
+                       const hier::Index &ip,
+                       const hier::Index &jp,
+                       const hier::Index &kp,
+                       const double &dx,
+                       const double &dy,
+                       const double &dz)
+  {
+    return aligned_terms(v,cell_moduli,center,x,ip,dx)
+	  +lame_mixed(v,cell_moduli,center,y,ip,jp,dx,dy)
+	  +lame_mixed(v,cell_moduli,center,z,ip,kp,dx,dz)
+	  +shear_noncell(v,edge_moduli,x,y,edge_y,ip,jp,dx,dy)
+	  +shear_noncell(v,edge_moduli,x,z,edge_z,ip,kp,dx,dz);
+  }
+
+   /*!
+    * @brief Solve the coarsest level using HYPRE
+    */
+   int
+   solveCoarsestLevel_HYPRE(
+      SAMRAIVectorReal<double>& error,
+      const SAMRAIVectorReal<double>& residual,
+      int ln);
+
+   /*!
+    * @brief AMR-unaware function to red or black smoothing on a single patch,
+    * for variable diffusion coefficient and variable scalar field.
+    *
+    * @param patch patch
+    * @param flux_data side-centered flux data
+    * @param rhs_data cell-centered rhs data
+    * @param scalar_field_data
+    *        cell-centered scalar field data
+    * @param soln_data cell-centered solution data
+    * @param red_or_black red-black switch.  Set to 'r' or 'b'.
+    * @param p_maxres max residual output.  Set to NULL to avoid computing.
+    */
+   void
+   redOrBlackSmoothingOnPatch(
+      const hier::Patch& patch,
+      const pdat::SideData<double>& flux_data,
+      const pdat::CellData<double>& rhs_data,
+      pdat::CellData<double>& soln_data,
+      char red_or_black,
+      double* p_maxres = NULL) const;
+
+   //@}
+
+   //@{ @name For executing, caching and resetting communication schedules.
+
+   /*!
+    * @brief Execute a refinement schedule
+    * for prolonging cell data.
+    *
+    * General notes regarding internal objects for communication:
+    * We maintain objects to support caching schedules to improve
+    * efficiency.  Communication is needed in 5 distinct tasks.
+    *   -# Prolongation
+    *   -# Restriction
+    *   -# Flux coarsening.  Changing the coarse grid flux to the
+    *      composite grid flux by coarsening the fine grid flux
+    *      at the coarse-fine boundaries.
+    *   -# Fill boundary data from other patches in the same level
+    *      and physical boundary condition.
+    *   -# Fill boundary data from same level, coarser levels
+    *      and physical boundary condition.
+    *
+    * For each task, we maintain a refine or coarsen operator,
+    * and a array of communication schedules (one for each
+    * destination level).
+    *
+    * The 5 member functions named @c xeqSchedule... execute
+    * communication schedules appropriate for five specific tasks.
+    * They use a cached schedule if possible or create and cache
+    * a new schedule if needed.  These functions and the data
+    * they manipulate are as follows:
+    * <ol>
+    *   <li> xeqScheduleProlongation():
+    *        prolongation_refine_operator
+    *        prolongation_refine_schedules
+    *   <li> xeqScheduleURestriction():
+    *        d_restriction_coarsen_operator,
+    *        urestriction_coarsen_schedules.
+    *   <li> xeqScheduleRRestriction():
+    *        restriction_coarsen_operator,
+    *        rrestriction_coarsen_schedules.
+    *   <li> xeqScheduleFluxCoarsen():
+    *        d_flux_coarsen_operator,
+    *        d_flux_coarsen_schedules.
+    *   <li> xeqScheduleGhostFill():
+    *        ghostfill_refine_operator,
+    *        ghostfill_refine_schedules.
+    *   <li> xeqScheduleGhostFillNoCoarse():
+    *        ghostfill_nocoarse_refine_operator,
+    *        ghostfill_nocoarse_refine_schedules.
+    * </ol>
+    *
+    * @return refinement schedule for prolongation
+    */
+   void
+   xeqScheduleProlongation(int p_dst, int p_src, int p_scr,
+                           int v_dst, int v_src, int v_scr,
+                           int dest_ln);
+
+   /*!
+    * @brief Execute schedule for restricting solution to the specified
+    * level or reregister an existing one.
+    *
+    * See general notes for xeqScheduleProlongation().
+    *
+    * @return coarsening schedule for restriction
+    */
+   void
+   xeqScheduleURestriction(int p_dst, int p_src, int v_dst, int v_src,
+                           int dest_ln);
+
+   /*!
+    * @brief Execute schedule for restricting residual to the specified
+    * level or reregister an existing one.
+    *
+    * See general notes for xeqScheduleProlongation().
+    *
+    * @return coarsening schedule for restriction
+    */
+   void
+   xeqScheduleRRestriction(int p_dst, int p_src, int v_dst, int v_src,
+                           int dest_ln);
+
+   /*!
+    * @brief Execute schedule for coarsening flux to the specified
+    * level or reregister an existing one.
+    *
+    * See general notes for xeqScheduleProlongation().
+    *
+    * @return coarsening schedule for setting composite grid flux at
+    * coarse-fine boundaries.
+    */
+   void
+   xeqScheduleFluxCoarsen(
+      int dst_id,
+      int src_id,
+      int dest_ln);
+
+   /*!
+    * @brief Execute schedule for filling ghosts on the specified
+    * level or reregister an existing one.
+    *
+    * See general notes for xeqScheduleProlongation().
+    *
+    * @return refine schedule for filling ghost data from coarser level
+    * and physical bc.
+    */
+   void
+   xeqScheduleGhostFill(int p_id, int v_id, int dest_ln);
+
+   /*!
+    * @brief Execute schedule for filling ghosts on the specified
+    * level or reregister an existing one.
+    * This version does not get data from coarser levels.
+    *
+    * See general notes for xeqScheduleProlongation().
+    *
+    * This function is used for the bottom solve level, since it does
+    * not access data from any coarser level.  (Ghost data obtained
+    * from coarser level must have been placed there before solve begins!)
+    *
+    * @return refine schedule for filling ghost data from same level
+    * and physical bc.
+    */
+   void
+   xeqScheduleGhostFillNoCoarse(int p_id, int v_id, int dest_ln);
+
+   //@}
+
+   //! @brief Return the patch data index for cell scratch data.
+   int
+   registerCellScratch() const;
+   //! @brief Return the patch data index for flux scratch data.
+   int
+   registerFluxScratch() const;
+   //! @brief Return the patch data index for outerflux scratch data.
+   int
+   registerOfluxScratch() const;
+
+   //! @brief Free static variables at shutdown time.
+   static void
+   finalizeCallback();
+
+   /*!
+    * @brief Object dimension.
+    */
+   const tbox::Dimension d_dim;
+
+   /*!
+    * @brief Object name.
+    */
+   std::string d_object_name;
+
+   //@{ @name Hierarchy-dependent objects.
+
+   /*!
+    * @brief Reference hierarchy
+    *
+    * This variable is non-null between the initializeOperatorState()
+    * and deallocateOperatorState() calls.  It is not truly needed,
+    * because the hierarchy is obtainable through variables in most
+    * function argument lists.  We use it to enforce working on one
+    * hierarchy at a time.
+    */
+   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
+
+   /*!
+    * @brief Coarsest level for solve.
+    */
+   int d_ln_min;
+
+   /*!
+    * @brief Finest level for solve.
+    */
+   int d_ln_max;
+
+   /*!
+    * @brief Description of coarse-fine boundaries.
+    *
+    * There is one coarse-fine boundary object for each level.
+    * d_coarse_fine_boundary[i] is the description of
+    * the coarse-fine boundary between level i and level i-1.
+    * The coarse-fine boundary does not exist at the coarsest level,
+    * although the hier::CoarseFineBoundary object still exists (it
+    * should not contain any boxes).
+    *
+    * This array is initialized in initializeOperatorState() and
+    * deallocated in deallocateOperatorState().  When allocated,
+    * it is allocated for the index range [0,d_ln_max], though
+    * the range [0,d_ln_min-1] is not used.  This is okay because
+    * hier::CoarseFineBoundary is a light object before
+    * it is set for a level.
+    */
+   tbox::Array<tbox::Pointer<hier::CoarseFineBoundary> > d_cf_boundary;
+
+   //@}
+
+   //@{
+   /*!
+    * @name Private state variables for solution process.
+    */
+
+   /*!
+    * @brief Smoothing choice.
+    * @see setSmoothingChoice.
+    */
+   std::string d_smoothing_choice;
+
+   /*!
+    * @brief Coarse level solver.
+    * @see setCoarsestLevelSolverChoice
+    */
+   std::string d_coarse_solver_choice;
+
+   /*!
+    * @brief Coarse-fine discretization method.
+    * @see setCoarseFineDiscretization().
+    */
+   std::string d_cf_discretization;
+
+   /*!
+    * @brief Coarse-fine discretization method.
+    *
+    * The name of the refinement operator used to prolong the
+    * coarse grid correction.
+    *
+    * @see setProlongationMethod()
+    */
+   std::string p_prolongation_method;
+   std::string v_prolongation_method;
+   std::string p_rrestriction_method;
+
+   /*!
+    * @brief Tolerance specified to coarse solver
+    * @see setCoarsestLevelSolverTolerance()
+    */
+   double d_coarse_solver_tolerance;
+
+   /*!
+    * @brief Coarse level solver iteration limit.
+    * @see setCoarsestLevelSolverMaxIterations()
+    */
+   int d_coarse_solver_max_iterations;
+
+   /*!
+    * @brief Residual tolerance to govern smoothing.
+    *
+    * When we use one of the internal error smoothing functions
+    * and want to terminate the smoothing sweeps at a certain
+    * level of residual, this will be set to > 0.  If it is
+    * < 0, the smoothing function effectively ignores it.
+    *
+    * This variable is needed because some coarse-level solver
+    * simply runs the smoothing function until convergence.
+    * It sets this variable to > 0, calls the smoothing function,
+    * then resets it to < 0.
+    */
+   double d_residual_tolerance_during_smoothing;
+
+   /*!
+    * @brief Id of moduli and dp.
+    *
+    * @see set_moduli_dp_id.
+    */
+  int cell_moduli_id, edge_moduli_id, dp_id;
+
+#ifdef HAVE_HYPRE
+   /*!
+    * @brief HYPRE coarse-level solver object.
+    */
+  Elastic::HypreSolver d_hypre_solver;
+#endif
+
+   /*!
+    * @brief Externally provided physical boundary condition object.
+    *
+    * see setPhysicalBcCoefObject()
+    */
+   // const RobinBcCoefStrategy* d_physical_bc_coef;
+
+   //@}
+
+   //@{ @name Internal context and scratch data
+
+   static tbox::Pointer<pdat::CellVariable<double> >
+   s_cell_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+
+   static tbox::Pointer<pdat::SideVariable<double> >
+   s_side_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+
+   /*!
+    * @brief Default context of internally maintained hierarchy data.
+    */
+   tbox::Pointer<hier::VariableContext> d_context;
+
+   /*!
+    * @brief ID of the solution-like scratch data.
+    *
+    * Set in constructor and never changed.
+    * Corresponds to a pdat::CellVariable<double> named
+    * @c d_object_name+"::cell_scratch".
+    * Scratch data is allocated and removed as needed
+    * to reduce memory usage.
+    */
+  int d_cell_scratch_id, d_side_scratch_id;
+
+   //@}
+
+   //@{
+   /*!
+    * @name Various refine and coarsen objects used internally.
+    */
+
+   //! @brief Error prolongation (refinement) operator.
+   tbox::Pointer<xfer::RefineOperator> p_prolongation_refine_operator;
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   p_prolongation_refine_schedules;
+
+   tbox::Pointer<xfer::RefineOperator> v_prolongation_refine_operator;
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   v_prolongation_refine_schedules;
+
+   //! @brief Solution restriction (coarsening) operator.
+   tbox::Pointer<xfer::CoarsenOperator> p_urestriction_coarsen_operator;
+   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
+   p_urestriction_coarsen_schedules;
+
+   tbox::Pointer<xfer::CoarsenOperator> v_urestriction_coarsen_operator;
+   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
+   v_urestriction_coarsen_schedules;
+
+   //! @brief Residual restriction (coarsening) operator.
+   tbox::Pointer<xfer::CoarsenOperator> p_rrestriction_coarsen_operator;
+   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
+   p_rrestriction_coarsen_schedules;
+
+   tbox::Pointer<xfer::CoarsenOperator> v_rrestriction_coarsen_operator;
+   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
+   v_rrestriction_coarsen_schedules;
+
+   //! @brief Refine operator for data from coarser level.
+   tbox::Pointer<xfer::RefineOperator> p_ghostfill_refine_operator;
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   p_ghostfill_refine_schedules;
+
+   tbox::Pointer<xfer::RefineOperator> v_ghostfill_refine_operator;
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   v_ghostfill_refine_schedules;
+
+   //! @brief Refine operator for data from same level.
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   p_nocoarse_refine_schedules;
+
+   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
+   v_nocoarse_refine_schedules;
+
+   //@}
+
+   /*!
+    * @brief Utility object employed in setting ghost cells and providing
+    * xfer::RefinePatchStrategy implementation.
+    *
+    * Since this class deals only in scalar variables having
+    * Robin boundary conditions, we take advantage of the corresponding
+    * implementation in CartesianRobinBcHelper.  Whenever
+    * we need an implementation of xfer::RefinePatchStrategy,
+    * this object is used.  Note that in the code, before we
+    * use this object to set ghost cell values, directly or
+    * indirectly by calling xfer::RefineSchedule::fillData(),
+    * we must tell the patch strategies the patch data index we want
+    * to set and whether we are setting data with homogeneous
+    * boundary condition.
+    */
+   P_Refine_Patch_Strategy p_refine_patch_strategy;
+   V_Refine_Patch_Strategy v_refine_patch_strategy;
+   V_Coarsen_Patch_Strategy v_coarsen_patch_strategy;
+
+   //@{
+   /*!
+    * @name Non-essential objects used in outputs and debugging.
+    */
+
+   /*!
+    * @brief Logging flag.
+    */
+   bool d_enable_logging;
+
+   /*!
+    * @brief Preconditioner using this object.
+    *
+    * See setPreconditioner().
+    */
+   const FACPreconditioner* d_preconditioner;
+
+   /*!
+    * @brief Hierarchy cell operator used in debugging.
+    */
+   tbox::Pointer<math::HierarchyCellDataOpsReal<double> > d_hopscell;
+
+   /*!
+    * @brief Hierarchy side operator used in debugging.
+    */
+   tbox::Pointer<math::HierarchySideDataOpsReal<double> > d_hopsside;
+
+   /*!
+    * @brief Timers for performance measurement.
+    */
+   tbox::Pointer<tbox::Timer> t_restrict_solution;
+   tbox::Pointer<tbox::Timer> t_restrict_residual;
+   tbox::Pointer<tbox::Timer> t_prolong;
+   tbox::Pointer<tbox::Timer> t_smooth_error;
+   tbox::Pointer<tbox::Timer> t_solve_coarsest;
+   tbox::Pointer<tbox::Timer> t_compute_composite_residual;
+   tbox::Pointer<tbox::Timer> t_compute_residual_norm;
+
+   static tbox::StartupShutdownManager::Handler
+   s_finalize_handler;
+};
+
+}
+}
+}
+
+#ifdef SAMRAI_INLINE
+#include "Elastic/FACOps.I"
+#endif
+
+#endif // included_solv_ElasticFACOps
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/FACOps.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/FACOps.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,193 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#ifndef SAMRAI_INLINE
+#include "Elastic/FACOps.I"
+#endif
+
+namespace SAMRAI {
+  namespace solv {
+
+    tbox::Pointer<pdat::CellVariable<double> >
+    Elastic::FACOps::s_cell_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+
+    tbox::Pointer<pdat::SideVariable<double> >
+    Elastic::FACOps::s_side_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+
+    tbox::StartupShutdownManager::Handler
+    Elastic::FACOps::s_finalize_handler(
+                                     0,
+                                     0,
+                                     0,
+                                     Elastic::FACOps::finalizeCallback,
+                                     tbox::StartupShutdownManager::priorityVariables);
+
+    /*
+********************************************************************
+* Constructor.                                                     *
+********************************************************************
+*/
+    Elastic::FACOps::FACOps(const tbox::Dimension& dim,
+                            const std::string& object_name,
+                            tbox::Pointer<tbox::Database> database):
+      d_dim(dim),
+      d_object_name(object_name),
+      d_hierarchy(),
+      d_ln_min(-1),
+      d_ln_max(-1),
+      d_cf_boundary(),
+      d_smoothing_choice("Tackley"),
+      d_coarse_solver_choice(
+#ifdef HAVE_HYPRE
+                             "hypre"
+#else
+                             "Tackley"
+#endif
+
+                             ),
+      d_cf_discretization("Ewing"),
+      p_prolongation_method("P_REFINE"),
+      v_prolongation_method("V_REFINE"),
+      p_rrestriction_method("CONSERVATIVE_COARSEN"),
+      d_coarse_solver_tolerance(1.e-8),
+      d_coarse_solver_max_iterations(10),
+      d_residual_tolerance_during_smoothing(-1.0),
+      cell_moduli_id(invalid_id),
+      edge_moduli_id(invalid_id),
+      dp_id(invalid_id),
+#ifdef HAVE_HYPRE
+      d_hypre_solver(dim,
+                     object_name + "::hypre_solver",
+                     database && database->isDatabase("hypre_solver") ?
+                     database->getDatabase("hypre_solver"):
+                     tbox::Pointer<tbox::Database>(NULL)),
+#endif
+      // d_physical_bc_coef(NULL),
+      d_context(hier::VariableDatabase::getDatabase()
+                ->getContext(object_name + "::PRIVATE_CONTEXT")),
+      d_cell_scratch_id(invalid_id),
+      d_side_scratch_id(invalid_id),
+      p_prolongation_refine_operator(),
+      p_prolongation_refine_schedules(),
+      v_prolongation_refine_operator(),
+      v_prolongation_refine_schedules(),
+      p_urestriction_coarsen_operator(),
+      p_urestriction_coarsen_schedules(),
+      v_urestriction_coarsen_operator(),
+      v_urestriction_coarsen_schedules(),
+      p_rrestriction_coarsen_operator(),
+      p_rrestriction_coarsen_schedules(),
+      v_rrestriction_coarsen_operator(),
+      v_rrestriction_coarsen_schedules(),
+      p_ghostfill_refine_operator(),
+      p_ghostfill_refine_schedules(),
+      v_ghostfill_refine_operator(),
+      v_ghostfill_refine_schedules(),
+      p_nocoarse_refine_schedules(),
+      v_nocoarse_refine_schedules(),
+      p_refine_patch_strategy(dim,
+                              d_object_name + "::refine patch strategy"),
+      v_refine_patch_strategy(dim,
+                              d_object_name + "::refine patch strategy"),
+      v_coarsen_patch_strategy(dim,
+                               d_object_name + "::coarsen patch strategy"),
+      d_enable_logging(false),
+      d_preconditioner(NULL),
+      d_hopscell(),
+      d_hopsside()
+    {
+
+      t_restrict_solution = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::restrictSolution()");
+      t_restrict_residual = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::restrictResidual()");
+      t_prolong = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::prolongErrorAndCorrect()");
+      t_smooth_error = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::smoothError()");
+      t_solve_coarsest = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::solveCoarsestLevel()");
+      t_compute_composite_residual = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::computeCompositeResidualOnLevel()");
+      t_compute_residual_norm = tbox::TimerManager::getManager()->
+        getTimer("solv::Elastic::FACOps::computeResidualNorm()");
+
+      if (d_dim == tbox::Dimension(1) || d_dim > tbox::Dimension(3)) {
+        TBOX_ERROR("Elastic::FACOps : DIM == 1 or > 3 not implemented yet.\n");
+      }
+
+      if (s_cell_scratch_var[dim.getValue() - 1].isNull()) {
+        TBOX_ASSERT(s_cell_scratch_var[dim.getValue() - 1].isNull());
+        TBOX_ASSERT(s_cell_scratch_var[dim.getValue() - 1].isNull());
+
+        std::ostringstream ss;
+        ss << "Elastic::FACOps::private_cell_scratch" << dim.getValue();
+        s_cell_scratch_var[dim.getValue() - 1] = new pdat::CellVariable<double>
+          (dim, ss.str());
+        ss.str("");
+        ss << "Elastic::FACOps::private_side_scratch" << dim.getValue();
+        s_side_scratch_var[dim.getValue() - 1] = new pdat::SideVariable<double>
+          (dim, ss.str());
+      }
+
+      hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
+      d_cell_scratch_id = vdb->
+        registerVariableAndContext(s_cell_scratch_var[dim.getValue() - 1],
+                                   d_context,
+                                   hier::IntVector::getOne(dim));
+      d_side_scratch_id = vdb->
+        registerVariableAndContext(s_side_scratch_var[dim.getValue() - 1],
+                                   d_context,
+                                   hier::IntVector::getOne(d_dim));
+
+      /*
+       * Some variables initialized by default are overriden by input.
+       */
+
+      if (database) {
+        d_coarse_solver_choice =
+          database->getStringWithDefault("coarse_solver_choice",
+                                         d_coarse_solver_choice);
+        d_coarse_solver_tolerance =
+          database->getDoubleWithDefault("coarse_solver_tolerance",
+                                         d_coarse_solver_tolerance);
+        d_coarse_solver_max_iterations =
+          database->getIntegerWithDefault("coarse_solver_max_iterations",
+                                          d_coarse_solver_max_iterations);
+        d_smoothing_choice =
+          database->getStringWithDefault("smoothing_choice",
+                                         d_smoothing_choice);
+
+        d_cf_discretization =
+          database->getStringWithDefault("cf_discretization",
+                                         d_cf_discretization);
+
+        p_prolongation_method =
+          database->getStringWithDefault("p_prolongation_method",
+                                         p_prolongation_method);
+
+        v_prolongation_method =
+          database->getStringWithDefault("v_prolongation_method",
+                                         v_prolongation_method);
+
+        p_rrestriction_method =
+          database->getStringWithDefault("p_rrestriction_method",
+                                         p_rrestriction_method);
+
+        d_enable_logging =
+          database->getBoolWithDefault("enable_logging",
+                                       d_enable_logging);
+
+      }
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/computeCompositeResidualOnLevel.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/computeCompositeResidualOnLevel.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,107 @@
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::computeCompositeResidualOnLevel
+(SAMRAIVectorReal<double>& residual,
+ const SAMRAIVectorReal<double>& solution,
+ const SAMRAIVectorReal<double>& rhs,
+ int ln,
+ bool error_equation_indicator) {
+
+  t_compute_composite_residual->start();
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (residual.getPatchHierarchy() != d_hierarchy
+      || solution.getPatchHierarchy() != d_hierarchy
+      || rhs.getPatchHierarchy() != d_hierarchy) {
+    TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
+               "internal hierarchy.");
+  }
+#endif
+  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
+
+  /*
+   * Set up the bc helper so that when we use a refine schedule
+   * to fill ghosts, the correct data is operated on.
+   */
+  const int p_id = solution.getComponentDescriptorIndex(0);
+  const int v_id = solution.getComponentDescriptorIndex(1);
+  p_refine_patch_strategy.setTargetDataId(p_id);
+  v_refine_patch_strategy.setTargetDataId(v_id);
+  // v_refine_patch_strategy.setHomogeneousBc(error_equation_indicator);
+
+  /*
+   * Assumptions:
+   * 1. Data does not yet exist in ghost boundaries.
+   * 2. Residual data on next finer grid (if any)
+   *    has been computed already.
+   * 3. Flux data from next finer grid (if any) has
+   *    been computed but has not been coarsened to
+   *    this level.
+   *
+   * Steps:
+   * S1. Fill solution ghost data by refinement
+   *     or setting physical boundary conditions.
+   *     This also brings in information from coarser
+   *     to form the composite grid flux.
+   * S2. Compute flux on ln.
+   * S3. If next finer is available,
+   *     Coarsen flux data on next finer level,
+   *     overwriting flux computed from coarse data.
+   * S4. Compute residual data from flux.
+   */
+
+  /* S1. Fill solution ghost data. */
+
+  set_boundaries(p_id,v_id,ln,error_equation_indicator);
+  if (ln > d_ln_min) {
+    /* Fill from current, next coarser level and physical boundary */
+    xeqScheduleGhostFill(p_id, v_id, ln);
+  } else {
+    /* Fill from current and physical boundary */
+    xeqScheduleGhostFillNoCoarse(p_id, v_id, ln);
+  }
+
+  /*
+   * S4. Compute residual on patches in level.
+   */
+
+  for (hier::PatchLevel::Iterator pi(*level); pi; pi++) {
+    tbox::Pointer<hier::Patch> patch = *pi;
+    tbox::Pointer<pdat::CellData<double> >
+      p_ptr = solution.getComponentPatchData(0, *patch);
+    tbox::Pointer<pdat::SideData<double> >
+      v_ptr = solution.getComponentPatchData(1, *patch);
+    tbox::Pointer<pdat::CellData<double> >
+      cell_moduli_ptr = patch->getPatchData(cell_moduli_id);
+    tbox::Pointer<pdat::CellData<double> >
+      p_rhs_ptr = rhs.getComponentPatchData(0, *patch);
+    tbox::Pointer<pdat::SideData<double> >
+      v_rhs_ptr = rhs.getComponentPatchData(1, *patch);
+    tbox::Pointer<pdat::CellData<double> >
+      p_resid_ptr = residual.getComponentPatchData(0, *patch);
+    tbox::Pointer<pdat::SideData<double> >
+      v_resid_ptr = residual.getComponentPatchData(1, *patch);
+
+    hier::Box pbox=patch->getBox();
+    pbox.growUpper(hier::IntVector::getOne(d_dim));
+    tbox::Pointer<geom::CartesianPatchGeometry>
+      geom = patch->getPatchGeometry();
+
+    switch(d_dim.getValue())
+      {
+      case 2:
+        residual_2D(*p_ptr,*v_ptr,*cell_moduli_ptr,*p_rhs_ptr,*v_rhs_ptr,
+                    *p_resid_ptr,*v_resid_ptr,*patch,pbox,*geom);
+        break;
+      case 3:
+        residual_3D(*p_ptr,*v_ptr,*cell_moduli_ptr,*p_rhs_ptr,*v_rhs_ptr,
+                    *p_resid_ptr,*v_resid_ptr,*patch,pbox,*geom);
+        break;
+      default:
+        abort();
+      }
+  }
+
+  t_compute_composite_residual->stop();
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/computeResidualNorm.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/computeResidualNorm.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,33 @@
+#include "Elastic/FACOps.h"
+
+double SAMRAI::solv::Elastic::FACOps::computeResidualNorm
+(const SAMRAIVectorReal<double>& residual,
+ int fine_ln,
+ int coarse_ln)
+{
+  if (coarse_ln != residual.getCoarsestLevelNumber() ||
+      fine_ln != residual.getFinestLevelNumber()) {
+    TBOX_ERROR("Elastic::FACOps::computeResidualNorm() is not\n"
+               << "set up to compute residual except on the range of\n"
+               << "levels defining the vector.\n");
+  }
+  t_compute_residual_norm->start();
+  /*
+   * The residual vector was cloned from vectors that has
+   * the proper weights associated with them, so we do not
+   * have to explicitly weight the residuals.
+   *
+   * maxNorm: not good to use because Hypre's norm does not
+   *   correspond to it.  Also maybe too sensitive to spikes.
+   * L2Norm: maybe good.  But does not correspond to the
+   *   scale of the quantity.
+   * L1Norm: maybe good.  Correspond to scale of quantity,
+   *   but may be too insensitive to spikes.
+   * RMSNorm: maybe good.
+   *
+   * We use maxNorm because it is a definite upper bound on the error.
+   */
+  double norm = residual.maxNorm();
+  t_compute_residual_norm->stop();
+  return norm;
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/computeVectorWeights.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/computeVectorWeights.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+namespace SAMRAI {
+  namespace solv {
+
+    /*
+********************************************************************
+* Compute the vector weight and put it at a specified patch data   *
+* index.                                                           *
+********************************************************************
+*/
+
+    void Elastic::FACOps::computeVectorWeights(
+                                            tbox::Pointer<hier::PatchHierarchy> hierarchy,
+                                            int weight_id,
+                                            int coarsest_ln,
+                                            int finest_ln) const
+    {
+      TBOX_ASSERT(!hierarchy.isNull());
+      TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
+
+      if (coarsest_ln == -1) coarsest_ln = 0;
+      if (finest_ln == -1) finest_ln = hierarchy->getFinestLevelNumber();
+      if (finest_ln < coarsest_ln) {
+        TBOX_ERROR(d_object_name
+                   << ": Illegal level number range.  finest_ln < coarsest_ln.");
+      }
+
+      int ln;
+      for (ln = finest_ln; ln >= coarsest_ln; --ln) {
+
+        /*
+         * On every level, first assign cell volume to vector weight.
+         */
+
+        tbox::Pointer<hier::PatchLevel> level =
+          hierarchy->getPatchLevel(ln);
+        for (hier::PatchLevel::Iterator p(level); p; p++) {
+          tbox::Pointer<hier::Patch> patch = *p;
+          tbox::Pointer<geom::CartesianPatchGeometry> patch_geometry =
+            patch->getPatchGeometry();
+          const double* dx = patch_geometry->getDx();
+          double cell_vol = dx[0];
+          if (d_dim > tbox::Dimension(1)) {
+            cell_vol *= dx[1];
+          }
+
+          if (d_dim > tbox::Dimension(2)) {
+            cell_vol *= dx[2];
+          }
+
+          tbox::Pointer<pdat::CellData<double> > w =
+            patch->getPatchData(weight_id);
+          if (!w) {
+            TBOX_ERROR(d_object_name
+                       << ": weight id must refer to a pdat::CellVariable");
+          }
+          w->fillAll(cell_vol);
+        }
+
+        /*
+         * On all but the finest level, assign 0 to vector
+         * weight to cells covered by finer cells.
+         */
+
+        if (ln < finest_ln) {
+
+          /*
+           * First get the boxes that describe index space of the next finer
+           * level and coarsen them to describe corresponding index space
+           * at this level.
+           */
+
+          tbox::Pointer<hier::PatchLevel> next_finer_level =
+            hierarchy->getPatchLevel(ln + 1);
+          hier::BoxArray coarsened_boxes = next_finer_level->getBoxes();
+          hier::IntVector coarsen_ratio(next_finer_level->getRatioToLevelZero());
+          coarsen_ratio /= level->getRatioToLevelZero();
+          coarsened_boxes.coarsen(coarsen_ratio);
+
+          /*
+           * Then set vector weight to 0 wherever there is
+           * a nonempty intersection with the next finer level.
+           * Note that all assignments are local.
+           */
+
+          for (hier::PatchLevel::Iterator p(level); p; p++) {
+
+            tbox::Pointer<hier::Patch> patch = *p;
+            for (int i = 0; i < coarsened_boxes.getNumberOfBoxes(); i++) {
+
+              hier::Box coarse_box = coarsened_boxes[i];
+              hier::Box intersection = coarse_box * (patch->getBox());
+              if (!intersection.empty()) {
+                tbox::Pointer<pdat::CellData<double> > w =
+                  patch->getPatchData(weight_id);
+                w->fillAll(0.0, intersection);
+
+              }  // assignment only in non-empty intersection
+            }  // loop over coarsened boxes from finer level
+          }  // loop over patches in level
+        }  // all levels except finest
+      }  // loop over levels
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/deallocateOperatorState.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/deallocateOperatorState.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+namespace SAMRAI {
+  namespace solv {
+
+    /*
+********************************************************************
+* FACOperatorStrategy virtual deallocateOperatorState        *
+* function.  Deallocate internal hierarchy-dependent data.         *
+* State is allocated iff hierarchy is set.                         *
+********************************************************************
+*/
+
+    void Elastic::FACOps::deallocateOperatorState()
+    {
+      if (d_hierarchy) {
+        d_cf_boundary.resizeArray(0);
+#ifdef HAVE_HYPRE
+        d_hypre_solver.deallocateSolverState();
+#endif
+        d_hierarchy.setNull();
+        d_ln_min = -1;
+        d_ln_max = -1;
+
+        p_prolongation_refine_schedules.setNull();
+        v_prolongation_refine_schedules.setNull();
+        p_urestriction_coarsen_schedules.setNull();
+        v_urestriction_coarsen_schedules.setNull();
+        p_rrestriction_coarsen_schedules.setNull();
+        v_rrestriction_coarsen_schedules.setNull();
+        p_ghostfill_refine_schedules.setNull();
+        v_ghostfill_refine_schedules.setNull();
+        p_nocoarse_refine_schedules.setNull();
+        v_nocoarse_refine_schedules.setNull();
+      }
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/finalizeCallback.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/finalizeCallback.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+namespace SAMRAI {
+  namespace solv {
+
+    void
+    Elastic::FACOps::finalizeCallback()
+    {
+      for (int d = 0; d < tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
+        s_cell_scratch_var[d].setNull();
+        s_side_scratch_var[d].setNull();
+      }
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/initializeOperatorState.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/initializeOperatorState.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,469 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+/*
+************************************************************************
+* FACOperatorStrategy virtual initializeOperatorState function.  *
+*                                                                      *
+* Set internal variables to correspond to the solution passed in.      *
+* Look up transfer operators.                                          *
+************************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::initializeOperatorState
+(const SAMRAIVectorReal<double>& solution,
+ const SAMRAIVectorReal<double>& rhs)
+{
+  deallocateOperatorState();
+  int ln;
+  hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
+
+  d_hierarchy = solution.getPatchHierarchy();
+  d_ln_min = solution.getCoarsestLevelNumber();
+  d_ln_max = solution.getFinestLevelNumber();
+  d_hopscell = new math::HierarchyCellDataOpsReal<double>(d_hierarchy,
+                                                          d_ln_min,
+                                                          d_ln_max);
+  d_hopsside = new math::HierarchySideDataOpsReal<double>(d_hierarchy,
+                                                          d_ln_min,
+                                                          d_ln_max);
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+
+  // if (d_physical_bc_coef == NULL) {
+  //   /*
+  //    * It's an error not to have bc object set.
+  //    * Note that the bc object cannot be passed in through
+  //    * the argument because the interface is inherited.
+  //    */
+  //   TBOX_ERROR(
+  //              d_object_name << ": No physical bc object in\n"
+  //              <<
+  //              "Elastic::FACOps::initializeOperatorState\n"
+  //              << "You must use "
+  //              <<
+  //              "Elastic::FACOps::setPhysicalBcCoefObject\n"
+  //              <<
+  //              "to set one before calling initializeOperatorState\n");
+  // }
+
+  if (solution.getNumberOfComponents() != 1) {
+    TBOX_WARNING(d_object_name
+                 << ": Solution vector has multiple components.\n"
+                 << "Solver is for component 0 only.\n");
+  }
+  if (rhs.getNumberOfComponents() != 1) {
+    TBOX_WARNING(d_object_name
+                 << ": RHS vector has multiple components.\n"
+                 << "Solver is for component 0 only.\n");
+  }
+
+  /*
+   * Make sure that solution and rhs data
+   *   are of correct type
+   *   are allocated
+   *   has sufficient ghost width
+   */
+  tbox::Pointer<hier::Variable> var;
+  {
+    vdb->mapIndexToVariable(rhs.getComponentDescriptorIndex(0),
+                            var);
+    if (!var) {
+      TBOX_ERROR(d_object_name << ": RHS component does not\n"
+                 << "correspond to a variable.\n");
+    }
+    tbox::Pointer<pdat::CellVariable<double> > cell_var = var;
+    if (!cell_var) {
+      TBOX_ERROR(d_object_name
+                 << ": RHS variable is not cell-centered double\n");
+    }
+  }
+  {
+    vdb->mapIndexToVariable(solution.getComponentDescriptorIndex(0),
+                            var);
+    if (!var) {
+      TBOX_ERROR(d_object_name << ": Solution component does not\n"
+                 << "correspond to a variable.\n");
+    }
+    tbox::Pointer<pdat::CellVariable<double> > cell_var = var;
+    if (!cell_var) {
+      TBOX_ERROR(d_object_name
+                 << ": Solution variable is not cell-centered double\n");
+    }
+  }
+  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
+    tbox::Pointer<hier::PatchLevel> level_ptr =
+      d_hierarchy->getPatchLevel(ln);
+    hier::PatchLevel& level = *level_ptr;
+    for (hier::PatchLevel::Iterator pi(level); pi; pi++) {
+      hier::Patch& patch = **pi;
+      tbox::Pointer<hier::PatchData> fd =
+        patch.getPatchData(rhs.getComponentDescriptorIndex(0));
+      if (fd) {
+        /*
+         * Some data checks can only be done if the data already exists.
+         */
+        tbox::Pointer<pdat::CellData<double> > cd = fd;
+        if (!cd) {
+          TBOX_ERROR(d_object_name
+                     << ": RHS data is not cell-centered double\n");
+        }
+        if (cd->getDepth() > 1) {
+          TBOX_WARNING(d_object_name
+                       << ": RHS data has multiple depths.\n"
+                       << "Solver is for depth 0 only.\n");
+        }
+      }
+      tbox::Pointer<hier::PatchData> ud =
+        patch.getPatchData(solution.getComponentDescriptorIndex(0));
+      if (ud) {
+        /*
+         * Some data checks can only be done if the data already exists.
+         */
+        tbox::Pointer<pdat::CellData<double> > cd = ud;
+        if (!cd) {
+          TBOX_ERROR(d_object_name
+                     << ": Solution data is not cell-centered double\n");
+        }
+        if (cd->getDepth() > 1) {
+          TBOX_WARNING(d_object_name
+                       << ": Solution data has multiple depths.\n"
+                       << "Solver is for depth 0 only.\n");
+        }
+        if (cd->getGhostCellWidth() < hier::IntVector::getOne(d_dim)) {
+          TBOX_ERROR(d_object_name
+                     << ": Solution data has insufficient ghost width\n");
+        }
+      }
+    }
+  }
+
+  /*
+   * Solution and rhs must have some similar properties.
+   */
+  if (rhs.getPatchHierarchy() != d_hierarchy
+      || rhs.getCoarsestLevelNumber() != d_ln_min
+      || rhs.getFinestLevelNumber() != d_ln_max) {
+    TBOX_ERROR(d_object_name << ": solution and rhs do not have\n"
+               << "the same set of patch levels.\n");
+  }
+
+#endif
+
+  /*
+   * Initialize the coarse-fine boundary description for the
+   * hierarchy.
+   */
+  d_cf_boundary.resizeArray(d_hierarchy->getNumberOfLevels());
+
+  hier::IntVector max_gcw(d_dim, 1);
+  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
+    d_cf_boundary[ln] = new hier::CoarseFineBoundary(*d_hierarchy,
+                                                     ln,
+                                                     max_gcw);
+  }
+
+  v_coarsen_patch_strategy.coarse_fine=d_cf_boundary;
+// #ifdef HAVE_HYPRE
+//   if (d_coarse_solver_choice == "hypre") {
+//     d_hypre_solver.initializeSolverState(d_hierarchy, d_ln_min);
+//     /*
+//      * Share the boundary condition object with the hypre solver
+//      * to make sure that boundary condition settings are consistent
+//      * between the two objects.
+//      */
+//     d_hypre_solver.setPhysicalBcCoefObject(d_physical_bc_coef);
+//     d_hypre_solver.setMatrixCoefficients(d_elastic_spec);
+//   }
+// #endif
+
+  /*
+   * Get the transfer operators.
+   * Cell (solution, error, etc) coarsening is conservative.
+   */
+  tbox::Pointer<geom::CartesianGridGeometry> geometry =
+    d_hierarchy->getGridGeometry();
+  tbox::Pointer<hier::Variable> variable;
+
+  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
+  p_prolongation_refine_operator =
+    geometry->lookupRefineOperator(variable,
+                                   p_prolongation_method);
+
+  vdb->mapIndexToVariable(d_side_scratch_id, variable);
+  v_prolongation_refine_operator =
+    geometry->lookupRefineOperator(variable,
+                                   v_prolongation_method);
+
+  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
+  p_urestriction_coarsen_operator =
+    geometry->lookupCoarsenOperator(variable,
+                                    "CONSERVATIVE_COARSEN");
+  p_rrestriction_coarsen_operator =
+    geometry->lookupCoarsenOperator(variable,
+                                   p_rrestriction_method);
+
+  vdb->mapIndexToVariable(d_side_scratch_id, variable);
+  v_urestriction_coarsen_operator =
+    v_rrestriction_coarsen_operator =
+    geometry->lookupCoarsenOperator(variable,
+                                    "V_COARSEN");
+
+  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
+  p_ghostfill_refine_operator =
+    geometry->lookupRefineOperator(variable,
+                                   "P_BOUNDARY_REFINE");
+
+  vdb->mapIndexToVariable(d_side_scratch_id, variable);
+  v_ghostfill_refine_operator =
+    geometry->lookupRefineOperator(variable,
+                                   "V_BOUNDARY_REFINE");
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (!p_prolongation_refine_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find p prolongation refine operator");
+  }
+  if (!v_prolongation_refine_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find v prolongation refine operator");
+  }
+  if (!p_urestriction_coarsen_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find p restriction coarsening operator");
+  }
+  if (!v_urestriction_coarsen_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find v restriction coarsening operator");
+  }
+  if (!p_rrestriction_coarsen_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find p restriction coarsening operator");
+  }
+  if (!v_rrestriction_coarsen_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find v restriction coarsening operator");
+  }
+  if (!p_ghostfill_refine_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find ghost filling refinement operator");
+  }
+  if (!v_ghostfill_refine_operator) {
+    TBOX_ERROR(d_object_name
+               << ": Cannot find ghost filling refinement operator");
+  }
+#endif
+
+  /*
+   * Make space for saving communication schedules.
+   * There is no need to delete the old schedules first
+   * because we have deallocated the solver state above.
+   */
+  p_prolongation_refine_schedules.resizeArray(d_ln_max + 1);
+  v_prolongation_refine_schedules.resizeArray(d_ln_max + 1);
+  p_ghostfill_refine_schedules.resizeArray(d_ln_max + 1);
+  v_ghostfill_refine_schedules.resizeArray(d_ln_max + 1);
+  p_nocoarse_refine_schedules.resizeArray(d_ln_max + 1);
+  v_nocoarse_refine_schedules.resizeArray(d_ln_max + 1);
+  p_urestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
+  p_rrestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
+  v_urestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
+  v_rrestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
+
+  xfer::RefineAlgorithm p_prolongation_refine_algorithm(d_dim),
+    v_prolongation_refine_algorithm(d_dim),
+    p_ghostfill_refine_algorithm(d_dim),
+    v_ghostfill_refine_algorithm(d_dim),
+    p_nocoarse_refine_algorithm(d_dim),
+    v_nocoarse_refine_algorithm(d_dim);
+  xfer::CoarsenAlgorithm p_urestriction_coarsen_algorithm(d_dim),
+    p_rrestriction_coarsen_algorithm(d_dim),
+    v_urestriction_coarsen_algorithm(d_dim),
+    v_rrestriction_coarsen_algorithm(d_dim);
+
+  /* This is a little confusing.  The only real purpose here is to
+     create a communication schedule.  That communication schedule is
+     then reused later when refining, though with a different source,
+     scratch, and destination.  So the arguments to registerRefine are
+     not all that important, because a different refineAlgorithm will
+     be used then. */
+
+  p_prolongation_refine_algorithm.
+    registerRefine(d_cell_scratch_id,
+                   solution.getComponentDescriptorIndex(0),
+                   d_cell_scratch_id,
+                   p_prolongation_refine_operator);
+  v_prolongation_refine_algorithm.
+    registerRefine(d_side_scratch_id,
+                   solution.getComponentDescriptorIndex(1),
+                   d_side_scratch_id,
+                   v_prolongation_refine_operator);
+  p_urestriction_coarsen_algorithm.
+    registerCoarsen(solution.getComponentDescriptorIndex(0),
+                    solution.getComponentDescriptorIndex(0),
+                    p_urestriction_coarsen_operator);
+  p_rrestriction_coarsen_algorithm.
+    registerCoarsen(rhs.getComponentDescriptorIndex(0),
+                    rhs.getComponentDescriptorIndex(0),
+                    p_rrestriction_coarsen_operator);
+  v_urestriction_coarsen_algorithm.
+    registerCoarsen(solution.getComponentDescriptorIndex(1),
+                    solution.getComponentDescriptorIndex(1),
+                    v_urestriction_coarsen_operator);
+  v_rrestriction_coarsen_algorithm.
+    registerCoarsen(rhs.getComponentDescriptorIndex(1),
+                    rhs.getComponentDescriptorIndex(1),
+                    v_rrestriction_coarsen_operator);
+  p_ghostfill_refine_algorithm.
+    registerRefine(solution.getComponentDescriptorIndex(0),
+                   solution.getComponentDescriptorIndex(0),
+                   solution.getComponentDescriptorIndex(0),
+                   p_ghostfill_refine_operator);
+  v_ghostfill_refine_algorithm.
+    registerRefine(solution.getComponentDescriptorIndex(1),
+                   solution.getComponentDescriptorIndex(1),
+                   solution.getComponentDescriptorIndex(1),
+                   v_ghostfill_refine_operator);
+  p_nocoarse_refine_algorithm.
+    registerRefine(solution.getComponentDescriptorIndex(0),
+                   solution.getComponentDescriptorIndex(0),
+                   solution.getComponentDescriptorIndex(0),
+                   tbox::Pointer<xfer::RefineOperator>(0));
+  v_nocoarse_refine_algorithm.
+    registerRefine(solution.getComponentDescriptorIndex(1),
+                   solution.getComponentDescriptorIndex(1),
+                   solution.getComponentDescriptorIndex(1),
+                   tbox::Pointer<xfer::RefineOperator>(0));
+
+  /* Refinement and ghost fill operators */
+  for (int dest_ln = d_ln_min + 1; dest_ln <= d_ln_max; ++dest_ln) {
+
+    tbox::Pointer<xfer::PatchLevelFullFillPattern>
+      fill_pattern(new xfer::PatchLevelFullFillPattern());
+    p_prolongation_refine_schedules[dest_ln] =
+      p_prolongation_refine_algorithm.
+      createSchedule(fill_pattern,
+                     d_hierarchy->getPatchLevel(dest_ln),
+                     tbox::Pointer<hier::PatchLevel>(),
+                     dest_ln - 1,
+                     d_hierarchy);
+    if (!p_prolongation_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for p prolongation!\n");
+    }
+    v_prolongation_refine_schedules[dest_ln] =
+      v_prolongation_refine_algorithm.
+      createSchedule(fill_pattern,
+                     d_hierarchy->getPatchLevel(dest_ln),
+                     tbox::Pointer<hier::PatchLevel>(),
+                     dest_ln - 1,
+                     d_hierarchy);
+    if (!v_prolongation_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for v prolongation!\n");
+    }
+    p_ghostfill_refine_schedules[dest_ln] =
+      p_ghostfill_refine_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     dest_ln - 1,
+                     d_hierarchy,
+                     &p_refine_patch_strategy);
+    if (!p_ghostfill_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for ghost filling!\n");
+    }
+    v_ghostfill_refine_schedules[dest_ln] =
+      v_ghostfill_refine_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     dest_ln - 1,
+                     d_hierarchy,
+                     &v_refine_patch_strategy);
+    if (!v_ghostfill_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for ghost filling!\n");
+    }
+    p_nocoarse_refine_schedules[dest_ln] =
+      p_nocoarse_refine_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln));
+    if (!p_nocoarse_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for ghost filling on bottom level!\n");
+    }
+    v_nocoarse_refine_schedules[dest_ln] =
+      v_nocoarse_refine_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln));
+    if (!v_nocoarse_refine_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a refine schedule for ghost filling on bottom level!\n");
+    }
+  }
+
+  /* Coarsening operators */
+  for (int dest_ln = d_ln_min; dest_ln < d_ln_max; ++dest_ln) {
+    p_urestriction_coarsen_schedules[dest_ln] =
+      p_urestriction_coarsen_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     d_hierarchy->getPatchLevel(dest_ln + 1));
+    if (!p_urestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a coarsen schedule for U p restriction!\n");
+    }
+    p_rrestriction_coarsen_schedules[dest_ln] =
+      p_rrestriction_coarsen_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     d_hierarchy->getPatchLevel(dest_ln + 1));
+    if (!p_rrestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a coarsen schedule for R p restriction!\n");
+    }
+
+    v_urestriction_coarsen_schedules[dest_ln] =
+      v_urestriction_coarsen_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     d_hierarchy->getPatchLevel(dest_ln + 1),
+                     &v_coarsen_patch_strategy);
+    if (!v_urestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a coarsen schedule for U v restriction!\n");
+    }
+    v_rrestriction_coarsen_schedules[dest_ln] =
+      v_rrestriction_coarsen_algorithm.
+      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
+                     d_hierarchy->getPatchLevel(dest_ln + 1),
+                     &v_coarsen_patch_strategy);
+    if (!v_rrestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR(d_object_name
+                 << ": Cannot create a coarsen schedule for R v restriction!\n");
+    }
+  }
+
+  /* Ordinary ghost fill operator on the coarsest level */
+  p_nocoarse_refine_schedules[d_ln_min] =
+    p_nocoarse_refine_algorithm.
+    createSchedule(d_hierarchy->getPatchLevel(d_ln_min));
+  if (!p_nocoarse_refine_schedules[d_ln_min]) {
+    TBOX_ERROR(
+               d_object_name
+               <<
+               ": Cannot create a refine schedule for p ghost filling on bottom level!\n");
+  }
+  v_nocoarse_refine_schedules[d_ln_min] =
+    v_nocoarse_refine_algorithm.
+    createSchedule(d_hierarchy->getPatchLevel(d_ln_min));
+  if (!v_nocoarse_refine_schedules[d_ln_min]) {
+    TBOX_ERROR(
+               d_object_name
+               <<
+               ": Cannot create a refine schedule for v ghost filling on bottom level!\n");
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/postprocessOneCycle.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/postprocessOneCycle.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+********************************************************************
+* FACOperatorStrategy virtual postprocessOneCycle function.  *
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::postprocessOneCycle
+(int fac_cycle_num,
+ const SAMRAIVectorReal<double>& current_soln,
+ const SAMRAIVectorReal<double>& residual)
+{
+  NULL_USE(current_soln);
+  NULL_USE(residual);
+
+  if (d_enable_logging) {
+    if (d_preconditioner) {
+      /*
+       * Output convergence progress.  This is probably only appropriate
+       * if the solver is NOT being used as a preconditioner.
+       */
+      double avg_factor, final_factor;
+      d_preconditioner->getConvergenceFactors(avg_factor, final_factor);
+      tbox::plog
+        << "iter=" << std::setw(4) << fac_cycle_num
+        << " resid=" << d_preconditioner->getResidualNorm()
+        << " net conv=" << d_preconditioner->getNetConvergenceFactor()
+        << " final conv=" << d_preconditioner->getNetConvergenceFactor()
+        << " avg conv=" << d_preconditioner->getAvgConvergenceFactor()
+        << std::endl;
+    }
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/prolongErrorAndCorrect.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/prolongErrorAndCorrect.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+***********************************************************************
+* FACOperatorStrategy virtual prolongErrorAndCorrect function.  *
+* After the prolongation, we set the physical boundary condition      *
+* for the correction, which is zero.  Other ghost cell values,        *
+* which are preset to zero, need not be set.                          *
+***********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::prolongErrorAndCorrect
+(const SAMRAIVectorReal<double>& s,
+ SAMRAIVectorReal<double>& d,
+ int dest_ln)
+{
+  t_prolong->start();
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (s.getPatchHierarchy() != d_hierarchy
+      || d.getPatchHierarchy() != d_hierarchy) {
+    TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
+               "internal state hierarchy.");
+  }
+#endif
+
+  tbox::Pointer<hier::PatchLevel> coarse_level =
+    d_hierarchy->getPatchLevel(dest_ln - 1);
+  tbox::Pointer<hier::PatchLevel> fine_level =
+    d_hierarchy->getPatchLevel(dest_ln);
+
+  /*
+   * Data is prolonged into the scratch space corresponding
+   * to index d_cell_scratch_id and allocated here.
+   */
+  fine_level->allocatePatchData(d_cell_scratch_id);
+  fine_level->allocatePatchData(d_side_scratch_id);
+
+  // int p_src(s.getComponentDescriptorIndex(0)),
+  //   v_src(s.getComponentDescriptorIndex(1)),
+  //   p_dst(d.getComponentDescriptorIndex(0)),
+  //   v_dst(d.getComponentDescriptorIndex(1));
+  // xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
+
+  /*
+   * Refine solution into scratch space to fill the fine level
+   * interior in the scratch space, then use that refined data
+   * to correct the fine level error.
+   */
+  p_refine_patch_strategy.setTargetDataId(d_cell_scratch_id);
+  v_refine_patch_strategy.setTargetDataId(d_side_scratch_id);
+  // v_refine_patch_strategy.setHomogeneousBc(true);
+  xeqScheduleProlongation(d_cell_scratch_id,
+                          s.getComponentDescriptorIndex(0),
+                          d_cell_scratch_id,
+                          d_side_scratch_id,
+                          s.getComponentDescriptorIndex(1),
+                          d_side_scratch_id,
+                          dest_ln);
+
+  set_boundaries(s.getComponentDescriptorIndex(0),
+                 s.getComponentDescriptorIndex(1),fine_level,true);
+  /*
+   * Add the refined error in the scratch space to the error currently
+   * residing in the destination level.
+   */
+  {
+    math::HierarchyCellDataOpsReal<double>
+      hierarchy_math_ops(d_hierarchy, dest_ln, dest_ln);
+    const int p_dst = d.getComponentDescriptorIndex(0);
+    hierarchy_math_ops.add(p_dst, p_dst, d_cell_scratch_id);
+  }
+  {
+    math::HierarchySideDataOpsReal<double>
+      hierarchy_math_ops(d_hierarchy, dest_ln, dest_ln);
+    const int v_dst = d.getComponentDescriptorIndex(1);
+    hierarchy_math_ops.add(v_dst, v_dst, d_side_scratch_id);
+  }
+  fine_level->deallocatePatchData(d_cell_scratch_id);
+  fine_level->deallocatePatchData(d_side_scratch_id);
+
+  t_prolong->stop();
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/residual_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/residual_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,83 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+
+void SAMRAI::solv::Elastic::FACOps::residual_2D
+(pdat::CellData<double> &p,
+ pdat::SideData<double> &v,
+ pdat::CellData<double> &cell_moduli,
+ pdat::CellData<double> &p_rhs,
+ pdat::SideData<double> &v_rhs,
+ pdat::CellData<double> &p_resid,
+ pdat::SideData<double> &v_resid,
+ hier::Patch &patch,
+ const hier::Box &pbox,
+ const geom::CartesianPatchGeometry &geom)
+{
+  const hier::Index ip(1,0), jp(0,1);
+
+  tbox::Pointer<pdat::NodeData<double> >
+    edge_moduli_ptr = patch.getPatchData(edge_moduli_id);
+  pdat::NodeData<double> &edge_moduli(*edge_moduli_ptr);
+
+  double dx = geom.getDx()[0];
+  double dy = geom.getDx()[1];
+
+  for(pdat::CellIterator ci(pbox); ci; ci++)
+    {
+      pdat::CellIndex center(*ci);
+      pdat::CellIndex up(center), down(center), right(center),
+        left(center);
+
+      ++up[1];
+      --down[1];
+      ++right[0];
+      --left[0];
+
+      const pdat::SideIndex
+        x(center,0,pdat::SideIndex::Lower),
+        y(center,1,pdat::SideIndex::Lower);
+      const pdat::NodeIndex
+        edge(center,pdat::NodeIndex::LowerLeft);
+
+      /* p */
+      if(center[0]!=pbox.upper(0) && center[1]!=pbox.upper(1))
+        {
+          p_resid(center)=0;
+        }
+
+      /* vx */
+      if(center[1]!=pbox.upper(1))
+        {
+          /* If x==0 */
+          if((center[0]==pbox.lower(0) && v(x-ip)==boundary_value)
+             || (center[0]==pbox.upper(0) && v(x+ip)==boundary_value))
+            {
+              v_resid(x)=0;
+            }
+          else
+            {
+              v_resid(x)=v_rhs(x)
+                - v_operator_2D(v,cell_moduli,edge_moduli,center,
+                                edge,x,y,ip,jp,dx,dy);
+            }
+        }
+
+      /* vy */
+      if(center[0]!=pbox.upper(0))
+        {
+          /* If y==0 */
+          if((center[1]==pbox.lower(1) && v(y-jp)==boundary_value)
+             || (center[1]==pbox.upper(1) && v(y+jp)==boundary_value))
+            {
+              v_resid(y)=0;
+            }
+          else
+            {
+              v_resid(y)=v_rhs(y)
+                - v_operator_2D(v,cell_moduli,edge_moduli,center,
+                                edge,y,x,jp,ip,dy,dx);
+            }
+        }
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/residual_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/residual_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,73 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+
+void SAMRAI::solv::Elastic::FACOps::residual_3D
+(pdat::CellData<double> &p,
+ pdat::SideData<double> &v,
+ pdat::CellData<double> &cell_moduli,
+ pdat::CellData<double> &p_rhs,
+ pdat::SideData<double> &v_rhs,
+ pdat::CellData<double> &p_resid,
+ pdat::SideData<double> &v_resid,
+ hier::Patch &patch,
+ const hier::Box &pbox,
+ const geom::CartesianPatchGeometry &geom)
+{
+  tbox::Pointer<pdat::EdgeData<double> >
+    edge_moduli_ptr = patch.getPatchData(edge_moduli_id);
+  pdat::EdgeData<double> &edge_moduli(*edge_moduli_ptr);
+
+  const double *Dx = geom.getDx();
+  const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
+  const hier::Index pp[]={ip,jp,kp};
+
+  for(pdat::CellIterator ci(pbox); ci; ci++)
+    {
+      pdat::CellIndex center(*ci);
+      pdat::CellIndex up(center), down(center), right(center),
+        left(center), front(center), back(center);
+
+      ++right[0];
+      --left[0];
+      ++up[1];
+      --down[1];
+      ++front[2];
+      --back[2];
+
+      /* p */
+      if(center[0]!=pbox.upper(0) && center[1]!=pbox.upper(1)
+         && center[2]!=pbox.upper(2))
+        {
+          p_resid(center)=0;
+        }
+
+      for(int ix=0;ix<3;++ix)
+        {
+          const int iy((ix+1)%3), iz((ix+2)%3);
+          const pdat::SideIndex
+            x(center,ix,pdat::SideIndex::Lower),
+            y(center,iy,pdat::SideIndex::Lower),
+            z(center,iz,pdat::SideIndex::Lower);
+          const pdat::EdgeIndex
+            edge_y(center,iy,pdat::EdgeIndex::LowerLeft),
+            edge_z(center,iz,pdat::EdgeIndex::LowerLeft);
+
+          if(center[iy]!=pbox.upper(iy) && center[iz]!=pbox.upper(iz))
+            {
+              if((center[ix]==pbox.lower(ix) && v(x-pp[ix])==boundary_value)
+                 || (center[ix]==pbox.upper(ix) && v(x+pp[ix])==boundary_value))
+                {
+                  v_resid(x)=0;
+                }
+              else
+                {
+                  v_resid(x)=v_rhs(x)
+                    - v_operator_3D(v,cell_moduli,edge_moduli,
+                                    center,edge_y,edge_z,x,y,z,
+                                    pp[ix],pp[iy],pp[iz],Dx[ix],Dx[iy],Dx[iz]);
+                }
+            }
+        }          
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/restrictResidual.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/restrictResidual.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+********************************************************************
+* FACOperatorStrategy virtual restrictresidual function.     *
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::restrictResidual
+(const SAMRAIVectorReal<double>& s,
+ SAMRAIVectorReal<double>& d,
+ int dest_ln)
+{
+  t_restrict_residual->start();
+
+  int p_src(s.getComponentDescriptorIndex(0)),
+    p_dst(d.getComponentDescriptorIndex(0)),
+    v_src(s.getComponentDescriptorIndex(1)),
+    v_dst(d.getComponentDescriptorIndex(1));
+
+  /* Need to do a sync because the coarsening for v uses ghost zones */
+  v_coarsen_patch_strategy.setSourceDataId(v_src);
+  xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
+
+  xeqScheduleRRestriction(p_dst,p_src,v_dst,v_src,dest_ln);
+
+  t_restrict_residual->stop();
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/restrictSolution.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/restrictSolution.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+********************************************************************
+* FACOperatorStrategy virtual restrictSolution function.     *
+* After restricting solution, update ghost cells of the affected   *
+* level.                                                           *
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::restrictSolution
+(const SAMRAIVectorReal<double>& s,
+ SAMRAIVectorReal<double>& d,
+ int dest_ln)
+{
+  t_restrict_solution->start();
+
+  int p_src(s.getComponentDescriptorIndex(0)),
+    p_dst(d.getComponentDescriptorIndex(0)),
+    v_src(s.getComponentDescriptorIndex(1)),
+    v_dst(d.getComponentDescriptorIndex(1));
+
+  /* Need to do a sync because the coarsening for v uses ghost zones. */
+  v_coarsen_patch_strategy.setSourceDataId(v_src);
+  xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
+
+  xeqScheduleURestriction(p_dst,p_src,v_dst,v_src,dest_ln);
+
+  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(dest_ln);
+  set_boundaries(p_dst,v_dst,level,false);
+  // v_refine_patch_strategy.setHomogeneousBc(false);
+  p_refine_patch_strategy.setTargetDataId(d.getComponentDescriptorIndex(0));
+  v_refine_patch_strategy.setTargetDataId(d.getComponentDescriptorIndex(1));
+
+  if (dest_ln == d_ln_min) {
+    xeqScheduleGhostFillNoCoarse(p_dst,v_dst,dest_ln);
+  } else {
+    xeqScheduleGhostFill(p_dst,v_dst,dest_ln);
+  }
+
+  t_restrict_solution->stop();
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/set_boundaries.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/set_boundaries.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+#include "Constants.h"
+#include "Elastic/set_boundary.h"
+
+/* Set the physical boundaries for the velocity. */
+
+void SAMRAI::solv::Elastic::FACOps::set_boundaries
+(const int &p_id, const int &v_id,
+ tbox::Pointer<hier::PatchLevel> &level, const bool &rhs)
+{
+  for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
+    {
+      tbox::Pointer<hier::Patch> patch = *pi;
+      set_boundary(*patch,p_id,v_id,rhs);
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/smoothError.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/smoothError.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+********************************************************************
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::smoothError
+(SAMRAIVectorReal<double>& data,
+ const SAMRAIVectorReal<double>& residual,
+ int ln,
+ int num_sweeps)
+{
+  t_smooth_error->start();
+
+  if (d_smoothing_choice == "Tackley") {
+    if(d_dim.getValue()==2)
+      smooth_Tackley_2D(data,residual,ln,num_sweeps,
+                        d_residual_tolerance_during_smoothing);
+    else if(d_dim.getValue()==3)
+      smooth_Tackley_3D(data,residual,ln,num_sweeps,
+                        d_residual_tolerance_during_smoothing);
+    else
+	TBOX_ERROR(d_object_name << ": Invalid dimension in Elastic::FACOps.");
+  } else {
+    TBOX_ERROR(d_object_name << ": Bad smoothing choice '"
+               << d_smoothing_choice
+               << "' in Elastic::FACOps.");
+  }
+
+  t_smooth_error->stop();
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/smooth_Tackley_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/smooth_Tackley_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,200 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+#include "Elastic/dRc_dp.h"
+/*
+********************************************************************
+* Workhorse function to smooth error using red-black               *
+* Gauss-Seidel iterations.                                         *
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::smooth_Tackley_2D
+(SAMRAIVectorReal<double>& solution,
+ const SAMRAIVectorReal<double>& residual,
+ int ln,
+ int num_sweeps,
+ double residual_tolerance)
+{
+  const int p_id(solution.getComponentDescriptorIndex(0)),
+    p_rhs_id(residual.getComponentDescriptorIndex(0)),
+    v_id(solution.getComponentDescriptorIndex(1)),
+    v_rhs_id(residual.getComponentDescriptorIndex(1));
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (solution.getPatchHierarchy() != d_hierarchy
+      || residual.getPatchHierarchy() != d_hierarchy)
+    {
+      TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
+                 "internal hierarchy.");
+    }
+#endif
+  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
+
+  /* Only need to sync the rhs once. This sync is needed because
+     calculating a new pressure update requires computing in the ghost
+     region so that the update for the velocity inside the box will be
+     correct. */
+  p_refine_patch_strategy.setTargetDataId(p_id);
+  v_refine_patch_strategy.setTargetDataId(v_id);
+  set_boundaries(p_id,v_id,level,true);
+  xeqScheduleGhostFillNoCoarse(p_rhs_id,v_rhs_id,ln);
+
+  if (ln > d_ln_min) {
+    /*
+     * Perform a one-time transfer of data from coarser level,
+     * to fill ghost boundaries that will not change through
+     * the smoothing loop.
+     */
+    xeqScheduleGhostFill(p_id, v_id, ln);
+  }
+
+  double theta_momentum=1.0;
+
+  /*
+   * Smooth the number of sweeps specified or until
+   * the convergence is satisfactory.
+   */
+  double maxres;
+  /*
+   * Instead of checking residual convergence globally, we check the
+   * converged flag.  This avoids possible round-off errors affecting
+   * different processes differently, leading to disagreement on
+   * whether to continue smoothing.
+   */
+  const hier::Index ip(1,0), jp(0,1);
+  bool converged = false;
+  for (int sweep=0; sweep < num_sweeps*(1<<(d_ln_max-ln)) && !converged;
+       ++sweep)
+    {
+      maxres=0;
+
+      /* vx sweep */
+      xeqScheduleGhostFillNoCoarse(p_id,invalid_id,ln);
+      for(int rb=0;rb<2;++rb)
+        {
+          xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
+          for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
+            {
+              tbox::Pointer<hier::Patch> patch = *pi;
+
+              tbox::Pointer<pdat::CellData<double> > p_ptr =
+                patch->getPatchData(p_id);
+              pdat::CellData<double> &p(*p_ptr);
+                
+              tbox::Pointer<pdat::SideData<double> > v_ptr =
+                patch->getPatchData(v_id);
+              pdat::SideData<double> &v(*v_ptr);
+              tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
+                patch->getPatchData(v_rhs_id);
+              pdat::SideData<double> &v_rhs(*v_rhs_ptr);
+                
+              tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
+                = patch->getPatchData(cell_moduli_id);
+              pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
+              tbox::Pointer<pdat::NodeData<double> > edge_visc_ptr
+                = patch->getPatchData(edge_moduli_id);
+              pdat::NodeData<double> &edge_moduli(*edge_visc_ptr);
+
+              hier::Box pbox=patch->getBox();
+              tbox::Pointer<geom::CartesianPatchGeometry>
+                geom = patch->getPatchGeometry();
+              double dx = geom->getDx()[0];
+              double dy = geom->getDx()[1];
+
+              for(int j=pbox.lower(1); j<=pbox.upper(1); ++j)
+                {
+                  /* Do the red-black skip */
+                  int i_min=pbox.lower(0) + (abs(pbox.lower(0) + j + rb))%2;
+                  for(int i=i_min; i<=pbox.upper(0)+1; i+=2)
+                    {
+                      pdat::CellIndex center(tbox::Dimension(2));
+                      center[0]=i;
+                      center[1]=j;
+
+                      /* Update v */
+                      smooth_V_2D(0,pbox,geom,center,ip,jp,
+                                  v,v_rhs,maxres,dx,dy,cell_moduli,
+                                  edge_moduli,theta_momentum);
+                    }
+                }
+            }
+          set_boundaries(invalid_id,v_id,level,true);
+        }
+
+
+      /* vy sweep */
+
+      for(int rb=0;rb<2;++rb)
+        {
+          xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
+          for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
+            {
+              tbox::Pointer<hier::Patch> patch = *pi;
+
+              tbox::Pointer<pdat::CellData<double> > p_ptr =
+                patch->getPatchData(p_id);
+              pdat::CellData<double> &p(*p_ptr);
+                
+              tbox::Pointer<pdat::SideData<double> > v_ptr =
+                patch->getPatchData(v_id);
+              pdat::SideData<double> &v(*v_ptr);
+              tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
+                patch->getPatchData(v_rhs_id);
+              pdat::SideData<double> &v_rhs(*v_rhs_ptr);
+                
+              tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
+                = patch->getPatchData(cell_moduli_id);
+              pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
+              tbox::Pointer<pdat::NodeData<double> > edge_visc_ptr
+                = patch->getPatchData(edge_moduli_id);
+              pdat::NodeData<double> &edge_moduli(*edge_visc_ptr);
+
+              hier::Box pbox=patch->getBox();
+              tbox::Pointer<geom::CartesianPatchGeometry>
+                geom = patch->getPatchGeometry();
+              double dx = geom->getDx()[0];
+              double dy = geom->getDx()[1];
+
+              for(int j=pbox.lower(1); j<=pbox.upper(1)+1; ++j)
+                {
+                  /* Do the red-black skip */
+                  int i_min=pbox.lower(0) + (abs(pbox.lower(0) + j + rb))%2;
+                  for(int i=i_min; i<=pbox.upper(0); i+=2)
+                    {
+                      pdat::CellIndex center(tbox::Dimension(2));
+                      center[0]=i;
+                      center[1]=j;
+
+                      /* Update v */
+                      smooth_V_2D(1,pbox,geom,center,jp,ip,
+                                  v,v_rhs,maxres,dy,dx,cell_moduli,
+                                  edge_moduli,theta_momentum);
+                    }
+                }
+            }
+          set_boundaries(invalid_id,v_id,level,true);
+        }
+
+      // if (residual_tolerance >= 0.0) {
+        /*
+         * Check for early end of sweeps due to convergence
+         * only if it is numerically possible (user gave a
+         * non negative value for residual tolerance).
+         */
+        converged = maxres < residual_tolerance;
+        const tbox::SAMRAI_MPI&
+          mpi(d_hierarchy->getDomainMappedBoxLevel().getMPI());
+        int tmp= converged ? 1 : 0;
+        if (mpi.getSize() > 1)
+          {
+            mpi.AllReduce(&tmp, 1, MPI_MIN);
+          }
+        converged=(tmp==1);
+        // if (d_enable_logging)
+        //   tbox::plog
+        //     // << d_object_name << "\n"
+        //     << "Tackley  " << ln << " " << sweep << " : " << maxres << "\n";
+      // }
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/smooth_Tackley_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/smooth_Tackley_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,148 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+#include "Elastic/dRc_dp.h"
+/*
+********************************************************************
+* Workhorse function to smooth error using red-black               *
+* Gauss-Seidel iterations.                                         *
+********************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACOps::smooth_Tackley_3D
+(SAMRAIVectorReal<double>& solution,
+ const SAMRAIVectorReal<double>& residual,
+ int ln,
+ int num_sweeps,
+ double residual_tolerance)
+{
+  const int p_id(solution.getComponentDescriptorIndex(0)),
+    p_rhs_id(residual.getComponentDescriptorIndex(0)),
+    v_id(solution.getComponentDescriptorIndex(1)),
+    v_rhs_id(residual.getComponentDescriptorIndex(1));
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (solution.getPatchHierarchy() != d_hierarchy
+      || residual.getPatchHierarchy() != d_hierarchy)
+    {
+      TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
+                 "internal hierarchy.");
+    }
+#endif
+  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
+
+  /* Only need to sync the rhs once. This sync is needed because
+     calculating a new pressure update requires computing in the ghost
+     region so that the update for the velocity inside the box will be
+     correct. */
+  p_refine_patch_strategy.setTargetDataId(p_id);
+  v_refine_patch_strategy.setTargetDataId(v_id);
+  set_boundaries(p_id,v_id,level,true);
+  xeqScheduleGhostFillNoCoarse(p_rhs_id,v_rhs_id,ln);
+
+  if (ln > d_ln_min) {
+    /*
+     * Perform a one-time transfer of data from coarser level,
+     * to fill ghost boundaries that will not change through
+     * the smoothing loop.
+     */
+    xeqScheduleGhostFill(p_id, v_id, ln);
+  }
+
+  double theta_momentum=1.0;
+
+  /*
+   * Smooth the number of sweeps specified or until
+   * the convergence is satisfactory.
+   */
+  double maxres;
+  /*
+   * Instead of checking residual convergence globally, we check the
+   * converged flag.  This avoids possible round-off errors affecting
+   * different processes differently, leading to disagreement on
+   * whether to continue smoothing.
+   */
+  const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
+  const hier::Index pp[]={ip,jp,kp};
+  bool converged = false;
+  for (int sweep=0; sweep < num_sweeps*(1<<(2*(d_ln_max-ln))) && !converged;
+       ++sweep)
+    {
+      maxres=0;
+
+      /* v sweeps */
+      xeqScheduleGhostFillNoCoarse(p_id,invalid_id,ln);
+
+      for(int ix=0;ix<3;++ix)
+        for(int rb=0;rb<2;++rb)
+          {
+            xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
+            for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
+              {
+                tbox::Pointer<hier::Patch> patch = *pi;
+
+                tbox::Pointer<pdat::CellData<double> > p_ptr =
+                  patch->getPatchData(p_id);
+                pdat::CellData<double> &p(*p_ptr);
+                
+                tbox::Pointer<pdat::SideData<double> > v_ptr =
+                  patch->getPatchData(v_id);
+                pdat::SideData<double> &v(*v_ptr);
+                tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
+                  patch->getPatchData(v_rhs_id);
+                pdat::SideData<double> &v_rhs(*v_rhs_ptr);
+                
+                tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
+                  = patch->getPatchData(cell_moduli_id);
+                pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
+                tbox::Pointer<pdat::EdgeData<double> > edge_visc_ptr
+                  = patch->getPatchData(edge_moduli_id);
+                pdat::EdgeData<double> &edge_moduli(*edge_visc_ptr);
+
+                hier::Box pbox=patch->getBox();
+                tbox::Pointer<geom::CartesianPatchGeometry>
+                  geom = patch->getPatchGeometry();
+                const double *Dx = geom->getDx();
+
+                for(int k=pbox.lower(2); k<=pbox.upper(2)+pp[ix][2]; ++k)
+                  for(int j=pbox.lower(1); j<=pbox.upper(1)+pp[ix][1]; ++j)
+                    {
+                      /* Do the red-black skip */
+                      int i_min=pbox.lower(0)
+                        + (abs(pbox.lower(0) + j + k + rb))%2;
+                      for(int i=i_min; i<=pbox.upper(0)+pp[ix][0]; i+=2)
+                        {
+                          pdat::CellIndex center(hier::Index(i,j,k));
+
+                          /* Update v */
+                          smooth_V_3D(ix,pbox,geom,v,v_rhs,cell_moduli,
+                                      edge_moduli,center,
+                                      Dx,theta_momentum,pp,maxres);
+                        }
+                    }
+              }
+            set_boundaries(invalid_id,v_id,level,true);
+          }
+
+      // if (residual_tolerance >= 0.0) {
+        /*
+         * Check for early end of sweeps due to convergence
+         * only if it is numerically possible (user gave a
+         * non negative value for residual tolerance).
+         */
+        converged = maxres < residual_tolerance;
+        const tbox::SAMRAI_MPI&
+          mpi(d_hierarchy->getDomainMappedBoxLevel().getMPI());
+        int tmp= converged ? 1 : 0;
+        if (mpi.getSize() > 1)
+          {
+            mpi.AllReduce(&tmp, 1, MPI_MIN);
+          }
+        converged=(tmp==1);
+        // if (d_enable_logging)
+        //   tbox::plog
+        //     // << d_object_name << "\n"
+        //     << "Tackley  " << ln << " " << sweep << " : " << maxres << "\n";
+      // }
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/smooth_V_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/smooth_V_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,79 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+#include "Elastic/dRm_dv.h"
+/*
+********************************************************************
+* Updates one component of the velocity during a red-black *
+* Gauss-Seidel iteration.  *
+********************************************************************
+*/
+void SAMRAI::solv::Elastic::FACOps::smooth_V_2D
+(const int &axis,
+ const hier::Box &pbox,
+ tbox::Pointer<geom::CartesianPatchGeometry> &geom,
+ const pdat::CellIndex &center,
+ const hier::Index &ip,
+ const hier::Index &jp,
+ pdat::SideData<double> &v,
+ pdat::SideData<double> &v_rhs,
+ double &maxres,
+ const double &dx,
+ const double &dy,
+ pdat::CellData<double> &cell_moduli,
+ pdat::NodeData<double> &edge_moduli,
+ const double &theta_momentum)
+{
+  const int off_axis=(axis==0) ? 1 : 0;
+
+  const pdat::SideIndex x(center,axis,pdat::SideIndex::Lower),
+    y(center,off_axis,pdat::SideIndex::Lower);
+  const pdat::NodeIndex edge(center,pdat::NodeIndex::LowerLeft);
+    
+  /* If at a Dirichlet 'x' boundary, leave vx as is */
+  if(!((center[axis]==pbox.lower(axis) && v(x-ip)==boundary_value)
+       || (center[axis]==pbox.upper(axis)+1 && v(x+ip)==boundary_value)))
+    {
+      /* If at the boundary, set things up so that the derivative does
+         not change. */
+      hier::Index offset(0,0);
+      offset[axis]=2;
+      bool set_lower_boundary(false), set_upper_boundary(false);
+      double dv_lower(0), dv_upper(0);
+      if(center[axis]==pbox.lower(axis)+1
+         && !geom->getTouchesRegularBoundary(axis,0))
+        {
+          set_lower_boundary=true;
+          dv_lower=v(x-offset) - v(x);
+        }
+      if(center[axis]==pbox.upper(axis)
+         && !geom->getTouchesRegularBoundary(axis,1))
+        {
+          set_upper_boundary=true;
+          dv_upper=v(x+offset) - v(x);
+        }
+
+      double C_vx=dRm_dv_2D(cell_moduli,edge_moduli,center,center-ip,
+                            edge+jp,edge,dx,dy);
+
+      double delta_Rx=v_rhs(x)
+        - v_operator_2D(v,cell_moduli,edge_moduli,center,
+                        edge,x,y,ip,jp,dx,dy);
+
+      /* No scaling here, though there should be. */
+      maxres=std::max(maxres,std::fabs(delta_Rx));
+
+      v(x)+=delta_Rx*theta_momentum/C_vx;
+
+      /* Set the boundary elements so that the derivative is
+         unchanged. */
+      if(set_lower_boundary)
+        {
+          v(x-offset)=v(x) + dv_lower;
+        }
+      if(set_upper_boundary)
+        {
+          v(x+offset)=v(x) + dv_upper;
+        }
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/smooth_V_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/smooth_V_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,78 @@
+#include "Elastic/FACOps.h"
+#include "Constants.h"
+#include "Elastic/dRc_dp.h"
+/*
+********************************************************************
+* Updates one component of the velocity during a red-black *
+* Gauss-Seidel iteration.  *
+********************************************************************
+*/
+void SAMRAI::solv::Elastic::FACOps::smooth_V_3D
+(const int &ix,
+ const hier::Box &pbox,
+ tbox::Pointer<geom::CartesianPatchGeometry> &geom,
+ pdat::SideData<double> &v,
+ pdat::SideData<double> &v_rhs,
+ pdat::CellData<double> &cell_moduli,
+ pdat::EdgeData<double> &edge_moduli,
+ const pdat::CellIndex &center,
+ const double Dx[3],
+ const double &theta_momentum,
+ const hier::Index pp[3],
+ double &maxres)
+{
+  const int iy((ix+1)%3), iz((ix+2)%3);
+  const pdat::SideIndex x(center,ix,pdat::SideIndex::Lower),
+    y(center,iy,pdat::SideIndex::Lower),
+    z(center,iz,pdat::SideIndex::Lower);
+  const pdat::EdgeIndex edge_y(center,iy,pdat::EdgeIndex::LowerLeft),
+    edge_z(center,iz,pdat::EdgeIndex::LowerLeft);
+    
+  /* If at a Dirichlet 'x' boundary, leave vx as is */
+  if(!((center[ix]==pbox.lower(ix) && v(x-pp[ix])==boundary_value)
+       || (center[ix]==pbox.upper(ix)+1 && v(x+pp[ix])==boundary_value)))
+    {
+      /* If at the boundary, set things up so that the derivative does
+         not change. */
+      hier::Index offset(0,0,0);
+      offset[ix]=2;
+      bool set_lower_boundary(false), set_upper_boundary(false);
+      double dv_lower(0), dv_upper(0);
+      if(center[ix]==pbox.lower(ix)+1
+         && !geom->getTouchesRegularBoundary(ix,0))
+        {
+          set_lower_boundary=true;
+          dv_lower=v(x-offset) - v(x);
+        }
+      if(center[ix]==pbox.upper(ix) && !geom->getTouchesRegularBoundary(ix,1))
+        {
+          set_upper_boundary=true;
+          dv_upper=v(x+offset) - v(x);
+        }
+
+      double C_vx=dRm_dv_3D(cell_moduli,edge_moduli,center,center-pp[ix],
+                            edge_y+pp[iz],edge_y,edge_z+pp[iy],edge_z,
+                            Dx[ix],Dx[iy],Dx[iz]);
+
+      double delta_Rx=v_rhs(x)
+        - v_operator_3D(v,cell_moduli,edge_moduli,center,edge_y,edge_z,
+                        x,y,z,pp[ix],pp[iy],pp[iz],Dx[ix],Dx[iy],Dx[iz]);
+
+      /* No scaling here, though there should be. */
+      maxres=std::max(maxres,std::fabs(delta_Rx));
+
+      v(x)+=delta_Rx*theta_momentum/C_vx;
+
+      /* Set the boundary elements so that the derivative is
+         unchanged. */
+      if(set_lower_boundary)
+        {
+          v(x-offset)=v(x) + dv_lower;
+        }
+      if(set_upper_boundary)
+        {
+          v(x+offset)=v(x) + dv_upper;
+        }
+    }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/solveCoarsestLevel.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/solveCoarsestLevel.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+/*
+********************************************************************
+* FACOperatorStrategy virtual solveCoarsestLevel             *
+* function                                                         *
+********************************************************************
+*/
+
+int SAMRAI::solv::Elastic::FACOps::solveCoarsestLevel
+(SAMRAIVectorReal<double>& data,
+ const SAMRAIVectorReal<double>& residual,
+ int coarsest_ln)
+{
+  t_solve_coarsest->start();
+
+  int return_value = 0;
+
+  if (d_coarse_solver_choice == "Tackley"
+      || d_coarse_solver_choice == "Gerya") {
+    d_residual_tolerance_during_smoothing = d_coarse_solver_tolerance;
+    smoothError(data,
+                residual,
+                coarsest_ln,
+                d_coarse_solver_max_iterations);
+    d_residual_tolerance_during_smoothing = -1.0;
+  } else if (d_coarse_solver_choice == "hypre") {
+#ifndef HAVE_HYPRE
+    TBOX_ERROR(d_object_name << ": Coarse level solver choice '"
+               << d_coarse_solver_choice
+               << "' unavailable in "
+               << "Elastic::FACOps::solveCoarsestLevel.");
+#else
+    return_value = solveCoarsestLevel_HYPRE(data, residual, coarsest_ln);
+#endif
+  } else {
+    TBOX_ERROR(
+               d_object_name << ": Bad coarse level solver choice '"
+               << d_coarse_solver_choice
+               <<
+               "' in Elastic::FACOps::solveCoarsestLevel.");
+  }
+
+  xeqScheduleGhostFillNoCoarse(data.getComponentDescriptorIndex(0),
+                               data.getComponentDescriptorIndex(1),
+                               coarsest_ln);
+  t_solve_coarsest->stop();
+
+  return return_value;
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/solveCoarsestLevel_HYPRE.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/solveCoarsestLevel_HYPRE.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+#include IOMANIP_HEADER_FILE
+
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/hier/Variable.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/PatchData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/HypreSolver.h"
+#include "SAMRAI/tbox/Array.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/xfer/CoarsenAlgorithm.h"
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/xfer/CoarsenSchedule.h"
+#include "SAMRAI/xfer/RefineAlgorithm.h"
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/xfer/RefineSchedule.h"
+#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
+
+namespace SAMRAI {
+  namespace solv {
+
+#ifdef HAVE_HYPRE
+    /*
+********************************************************************
+* Solve coarsest level using Hypre                                 *
+* We only solve for the error, so we always use homogeneous bc.    *
+********************************************************************
+*/
+
+    int Elastic::FACOps::solveCoarsestLevel_HYPRE(
+                                               SAMRAIVectorReal<double>& data,
+                                               const SAMRAIVectorReal<double>& residual,
+                                               int coarsest_ln) {
+
+      NULL_USE(coarsest_ln);
+
+#ifndef HAVE_HYPRE
+      TBOX_ERROR(d_object_name << ": Coarse level solver choice '"
+                 << d_coarse_solver_choice
+                 << "' unavailable in "
+                 << "Elastic::FACOps::solveCoarsestLevel.");
+
+      return 0;
+
+#else
+
+      d_hypre_solver.setStoppingCriteria(d_coarse_solver_max_iterations,
+                                         d_coarse_solver_tolerance);
+      const int solver_ret =
+        d_hypre_solver.solveSystem(
+                                   data.getComponentDescriptorIndex(0),
+                                   residual.getComponentDescriptorIndex(0),
+                                   true);
+      /*
+       * Present data on the solve.
+       * The Hypre solver returns 0 if converged.
+       */
+      if (d_enable_logging) tbox::plog
+                              << d_object_name << " Hypre solve " << (solver_ret ? "" : "NOT ")
+                              << "converged\n"
+                              << "\titerations: " << d_hypre_solver.getNumberOfIterations() << "\n"
+                              << "\tresidual: " << d_hypre_solver.getRelativeResidualNorm() << "\n";
+
+      return !solver_ret;
+
+#endif
+
+    }
+#endif
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/xeqScheduleGhostFill.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/xeqScheduleGhostFill.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::xeqScheduleGhostFill(int p_id, int v_id,
+                                                      int dest_ln)
+{
+  /* p */
+  {
+    if (!p_ghostfill_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(p_id,p_id,p_id,p_ghostfill_refine_operator);
+    refiner.resetSchedule(p_ghostfill_refine_schedules[dest_ln]);
+    p_ghostfill_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+
+  /* v */
+  {
+    if (!v_ghostfill_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+    set_boundaries(invalid_id,v_id,dest_ln-1);
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(v_id,v_id,v_id,v_ghostfill_refine_operator);
+    refiner.resetSchedule(v_ghostfill_refine_schedules[dest_ln]);
+    v_ghostfill_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/xeqScheduleGhostFillNoCoarse.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/xeqScheduleGhostFillNoCoarse.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::xeqScheduleGhostFillNoCoarse(int p_id,
+                                                              int v_id,
+                                                              int dest_ln)
+{
+  /* p */
+  if(p_id!=invalid_id)
+  {
+    if (!p_nocoarse_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected cell schedule not found.");
+    }
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(p_id,p_id,p_id,tbox::Pointer<xfer::RefineOperator>(0));
+    refiner.resetSchedule(p_nocoarse_refine_schedules[dest_ln]);
+    p_nocoarse_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+
+  /* v */
+  if(v_id!=invalid_id)
+  {
+    if (!v_nocoarse_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected side schedule not found.");
+    }
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(v_id,v_id,v_id,tbox::Pointer<xfer::RefineOperator>(0));
+    refiner.resetSchedule(v_nocoarse_refine_schedules[dest_ln]);
+    v_nocoarse_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/xeqScheduleProlongation.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/xeqScheduleProlongation.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::xeqScheduleProlongation
+(int p_dst, int p_src, int p_scr, int v_dst, int v_src, int v_scr,
+ int dest_ln)
+{
+  /* p */
+  {
+    if (!p_prolongation_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(p_dst, p_src, p_scr, p_prolongation_refine_operator);
+    refiner.resetSchedule(p_prolongation_refine_schedules[dest_ln]);
+    p_prolongation_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+
+  /* v */
+  {
+    if (!v_prolongation_refine_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+    xfer::RefineAlgorithm refiner(d_dim);
+    refiner.registerRefine(v_dst, v_src, v_scr, v_prolongation_refine_operator);
+    refiner.resetSchedule(v_prolongation_refine_schedules[dest_ln]);
+    v_prolongation_refine_schedules[dest_ln]->fillData(0.0,false);
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/xeqScheduleRRestriction.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/xeqScheduleRRestriction.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::xeqScheduleRRestriction(int p_dst, int p_src,
+                                                         int v_dst, int v_src,
+                                                         int dest_ln)
+{
+  /* p */
+  {
+    if (!p_rrestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+
+    xfer::CoarsenAlgorithm coarsener(d_dim);
+    coarsener.registerCoarsen(p_dst,p_src,p_rrestriction_coarsen_operator);
+    coarsener.resetSchedule(p_rrestriction_coarsen_schedules[dest_ln]);
+    p_rrestriction_coarsen_schedules[dest_ln]->coarsenData();
+  }
+
+  /* v */
+  {
+    if (!v_rrestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+
+    xfer::CoarsenAlgorithm coarsener(d_dim);
+    coarsener.registerCoarsen(v_dst,v_src,v_rrestriction_coarsen_operator);
+    coarsener.resetSchedule(v_rrestriction_coarsen_schedules[dest_ln]);
+    v_rrestriction_coarsen_schedules[dest_ln]->coarsenData();
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACOps/xeqScheduleURestriction.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACOps/xeqScheduleURestriction.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Operator class for cell-centered scalar Elastic using FAC 
+ *
+ ************************************************************************/
+#include "Elastic/FACOps.h"
+
+void SAMRAI::solv::Elastic::FACOps::xeqScheduleURestriction(int p_dst, int p_src,
+                                                         int v_dst, int v_src,
+                                                         int dest_ln)
+{
+  /* p */
+  {
+    if (!p_urestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+
+    xfer::CoarsenAlgorithm coarsener(d_dim);
+    coarsener.registerCoarsen(p_dst, p_src, p_urestriction_coarsen_operator);
+    coarsener.resetSchedule(p_urestriction_coarsen_schedules[dest_ln]);
+    p_urestriction_coarsen_schedules[dest_ln]->coarsenData();
+  }
+
+  /* v */
+  {
+    if (!v_urestriction_coarsen_schedules[dest_ln]) {
+      TBOX_ERROR("Expected schedule not found.");
+    }
+
+    xfer::CoarsenAlgorithm coarsener(d_dim);
+    coarsener.registerCoarsen(v_dst, v_src, v_urestriction_coarsen_operator);
+    coarsener.resetSchedule(v_urestriction_coarsen_schedules[dest_ln]);
+    v_urestriction_coarsen_schedules[dest_ln]->coarsenData();
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver.I
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver.I	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar elastic equation. 
+ *
+ ************************************************************************/
+namespace SAMRAI {
+namespace solv {
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::set_P_ProlongationMethod(
+   const std::string& p_prolongation_method)
+{
+   d_fac_ops.set_P_ProlongationMethod(p_prolongation_method);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::set_V_ProlongationMethod(
+   const std::string& v_prolongation_method)
+{
+   d_fac_ops.set_V_ProlongationMethod(v_prolongation_method);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setCoarsestLevelSolverChoice(
+   const std::string& choice)
+{
+   d_fac_ops.setCoarsestLevelSolverChoice(choice);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setCoarsestLevelSolverTolerance(
+   double tol)
+{
+   d_fac_ops.setCoarsestLevelSolverTolerance(tol);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setCoarsestLevelSolverMaxIterations(
+   int max_iterations)
+{
+   d_fac_ops.setCoarsestLevelSolverMaxIterations(max_iterations);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setCoarseFineDiscretization(
+   const std::string& coarsefine_method)
+{
+   d_fac_ops.setCoarseFineDiscretization(coarsefine_method);
+}
+
+#ifdef HAVE_HYPRE
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setUseSMG(
+   bool use_smg)
+{
+   if (d_solver_is_initialized) {
+      TBOX_ERROR(
+         d_object_name << ": setUseSMG(bool) may NOT be called\n"
+         <<
+         "while the solver state is initialized, as that\n"
+         << "would lead to a corrupted solver state.\n");
+   }
+   d_fac_ops.setUseSMG(use_smg);
+}
+#endif
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setPresmoothingSweeps(
+   int num_pre_sweeps) {
+   d_fac_precond.setPresmoothingSweeps(num_pre_sweeps);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setPostsmoothingSweeps(
+   int num_post_sweeps) {
+   d_fac_precond.setPostsmoothingSweeps(num_post_sweeps);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setMaxCycles(
+   int max_cycles) {
+   d_fac_precond.setMaxCycles(max_cycles);
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::setResidualTolerance(
+   double residual_tol) {
+   d_fac_precond.setResidualTolerance(residual_tol);
+}
+
+SAMRAI_INLINE_KEYWORD
+int Elastic::FACSolver::getNumberOfIterations() const
+{
+   return d_fac_precond.getNumberOfIterations();
+}
+
+SAMRAI_INLINE_KEYWORD
+double Elastic::FACSolver::getResidualNorm() const
+{
+   return d_fac_precond.getResidualNorm();
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::FACSolver::getConvergenceFactors(
+   double& avg_factor,
+   double& final_factor)
+const
+{
+   d_fac_precond.getConvergenceFactors(avg_factor, final_factor);
+}
+
+}
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,674 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#ifndef included_solv_ElasticFACSolver
+#define included_solv_ElasticFACSolver
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/solv/FACPreconditioner.h"
+#include "Elastic/FACOps.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/tbox/Database.h"
+#include "SAMRAI/tbox/Pointer.h"
+
+namespace SAMRAI {
+namespace solv {
+namespace Elastic {
+/*!
+ * @brief Class for solving scalar Elastic's equation on SAMR grid,
+ * wrapping up lower-level components (FAC cycling, Elastic equation
+ * operations and boundary conditions) in a single high-level interface.
+ *
+ * Note: this class provides a backward-compatible interface to
+ * the soon-to-be obsolete Elastic::HierarchySolver<DIM> class.
+ * Although this class hides the lower-level components (FAC cycling,
+ * Elastic equation operations and boundary conditions), it is
+ * perfectly acceptable to use those lower-level components directly.
+ *
+ * We solve the equation
+ *    div(D grad(u)) + Cu = f
+ * where D is a side-centered array and C is a cell-centered array.
+ * u and f are also cell-centered.
+ * Boundary conditions supported are Dirichlet, Neumann and mixed
+ * (Dirichlet on some faces and Neumann on others).
+ *
+ * This class is a wrapper, providing a single class that coordinates
+ * three major components: the FAC solver, the cell-centered Elastic
+ * FAC operator and a default Robin bc coefficient implelemtation.
+ * It is perfectly acceptable to use those classes outside of this
+ * class.
+ *
+ * The underlying solver is an FAC solver using cell-centered
+ * discretization.  The difference scheme is second-order
+ * central-difference.  On coarse-fine boundaries within the
+ * solution levels, the composite grid operator uses, by default,
+ * the discretization method of Ewing, Lazarov and Vassilevski
+ * ("Local Refinement Techniques for Elliptic Problems on
+ * Cell-Centered Grids, I. Error Analysis", Mathematics of
+ * Computation, Vol. 56, No. 194, April 1991, pp. 437-461).
+ *
+ * Typical use of this class is:
+ * -# Construct a Elastic::FACSolver object, providing it
+ *    the hierarchy and range of levels participating in the solve.
+ * -# Set the parameters C and D using the functions named @c setC...
+ *    and @c setD...  By default, D=1 and C=0 everywhere.
+ * -# Call setBoundaries() to state the types boundary conditions,
+ *    along with supplemental data for setting those boundary
+ *    conditions.
+ * -# Call initializeSolverState() to set up information
+ *    internal to the solver.  This is step is not required
+ *    but will save setup costs if you are making multiple
+ *    solves.  This commits the object to the current hierarchy state
+ *    and the specific @em types of boundary conditions you selected,
+ *    It does NOT commit to the specific @em values of the boundary
+ *    condition.  A hierarchy change (through adaption or other means)
+ *    invalidates the state, thus you must reinitialize or
+ *    deallocateSolverState() the state before another solve.
+ * -# Solve the equation with solveSystem().  You provide the
+ *    patch data indices for the solution u and the right hand
+ *    side f.  u must have at least one ghost cell and where
+ *    a Dirichlet boundary condition applies, those cells
+ *    must be set to the value on the boundary.  If only Neumann
+ *    boundary conditions are used, the ghost cell values
+ *    do not matter.
+ * -# Call deallocateSolverState() to free up internal resources,
+ *    if initializeSolverState() was called before the solve.
+ *
+ * After the solve, information on the solve can be obtained
+ * by calling one of these functions:
+ * - getNumberOfIterations() gives the number of FAC cycles used.
+ * - getConvergenceFactors() gives the average and final convergence
+ *   factors for the solve.
+ * - getResidualNorm() gives the final residual
+ *
+ * Finer solver controls can be set using the functions in this class.
+ *
+ * Object of this class can be set using input databases.
+ * The following parameters can be set.  Each is shown with its
+ * default value in the case where hypre is used.
+ * @verbatim
+ * enable_logging = TRUE // Bool flag to switch logging on/off
+ * max_cycles = 10       // Integer number of max FAC cycles to use
+ * residual_tol = 1.e-6  // Residual tolerance to solve for
+ * num_pre_sweeps = 1    // Number of presmoothing sweeps to use
+ * num_post_sweeps = 1   // Number of postsmoothing sweeps to use
+ * coarse_fine_discretization = "Ewing" // Name of coarse-fine discretization
+ * prolongation_method = "CONSTANT_REFINE" // Name of prolongation method
+ * coarse_solver_choice = "hypre"  // Name of coarse level solver
+ * coarse_solver_tolerance = 1e-10 // Coarse level tolerance
+ * coarse_solver_max_iterations = 20 // Coarse level max iterations
+ * use_smg = "FALSE"     // Whether to use hypre's smg solver
+ *                       // (alternative is the pfmg solver)
+ * @endverbatim
+ *
+ */
+  class FACSolver
+{
+
+public:
+   /*!
+    * @brief Construct a solver.
+    *
+    * If the database is not NULL, initial settings will be set
+    * using the database.
+    * The solver is uninitialized until initializeSolverState()
+    * is called.
+    *
+    * @param object_name Name of object used in outputs
+    * @param database tbox::Database for initialization (may be NULL)
+    */
+   FACSolver(
+      const tbox::Dimension& dim,
+      const std::string& object_name,
+      tbox::Pointer<tbox::Database> database =
+         tbox::Pointer<tbox::Database>());
+
+   /*!
+    * @brief Destructor.
+    */
+   ~FACSolver(
+      void);
+
+   /*!
+    * @brief Enable logging.
+    *
+    * To disable, pass in @c false.
+    */
+   void
+   enableLogging(
+      bool logging);
+
+   /*!
+    * @brief Solve Elastic's equation, assuming an uninitialized
+    * solver state.
+    *
+    * Here, u is the "solution" patch data index and f is the
+    * right hand side patch data index.
+    * The return value is true if the solver converged and false otherwise.
+    *
+    * This function is a wrapper.
+    * It simply initializes the solver state, call the
+    * solveSystem(const int,const int) for the initialized solver then
+    * deallocates the solver state.
+    *
+    * Upon return from this function,
+    * solution will contain the result of the solve.
+    *
+    * See initializeSolverState() for opportunities to save overhead
+    * when using multiple consecutive solves.
+    *
+    * @see solveSystem(const int,const int)
+    *
+    * @param solution hier::Patch data index for solution u
+    * @param rhs hier::Patch data index for right hand side f
+    * @param hierarchy The patch hierarchy to solve on
+    * @param coarse_ln The coarsest level in the solve.
+    * @param fine_ln The finest level in the solve.
+    *
+    * @return whether solver converged to specified level
+    *
+    * @see initializeSolverState
+    */
+   bool
+   solveSystem(
+      const int p,
+      const int cell_moduli,
+      const int edge_moduli,
+      const int dp,
+      const int p_rhs,
+      const int v,
+      const int v_rhs,
+      tbox::Pointer<hier::PatchHierarchy> hierarchy,
+      int coarse_ln = -1,
+      int fine_ln = -1);
+
+   /*!
+    * @brief Solve Elastic's equation using the current solver state
+    * set by initializeSolverState().
+    *
+    * When the solver state has been initialized, this function may
+    * be called repeadedly with different values on the rhs.
+    * There is some cost savings for multiple solves when this
+    * is done.
+    *
+    * Before calling this function, the solution and
+    * right-hand-side quantities should be set properly by the user
+    * on all patch interiors on the range of levels covered by the
+    * FAC iteration.  All data for these patch data index should be allocated.
+    * Thus, the user is responsible for managing the
+    * storage for the solution and right-hand-side.
+    *
+    * @return whether solver converged to specified level
+    *
+    * @see solveSystem( const int, const int, tbox::Pointer< hier::PatchHierarchy >, int, int);
+    */
+   bool
+   solveSystem(const int p, const int p_rhs,
+               const int v, const int v_rhs);
+
+   /*!
+    * @brief Specify the boundary conditions that are to be used at the
+    * physical domain boundary.
+    *
+    * This method is used to set up the default SimpleCellRobinBcCoefs
+    * object for specifying boundary conditions.  Note that you may
+    * alternatively provide your own implementation of the Robin
+    * boundary condition coefficients using the setBcObject() method.
+    *
+    * The boundary conditions specified as the
+    * std::string argument "boundary_type."  The boundary type argument can be
+    * "Dirichlet", "Neumann", or "Mixed".
+    *
+    * If using Dirichlet boundary conditions, then before the solver is
+    * called, the storage for the unknown u
+    * must have a mapped_box_level of ghost cells at least one cell wide that includes
+    * the Dirichlet boundary values.
+    *
+    * If using Neumann boundary conditions, then before the solver is called,
+    * the outerface boundary flux data must be set for the Neumann conditions.
+    * The fluxes argument gives the patch data index of this flux
+    * data.
+    *
+    * The mixed boundary type is for a mixture of Dirichlet and Neumann
+    * boundary conditions are used at the physical domain boundary.
+    * The fluxes argument gives the patch data index of the outerface data
+    * that specifies the flux data for the Neumann conditions.  The flags
+    * array is an outerface data array of integer flags that specifies whether
+    * Dirichlet (flag == zero) or Neumann (flag == one) conditions are to be
+    * used at a particular cell boundary face.  Note that the flag data must
+    * be set before the matrix entries can be computed and the flux data
+    * must be set before the solver is called.  The bdry_types argument can
+    * be used if the boundary conditions are mixed but one or more of the
+    * faces of the physical boundary are entirely either Dirichlet or
+    * Neumann boundaries.  The bdry_types argument should be an array of
+    * 2*DIM integers, specifying the boundary conditions on each side of
+    * the physical domain.  It should be ordered {x_lo, x_hi, y_lo, y_hi,
+    * z_lo, z_hi}, with the values for each face being 0 for Dirichlet
+    * conditions, 1 for Neumann conditions, and 2 for mixed boundary
+    * conditions.  The bdry_type argument is never required, but if used
+    * it can sometimes make the Elastic::HYPRESolver class more efficient.
+    */
+
+   void
+   setBoundaries(
+      const std::string& boundary_type,
+      const int fluxes = -1,
+      const int flags = -1,
+      int* bdry_types = NULL);
+
+   /*!
+    * @brief Override internal implementation to set boundary condition
+    * coefficients with user-provided implementation.
+    *
+    * This function is used to override the default internal
+    * object for setting Robin boundary condition coefficients.
+    * You should override when you need to avoid the limitations
+    * of the SimpleCellRobinBcCoefs class or you prefer to
+    * use your own implementation.
+    *
+    * Note that an important limitation of the SimpleCellRobinBcCoefs
+    * class is the inability to support linear interpolation in
+    * the prolongation step.
+    *
+    * Once the boundary condition object is overwritten by this
+    * method, you must no longer call the setBoundaries() method.
+    */
+   void
+   setBcObject(
+      const RobinBcCoefStrategy* bc_object);
+
+   //!@{ @name Specifying PDE parameters
+
+   /*!
+    * @brief Set the patch data index for variable D.
+    *
+    * In addition, disregard any previous D
+    * specified by setDConstant().
+    */
+   void
+   setDPatchDataId(
+      int id);
+
+   /*!
+    * @brief Set the scalar value variable D.
+    *
+    * In addition, disregard any previous D
+    * specified by setDPatchDataId().
+    */
+   void
+   setDConstant(
+      double scalar);
+
+   /*!
+    * @brief Set the scalar value variable C.
+    *
+    * In addition, disregard any previous C
+    * specified by setCConstant().
+    */
+   void
+   setCPatchDataId(
+      int id);
+
+   /*!
+    * @brief Set the patch data index for variable C.
+    *
+    * In addition, disregard any previous C
+    * specified by setCConstant().
+    */
+   void
+   setCConstant(
+      double scalar);
+
+   //@}
+
+   //@{ @name Functions for setting solver mathematic algorithm controls
+
+   /*!
+    * @brief Set coarse level solver.
+    *
+    * Select from these:
+    * - @c "Tackley"
+    * - @c "Gerya"
+    * - @c "hypre" (only if the HYPRE library is available).
+    */
+   void
+   setCoarsestLevelSolverChoice(
+      const std::string& choice);
+
+   /*!
+    * @brief Set tolerance for coarse level solve.
+    *
+    * If the coarse level solver requires a tolerance
+    * (currently, they all do), the specified value is used.
+    */
+   void
+   setCoarsestLevelSolverTolerance(
+      double tol);
+
+   /*!
+    * @brief Set max iterations for coarse level solve.
+    *
+    * If the coarse level solver requires a max iteration limit
+    * (currently, they all do), the specified value is used.
+    */
+   void
+   setCoarsestLevelSolverMaxIterations(
+      int max_iterations);
+
+#ifdef HAVE_HYPRE
+   /*!
+    * @brief Set whether to use HYPRe's PFMG algorithm instead of the
+    * SMG algorithm.
+    *
+    * The flag is used to select which of HYPRE's linear solver algorithms
+    * to use if true, the semicoarsening multigrid algorithm is used, and if
+    * false, the ``PF'' multigrid algorithm is used.
+    * By default, the SMG algorithm is used.
+    *
+    * This setting has effect only when HYPRe is chosen for the coarsest
+    * level solver.  See setCoarsestLevelSolverChoice().
+    *
+    * Changing the algorithm must be done before setting up the matrix
+    * coefficients.
+    */
+   void
+   setUseSMG(
+      bool use_smg);
+#endif
+
+   /*!
+    * @brief Set the coarse-fine boundary discretization method.
+    *
+    * Specify the @c op_name std::string which will be passed to
+    * xfer::Geometry::lookupRefineOperator() to get the operator
+    * for setting fine grid ghost cells from the coarse grid.
+    * Note that chosing this operator implicitly choses the
+    * discretization method at the coarse-fine boundary.
+    *
+    * There is one important instance where this std::string is
+    * @em not passed to xfer::Geometry::lookupRefineOperator().
+    * If this variable is set to "Ewing", a constant refinement
+    * method is used along with Ewing's correction.
+    * For a reference to the correction method, see
+    * "Local Refinement Techniques for Elliptic Problems on Cell-Centered
+    * Grids, I. Error Analysis", Mathematics of Computation, Vol. 56, No. 194,
+    * April 1991, pp. 437-461.
+    *
+    * @param coarsefine_method String selecting the coarse-fine discretization method.
+    */
+   void
+   setCoarseFineDiscretization(
+      const std::string& coarsefine_method);
+
+   /*!
+    * @brief Set the name of the prolongation method.
+    *
+    * Specify the @c op_name std::string which will be passed to
+    * xfer::Geometry::lookupRefineOperator() to get the operator
+    * for prolonging the coarse-grid correction.
+    *
+    * By default, "CONSTANT_REFINE" is used.  "LINEAR_REFINE" seems to
+    * to lead to faster convergence, but it does NOT satisfy the Galerkin
+    * condition.
+    *
+    * Prolonging using linear refinement requires a Robin bc
+    * coefficient implementation that is capable of delivering
+    * coefficients for non-hierarchy data, because linear refinement
+    * requires boundary conditions to be set on temporary levels.
+    *
+    * @param prolongation_method String selecting the coarse-fine discretization method.
+    */
+   void
+   set_P_ProlongationMethod(
+      const std::string& prolongation_method);
+
+   void
+   set_V_ProlongationMethod(
+      const std::string& prolongation_method);
+
+   /*!
+    * @brief Set the number of pre-smoothing sweeps during
+    * FAC iteration process.
+    *
+    * Presmoothing is applied during the fine-to-coarse phase of the
+    * iteration.  The default is to use one sweep.
+    *
+    * @param num_pre_sweeps Number of presmoothing sweeps
+    */
+   void
+   setPresmoothingSweeps(
+      int num_pre_sweeps);
+
+   /*!
+    * @brief Set the number of post-smoothing sweeps during
+    * FAC iteration process.
+    *
+    * Postsmoothing is applied during the coarse-to-fine phase of the
+    * iteration.  The default is to use one sweep.
+    *
+    * @param num_post_sweeps Number of postsmoothing sweeps
+    */
+   void
+   setPostsmoothingSweeps(
+      int num_post_sweeps);
+
+   /*!
+    * @brief Set the max number of iterations (cycles) to use per solve.
+    */
+   void
+   setMaxCycles(
+      int max_cycles);
+
+   /*!
+    * @brief Set the residual tolerance for stopping.
+    *
+    * If you want the prescribed maximum number of cycles to always be taken,
+    * set the residual tolerance to a negative number.
+    */
+   void
+   setResidualTolerance(
+      double residual_tol);
+
+   //@}
+
+   /*!
+    * @brief Prepare the solver's internal state for solving
+    *
+    * In the interest of efficiency, this class may prepare and
+    * cache some hierarchy-dependent objects.  Though it is not required,
+    * initializing the solver state makes for greater efficiency
+    * when you are doing multiple solves on the same system of
+    * equation.  If you do not initialize the state, it is initialized
+    * and deallocated each time you call solveSystem(const int, const int).
+    * The state must be reinitialized if the hierarchy or a boundary
+    * condition type changes.
+    *
+    * To unset the data set in this function,
+    * see deallocateSolverState().
+    *
+    * The @c solution and @c rhs patch data indices in the argument
+    * list are used to determine the @em form of the data you
+    * plan to use in the solve.  They need not be the same data
+    * you solve on, but they should be similar.  Both must represent
+    * cell-centered double data.  The solution must have at least one
+    * ghost cell width, though this is not checked in the initialize
+    * phase, because data is not required yet.
+    *
+    * @param solution solution patch data index for u
+    * @param rhs right hand side patch data index for f
+    * @param hierarchy The patch hierarchy to solve on
+    * @param coarse_level The coarsest level in the solve
+    * @param fine_level The finest level in the solve
+    */
+   void
+   initializeSolverState(const int p,
+                         const int cell_moduli,
+                         const int edge_moduli,
+                         const int dp,
+                         const int p_rhs,
+                         const int v,
+                         const int v_rhs,
+                         tbox::Pointer<hier::PatchHierarchy> hierarchy,
+                         const int coarse_level = -1,
+                         const int fine_level = -1);
+
+   /*!
+    * @brief Remove the solver's internal state data
+    *
+    * Remove all hierarchy-dependent data set by initializeSolverState.
+    * It is safe to call deallocateSolverState() even state is already
+    * deallocated, but nothing is done in that case.
+    *
+    * @see initializeSolverState()
+    */
+   void
+   deallocateSolverState();
+
+   //@{
+   //! @name Functions to get data on last solve.
+
+   /*!
+    * @brief Return FAC iteration count from last (or current
+    * if there is one) FAC iteration process.
+    */
+   int
+   getNumberOfIterations() const;
+
+   /*!
+    * @brief Get average convergance rate and convergence rate of
+    * the last (or current if there is one) FAC solve.
+    *
+    * @param avg_factor average convergence factor over current FAC cycles
+    * @param final_factor convergence factor of the last FAC cycle
+    */
+   void
+   getConvergenceFactors(
+      double& avg_factor,
+      double& final_factor) const;
+
+   /*!
+    * @brief Return residual norm from the just-completed FAC iteration.
+    *
+    * The norm return value is computed as the maximum norm over all
+    * patch levels involved in the solve.  The value corresponds to the
+    * norm applied in the user-defined residual computation.
+    *
+    * The latest computed norm is the one returned.
+    */
+   double
+   getResidualNorm() const;
+
+  void set_boundaries(const int &p_id, const int &v_id,
+                      tbox::Pointer<hier::PatchLevel> &level,
+                      const bool &homogeneous)
+  {
+    d_fac_ops.set_boundaries(p_id,v_id,level,homogeneous);
+  }
+
+
+   //@}
+
+private:
+   /*!
+    * @brief Set state using database
+    *
+    * See the class description for the parameters that can be set
+    * from a database.
+    *
+    * @param database Input database.  If a NULL pointer is given,
+    * nothing is done.
+    */
+   void
+   getFromInput(
+      tbox::Pointer<tbox::Database> database);
+
+   /*
+    * @brief Set @c d_uv and @c d_fv to vectors wrapping the data
+    * specified by patch data indices u and f.
+    */
+   void
+   createVectorWrappers(int p, int p_rhs, int v, int v_rhs);
+
+   /*
+    * @brief Destroy vector wrappers referenced to by @c d_uv and @c d_fv.
+    */
+   void
+   destroyVectorWrappers();
+
+   /*
+    * @brief Initialize static members
+    */
+   static void
+   initializeStatics();
+
+   const tbox::Dimension d_dim;
+
+   /*!
+    * @brief Object name.
+    */
+   std::string d_object_name;
+
+   /*!
+    * @brief FAC operator implementation corresponding to cell-centered
+    * Elastic discretization.
+    */
+  FACOps d_fac_ops;
+
+   /*!
+    * @brief FAC preconditioner algorithm.
+    */
+   FACPreconditioner d_fac_precond;
+
+   /*!
+    * @brief Robin bc object in use.
+    */
+   const RobinBcCoefStrategy* d_bc_object;
+
+   /*
+    * @brief Default implementation of RobinBcCoefStrategy
+    */
+   SimpleCellRobinBcCoefs d_simple_bc;
+
+   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
+   int d_ln_min;
+   int d_ln_max;
+
+   /*!
+    * @brief Context for all internally maintained data.
+    */
+   tbox::Pointer<hier::VariableContext> d_context;
+   /*
+    * @brief Vector wrapper for solution.
+    * @see createVectorWrappers(), destroyVectorWrappers()
+    */
+   tbox::Pointer<SAMRAIVectorReal<double> > d_uv;
+   /*
+    * @brief Vector wrapper for source.
+    * @see createVectorWrappers(), destroyVectorWrappers()
+    */
+   tbox::Pointer<SAMRAIVectorReal<double> > d_fv;
+
+   bool d_solver_is_initialized;
+   bool d_enable_logging;
+
+   static bool s_initialized;
+   static int s_weight_id[SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+   static int s_instance_counter[SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+};
+
+}
+}
+}
+
+#ifdef SAMRAI_INLINE
+#include "Elastic/FACSolver.I"
+#endif
+
+#endif  // included_solv_ElasticFACSolver
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/FACSolver.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/FACSolver.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar elastic equation. 
+ *
+ ************************************************************************/
+#ifndef included_solv_ElasticFACSolver_C
+#define included_solv_ElasticFACSolver_C
+
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+#ifndef SAMRAI_INLINE
+#include "Elastic/FACSolver.I"
+#endif
+
+namespace SAMRAI {
+  namespace solv {
+
+    /*
+*************************************************************************
+*                                                                       *
+* Initialize the static data members.                                   *
+*                                                                       *
+*************************************************************************
+*/
+
+    bool Elastic::FACSolver::s_initialized = 0;
+    int Elastic::FACSolver::s_weight_id[SAMRAI::tbox::Dimension::
+                                        MAXIMUM_DIMENSION_VALUE];
+    int Elastic::FACSolver::s_instance_counter[SAMRAI::tbox::Dimension::
+                                               MAXIMUM_DIMENSION_VALUE];
+
+    /*
+*************************************************************************
+*                                                                       *
+* Constructor sets uninitialized solver state.                          *
+* Set default iteration and convergence parameters.                     *
+*                                                                       *
+* By default settings:                                                  *
+*   - Elastic equation specified has D=1, C=0.                          *
+*   - State is uninitialized                                            *
+*   - Logging is disabled                                               *
+*   - Context for internal data is set based on object name.            *
+*                                                                       *
+*************************************************************************
+*/
+
+    Elastic::FACSolver::FACSolver(const tbox::Dimension& dim,
+                                  const std::string& object_name,
+                                  tbox::Pointer<tbox::Database> database):
+      d_dim(dim),
+      d_object_name(object_name),
+      d_fac_ops(d_dim, object_name + "::fac_ops",database),
+      d_fac_precond(object_name + "::fac_precond", d_fac_ops),
+      d_bc_object(NULL),
+      d_simple_bc(d_dim, object_name + "::bc"),
+      d_hierarchy(NULL),
+      d_ln_min(-1),
+      d_ln_max(-1),
+      d_context(hier::VariableDatabase::getDatabase()
+                ->getContext(object_name + "::CONTEXT")),
+      d_uv(NULL),
+      d_fv(NULL),
+      d_solver_is_initialized(false),
+      d_enable_logging(false)
+    {
+
+      if (!s_initialized) {
+        initializeStatics();
+      }
+
+      setMaxCycles(10);
+      setResidualTolerance(1e-6);
+      setPresmoothingSweeps(1);
+      setPostsmoothingSweeps(1);
+      setCoarseFineDiscretization("Ewing");
+// #ifdef HAVE_HYPRE
+//       setCoarsestLevelSolverChoice("hypre");
+//       setCoarsestLevelSolverTolerance(1e-10);
+//       setCoarsestLevelSolverMaxIterations(20);
+//       setUseSMG(true);
+// #else
+      setCoarsestLevelSolverChoice("Tackley");
+      setCoarsestLevelSolverTolerance(1e-8);
+      setCoarsestLevelSolverMaxIterations(10);
+// #endif
+
+      /*
+       * Construct integer tag variables and add to variable database.  Note that
+       * variables and patch data indices are shared among all instances.
+       * The VariableDatabase holds the variables, once contructed and
+       * registered via the VariableDatabase::registerInternalSAMRAIVariable()
+       * function call.  Note that variables are registered and patch data indices
+       * are made only for the first time through the constructor.
+       */
+      hier::VariableDatabase* var_db = hier::VariableDatabase::getDatabase();
+
+      {
+        static std::string cell_weight_name("Elastic::FACSolver_cell_weight");
+
+        tbox::Pointer<pdat::CellVariable<double> >
+          weight = var_db->getVariable(cell_weight_name);
+        if (weight.isNull()) {
+          weight = new pdat::CellVariable<double>(d_dim, cell_weight_name, 1);
+        }
+
+        if (s_weight_id[d_dim.getValue() - 1] < 0) {
+          s_weight_id[d_dim.getValue() - 1] =
+            var_db->registerInternalSAMRAIVariable
+            (weight,hier::IntVector::getZero(d_dim));
+        }
+      }
+
+      {
+        static std::string side_weight_name("Elastic::FACSolver_side_weight");
+
+        tbox::Pointer<pdat::SideVariable<double> >
+          weight = var_db->getVariable(side_weight_name);
+        if (weight.isNull()) {
+          weight = new pdat::SideVariable<double>(d_dim, side_weight_name, 1);
+        }
+
+        if (s_weight_id[d_dim.getValue() - 2] < 0) {
+          s_weight_id[d_dim.getValue() - 2] =
+            var_db->registerInternalSAMRAIVariable
+            (weight,hier::IntVector::getZero(d_dim));
+        }
+      }
+
+      // /*
+      //  * The default RobinBcCoefStrategy used,
+      //  * SimpleCellRobinBcCoefs only works with constant refine
+      //  * for prolongation.  So we use constant refinement
+      //  * for prolongation by default.
+      //  */
+      // setProlongationMethod("CONSTANT_REFINE");
+
+      /*
+       * The FAC operator optionally uses the preconditioner
+       * to get data for logging.
+       */
+      d_fac_ops.setPreconditioner((const FACPreconditioner *)(&d_fac_precond));
+
+      if (database) {
+        getFromInput(database);
+      }
+
+      s_instance_counter[d_dim.getValue() - 1]++;
+    }
+
+  }
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/FACSolver_Destructor.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/FACSolver_Destructor.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+    /*
+*************************************************************************
+*                                                                       *
+* Destructor for Elastic::FACSolver.                            *
+* Deallocate internal data.                                             *
+*                                                                       *
+*************************************************************************
+*/
+    Elastic::FACSolver::~FACSolver()
+    {
+      s_instance_counter[d_dim.getValue() - 1]--;
+      deallocateSolverState();
+      if (s_instance_counter[d_dim.getValue() - 1] == 0) {
+        hier::VariableDatabase::getDatabase()->
+          removeInternalSAMRAIVariablePatchDataIndex(s_weight_id[d_dim.getValue() - 1]);
+        s_weight_id[d_dim.getValue() - 1] = -1;
+      }
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/createVectorWrappers.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/createVectorWrappers.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+void SAMRAI::solv::Elastic::FACSolver::createVectorWrappers(int p, int p_rhs,
+                                                         int v, int v_rhs) {
+
+  hier::VariableDatabase& vdb(*hier::VariableDatabase::getDatabase());
+  tbox::Pointer<hier::Variable> variable;
+
+  if (!d_uv || d_uv->getComponentDescriptorIndex(0) != p) {
+    d_uv.setNull();
+    d_uv = new SAMRAIVectorReal<double>(d_object_name + "::uv",
+                                        d_hierarchy,
+                                        d_ln_min,
+                                        d_ln_max);
+    /* Add p */
+    vdb.mapIndexToVariable(p, variable);
+#ifdef DEBUG_CHECK_ASSERTIONS
+    if (!variable) {
+      TBOX_ERROR(d_object_name << ": No variable for patch data index "
+                 << p << "\n");
+    }
+    tbox::Pointer<pdat::CellVariable<double> > cell_variable = variable;
+    if (!cell_variable) {
+      TBOX_ERROR(d_object_name << ": hier::Patch data index " << p
+                 << " is not a cell-double variable.\n");
+    }
+#endif
+    d_uv->addComponent(variable, p, s_weight_id[d_dim.getValue() - 1]);
+
+    /* Add v */
+    vdb.mapIndexToVariable(v, variable);
+#ifdef DEBUG_CHECK_ASSERTIONS
+    if (!variable) {
+      TBOX_ERROR(d_object_name << ": No variable for patch data index "
+                 << v << "\n");
+    }
+    tbox::Pointer<pdat::SideVariable<double> > side_variable = variable;
+    if (!side_variable) {
+      TBOX_ERROR(d_object_name << ": hier::Patch data index " << v
+                 << " is not a side-double variable.\n");
+    }
+#endif
+    d_uv->addComponent(variable, v);
+  }
+
+  if (!d_fv || d_fv->getComponentDescriptorIndex(0) != p_rhs) {
+    d_fv.setNull();
+    d_fv = new SAMRAIVectorReal<double>(d_object_name + "::fv",
+                                        d_hierarchy,
+                                        d_ln_min,
+                                        d_ln_max);
+    /* Add p_rhs */
+    vdb.mapIndexToVariable(p_rhs, variable);
+#ifdef DEBUG_CHECK_ASSERTIONS
+    if (!variable) {
+      TBOX_ERROR(d_object_name << ": No variable for patch data index "
+                 << p_rhs << "\n");
+    }
+    tbox::Pointer<pdat::CellVariable<double> > cell_variable = variable;
+    if (!cell_variable) {
+      TBOX_ERROR(d_object_name << ": hier::Patch data index " << p_rhs
+                 << " is not a cell-double variable.\n");
+    }
+#endif
+    d_fv->addComponent(variable, p_rhs, s_weight_id[d_dim.getValue() - 1]);
+
+    /* Add v_rhs */
+    vdb.mapIndexToVariable(v_rhs, variable);    
+#ifdef DEBUG_CHECK_ASSERTIONS
+    if (!variable) {
+      TBOX_ERROR(d_object_name << ": No variable for patch data index "
+                 << v_rhs << "\n");
+    }
+    tbox::Pointer<pdat::SideVariable<double> > side_variable = variable;
+    if (!side_variable) {
+      TBOX_ERROR(d_object_name << ": hier::Patch data index " << v_rhs
+                 << " is not a cell-double variable.\n");
+    }
+#endif
+    d_fv->addComponent(variable, v_rhs);
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/deallocateSolverState.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/deallocateSolverState.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+    void Elastic::FACSolver::deallocateSolverState()
+    {
+      if (d_hierarchy) {
+
+        d_fac_precond.deallocateSolverState();
+
+        /*
+         * Delete internally managed data.
+         */
+        int ln;
+        for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
+          d_hierarchy->getPatchLevel(ln)->deallocatePatchData(s_weight_id[d_dim.getValue()
+                                                                          - 1]);
+        }
+
+        d_hierarchy.setNull();
+        d_ln_min = -1;
+        d_ln_max = -1;
+        d_solver_is_initialized = false;
+
+        destroyVectorWrappers();
+
+      }
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/destroyVectorWrappers.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/destroyVectorWrappers.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+    /*
+***********************************************************************
+* Delete the vector wrappers.  Do not freeVectorComponents because    *
+* we do not control their data allocation.  The user does that.       *
+***********************************************************************
+*/
+    void Elastic::FACSolver::destroyVectorWrappers() {
+      d_uv.setNull();
+      d_fv.setNull();
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/enableLogging.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/enableLogging.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+
+    /*
+*************************************************************************
+* Enable logging and propagate logging flag to major components.        *
+*************************************************************************
+*/
+
+    void Elastic::FACSolver::enableLogging(
+                                        bool logging)
+    {
+      d_enable_logging = logging;
+      d_fac_precond.enableLogging(d_enable_logging);
+      d_fac_ops.enableLogging(d_enable_logging);
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/getFromInput.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/getFromInput.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+
+    /*
+********************************************************************
+* Set state from database                                          *
+*                                                                  *
+* Do not allow FAC preconditioner and Elastic FAC operators to be  *
+* set from database, as that may cause them to be inconsistent     *
+* with this object if user does not coordinate the inputs          *
+* correctly.  This is also why we don't allow direct access to     *
+* those objects.  The responsibility for maintaining consistency   *
+* lies in the public functions to set parameters, so use them      *
+* instead of setting the parameters directly in this function.     *
+********************************************************************
+*/
+
+    void Elastic::FACSolver::getFromInput(
+                                       tbox::Pointer<tbox::Database> database)
+    {
+      if (database) {
+        if (database->isBool("enable_logging")) {
+          bool logging = database->getBool("enable_logging");
+          enableLogging(logging);
+        }
+        if (database->isInteger("max_cycles")) {
+          int max_cycles = database->getInteger("max_cycles");
+          setMaxCycles(max_cycles);
+        }
+        if (database->isDouble("residual_tol")) {
+          double residual_tol = database->getDouble("residual_tol");
+          setResidualTolerance(residual_tol);
+        }
+        if (database->isInteger("num_pre_sweeps")) {
+          int num_pre_sweeps = database->getInteger("num_pre_sweeps");
+          setPresmoothingSweeps(num_pre_sweeps);
+        }
+        if (database->isInteger("num_post_sweeps")) {
+          int num_post_sweeps = database->getInteger("num_post_sweeps");
+          setPostsmoothingSweeps(num_post_sweeps);
+        }
+        if (database->isString("coarse_fine_discretization")) {
+          std::string s = database->getString("coarse_fine_discretization");
+          setCoarseFineDiscretization(s);
+        }
+        if (database->isString("p_prolongation_method")) {
+          std::string s = database->getString("p_prolongation_method");
+          set_P_ProlongationMethod(s);
+        }
+        if (database->isString("v_prolongation_method")) {
+          std::string s = database->getString("v_prolongation_method");
+          set_V_ProlongationMethod(s);
+        }
+        if (database->isString("coarse_solver_choice")) {
+          std::string s = database->getString("coarse_solver_choice");
+          setCoarsestLevelSolverChoice(s);
+        }
+        if (database->isDouble("coarse_solver_tolerance")) {
+          double tol = database->getDouble("coarse_solver_tolerance");
+          setCoarsestLevelSolverTolerance(tol);
+        }
+        if (database->isInteger("coarse_solver_max_iterations")) {
+          int itr = database->getInteger("coarse_solver_max_iterations");
+          setCoarsestLevelSolverMaxIterations(itr);
+        }
+#ifdef HAVE_HYPRE
+        if (database->isBool("use_smg")) {
+          bool smg = database->getBool("use_smg");
+          setUseSMG(smg);
+        }
+#endif
+      }
+    }
+
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/initializeSolverState.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/initializeSolverState.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+/*
+*************************************************************************
+*                                                                       *
+* Prepare internal data for solve.                                      *
+* Allocate scratch data.  Create vectors for u and f                    *
+* required by the FACPreconditioner interface.                    *
+* Set up internal boundary condition object.                            *
+* Share data to coordinate with FAC preconditioner and                  *
+* Elastic FAC operator.                                                 *
+*                                                                       *
+*************************************************************************
+*/
+
+void SAMRAI::solv::Elastic::FACSolver::initializeSolverState
+(const int p,
+ const int cell_moduli,
+ const int edge_moduli,
+ const int dp,
+ const int p_rhs,
+ const int v,
+ const int v_rhs,
+ tbox::Pointer<hier::PatchHierarchy> hierarchy,
+ const int coarse_level,
+ const int fine_level)
+{
+  TBOX_ASSERT(!hierarchy.isNull());
+  TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
+
+  if (d_bc_object == NULL) {
+    TBOX_ERROR(
+               d_object_name << ": No BC coefficient strategy object!\n"
+               <<
+               "Use either setBoundaries or setPhysicalBcCoefObject\n"
+               << "to specify the boundary conidition.\n");
+  }
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (p < 0 || p_rhs < 0) {
+    TBOX_ERROR(d_object_name << ": Bad patch data id.\n");
+  }
+#endif
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (!hierarchy) {
+    TBOX_ERROR(d_object_name << ": NULL hierarchy pointer not allowed\n"
+               << "in inititialization.");
+  }
+#endif
+  d_hierarchy = hierarchy;
+
+  d_ln_min = coarse_level;
+  d_ln_max = fine_level;
+  if (d_ln_min == -1) {
+    d_ln_min = 0;
+  }
+  if (d_ln_max == -1) {
+    d_ln_max = d_hierarchy->getFinestLevelNumber();
+  }
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (d_ln_min < 0 || d_ln_max < 0 || d_ln_min > d_ln_max) {
+    TBOX_ERROR(d_object_name << ": Bad range of levels in\n"
+               << "inititialization.\n");
+  }
+#endif
+
+  int ln;
+  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
+    d_hierarchy->getPatchLevel(ln)->allocatePatchData(s_weight_id[d_dim.getValue() - 1]);
+  }
+
+  d_fac_ops.computeVectorWeights(d_hierarchy,
+                                 s_weight_id[d_dim.getValue() - 1],
+                                 d_ln_min,
+                                 d_ln_max);
+
+  if (d_bc_object == &d_simple_bc) {
+    d_simple_bc.setHierarchy(d_hierarchy,
+                             d_ln_min,
+                             d_ln_max);
+  }
+
+  d_fac_ops.set_moduli_id(cell_moduli,edge_moduli);
+
+  createVectorWrappers(p, p_rhs, v, v_rhs);
+
+  d_fac_precond.initializeSolverState(*d_uv, *d_fv);
+
+  d_solver_is_initialized = true;
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/initializeStatics.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/initializeStatics.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+    void Elastic::FACSolver::initializeStatics() {
+
+      for (int d = 0; d < SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
+        s_weight_id[d] = -1;
+        s_instance_counter[d] = -1;
+      }
+
+      s_initialized = 1;
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/setBcObject.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/setBcObject.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+
+    void Elastic::FACSolver::setBcObject(
+                                      const RobinBcCoefStrategy* bc_object)
+    {
+#ifdef DEBUG_CHECK_ASSERTIONS
+      if (!bc_object) {
+        TBOX_ERROR(d_object_name << ": NULL pointer for boundary condition\n"
+                   << "object.\n");
+      }
+#endif
+      d_bc_object = bc_object;
+      // d_fac_ops.setPhysicalBcCoefObject(d_bc_object);
+    }
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/setBoundaries.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/setBoundaries.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,45 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+namespace SAMRAI {
+  namespace solv {
+
+    void Elastic::FACSolver::setBoundaries(
+                                        const std::string& boundary_type,
+                                        const int fluxes,
+                                        const int flags,
+                                        int* bdry_types)
+    {
+#ifdef DEBUG_CHECK_ASSERTIONS
+      if (d_bc_object != NULL && d_bc_object != &d_simple_bc) {
+        TBOX_ERROR(
+                   d_object_name << ": Bad attempt to set boundary condition\n"
+                   <<
+                   "by using default bc object after it has been overriden.\n");
+      }
+#endif
+      d_simple_bc.setBoundaries(boundary_type,
+                                fluxes,
+                                flags,
+                                bdry_types);
+      d_bc_object = &d_simple_bc;
+      // d_fac_ops.setPhysicalBcCoefObject(d_bc_object);
+    }
+
+
+  }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/FACSolver/solveSystem.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/FACSolver/solveSystem.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   High-level solver (wrapper) for scalar Elastic equation. 
+ *
+ ************************************************************************/
+#include "SAMRAI/pdat/CellVariable.h"
+#include "Elastic/FACSolver.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+
+#include IOMANIP_HEADER_FILE
+
+/*
+*************************************************************************
+*                                                                       *
+* Solve the linear system and report whether iteration converged.       *
+*                                                                       *
+* This version is for an initialized solver state.                      *
+* Before solving, set the final piece of the boundary condition,        *
+* which is not known until now, and initialize some internal            *
+* solver quantities.                                                    *
+*                                                                       *
+*************************************************************************
+*/
+
+bool SAMRAI::solv::Elastic::FACSolver::solveSystem(const int p,
+                                                const int p_rhs,
+                                                const int v, const int v_rhs)
+{
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (!d_solver_is_initialized) {
+    TBOX_ERROR(
+               d_object_name << ".solveSystem(int,int): uninitialized\n"
+               <<
+               "solver state.  You must call initializeSolverState()\n"
+               <<
+               "before using this function.  Or you can use\n"
+               <<
+               "solveSystem(int,int,...) to initialize the solver,\n"
+               << "solve and deallocate the solver.\n");
+  }
+  if (p < 0 || p_rhs < 0 || v < 0 || v_rhs < 0) {
+    TBOX_ERROR(d_object_name << ": Bad patch data id.\n");
+  }
+#endif
+  if (d_bc_object == &d_simple_bc) {
+    /*
+     * Knowing that we are using the SimpelCellRobinBcCoefsX
+     * implementation of RobinBcCoefStrategy, we must save
+     * the ghost data in u before solving.
+     * The solver overwrites it, but SimpleCellRobinBcCoefs
+     * needs to get to access it repeatedly.
+     */
+    d_simple_bc.cacheDirichletData(p);
+  }
+
+  createVectorWrappers(p, p_rhs, v, v_rhs);
+  bool solver_rval;
+
+  solver_rval = d_fac_precond.solveSystem(*d_uv, *d_fv);
+
+  return solver_rval;
+}
+
+/*
+*************************************************************************
+*                                                                       *
+* Solve the linear system and report whether iteration converged.       *
+*                                                                       *
+* This version is for an uninitialized solver state.                    *
+* 1. Initialize the (currently uninitialized) solver state.             *
+* 2. Solve.                                                             *
+* 3. Deallocate the solver state.                                       *
+*                                                                       *
+*************************************************************************
+*/
+
+bool SAMRAI::solv::Elastic::FACSolver::solveSystem
+(const int p,
+ const int cell_moduli,
+ const int edge_moduli,
+ const int dp,
+ const int p_rhs,
+ const int v,
+ const int v_rhs,
+ tbox::Pointer<hier::PatchHierarchy>
+ hierarchy,
+ int coarse_ln,
+ int fine_ln)
+{
+  TBOX_ASSERT(!hierarchy.isNull());
+  TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
+
+  if (d_enable_logging) {
+    tbox::plog << "Elastic::FACSolver::solveSystem (" << d_object_name
+               << ")\n";
+  }
+#ifdef DEBUG_CHECK_ASSERTIONS
+  if (d_solver_is_initialized) {
+    TBOX_ERROR(
+               d_object_name << ".solveSystem(int,int,...): initialized\n"
+               <<
+               "solver state.  This function can only used when the\n"
+               <<
+               "solver state is uninitialized.  You should deallocate\n"
+               <<
+               "the solver state or use solveSystem(int,int).\n");
+  }
+  if (!hierarchy) {
+    TBOX_ERROR(d_object_name << ".solveSystem(): Null hierarchy\n"
+               << "specified.\n");
+  }
+#endif
+  initializeSolverState(p, cell_moduli, edge_moduli, dp, p_rhs, v, v_rhs,
+                        hierarchy, coarse_ln, fine_ln);
+
+  bool solver_rval;
+  solver_rval = solveSystem(p, p_rhs, v, v_rhs);
+
+  deallocateSolverState();
+
+  return solver_rval;
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/HypreSolver.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/HypreSolver.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,1549 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Hypre solver interface for diffusion-like elliptic problems. 
+ *
+ ************************************************************************/
+#ifndef included_solv_ElasticHypreSolver_C
+#define included_solv_ElasticHypreSolver_C
+
+#include "Elastic/HypreSolver.h"
+
+#ifdef HAVE_HYPRE
+
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/geom/CartesianGridGeometry.h"
+#include "SAMRAI/math/ArrayDataBasicOps.h"
+#include "SAMRAI/math/PatchSideDataBasicOps.h"
+#include "SAMRAI/pdat/ArrayData.h"
+#include "SAMRAI/pdat/CellIndex.h"
+#include "SAMRAI/pdat/CellIterator.h"
+#include "SAMRAI/pdat/FaceIndex.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideIndex.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/pdat/OuterfaceData.h"
+#include "SAMRAI/pdat/OutersideData.h"
+#include "SAMRAI/hier/BoundaryBoxUtils.h"
+#include "SAMRAI/hier/VariableDatabase.h"
+#include "SAMRAI/tbox/MathUtilities.h"
+#include "SAMRAI/tbox/SAMRAI_MPI.h"
+#include "SAMRAI/tbox/SAMRAIManager.h"
+#include "SAMRAI/tbox/PIO.h"
+#include "SAMRAI/tbox/Timer.h"
+#include "SAMRAI/tbox/TimerManager.h"
+#include "SAMRAI/tbox/StartupShutdownManager.h"
+#include "SAMRAI/tbox/Utilities.h"
+
+#include <cstdlib>
+
+#ifndef SAMRAI_INLINE
+#include "Elastic/HypreSolver.I"
+#endif
+
+extern "C" {
+
+#ifdef __INTEL_COMPILER
+#pragma warning (disable:1419)
+#endif
+
+void F77_FUNC(compdiagvariablec2d, COMPDIAGVARIABLEC2D) (
+   double* diag,
+   const double* c,
+   const double* offdiagi,
+   const double* offdiagj,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(compdiagscalarc2d, COMPDIAGSCALARC2D) (
+   double* diag,
+   const double* c,
+   const double* offdiagi,
+   const double* offdiagj,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(compdiagzeroc2d, COMPDIAGZEROC2D) (
+   double* diag,
+   const double* offdiagi,
+   const double* offdiagj,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(adjbdry2d, ADJBDRY2D) (
+   double* diag,
+   const double* offdiagi,
+   const double* offdiagj,
+   const int* pifirst, const int* pilast,
+   const int* pjfirst, const int* pjlast,
+   const double* acoef,
+   const double* bcoef,
+   const int* aifirst, const int* ailast,
+   const int* ajfirst, const int* ajlast,
+   const double* Ak0,
+   const int* kifirst, const int* kilast,
+   const int* kjfirst, const int* kjlast,
+   const int* lower, const int* upper,
+   const int* location,
+   const double* h);
+void F77_FUNC(adjbdryconstoffdiags2d, ADJBDRYCONSTOFFDIAGS2D) (
+   double* diag,
+   const double* offdiag,
+   const int* pifirst,
+   const int* pilast,
+   const int* pjfirst,
+   const int* pjlast,
+   const double* acoef,
+   const int* aifirst,
+   const int* ailast,
+   const int* ajfirst,
+   const int* ajlast,
+   const double* Ak0,
+   const int* kifirst,
+   const int* kilast,
+   const int* kjfirst,
+   const int* kjlast,
+   const int* lower, const int* upper,
+   const int* location,
+   const double* h);
+void F77_FUNC(adjustrhs2d, ADJUSTRHS2D) (double* rhs,
+   const int* rifirst,
+   const int* rilast,
+   const int* rjfirst,
+   const int* rjlast,
+   const double* Ak0,
+   const int* kifirst,
+   const int* kilast,
+   const int* kjfirst,
+   const int* kjlast,
+   const double* gcoef,
+   const int* aifirst,
+   const int* ailast,
+   const int* ajfirst,
+   const int* ajlast,
+   const int* lower, const int* upper,
+   const int* location);
+
+void F77_FUNC(compdiagvariablec3d, COMPDIAGVARIABLEC3D) (
+   double* diag,
+   const double* c,
+   const double* offdiagi,
+   const double* offdiagj,
+   const double* offdiagk,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const int* kfirst,
+   const int* klast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(compdiagscalarc3d, COMPDIAGSCALARC3D) (
+   double* diag,
+   const double* c,
+   const double* offdiagi,
+   const double* offdiagj,
+   const double* offdiagk,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const int* kfirst,
+   const int* klast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(compdiagzeroc3d, COMPDIAGZEROC3D) (
+   double* diag,
+   const double* offdiagi,
+   const double* offdiagj,
+   const double* offdiagk,
+   const int* ifirst,
+   const int* ilast,
+   const int* jfirst,
+   const int* jlast,
+   const int* kfirst,
+   const int* klast,
+   const double* cscale,
+   const double* dscale);
+void F77_FUNC(adjbdry3d, ADJBDRY3D) (
+   double* diag,
+   const double* offdiagi,
+   const double* offdiagj,
+   const double* offdiagk,
+   const int* pifirst,
+   const int* pilast,
+   const int* pjfirst,
+   const int* pjlast,
+   const int* pkfirst,
+   const int* pklast,
+   const double* acoef,
+   const double* bcoef,
+   const int* aifirst,
+   const int* ailast,
+   const int* ajfirst,
+   const int* ajlast,
+   const int* akfirst,
+   const int* aklast,
+   const double* Ak0,
+   const int* kifirst,
+   const int* kilast,
+   const int* kjfirst,
+   const int* kjlast,
+   const int* kkfirst,
+   const int* kklast,
+   const int* lower, const int* upper,
+   const int* location,
+   const double* h);
+void F77_FUNC(adjbdryconstoffdiags3d, ADJBDRYCONSTOFFDIAGS3D) (
+   double* diag,
+   const double* offdiag,
+   const int* pifirst,
+   const int* pilast,
+   const int* pjfirst,
+   const int* pjlast,
+   const int* pkfirst,
+   const int* pklast,
+   const double* acoef,
+   const int* aifirst,
+   const int* ailast,
+   const int* ajfirst,
+   const int* ajlast,
+   const int* akfirst,
+   const int* aklast,
+   const double* Ak0,
+   const int* kifirst,
+   const int* kilast,
+   const int* kjfirst,
+   const int* kjlast,
+   const int* kkfirst,
+   const int* kklast,
+   const int* lower, const int* upper,
+   const int* location,
+   const double* h);
+void F77_FUNC(adjustrhs3d, ADJUSTRHS3D) (double* rhs,
+   const int* rifirst,
+   const int* rilast,
+   const int* rjfirst,
+   const int* rjlast,
+   const int* rkfirst,
+   const int* rklast,
+   const double* Ak0,
+   const int* kifirst,
+   const int* kilast,
+   const int* kjfirst,
+   const int* kjlast,
+   const int* kkfirst,
+   const int* kklast,
+   const double* gcoef,
+   const int* aifirst,
+   const int* ailast,
+   const int* ajfirst,
+   const int* ajlast,
+   const int* akfirst,
+   const int* aklast,
+   const int* lower, const int* upper,
+   const int* location);
+
+}
+
+namespace SAMRAI {
+namespace solv {
+
+tbox::Pointer<pdat::OutersideVariable<double> >
+Elastic::HypreSolver::s_Ak0_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+
+  tbox::StartupShutdownManager::Handler Elastic::HypreSolver::s_finalize_handler(
+   0,
+   0,
+   0,
+   Elastic::HypreSolver::finalizeCallback,
+   tbox::StartupShutdownManager::priorityVariables);
+
+/*
+ *************************************************************************
+ * Constructor                                                           *
+ *************************************************************************
+ */
+
+  Elastic::HypreSolver::HypreSolver(
+   const tbox::Dimension& dim,
+   const std::string& object_name,
+   tbox::Pointer<tbox::Database> database):
+   d_dim(dim),
+   d_object_name(object_name),
+   d_hierarchy(NULL),
+   d_ln(-1),
+   d_context(hier::VariableDatabase::getDatabase()->
+             getContext(object_name + "::context")),
+   d_cf_boundary(),
+   d_physical_bc_coef_strategy(&d_physical_bc_simple_case),
+   d_physical_bc_variable(NULL),
+   d_physical_bc_simple_case(dim, d_object_name + "::simple bc"),
+   d_cf_bc_coef(dim, object_name + "::coarse-fine bc coefs"),
+   d_coarsefine_bc_variable(NULL),
+   d_Ak0_id(-1),
+   d_soln_depth(0),
+   d_rhs_depth(0),
+   d_max_iterations(10),
+   d_relative_residual_tol(1e-10),
+   d_number_iterations(-1),
+   d_num_pre_relax_steps(1),
+   d_num_post_relax_steps(1),
+   d_relative_residual_norm(-1.0),
+   d_use_smg(false),
+   d_grid(NULL),
+   d_stencil(NULL),
+   d_matrix(NULL),
+   d_linear_rhs(NULL),
+   d_linear_sol(NULL),
+   d_mg_data(NULL),
+   d_print_solver_info(false)
+{
+   if (d_dim == tbox::Dimension(1) || d_dim > tbox::Dimension(3)) {
+      TBOX_ERROR(" Elastic::HypreSolver : DIM == 1 or > 3 not implemented");
+   }
+
+   t_solve_system = tbox::TimerManager::getManager()->
+      getTimer("solv::Elastic::HypreSolver::solveSystem()");
+   t_set_matrix_coefficients = tbox::TimerManager::getManager()->
+      getTimer("solv::Elastic::HypreSolver::setMatrixCoefficients()");
+
+   hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
+   if (s_Ak0_var[d_dim.getValue() - 1].isNull()) {
+      s_Ak0_var[d_dim.getValue() - 1] = new
+         pdat::OutersideVariable<double>(d_dim, d_object_name + "::Ak0", 1);
+   }
+   d_Ak0_id =
+      vdb->registerVariableAndContext(s_Ak0_var[d_dim.getValue() - 1],
+         d_context,
+         hier::IntVector::getZero(d_dim));
+   if (database) {
+      getFromInput(database);
+   }
+}
+
+/*
+ ********************************************************************
+ * Set state from database                                          *
+ ********************************************************************
+ */
+
+  void Elastic::HypreSolver::getFromInput(
+   tbox::Pointer<tbox::Database> database)
+{
+   if (database) {
+      d_print_solver_info = database->getBoolWithDefault("print_solver_info",
+            d_print_solver_info);
+      d_max_iterations = database->getIntegerWithDefault("max_iterations",
+            d_max_iterations);
+      d_relative_residual_tol = database->getDoubleWithDefault(
+            "relative_residual_tol",
+            d_relative_residual_tol);
+      if (database->isDouble("residual_tol")) {
+         TBOX_ERROR("Elastic::HypreSolver input error.\n"
+            << "The parameter 'residual_tol' has been replaced\n"
+            << "by 'relative_residual_tol' to be more descriptive.\n"
+            << "Please change the parameter name in the input database.");
+      }
+      d_num_pre_relax_steps =
+         database->getIntegerWithDefault("num_pre_relax_steps",
+            d_num_pre_relax_steps);
+      if (d_num_pre_relax_steps < 0) {
+         TBOX_ERROR(d_object_name << ": Number of relaxation steps must be\n"
+                                  << "non-negative.\n");
+      }
+      d_num_post_relax_steps =
+         database->getIntegerWithDefault("num_post_relax_steps",
+            d_num_post_relax_steps);
+      if (d_num_post_relax_steps < 0) {
+         TBOX_ERROR(d_object_name << ": Number of relaxation steps must be\n"
+                                  << "non-negative.\n");
+      }
+      if (database->isBool("use_smg")) {
+         bool use_smg = database->getBool("use_smg");
+         if (use_smg != d_use_smg) {
+            setUseSMG(use_smg);
+         }
+      }
+   }
+}
+
+/*
+ ********************************************************************
+ * Initialize internal data for a given hierarchy level             *
+ * After setting internal data, propagate the information           *
+ * to the major algorithm objects.  Allocate data for               *
+ * storing boundary condition-dependent quantities for              *
+ * adding to souce term before solving.                             *
+ ********************************************************************
+ */
+
+  void Elastic::HypreSolver::initializeSolverState(
+   tbox::Pointer<hier::PatchHierarchy> hierarchy,
+   int ln)
+{
+   TBOX_ASSERT(!hierarchy.isNull());
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
+
+   deallocateSolverState();
+
+   d_hierarchy = hierarchy;
+   d_ln = ln;
+
+   hier::IntVector max_gcw(d_dim, 1);
+   d_cf_boundary = new hier::CoarseFineBoundary(*d_hierarchy, d_ln, max_gcw);
+
+   d_physical_bc_simple_case.setHierarchy(d_hierarchy, d_ln, d_ln);
+
+   d_number_iterations = -1;
+   d_relative_residual_norm = -1.0;
+
+   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
+   level->allocatePatchData(d_Ak0_id);
+   allocateHypreData();
+}
+
+/*
+ ********************************************************************
+ * Deallocate data initialized by initializeSolverState             *
+ ********************************************************************
+ */
+
+  void Elastic::HypreSolver::deallocateSolverState()
+{
+   if (d_hierarchy.isNull()) return;
+
+   d_cf_boundary->clear();
+   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
+   level->deallocatePatchData(d_Ak0_id);
+   deallocateHypreData();
+   d_hierarchy.setNull();
+   d_ln = -1;
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Allocate the HYPRE data structures that depend only on the level      *
+ * and will not change (grid, stencil, matrix, and vectors).             *
+ *                                                                       *
+ *************************************************************************
+ */
+  void Elastic::HypreSolver::allocateHypreData()
+{
+   tbox::SAMRAI_MPI::Comm communicator = d_hierarchy->getDomainMappedBoxLevel().getMPI().getCommunicator();
+
+   /*
+    * Set up the grid data - only set grid data for local boxes
+    */
+
+   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
+   tbox::Pointer<geom::CartesianGridGeometry> grid_geometry =
+      d_hierarchy->getGridGeometry();
+   const hier::IntVector ratio = level->getRatioToLevelZero();
+   hier::IntVector periodic_shift =
+      grid_geometry->getPeriodicShift(ratio);
+
+   int periodic_flag[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
+   int d;
+   bool is_periodic = false;
+   for (d = 0; d < d_dim.getValue(); ++d) {
+      periodic_flag[d] = periodic_shift[d] != 0;
+      is_periodic = is_periodic || periodic_flag[d];
+   }
+
+   HYPRE_StructGridCreate(communicator, d_dim.getValue(), &d_grid);
+   for (hier::PatchLevel::Iterator p(level); p; p++) {
+      const hier::Box& box = (*p)->getBox();
+      hier::Index lower = box.lower();
+      hier::Index upper = box.upper();
+      HYPRE_StructGridSetExtents(d_grid, &lower[0], &upper[0]);
+   }
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+   if (is_periodic) {
+      const hier::BoxArray& level_domain = level->getPhysicalDomain();
+      hier::Box domain_bound(level_domain[0]);
+      for (int i = 1; i < level_domain.size(); ++i) {
+         domain_bound.lower().min(level_domain[i].lower());
+         domain_bound.upper().max(level_domain[i].upper());
+      }
+      for (d = 0; d < d_dim.getValue(); ++d) {
+         if (periodic_flag[d] == true) {
+            int tmpi = 1;
+            unsigned int p_of_two;
+            for (p_of_two = 0; p_of_two < 8 * sizeof(p_of_two) - 1;
+                 ++p_of_two) {
+               if (tmpi == domain_bound.numberCells(d)) {
+                  break;
+               }
+               if (tmpi > domain_bound.numberCells(d)) {
+                  TBOX_ERROR(
+                     d_object_name << ": Hypre currently requires\n"
+                     <<
+                     "that grid size in periodic directions be\n"
+                     <<
+                     "powers of two.  (This requirement may go\n"
+                     <<
+                     "away in future versions of hypre.)\n"
+                     << "Size problem in direction "
+                     << d << "\n"
+                     << "Domain bound is "
+                     << domain_bound << ",\n"
+                     << "Size of "
+                     << domain_bound.numberCells() << "\n");
+               }
+               tmpi = tmpi ? tmpi << 1 : 1;
+            }
+         }
+      }
+   }
+#endif
+
+   HYPRE_StructGridSetPeriodic(d_grid, &periodic_shift[0]);
+   HYPRE_StructGridAssemble(d_grid);
+
+   {
+      /*
+       * Allocate stencil data and set stencil offsets
+       */
+
+      if (d_dim == tbox::Dimension(1)) {
+         const int stencil_size = 2;
+         int stencil_offsets[2][1] = {
+            { -1 }, { 0 }
+         };
+         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
+         for (int s = 0; s < stencil_size; s++) {
+            HYPRE_StructStencilSetElement(d_stencil, s,
+               stencil_offsets[s]);
+         }
+      } else if (d_dim == tbox::Dimension(2)) {
+         const int stencil_size = 3;
+         int stencil_offsets[3][2] = {
+            { -1, 0 }, { 0, -1 }, { 0, 0 }
+         };
+         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
+         for (int s = 0; s < stencil_size; s++) {
+            HYPRE_StructStencilSetElement(d_stencil, s,
+               stencil_offsets[s]);
+         }
+      } else if (d_dim == tbox::Dimension(3)) {
+         const int stencil_size = 4;
+         int stencil_offsets[4][3] = {
+            { -1, 0, 0 }, { 0, -1, 0 }, { 0, 0, -1 }, { 0, 0, 0 }
+         };
+         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
+         for (int s = 0; s < stencil_size; s++) {
+            HYPRE_StructStencilSetElement(d_stencil, s,
+               stencil_offsets[s]);
+         }
+      }
+   }
+
+   {
+      int full_ghosts1[2 * 3] = { 1, 1, 0, 0, 0, 0 };
+      int no_ghosts1[2 * 3] = { 0, 0, 0, 0, 0, 0 };
+
+      int full_ghosts2[2 * 3] = { 1, 1, 1, 1, 0, 0 };
+      int no_ghosts2[2 * 3] = { 0, 0, 0, 0, 0, 0 };
+
+      int full_ghosts3[2 * 3] = { 1, 1, 1, 1, 1, 1 };
+      int no_ghosts3[2 * 3] = { 0, 0, 0, 0, 0, 0 };
+
+      /*
+       * Allocate the structured matrix
+       */
+
+      int* full_ghosts = NULL;
+      int* no_ghosts = NULL;
+
+      if (d_dim == tbox::Dimension(1)) {
+         full_ghosts = full_ghosts1;
+         no_ghosts = no_ghosts1;
+      } else if (d_dim == tbox::Dimension(2)) {
+         full_ghosts = full_ghosts2;
+         no_ghosts = no_ghosts2;
+      } else if (d_dim == tbox::Dimension(3)) {
+         full_ghosts = full_ghosts3;
+         no_ghosts = no_ghosts3;
+      } else {
+         TBOX_ERROR(
+            "Elastic::HypreSolver does not yet support dimension " << d_dim);
+      }
+
+      HYPRE_StructMatrixCreate(communicator,
+         d_grid,
+         d_stencil,
+         &d_matrix);
+      HYPRE_StructMatrixSetNumGhost(d_matrix, full_ghosts);
+      HYPRE_StructMatrixSetSymmetric(d_matrix, 1);
+      HYPRE_StructMatrixInitialize(d_matrix);
+
+      HYPRE_StructVectorCreate(communicator,
+         d_grid,
+         &d_linear_rhs);
+      HYPRE_StructVectorSetNumGhost(d_linear_rhs, no_ghosts);
+      HYPRE_StructVectorInitialize(d_linear_rhs);
+
+      HYPRE_StructVectorCreate(communicator,
+         d_grid,
+         &d_linear_sol);
+      HYPRE_StructVectorSetNumGhost(d_linear_sol, full_ghosts);
+      HYPRE_StructVectorInitialize(d_linear_sol);
+   }
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * The destructor deallocates solver data.                               *
+ *                                                                       *
+ *************************************************************************
+ */
+
+  Elastic::HypreSolver::~HypreSolver()
+{
+   deallocateHypreData();
+
+   if (!d_hierarchy.isNull()) {
+      tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(0);
+      level->deallocatePatchData(d_Ak0_id);
+   }
+   hier::VariableDatabase* vdb =
+      hier::VariableDatabase::getDatabase();
+   vdb->removePatchDataIndex(d_Ak0_id);
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Deallocate HYPRE data and solver.  HYPRE requires that we             *
+ * check whether HYPRE has already deallocated this data.                *
+ * Note that the HYPRE solver, d_mg_data, was created at                 *
+ * the end of setMatrixCoefficients.                                     *
+ *                                                                       *
+ *************************************************************************
+ */
+
+  void Elastic::HypreSolver::deallocateHypreData()
+{
+   if (d_stencil) {
+      HYPRE_StructStencilDestroy(d_stencil);
+      d_stencil = NULL;
+   }
+   if (d_grid) {
+      HYPRE_StructGridDestroy(d_grid);
+      d_grid = NULL;
+   }
+   if (d_matrix) {
+      HYPRE_StructMatrixDestroy(d_matrix);
+      d_matrix = NULL;
+   }
+   if (d_linear_rhs) {
+      HYPRE_StructVectorDestroy(d_linear_rhs);
+      d_linear_rhs = NULL;
+   }
+   if (d_linear_sol) {
+      HYPRE_StructVectorDestroy(d_linear_sol);
+      d_linear_sol = NULL;
+   }
+   destroyHypreSolver();
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Copy data into the HYPRE vector structures.                           *
+ *                                                                       *
+ *************************************************************************
+ */
+
+  void Elastic::HypreSolver::copyToHypre(
+   HYPRE_StructVector vector,
+   pdat::CellData<double>& src,
+   int depth,
+   const hier::Box& box)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, src, box);
+
+   for (pdat::CellIterator c(box); c; c++) {
+      hier::IntVector ic = c();
+      HYPRE_StructVectorSetValues(vector, &ic[0], src(c(), depth));
+   }
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Copy data out of the HYPRE vector structures.                         *
+ *                                                                       *
+ *************************************************************************
+ */
+
+  void Elastic::HypreSolver::copyFromHypre(
+   pdat::CellData<double>& dst,
+   int depth,
+   HYPRE_StructVector vector,
+   const hier::Box box)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, dst, box);
+
+   for (pdat::CellIterator c(box); c; c++) {
+      double value;
+      hier::IntVector ic = c();
+      HYPRE_StructVectorGetValues(vector, &ic[0], &value);
+      dst(c(), depth) = value;
+   }
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Set the matrix coefficients for the linear system.                    *
+ * The matrix coefficients are dependent on the problem                  *
+ * specification described by the Elastic::Specificiations            *
+ * object and by the boundary condition.                                 *
+ *                                                                       *
+ *************************************************************************
+ */
+
+  void Elastic::HypreSolver::setMatrixCoefficients()
+{
+   if (d_physical_bc_coef_strategy == NULL) {
+      TBOX_ERROR(
+         d_object_name << ": No BC coefficient strategy object!\n"
+         <<
+         "Use either setBoundaries or setPhysicalBcCoefObject\n"
+         <<
+         "to specify the boundary conidition.  Do it before\n"
+         << "calling setMatrixCoefficients.");
+   }
+
+   t_set_matrix_coefficients->start();
+
+   int i = 0;
+
+   tbox::Pointer<pdat::CellData<double> > C_data;
+   tbox::Pointer<pdat::SideData<double> > D_data;
+
+   /*
+    * Some computations can be done using high-level math objects.
+    * Define the math objects.
+    */
+   math::ArrayDataBasicOps<double> array_math;
+   math::PatchSideDataBasicOps<double> patch_side_math;
+
+   /*
+    * The value of the ghost cell based on the Robin boundary condition
+    * can be written as the sum of a constant, k0, plus a multiple of the
+    * internal cell value, k1*ui.  k1*ui depends on the value of u so it
+    * contributes to the product Au,
+    * while the constant k0 contributes the right hand side f.
+    * We save Ak0 = A*k0(a) to add to f when solving.
+    * We assume unit g here because we will multiply it in just before
+    * solving, thus allowing everything that does not affect A to change
+    * from solve to solve.
+    */
+   tbox::Pointer<pdat::OutersideData<double> > Ak0;
+
+   /*
+    * Loop over patches and set matrix entries for each patch.
+    */
+   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
+   const hier::IntVector no_ghosts(d_dim, 0);
+   for (hier::PatchLevel::Iterator pi(*level); pi; pi++) {
+
+      hier::Patch& patch = **pi;
+
+      tbox::Pointer<geom::CartesianPatchGeometry> pg =
+         patch.getPatchGeometry();
+
+      const double* h = pg->getDx();
+
+      const hier::Box patch_box = patch.getBox();
+      const hier::Index patch_lo = patch_box.lower();
+      const hier::Index patch_up = patch_box.upper();
+
+      Ak0 = patch.getPatchData(d_Ak0_id);
+
+      Ak0->fillAll(0.0);
+
+      pdat::CellData<double> diagonal(patch_box, 1, no_ghosts);
+
+      /*
+       * Set diagonals to zero so we can accumulate to it.
+       * Accumulation is used at boundaries to shift weights
+       * for ghost cells onto the diagonal.
+       */
+      diagonal.fillAll(0.0);
+
+      const tbox::Pointer<geom::CartesianPatchGeometry>
+      geometry = patch.getPatchGeometry();
+
+      const hier::Index ifirst = patch_box.lower();
+      const hier::Index ilast = patch_box.upper();
+
+      /*
+       * Storage for off-diagonal entries,
+       * which can be variable or constant.
+       */
+      pdat::SideData<double> off_diagonal(patch_box, 1, no_ghosts);
+
+      /*
+       * Compute all off-diagonal entries with no regard to BCs.
+       * These off-diagonal entries are simply D/(h*h), according
+       * to our central difference formula.
+       */
+      for (i = 0; i < d_dim.getValue(); ++i) {
+        hier::Box sbox(patch_box);
+        sbox.growUpper(i, 1);
+        array_math.scale(off_diagonal.getArrayData(i),
+                         1.0 / (h[i] * h[i]),
+                         D_data->getArrayData(i),
+                         sbox);
+      }
+
+      /*
+       * Compute diagonal entries using off-diagonal contributions.
+       */
+      computeDiagonalEntries(diagonal,
+                             *C_data,
+                             off_diagonal,
+                             patch_box);
+
+      /*
+       * Walk physical domain boundaries and adjust off-diagonals
+       * before computation of diagonal entries.
+       * The exterior cell's value is
+       * uo = ( h*gamma + ui*(beta-h*alpha/2) )/( beta+h*alpha/2 )
+       *   = k0 + k1*ui
+       * where k0 = h*gamma/( beta+h*alpha/2 )
+       * k1 = ( beta-h*alpha/2 )/( beta+h*alpha/2 )
+       * Split coupling between interior-exterior cells
+       * into two parts: interior-interior coupling (k1)
+       * and rhs contribution (k0).
+       */
+      {
+         const tbox::Array<hier::BoundaryBox>& surface_boxes =
+            pg->getCodimensionBoundaries(1);
+         const int n_bdry_boxes = surface_boxes.getSize();
+         for (int n = 0; n < n_bdry_boxes; ++n) {
+
+            const hier::BoundaryBox& boundary_box = surface_boxes[n];
+            if (boundary_box.getBoundaryType() != 1) {
+               TBOX_ERROR(
+                  d_object_name << ": Illegal boundary type in "
+                  <<
+                  "Elastic::HypreSolver::setMatrixCoefficients\n");
+            }
+            const hier::BoundaryBoxUtils bbu(boundary_box);
+            const int location_index = boundary_box.getLocationIndex();
+            const hier::BoundaryBox trimmed_boundary_box =
+               bbu.trimBoundaryBox(patch.getBox());
+            const hier::Box bccoef_box =
+               bbu.getSurfaceBoxFromBoundaryBox();
+            tbox::Pointer<pdat::ArrayData<double> >
+            acoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
+            tbox::Pointer<pdat::ArrayData<double> >
+            bcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
+            tbox::Pointer<pdat::ArrayData<double> >
+            gcoef_data(NULL);
+            static const double fill_time = 0.0;
+            d_physical_bc_coef_strategy->setBcCoefs(acoef_data,
+               bcoef_data,
+               gcoef_data,
+               d_physical_bc_variable,
+               patch,
+               boundary_box,
+               fill_time);
+            pdat::ArrayData<double>& Ak0_data =
+               Ak0->getArrayData(location_index / 2,
+                  location_index % 2);
+            adjustBoundaryEntries(diagonal,
+               off_diagonal,
+               patch_box,
+               *acoef_data,
+               *bcoef_data,
+               bccoef_box,
+               Ak0_data,
+               trimmed_boundary_box,
+               h);
+         }
+      }
+
+      /*
+       * Walk coarse-fine boundaries and adjust off-diagonals
+       * according data in ghost cells.
+       */
+      if (d_ln > 0) {
+         /*
+          * There are potentially coarse-fine boundaries to deal with.
+          */
+
+         tbox::Array<hier::BoundaryBox> surface_boxes;
+
+         if (d_dim == tbox::Dimension(2)) {
+            surface_boxes = d_cf_boundary->getEdgeBoundaries(pi->getGlobalId());
+         } else if (d_dim == tbox::Dimension(3)) {
+            surface_boxes = d_cf_boundary->getFaceBoundaries(pi->getGlobalId());
+         }
+
+         const int n_bdry_boxes = surface_boxes.getSize();
+         for (int n = 0; n < n_bdry_boxes; ++n) {
+
+            const hier::BoundaryBox& boundary_box = surface_boxes[n];
+            if (boundary_box.getBoundaryType() != 1) {
+               TBOX_ERROR(
+                  d_object_name << ": Illegal boundary type in "
+                  <<
+                  "Elastic::HypreSolver::setMatrixCoefficients\n");
+            }
+            const int location_index = boundary_box.getLocationIndex();
+            const hier::BoundaryBoxUtils bbu(boundary_box);
+            const hier::BoundaryBox trimmed_boundary_box =
+               bbu.trimBoundaryBox(patch.getBox());
+            const hier::Box bccoef_box =
+               bbu.getSurfaceBoxFromBoundaryBox();
+            tbox::Pointer<pdat::ArrayData<double> >
+            acoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
+            tbox::Pointer<pdat::ArrayData<double> >
+            bcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
+            tbox::Pointer<pdat::ArrayData<double> >
+            gcoef_data(NULL);
+            static const double fill_time = 0.0;
+            /*
+             * Reset invalid ghost data id to help detect use in setBcCoefs.
+             */
+            d_cf_bc_coef.setGhostDataId(-1, hier::IntVector::getZero(d_dim));
+            d_cf_bc_coef.setBcCoefs(acoef_data,
+               bcoef_data,
+               gcoef_data,
+               d_coarsefine_bc_variable,
+               patch,
+               boundary_box,
+               fill_time);
+            pdat::ArrayData<double>& Ak0_data =
+               Ak0->getArrayData(location_index / 2,
+                  location_index % 2);
+            adjustBoundaryEntries(diagonal,
+               off_diagonal,
+               patch_box,
+               *acoef_data,
+               *bcoef_data,
+               bccoef_box,
+               Ak0_data,
+               trimmed_boundary_box,
+               h);
+         }
+      }
+
+      /*
+       * Copy matrix entries to HYPRE matrix structure.  Note that
+       * we translate our temporary diagonal/off-diagonal storage into the
+       * HYPRE symmetric storage scheme for the stencil specified earlier.
+       */
+      const int stencil_size = d_dim.getValue() + 1;
+      int stencil_indices[stencil_size];
+      double mat_entries[stencil_size];
+
+      for (i = 0; i < stencil_size; i++) stencil_indices[i] = i;
+
+      pdat::CellIterator ic(patch_box);
+
+      /*
+       * To do: This loop uses inefficient high-level syntax.
+       * See if it can be replaced by a Fortran loop or if we
+       * can set matrix entries for an entire box at once.
+       */
+      for ( ; ic; ic++) {
+
+         hier::IntVector icell = ic();
+         pdat::SideIndex ixlower(ic(),
+                                 pdat::SideIndex::X,
+                                 pdat::SideIndex::Lower);
+         mat_entries[0] = (off_diagonal)(ixlower);
+
+         if (d_dim > tbox::Dimension(1)) {
+            pdat::SideIndex iylower(ic(),
+                                    pdat::SideIndex::Y,
+                                    pdat::SideIndex::Lower);
+            mat_entries[1] = (off_diagonal)(iylower);
+         }
+
+         if (d_dim > tbox::Dimension(2)) {
+            pdat::SideIndex izlower(ic(),
+                                    pdat::SideIndex::Z,
+                                    pdat::SideIndex::Lower);
+            // The "funny" indexing prevents a warning when compiling for
+            // DIM < 2.  This code is only reached if DIM > 2 when
+            // executing.
+            mat_entries[d_dim.getValue() > 2 ? 2 : 0] = (off_diagonal)(izlower);
+         }
+
+         mat_entries[d_dim.getValue()] = (diagonal)(ic());
+         HYPRE_StructMatrixSetValues(d_matrix, &icell[0],
+            stencil_size, stencil_indices,
+            mat_entries);
+      } // end cell loop
+
+   } // end patch loop
+
+   if (d_print_solver_info) {
+      HYPRE_StructMatrixPrint("mat_bA.out", d_matrix, 1);
+   }
+
+   HYPRE_StructMatrixAssemble(d_matrix);
+
+   if (d_print_solver_info) {
+      HYPRE_StructMatrixPrint("mat_aA.out", d_matrix, 1);
+   }
+
+   t_set_matrix_coefficients->stop();
+
+   setupHypreSolver();
+}
+
+/*
+ **********************************************************************
+ * Add g*A*k0(a) from physical boundaries to rhs.                     *
+ * This operation is done for physical as well as cf boundaries,      *
+ * so it is placed in a function.                                     *
+ **********************************************************************
+ */
+
+  void Elastic::HypreSolver::add_gAk0_toRhs(
+   const hier::Patch& patch,
+   const tbox::Array<hier::BoundaryBox>& bdry_boxes,
+   const RobinBcCoefStrategy* robin_bc_coef,
+   pdat::CellData<double>& rhs)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, patch, rhs);
+
+   /*
+    * g*A*k0(a) is the storage for adjustments to be made to the rhs
+    * when we solve. This is the value of the weight of the ghost cell
+    * value for the interior cell, times k0.  It is independent of u,
+    * and so is moved to the rhs.  Before solving, g*A*k0(a) is added
+    * to rhs.
+    */
+   tbox::Pointer<pdat::OutersideData<double> > Ak0;
+
+   tbox::Pointer<geom::CartesianPatchGeometry> pg =
+      patch.getPatchGeometry();
+
+   Ak0 = patch.getPatchData(d_Ak0_id);
+
+   const int n_bdry_boxes = bdry_boxes.getSize();
+   for (int n = 0; n < n_bdry_boxes; ++n) {
+
+      const hier::BoundaryBox& boundary_box = bdry_boxes[n];
+#ifdef DEBUG_CHECK_ASSERTIONS
+      if (boundary_box.getBoundaryType() != 1) {
+         TBOX_ERROR(d_object_name << ": Illegal boundary type in "
+                                  << "Elastic::HypreSolver::add_gAk0_toRhs\n");
+      }
+#endif
+      const int location_index = boundary_box.getLocationIndex();
+      const hier::BoundaryBoxUtils bbu(boundary_box);
+      const hier::BoundaryBox trimmed_boundary_box =
+         bbu.trimBoundaryBox(patch.getBox());
+      const hier::Index& lower = trimmed_boundary_box.getBox().lower();
+      const hier::Index& upper = trimmed_boundary_box.getBox().upper();
+      const hier::Box& rhsbox = rhs.getArrayData().getBox();
+      const hier::Box& Ak0box = Ak0->getArrayData(location_index / 2,
+            location_index % 2).getBox();
+      const hier::Box bccoef_box = bbu.getSurfaceBoxFromBoundaryBox();
+      tbox::Pointer<pdat::ArrayData<double> >
+      acoef_data(NULL);
+      tbox::Pointer<pdat::ArrayData<double> >
+      bcoef_data(NULL);
+      tbox::Pointer<pdat::ArrayData<double> >
+      gcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
+      static const double fill_time = 0.0;
+      robin_bc_coef->setBcCoefs(acoef_data,
+         bcoef_data,
+         gcoef_data,
+         d_physical_bc_variable,
+         patch,
+         boundary_box,
+         fill_time);
+      /*
+       * Nomenclature for indices: cel=first-cell, gho=ghost,
+       * beg=beginning, end=ending.
+       */
+      if (d_dim == tbox::Dimension(2)) {
+         F77_FUNC(adjustrhs2d, ADJUSTRHS2D) (rhs.getPointer(d_rhs_depth),
+            &rhsbox.lower()[0],
+            &rhsbox.upper()[0],
+            &rhsbox.lower()[1],
+            &rhsbox.upper()[1],
+            Ak0->getPointer(location_index / 2, location_index % 2),
+            &Ak0box.lower()[0],
+            &Ak0box.upper()[0],
+            &Ak0box.lower()[1],
+            &Ak0box.upper()[1],
+            gcoef_data->getPointer(),
+            &bccoef_box.lower()[0],
+            &bccoef_box.upper()[0],
+            &bccoef_box.lower()[1],
+            &bccoef_box.upper()[1],
+            &lower[0], &upper[0],
+            &location_index);
+      } else if (d_dim == tbox::Dimension(3)) {
+         F77_FUNC(adjustrhs3d, ADJUSTRHS3D) (rhs.getPointer(d_rhs_depth),
+            &rhsbox.lower()[0],
+            &rhsbox.upper()[0],
+            &rhsbox.lower()[1],
+            &rhsbox.upper()[1],
+            &rhsbox.lower()[2],
+            &rhsbox.upper()[2],
+            Ak0->getPointer(location_index / 2, location_index % 2),
+            &Ak0box.lower()[0],
+            &Ak0box.upper()[0],
+            &Ak0box.lower()[1],
+            &Ak0box.upper()[1],
+            &Ak0box.lower()[2],
+            &Ak0box.upper()[2],
+            gcoef_data->getPointer(),
+            &bccoef_box.lower()[0],
+            &bccoef_box.upper()[0],
+            &bccoef_box.lower()[1],
+            &bccoef_box.upper()[1],
+            &bccoef_box.lower()[2],
+            &bccoef_box.upper()[2],
+            &lower[0], &upper[0],
+            &location_index);
+      }
+   }
+}
+
+/*
+ *************************************************************************
+ * Create the hypre solver and set it according to the current state.    *
+ *************************************************************************
+ */
+void Elastic::HypreSolver::setupHypreSolver()
+{
+   TBOX_ASSERT(d_mg_data == NULL);
+
+   tbox::SAMRAI_MPI::Comm communicator = d_hierarchy->getDomainMappedBoxLevel().getMPI().getCommunicator();
+
+   if (d_use_smg) {
+      HYPRE_StructSMGCreate(communicator, &d_mg_data);
+      HYPRE_StructSMGSetMemoryUse(d_mg_data, 0);
+      HYPRE_StructSMGSetMaxIter(d_mg_data, d_max_iterations);
+      HYPRE_StructSMGSetTol(d_mg_data, d_relative_residual_tol);
+      HYPRE_StructSMGSetLogging(d_mg_data, 1);
+      HYPRE_StructSMGSetNumPreRelax(d_mg_data,
+         d_num_pre_relax_steps);
+      HYPRE_StructSMGSetNumPostRelax(d_mg_data,
+         d_num_post_relax_steps);
+      HYPRE_StructSMGSetup(d_mg_data,
+         d_matrix,
+         d_linear_rhs,
+         d_linear_sol);
+   } else {
+      HYPRE_StructPFMGCreate(communicator, &d_mg_data);
+      HYPRE_StructPFMGSetMaxIter(d_mg_data, d_max_iterations);
+      HYPRE_StructPFMGSetTol(d_mg_data, d_relative_residual_tol);
+      HYPRE_StructPFMGSetLogging(d_mg_data, 1);
+      HYPRE_StructPFMGSetNumPreRelax(d_mg_data,
+         d_num_pre_relax_steps);
+      HYPRE_StructPFMGSetNumPostRelax(d_mg_data,
+         d_num_post_relax_steps);
+      HYPRE_StructPFMGSetup(d_mg_data,
+         d_matrix,
+         d_linear_rhs,
+         d_linear_sol);
+   }
+}
+
+void Elastic::HypreSolver::destroyHypreSolver()
+{
+   if (d_mg_data != NULL) {
+      if (d_use_smg) {
+         HYPRE_StructSMGDestroy(d_mg_data);
+      } else {
+         HYPRE_StructPFMGDestroy(d_mg_data);
+      }
+      d_mg_data = NULL;
+   }
+}
+
+/*
+ *************************************************************************
+ *                                                                       *
+ * Solve the linear system.  This routine assumes that the boundary      *
+ * conditions and the matrix coefficients have been specified.           *
+ *                                                                       *
+ *************************************************************************
+ */
+
+int Elastic::HypreSolver::solveSystem(
+   const int u,
+   const int f,
+   bool homogeneous_bc)
+{
+   if (d_physical_bc_coef_strategy == NULL) {
+      TBOX_ERROR(
+         d_object_name << ": No BC coefficient strategy object!\n"
+         <<
+         "Use either setBoundaries or setPhysicalBcCoefObject\n"
+         <<
+         "to specify the boundary conidition.  Do it before\n"
+         << "calling solveSystem.");
+   }
+   // Tracer t("Elastic::HypreSolver::solveSystem");
+
+   t_solve_system->start();
+
+   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(u >= 0);
+   TBOX_ASSERT(
+      u < level->getPatchDescriptor()->getMaxNumberRegisteredComponents());
+   TBOX_ASSERT(f >= 0);
+   TBOX_ASSERT(
+      f < level->getPatchDescriptor()->getMaxNumberRegisteredComponents());
+#endif
+
+   if (d_physical_bc_coef_strategy == &d_physical_bc_simple_case) {
+      /*
+       * If we are using the simple bc implementation, the final piece
+       * of information it requires is the Dirichlet boundary value
+       * set in the ghost cells.  Now that we have the ghost cell data,
+       * we can complete the boundary condition setup.
+       */
+      d_physical_bc_simple_case.cacheDirichletData(u);
+   }
+
+   /*
+    * Modify right-hand-side to account for boundary conditions and
+    * copy solution and right-hand-side to HYPRE structures.
+    */
+
+   const hier::IntVector no_ghosts(d_dim, 0);
+   const hier::IntVector ghosts(d_dim, 1);
+
+   /*
+    * At coarse-fine boundaries, we expect ghost cells to have correct
+    * values to be used in our bc, so u provides the ghost cell data.
+    * Assume that the user only provided data for the immediate first
+    * ghost cell, so pass zero for the number of extensions fillable.
+    */
+   d_cf_bc_coef.setGhostDataId(u, hier::IntVector::getZero(d_dim));
+
+   for (hier::PatchLevel::Iterator p(level); p; p++) {
+      tbox::Pointer<hier::Patch> patch = *p;
+
+      const hier::Box box = patch->getBox();
+
+      /*
+       * Set up variable data needed to prepare linear system solver.
+       */
+      tbox::Pointer<pdat::CellData<double> > u_data_ = patch->getPatchData(u);
+#ifdef DEBUG_CHECK_ASSERTIONS
+      TBOX_ASSERT(!u_data_.isNull());
+#endif
+      pdat::CellData<double>& u_data = *u_data_;
+      pdat::CellData<double> rhs_data(box, 1, no_ghosts);
+
+      /*
+       * Copy rhs and solution from the hierarchy into HYPRE structures.
+       * For rhs, add in the contribution from boundary conditions, if
+       * needed.  If boundary condition is homogenous, this only adds
+       * zero, so we skip it.
+       */
+      copyToHypre(d_linear_sol, u_data, d_soln_depth, box);
+      rhs_data.copy(*(patch->getPatchData(f)));
+      if (!homogeneous_bc) {
+         /*
+          * Add g*A*k0(a) from physical and coarse-fine boundaries to rhs.
+          */
+         add_gAk0_toRhs(*patch,
+            patch->getPatchGeometry()->getCodimensionBoundaries(1),
+            d_physical_bc_coef_strategy,
+            rhs_data);
+         add_gAk0_toRhs(*patch,
+            d_cf_boundary->getBoundaries(patch->getGlobalId(), 1),
+            &d_cf_bc_coef,
+            rhs_data);
+      }
+      copyToHypre(d_linear_rhs, rhs_data, d_rhs_depth, box);
+
+   } // end patch loop
+
+   /*
+    * Reset invalid ghost data id to help detect erroneous further use.
+    */
+   d_cf_bc_coef.setGhostDataId(-1, hier::IntVector::getZero(d_dim));
+
+   /*
+    * Finish assembly of the vectors
+    */
+   HYPRE_StructVectorAssemble(d_linear_sol);
+
+   HYPRE_StructVectorAssemble(d_linear_rhs);
+
+   /*
+    * Solve the system - zero means convergence
+    * Solve takes the same arguments as Setup
+    */
+
+   if (d_print_solver_info) {
+      HYPRE_StructVectorPrint("sol0.out", d_linear_sol, 1);
+      HYPRE_StructMatrixPrint("mat0.out", d_matrix, 1);
+      HYPRE_StructVectorPrint("rhs.out", d_linear_rhs, 1);
+   }
+
+   if (d_use_smg) {
+      // HYPRE_StructSMGSetMaxIter(d_mg_data, d_max_iterations);
+      HYPRE_StructSMGSetTol(d_mg_data, d_relative_residual_tol);
+      /* converge = */ HYPRE_StructSMGSolve(d_mg_data,
+         d_matrix,
+         d_linear_rhs,
+         d_linear_sol);
+   } else {
+      // HYPRE_StructPFMGSetMaxIter(d_mg_data, d_max_iterations);
+      HYPRE_StructPFMGSetTol(d_mg_data, d_relative_residual_tol);
+      /* converge = */ HYPRE_StructPFMGSolve(d_mg_data,
+         d_matrix,
+         d_linear_rhs,
+         d_linear_sol);
+   }
+
+   if (d_print_solver_info) {
+      HYPRE_StructMatrixPrint("mat.out", d_matrix, 1);
+      HYPRE_StructVectorPrint("sol.out", d_linear_sol, 1);
+   }
+
+   if (d_use_smg) {
+      HYPRE_StructSMGGetNumIterations(d_mg_data,
+         &d_number_iterations);
+      HYPRE_StructSMGGetFinalRelativeResidualNorm(d_mg_data,
+         &d_relative_residual_norm);
+   } else {
+      HYPRE_StructPFMGGetNumIterations(d_mg_data,
+         &d_number_iterations);
+      HYPRE_StructPFMGGetFinalRelativeResidualNorm(d_mg_data,
+         &d_relative_residual_norm);
+   }
+
+   /*
+    * Pull the solution vector out of the HYPRE structures
+    */
+   for (hier::PatchLevel::Iterator ip(level); ip; ip++) {
+      tbox::Pointer<hier::Patch> patch = *ip;
+      tbox::Pointer<pdat::CellData<double> > u_data_ = patch->getPatchData(u);
+      pdat::CellData<double>& u_data = *u_data_;
+      copyFromHypre(u_data,
+         d_soln_depth,
+         d_linear_sol,
+         patch->getBox());
+   }
+
+   t_solve_system->stop();
+
+   return d_relative_residual_norm <= d_relative_residual_tol;
+}
+
+void Elastic::HypreSolver::computeDiagonalEntries(
+   pdat::CellData<double>& diagonal,
+   const pdat::CellData<double>& C_data,
+   const pdat::SideData<double>& off_diagonal,
+   const hier::Box& patch_box)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(d_dim,
+      diagonal,
+      C_data,
+      off_diagonal,
+      patch_box);
+
+   const hier::Index patch_lo = patch_box.lower();
+   const hier::Index patch_up = patch_box.upper();
+   const double c = 1.0, d = 1.0;
+   if (d_dim == tbox::Dimension(2)) {
+      F77_FUNC(compdiagvariablec2d, COMPDIAGVARIABLEC2D) (diagonal.getPointer(),
+         C_data.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &c, &d);
+   } else if (d_dim == tbox::Dimension(3)) {
+      F77_FUNC(compdiagvariablec3d, COMPDIAGVARIABLEC3D) (diagonal.getPointer(),
+         C_data.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         off_diagonal.getPointer(2),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &patch_lo[2], &patch_up[2],
+         &c, &d);
+   }
+}
+
+void Elastic::HypreSolver::computeDiagonalEntries(
+   pdat::CellData<double>& diagonal,
+   const double C,
+   const pdat::SideData<double>& off_diagonal,
+   const hier::Box& patch_box)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS3(d_dim, diagonal, off_diagonal, patch_box);
+
+   const hier::Index patch_lo = patch_box.lower();
+   const hier::Index patch_up = patch_box.upper();
+   const double c = 1.0, d = 1.0;
+   if (d_dim == tbox::Dimension(2)) {
+      F77_FUNC(compdiagscalarc2d, COMPDIAGSCALARC2D) (diagonal.getPointer(),
+         &C,
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &c, &d);
+   } else if (d_dim == tbox::Dimension(3)) {
+      F77_FUNC(compdiagscalarc3d, COMPDIAGSCALARC3D) (diagonal.getPointer(),
+         &C,
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         off_diagonal.getPointer(2),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &patch_lo[2], &patch_up[2],
+         &c, &d);
+   } else {
+      TBOX_ERROR("Elastic::HypreSolver error...\n"
+         << "DIM > 3 not supported." << std::endl);
+   }
+}
+
+void Elastic::HypreSolver::computeDiagonalEntries(
+   pdat::CellData<double>& diagonal,
+   const pdat::SideData<double>& off_diagonal,
+   const hier::Box& patch_box)
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS3(d_dim, diagonal, off_diagonal, patch_box);
+
+   const hier::Index patch_lo = patch_box.lower();
+   const hier::Index patch_up = patch_box.upper();
+   const double c = 1.0, d = 1.0;
+   if (d_dim == tbox::Dimension(2)) {
+      F77_FUNC(compdiagzeroc2d, COMPDIAGZEROC2D) (diagonal.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &c, &d);
+   } else if (d_dim == tbox::Dimension(3)) {
+      F77_FUNC(compdiagzeroc3d, COMPDIAGZEROC3D) (diagonal.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         off_diagonal.getPointer(2),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &patch_lo[2], &patch_up[2],
+         &c, &d);
+   } else {
+      TBOX_ERROR("Elastic::HypreSolver error...\n"
+         << "DIM > 3 not supported." << std::endl);
+   }
+}
+
+void Elastic::HypreSolver::adjustBoundaryEntries(
+   pdat::CellData<double>& diagonal,
+   const pdat::SideData<double>& off_diagonal,
+   const hier::Box& patch_box,
+   const pdat::ArrayData<double>& acoef_data,
+   const pdat::ArrayData<double>& bcoef_data,
+   const hier::Box bccoef_box,
+   pdat::ArrayData<double>& Ak0_data,
+   const hier::BoundaryBox& trimmed_boundary_box,
+   const double h[tbox::Dimension::MAXIMUM_DIMENSION_VALUE])
+{
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS8(d_dim, diagonal, off_diagonal, patch_box,
+      acoef_data, bcoef_data,
+      bccoef_box, Ak0_data, trimmed_boundary_box);
+
+   const hier::Index patch_lo = patch_box.lower();
+   const hier::Index patch_up = patch_box.upper();
+   const int location_index = trimmed_boundary_box.getLocationIndex();
+   const hier::Index& lower = trimmed_boundary_box.getBox().lower();
+   const hier::Index& upper = trimmed_boundary_box.getBox().upper();
+   const hier::Box& Ak0_box = Ak0_data.getBox();
+   if (d_dim == tbox::Dimension(2)) {
+      F77_FUNC(adjbdry2d, ADJBDRY2D) (diagonal.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         acoef_data.getPointer(),
+         bcoef_data.getPointer(),
+         &bccoef_box.lower()[0],
+         &bccoef_box.upper()[0],
+         &bccoef_box.lower()[1],
+         &bccoef_box.upper()[1],
+         Ak0_data.getPointer(),
+         &Ak0_box.lower()[0],
+         &Ak0_box.upper()[0],
+         &Ak0_box.lower()[1],
+         &Ak0_box.upper()[1],
+         &lower[0], &upper[0],
+         &location_index, h);
+   } else if (d_dim == tbox::Dimension(3)) {
+      F77_FUNC(adjbdry3d, ADJBDRY3D) (diagonal.getPointer(),
+         off_diagonal.getPointer(0),
+         off_diagonal.getPointer(1),
+         off_diagonal.getPointer(2),
+         &patch_lo[0], &patch_up[0],
+         &patch_lo[1], &patch_up[1],
+         &patch_lo[2], &patch_up[2],
+         acoef_data.getPointer(),
+         bcoef_data.getPointer(),
+         &bccoef_box.lower()[0],
+         &bccoef_box.upper()[0],
+         &bccoef_box.lower()[1],
+         &bccoef_box.upper()[1],
+         &bccoef_box.lower()[2],
+         &bccoef_box.upper()[2],
+         Ak0_data.getPointer(),
+         &Ak0_box.lower()[0],
+         &Ak0_box.upper()[0],
+         &Ak0_box.lower()[1],
+         &Ak0_box.upper()[1],
+         &Ak0_box.lower()[2],
+         &Ak0_box.upper()[2],
+         &lower[0], &upper[0],
+         &location_index, h);
+   } else {
+      TBOX_ERROR("Elastic::HypreSolver error...\n"
+         << "DIM > 3 not supported." << std::endl);
+   }
+}
+
+void
+Elastic::HypreSolver::finalizeCallback()
+{
+   for (int d = 0; d < tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
+      s_Ak0_var[d].setNull();
+   }
+}
+
+}
+}
+
+#endif
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/HypreSolver.I
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/HypreSolver.I	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Level solver for diffusion-like elliptic problems. 
+ *
+ ************************************************************************/
+namespace SAMRAI {
+namespace solv {
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setSolnIdDepth(
+   const int depth) {
+   d_soln_depth = depth;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setRhsIdDepth(
+   const int depth) {
+   d_rhs_depth = depth;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setUseSMG(
+   bool use_smg) {
+   d_use_smg = use_smg;
+}
+
+/*
+ ********************************************************************
+ * Specify bc using the default internal bc coefficient object.     *
+ * Clear up data supporting external bc coefficient setter.         *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setBoundaries(
+   const std::string& boundary_type,
+   const int fluxes,
+   const int flags,
+   int* bdry_types)
+{
+   d_physical_bc_simple_case.setBoundaries(boundary_type,
+      fluxes,
+      flags,
+      bdry_types);
+   d_physical_bc_coef_strategy = &d_physical_bc_simple_case;
+   d_physical_bc_variable.setNull();
+}
+
+/*
+ ********************************************************************
+ * Set the physical boundary condition object.                      *
+ ********************************************************************
+ */
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setPhysicalBcCoefObject(
+   const RobinBcCoefStrategy* physical_bc_coef_strategy,
+   const tbox::Pointer<hier::Variable> variable)
+{
+   d_physical_bc_coef_strategy = physical_bc_coef_strategy;
+   d_physical_bc_variable = variable;
+}
+
+SAMRAI_INLINE_KEYWORD
+int Elastic::HypreSolver::getNumberOfIterations() const
+{
+   return d_number_iterations;
+}
+
+SAMRAI_INLINE_KEYWORD
+double Elastic::HypreSolver::getRelativeResidualNorm() const
+{
+   return d_relative_residual_norm;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setNumPreRelaxSteps(
+   const int steps)
+{
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(!d_hierarchy.isNull());
+#endif
+   d_num_pre_relax_steps = steps;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setNumPostRelaxSteps(
+   const int steps)
+{
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(!d_hierarchy.isNull());
+#endif
+   d_num_post_relax_steps = steps;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setPrintSolverInfo(
+   const bool print)
+{
+   d_print_solver_info = print;
+}
+
+SAMRAI_INLINE_KEYWORD
+void Elastic::HypreSolver::setStoppingCriteria(
+   const int max_iterations,
+   const double residual_tol)
+{
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(max_iterations >= 0);
+   TBOX_ASSERT(residual_tol >= 0.0);
+#endif
+   d_max_iterations = max_iterations;
+   d_relative_residual_tol = residual_tol;
+}
+
+}
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/HypreSolver.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/HypreSolver.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,616 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Hypre solver interface for diffusion-like elliptic problems. 
+ *
+ ************************************************************************/
+#ifndef included_solv_ElasticHypreSolver
+#define included_solv_ElasticHypreSolver
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#ifdef HAVE_HYPRE
+
+#ifndef included_HYPRE_struct_ls
+/*
+ * This might break things if F77_FUNC_ is different for hypre vs
+ * SAMRAI autoconf detection.  But then C/C++ macros are totally
+ * broken due to namespace collision as this example highlights so
+ * resorting to hacks are necessary.
+ */
+#ifdef F77_FUNC_
+#undef F77_FUNC_
+#endif
+#include "HYPRE_struct_ls.h"
+#define included_HYPRE_struct_ls
+#endif
+
+#include "SAMRAI/solv/GhostCellRobinBcCoefs.h"
+#include "SAMRAI/solv/RobinBcCoefStrategy.h"
+#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/OutersideVariable.h"
+#include "SAMRAI/hier/BoxList.h"
+#include "SAMRAI/hier/CoarseFineBoundary.h"
+#include "SAMRAI/hier/PatchHierarchy.h"
+#include "SAMRAI/hier/PatchLevel.h"
+#include "SAMRAI/hier/VariableContext.h"
+#include "SAMRAI/tbox/Database.h"
+#include "SAMRAI/tbox/Pointer.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace solv {
+namespace Elastic {
+/*!
+ * @brief Use the HYPRE preconditioner library to solve (the cell-centered)
+ * Elastic's equation on a single level in a hierarchy.
+ *
+ * Class Elastic::HypreSolver uses the HYPRE preconditioner library
+ * to solve linear equations of the form
+ * @f$ \nabla ( D \nabla u ) + C u = f @f$, where
+ * C is a cell-centered array, D is a face-centered array,
+ * and u and f are cell-centered arrays
+ * (see Elastic::Specifications).
+ * The discretization is the standard second order
+ * finite difference stencil.
+ *
+ * Robin boundary conditions are used through the
+ * interface class RobinBcCoefStrategy.
+ * Periodic boundary conditions are not supported yet.
+ *
+ * The user must perform the following steps to use
+ * Elastic::HypreSolver:
+ * - Create a Elastic::HypreSolver object.
+ * - Initialize Elastic::HypreSolver object with a patch hierarchy,
+ *   using the function initializeSolverState().
+ * - Use the functions setPhysicalBcCoefObject()
+ *   to provide implementations of RobinBcCoefStrategy.
+ *   (For most problems you can probably find a suitable
+ *   implementation to use without implementing the
+ *   strategy yourself.  See for example
+ *   SimpleCellRobinBcCoefs and GhostCellRobinBcCoefs.)
+ * - Set the matrix coefficients in the linear system,
+ *   using the function setMatrixCoefficients().
+ * - Specify the stopping criteria using setStoppingCriteria().
+ * - Solve the linear system, passing in u and f as the patch
+ *   indices of the solution and the right hand side, respectively.
+ *
+ * Sample parameters for initialization from database (and their
+ * default values):
+ * @verbatim
+ *     print_solver_info = FALSE      // Whether to print some data for debugging
+ *     max_iterations = 10            // Max iterations used by Hypre
+ *     relative_residual_tol = 1.0e-8 // Residual tolerance used by Hypre
+ *     num_pre_relax_steps = 1        // # of presmoothing steps used by Hypre
+ *     num_post_relax_steps = 1       // # of postsmoothing steps used by Hypre
+ *     use_smg = FALSE                // Whether to use hypre's smg solver
+ *                                    // (alternative is the pfmg solver)
+ * @endverbatim
+ */
+
+class HypreSolver
+{
+public:
+   /*!
+    * @brief Constructor.
+    *
+    * @param object_name Name of object.
+    * @param database tbox::Database for input.
+    */
+   HypreSolver(
+      const tbox::Dimension& dim,
+      const std::string& object_name,
+      tbox::Pointer<tbox::Database> database =
+         tbox::Pointer<tbox::Database>(NULL));
+
+   /*!
+    * The Elastic destructor releases all internally managed data.
+    */
+   ~HypreSolver();
+
+   /*!
+    * @brief Initialize to a given hierarchy.
+    *
+    * Initializer Elastic solver for a patch level in a hierarchy.
+    *
+    * @param hierarchy Hierarchy
+    * @param ln Level number
+    */
+   void
+   initializeSolverState(
+      tbox::Pointer<hier::PatchHierarchy> hierarchy,
+      int ln = 0);
+
+   /*!
+    * @brief Reset to an uninitialized state.
+    */
+   void
+   deallocateSolverState();
+
+   /*!
+    * @brief Set the matrix coefficients
+    *
+    * For information describing the Elastic equation parameters,
+    * see the light-weight Elastic::Specifications class where
+    * you set the values of C and D.
+    *
+    * This method must be called before solveSystem().
+    */
+   void
+   setMatrixCoefficients();
+
+   /*!
+    * @brief Set default depth of the solution data involved in the solve.
+    *
+    * If the solution data has multiple depths,
+    * the solver uses just one depth at a time.
+    * The default depth is the first depth.
+    * Use this function to change it.
+    * This is not used to set the depth of the data (which is not
+    * controled by this class) but the depth used in the solve.
+    *
+    * Changing the depth after setting up the matrix is permissible,
+    * as the solution data does not affect the matrix.
+    */
+   void
+   setSolnIdDepth(
+      const int depth);
+
+   /*!
+    * @brief Set default depth of the rhs data involved in the solve.
+    *
+    * If the rhs data has multiple depths,
+    * the solver uses just one depth at a time.
+    * The default depth is the first depth.
+    * Use this function to change it.
+    * This is not used to set the depth of the data (which is not
+    * controled by this class) but the depth used in the solve.
+    *
+    * Changing the depth after setting up the matrix is permissible,
+    * as the rhs data does not affect the matrix.
+    */
+   void
+   setRhsIdDepth(
+      const int depth);
+
+   /*!
+    * @brief Set the stopping criteria (max iterations and residual
+    * tolerance) for the linear solver.
+    *
+    * @param max_iterations gives the maximum number of iterations
+    * @param relative_residual_tol the maximum error tolerance
+    */
+   void
+   setStoppingCriteria(
+      const int max_iterations = 10,
+      const double relative_residual_tol = 1.0e-6);
+
+   /*!
+    * @brief Solve the linear system Au=f.
+    *
+    * The solution u and the right hand side f are
+    * specified via patch indices on the patch hierarchy.
+    *
+    * Member functions getNumberOfIterations() return the iterations
+    * from the solver.
+    * Note that the matrix coefficients and boundary condition object
+    * must have been set up before this function is called.
+    * As long as the matrix coefficients do not change,
+    * this routine may be called repeatedly to solve any number of linear
+    * systems (with the right-hand side varying).
+    * If the boundary conditions or matrix coefficients are changed
+    * then function setMatrixCoefficients() must be called again.
+    *
+    * When computing the matrix coefficients in setMatrixCoefficients(),
+    * the inhomogeneous portion of the boundary condition (constant
+    * terms, independent of u and thus having no effect on the matrix)
+    * are saved and added to the source term, f,
+    * before performing the matrix solve.  In some situations, it may be
+    * useful to not add the inhomogeneous portion to f.  The flag argument
+    * @c homoegneous_bc is used for this.  (This is a sort of optimization,
+    * to avoid having to re-call setMatrixCoefficients() to change the
+    * inhomogeneous portion.)
+    *
+    * @param u Descriptor of cell-centered unknown variable.
+    * @param f Descriptor of cell-centered source variable.
+    * @param homogeneous_bc Whether homogeneous boundary conditions
+    *        are assumed.
+    *
+    * @return whether solver converged to specified level
+    */
+   int
+   solveSystem(
+      const int u,
+      const int f,
+      bool homogeneous_bc = false);
+
+   /*!
+    * @brief Return the number of iterations taken by the solver to converge.
+    *
+    * @return number of iterations taken by the solver to converge
+    */
+   int
+   getNumberOfIterations() const;
+
+   /*!
+    * @brief Set the number of pre-relax steps used by the Hypre solve.
+    */
+   void
+   setNumPreRelaxSteps(
+      const int steps);
+
+   /*!
+    * @brief Set the number of post-relax steps used by the Hypre solve.
+    */
+   void
+   setNumPostRelaxSteps(
+      const int steps);
+
+   /*!
+    * @brief Return the final residual norm returned by the Hypre solve.
+    * @return final residual norm returned by the Hypre solve.
+    */
+   double
+   getRelativeResidualNorm() const;
+
+   /*!
+    * @brief Set whether to use Hypre's PFMG algorithm instead of the
+    * SMG algorithm.
+    *
+    * The flag is used to select which of HYPRE's linear solver algorithms
+    * to use if true, the semicoarsening multigrid algorithm is used, and if
+    * false, the "PF" multigrid algorithm is used.
+    * By default, the SMG algorithm is used.
+    *
+    * Changing the algorithm must be done before setting up the matrix
+    * coefficients.
+    */
+   void
+   setUseSMG(
+      bool use_smg);
+
+   /*!
+    * @brief Specify boundary condition directly, without using
+    * a RobinBcCoefStrategy object.
+    *
+    * Use @em either setBoundaries() @em or setPhysicalBcCoefObject(),
+    * but not both.
+    *
+    * A SimpleCelBcCoef object is used to interpret and implement
+    * the specified boundary conditions.
+    * See SimpleCellRobinBcCoefs::setBoundaries()
+    * for an explanation of the arguments.
+    */
+   void
+   setBoundaries(
+      const std::string& boundary_type,
+      const int fluxes = -1,
+      const int flags = -1,
+      int* bdry_types = NULL);
+
+   /*!
+    * @brief Specify boundary condition through the use of a
+    * Robin boundary condition object.
+    *
+    * Use @em either setBoundaries() @em or setPhysicalBcCoefObject(),
+    * but not both.
+    *
+    * The Robin boundary condition object is used when setting
+    * the matrix coefficient and when solving the system.
+    * If your boundary conditions are fixed values at ghost
+    * cell centers, use the GhostCellRobinBcCoefs
+    * implementation of the RobinBcCoefStrategy strategy.
+    *
+    * @param physical_bc_coef_strategy tbox::Pointer a concrete
+    *        implementation of the Robin bc strategy.
+    * @param variable hier::Variable pointer to be passed
+    *        to RobinBcCoefStrategy::setBcCoefs(),
+    *        but otherwise unused by this class.
+    */
+   void
+   setPhysicalBcCoefObject(
+      const RobinBcCoefStrategy* physical_bc_coef_strategy,
+      const tbox::Pointer<hier::Variable> variable =
+         tbox::Pointer<hier::Variable>(NULL));
+
+   /*!
+    * @brief Set the flag for printing solver information.
+    *
+    * This optional function is used primarily for debugging.
+    *
+    * If set true, it will print the HYPRE matrix information
+    * to the following files:
+    *
+    * - mat_bA.out - before setting matrix coefficients in matrix assemble
+    * - mat_aA.out - after setting matrix coefficients in matrix assemble
+    * - sol0.out   - u before solve (i.e. for system Au = b)
+    * - sol.out    - u after solve
+    * - mat0.out   - A before solve
+    * - mat.out    - A after solve
+    * - rhs.out    - b before and after solve
+    *
+    * If this method is not called, or the flag is set false, no printing
+    * will occur.
+    */
+   void
+   setPrintSolverInfo(
+      const bool print);
+
+private:
+   /*!
+    * @brief Set state using database
+    *
+    * See the class description for the parameters that can be set
+    * from a database.
+    *
+    * @param database Input database.  If a NULL pointer is given,
+    * nothing is done.
+    */
+   void
+   getFromInput(
+      tbox::Pointer<tbox::Database> database);
+
+   void
+   setupHypreSolver();
+   void
+   destroyHypreSolver();
+   void
+   allocateHypreData();
+   void
+   deallocateHypreData();
+
+   void
+   copyToHypre(
+      HYPRE_StructVector vector,
+      pdat::CellData<double>& src,
+      int depth,
+      const hier::Box& box);
+   void
+   copyFromHypre(
+      pdat::CellData<double>& dst,
+      int depth,
+      HYPRE_StructVector vector,
+      const hier::Box box);
+
+   /*!
+    * @brief Add g*A*k0(a) from boundaries to rhs.
+    *
+    * Move the constant portion of the boundary condition
+    * contribution to the right hand side and add it to the existing rhs.
+    * This operation is done for physical as well as cf boundaries,
+    * so it is placed in a function.
+    *
+    * The boundary boxes given must be to either the physical
+    * boundary or coarse-fine boundary for the patch.  The
+    * bc coefficient implementation should correspond to the
+    * boundary being worked on.
+    */
+   void
+   add_gAk0_toRhs(
+      const hier::Patch& patch,
+      const tbox::Array<hier::BoundaryBox>& bdry_boxes,
+      const RobinBcCoefStrategy* robin_bc_coef,
+      pdat::CellData<double>& rhs);
+
+   //@{
+
+   /*!
+    * @name Dimension-independent functions to organize Fortran interface.
+    */
+
+   //! @brief Compute diagonal entries of the matrix when C is variable.
+   void
+   computeDiagonalEntries(
+      pdat::CellData<double>& diagonal,
+      const pdat::CellData<double>& C_data,
+      const pdat::SideData<double>& variable_off_diagonal,
+      const hier::Box& patch_box);
+   //! @brief Compute diagonal entries of the matrix when C is constant.
+   void
+   computeDiagonalEntries(
+      pdat::CellData<double>& diagonal,
+      const double C,
+      const pdat::SideData<double>& variable_off_diagonal,
+      const hier::Box& patch_box);
+   //! @brief Compute diagonal entries of the matrix when C is zero.
+   void
+   computeDiagonalEntries(
+      pdat::CellData<double>& diagonal,
+      const pdat::SideData<double>& variable_off_diagonal,
+      const hier::Box& patch_box);
+   /*!
+    * @brief Adjust boundary entries for variable off-diagonals.
+    *
+    * At the same time, save information that are needed to adjust
+    * the rhs.
+    */
+   void
+   adjustBoundaryEntries(
+      pdat::CellData<double>& diagonal,
+      const pdat::SideData<double>& variable_off_diagonal,
+      const hier::Box& patch_box,
+      const pdat::ArrayData<double>& acoef_data,
+      const pdat::ArrayData<double>& bcoef_data,
+      const hier::Box bccoef_box,
+      pdat::ArrayData<double>& Ak0_data,
+      const hier::BoundaryBox& trimmed_boundary_box,
+      const double h[tbox::Dimension::MAXIMUM_DIMENSION_VALUE]);
+
+   //@}
+
+   //! @brief Free static variables at shutdown time.
+   static void
+   finalizeCallback();
+
+   /*!
+    * @brief Object dimension.
+    */
+   const tbox::Dimension d_dim;
+
+   /*!
+    * @brief Object name.
+    */
+   std::string d_object_name;
+
+   /*!
+    * @brief Associated hierarchy.
+    */
+   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
+
+   /*!
+    * @brief Associated level number.
+    *
+    * Currently, this must be level number 0.
+    */
+   int d_ln;
+
+   /*!
+    * @brief Scratch context for this object.
+    */
+   tbox::Pointer<hier::VariableContext> d_context;
+
+   //@{ @name Boundary condition handling
+
+   /*!
+    * @brief The coarse-fine boundary description for level d_ln.
+    *
+    * The coarse-fine boundary is computed when the operator
+    * state is initialized.  It is used to allow solves on
+    * levels that are not the coarsest in the hierarchy.
+    */
+   tbox::Pointer<hier::CoarseFineBoundary> d_cf_boundary;
+
+   /*!
+    * @brief Robin boundary coefficient object for physical
+    * boundaries.
+    *
+    * If d_physical_bc_coef_strategy is set, use it, otherwise,
+    * use d_physical_bc_simple_case.
+    */
+   const RobinBcCoefStrategy* d_physical_bc_coef_strategy;
+   tbox::Pointer<hier::Variable> d_physical_bc_variable;
+
+   /*!
+    * @brief Implementation of Robin boundary conefficients
+    * for the case of simple boundary conditions.
+    */
+   SimpleCellRobinBcCoefs d_physical_bc_simple_case;
+
+   /*!
+    * @brief Robin boundary coefficient object for coarse-fine
+    * boundaries.
+    *
+    * This is a GhostCellRobinBcCoefs object because we
+    * expect the users to have the correct ghost cell values
+    * in the coarse-fine boundaries before solving.
+    */
+   GhostCellRobinBcCoefs d_cf_bc_coef;
+   tbox::Pointer<hier::Variable> d_coarsefine_bc_variable;
+
+   //@}
+
+   /*!
+    * @brief hier::Patch index of A*k0(a) quantity
+    *
+    * A*k0(a) is the quantity that is saved for
+    * later adding to the rhs.
+    *
+    * The Robin bc is expressed by the coefficients a and g
+    * on the boundary (see RobinBcCoefStrategy).
+    * This class uses a central difference approximation of
+    * the Robin bc, which results in the value at a ghost cell,
+    * uo, being writen as uo = g*k0(a) + k1(a)*ui, where ui is
+    * the first interior cell value, k0 and k1 depend on a as
+    * indicated.
+    *
+    * In setting up the Au=f system, the contribution of k1(a)*ui
+    * is incorporated into the product Au.  The contribution of
+    * A*g*k0(a) should be moved to the right hand side and saved for
+    * later adding to f.  However, the value of g is not provided
+    * until solve time.  Therefore, we save just A*k0(a) at the
+    * patch data index d_Ak0_id.
+    */
+   int d_Ak0_id;
+
+   static tbox::Pointer<pdat::OutersideVariable<double> > s_Ak0_var[tbox::
+                                                                    Dimension::
+                                                                    MAXIMUM_DIMENSION_VALUE];
+
+   /*!
+    * @brief Depth of the solution variable.
+    */
+   int d_soln_depth;
+
+   /*!
+    * @brief Depth of the rhs variable.
+    */
+   int d_rhs_depth;
+
+   int d_max_iterations;
+   double d_relative_residual_tol;
+
+   int d_number_iterations; // iterations in solver
+   int d_num_pre_relax_steps;  // pre-relax steps in solver
+   int d_num_post_relax_steps; // post-relax steps in solver
+   double d_relative_residual_norm;  // norm from solver
+
+   /*@
+    * @brief Flag to use SMG or PFMG (default)
+    */
+   bool d_use_smg;
+
+   //@{
+   //! @name Hypre object
+   //! @brief HYPRE grid
+   HYPRE_StructGrid d_grid;
+   //! @brief HYPRE stencil
+   HYPRE_StructStencil d_stencil;
+   //! @brief HYPRE structured matrix
+   HYPRE_StructMatrix d_matrix;
+   //! @brief Hypre RHS vector for linear solves
+   HYPRE_StructVector d_linear_rhs;
+   //! @brief Hypre solution vector
+   HYPRE_StructVector d_linear_sol;
+   //! @brief Hypre SMG solver data
+   HYPRE_StructSolver d_mg_data;
+   //@}
+
+   //@{
+
+   //! @name Variables for debugging and analysis.
+
+   /*!
+    * @brief Flag to print solver info
+    *
+    * See setPrintSolverInfo().
+    */
+   bool d_print_solver_info;
+
+   //@}
+
+   /*!
+    * @brief Timers for performance measurement.
+    */
+   tbox::Pointer<tbox::Timer> t_solve_system;
+   tbox::Pointer<tbox::Timer> t_set_matrix_coefficients;
+
+   static tbox::StartupShutdownManager::Handler s_finalize_handler;
+};
+
+}
+}
+} // namespace SAMRAI
+
+#ifdef SAMRAI_INLINE
+#include "Elastic/HypreSolver.I"
+#endif
+
+#endif
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Boundary_Refine.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Boundary_Refine.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for cell-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_P_Boundary_Refine
+#define included_geom_P_Boundary_Refine
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class P_Boundary_Refine implements the special interpolation needed
+ * for the boundary elements on the coarse-fine interface.
+ *
+ * The findRefineOperator() operator function returns true if the input
+ * variable is cell-centered double, and the std::string is "P_BOUNDARY_REFINE".
+ *
+ * @see xfer::RefineOperator
+ */
+
+class P_Boundary_Refine:
+  public xfer::RefineOperator
+{
+public:
+  /**
+   * Uninteresting default constructor.
+   */
+  explicit P_Boundary_Refine(const tbox::Dimension& dim):
+    xfer::RefineOperator(dim, "P_BOUNDARY_REFINE")
+  {
+    d_name_id = "P_BOUNDARY_REFINE";
+  }
+
+
+  /**
+   * Uninteresting virtual destructor.
+   */
+  virtual ~P_Boundary_Refine(){}
+
+  /**
+   * Return true if the variable and name std::string match cell-centered
+   * double linear interpolation; otherwise, return false.
+   */
+  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
+                          const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /**
+   * Return name std::string identifier of this refinement operator.
+   */
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  /**
+   * The priority of cell-centered double linear interpolation is 0.
+   * It will be performed before any user-defined interpolation operations.
+   */
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  /**
+   * The stencil width of the linear interpolation operator is the vector
+   * of ones.  That is, its stencil extends one cell outside the fine box.
+   */
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getOne(getDim());
+  }
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the cell-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the boxes contained in fine_overlap
+   * It is assumed that the coarse patch contains sufficient data for the
+   * stencil width of the refinement operator.
+   */
+  virtual void refine(hier::Patch& fine,
+                      const hier::Patch& coarse,
+                      const int dst_component,
+                      const int src_component,
+                      const hier::BoxOverlap& fine_overlap,
+                      const hier::IntVector& ratio) const;
+
+
+private:
+  std::string d_name_id;
+
+  void Update_P_2D(const pdat::CellIndex &fine,
+                   const hier::Index &ip, const hier::Index &jp,
+                   const int &j, const int &j_max,
+                   SAMRAI::pdat::CellData<double> &p,
+                   SAMRAI::pdat::CellData<double> &p_fine)
+    const;
+
+  void Update_P_3D(const pdat::CellIndex &fine,
+                   const hier::Index &ip, const hier::Index &jp,
+                   const hier::Index &kp,
+                   const int &j, const int &k, const int &j_max, const int &k_max,
+                   SAMRAI::pdat::CellData<double> &p,
+                   SAMRAI::pdat::CellData<double> &p_fine)
+    const;
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Boundary_Refine/Update_P_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Boundary_Refine/Update_P_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,74 @@
+#include "Elastic/P_Boundary_Refine.h"
+
+/* Interpolate the pressure from the coarse (C) to the fine (f+/-)
+   coordinates using the intermediate fine points (F+/-, F_).
+
+         i-1      i       i+1
+
+        ------- -------
+       |       |       |
+   j-1 |   C   |   C   |   C
+       |       |       |
+        ------- -------
+       |       |f- F-  |
+   j   |   C   |F_ C   |   C
+       |       |f+ F+  |
+        ------- -------
+       |       |       |
+   j+1 |   C   |   C   |   C
+       |       |       |
+        ------- -------
+
+   C= a + b*x + c*x^2 + d*y + e*y^2 + f*x*y
+
+   C(0,0)=a
+   C(+,0)=a+b+c
+   C(-,0)=a-b+c
+   C(0,+)=a+d+e
+   C(0,-)=a-d+e
+   C(-,-)=a-b+c-d+e+f
+
+   f(-,-) = a - b/4 + c/16 - d/4 + e/16 + f/16
+          = C(-,-)/16 + (15/16)*C(0,0)
+            + (3/32)*(-C(+,0) - C(0,+) + C(-,0) + C(0,-))
+   
+   This example show a boundary in the positive x direction.  To reverse
+   the direction, pass in ip -> -ip.  To do the y direction, switch ip
+   and jp, and replace j with i.
+
+*/
+     
+
+void SAMRAI::geom::P_Boundary_Refine::Update_P_2D
+(const pdat::CellIndex &fine,
+ const hier::Index &ip, const hier::Index &jp,
+ const int &j, const int &j_max,
+ SAMRAI::pdat::CellData<double> &p,
+ SAMRAI::pdat::CellData<double> &p_fine) const
+{
+  pdat::CellIndex center(fine);
+  center.coarsen(hier::Index(2,2));
+
+    
+  /* If we are at an even index, update both of the elements in the cell */
+  if(j%2==0)
+    {
+      const double p_low=p(center-ip-jp)/16 + (15.0/16)*p(center)
+        + (3.0/32)*(-p(center+ip) - p(center+jp) + p(center-ip) + p(center-jp));
+      p_fine(fine)=p_low;
+      if(j<j_max)
+        {
+          const double p_high=p(center-ip+jp)/16 + (15.0/16)*p(center)
+            + (3.0/32)*(-p(center+ip) - p(center-jp)
+                        + p(center-ip) + p(center+jp));
+          p_fine(fine+jp)=p_high;
+        }
+    }
+  else
+    {
+      const double p_high=p(center-ip+jp)/16 + (15.0/16)*p(center)
+        + (3.0/32)*(-p(center+ip) - p(center-jp)
+                    + p(center-ip) + p(center+jp));
+      p_fine(fine)=p_high;
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Boundary_Refine/Update_P_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Boundary_Refine/Update_P_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,113 @@
+#include "Elastic/P_Boundary_Refine.h"
+
+/* Interpolate the pressure from the coarse (C) to the fine (f+/-)
+   coordinates using the intermediate fine points (F+/-, F_).
+
+          i-1      i       i+1
+
+        ------- -------
+       |       |       |
+   j-1 |  C    |   C   |   C
+       |       |       |
+       ------- -------
+       |       |f- Y-  |
+   j   |   C   |X_ C   |   C
+       |       |f+ Y+  |
+       ------- -------
+       |       |       |
+   j+1 |   C   |   C   |   C
+       |       |       |
+       ------- -------
+
+
+   C= a + b*x + c*x^2 + d*y + e*y^2 + f*z + g*z^2
+        + h*x*y + i*x*z + j*y*z + k*x*y*z
+
+   C(0,0,0)=a
+   C(+,0,0)=a+b+c
+   C(-,0,0)=a-b+c
+   C(0,+,0)=a+d+e
+   C(0,-,0)=a-d+e
+   C(-,-,0)=a-b+c-d+e+h
+   C(-,-,-)=a-b+c-d+e-f+g+h+i+j-k
+
+   f(-,-) = a - b/4 + c/16 - d/4 + e/16 - f/4 + g/16 + h/16 + i/16 + j/16 - k/64
+          = C(-,-)/64 + (63/64)*C(0,0)
+            - (6/64)*(C(+,0,0) + C(0,+,0) + C(0,0,+))
+            + (3/64)*(C(-,0,0) + C(0,-,0) + C(0,0,-)
+                      + C(-,-,0) + C(-,0,-) + C(0,-,-))
+
+   Note that if, for example, C is constant in the Z direction, then
+   this formula reduces to the one used in Update_P_2D.
+
+   This example show a boundary in the positive x direction.  To
+   reverse the direction, pass in ip -> -ip.  To do the y direction,
+   rotate [ip,jp,kp], and switch j with k.  To do z, rotate again and
+   switch k with i.
+*/
+     
+
+void SAMRAI::geom::P_Boundary_Refine::Update_P_3D
+(const pdat::CellIndex &fine,
+ const hier::Index &ip, const hier::Index &jp, const hier::Index &kp,
+ const int &j, const int &k, const int &j_max, const int &k_max,
+ SAMRAI::pdat::CellData<double> &p,
+ SAMRAI::pdat::CellData<double> &p_fine) const
+{
+  pdat::CellIndex center(fine);
+  center.coarsen(hier::Index(2,2,2));
+
+  const double p_mmm=p(center-ip-jp-kp)/64 + (63.0/64)*p(center)
+    - (3.0/32) * (p(center+ip) + p(center+jp) + p(center+kp))
+    + (3.0/64) * (p(center-ip) + p(center-jp) + p(center-kp)
+                  + p(center-ip-jp) + p(center-jp-kp) + p(center-ip-kp));
+
+  const double p_mmp=p(center-ip-jp+kp)/64 + (63.0/64)*p(center)
+    - (3.0/32) * (p(center+ip) + p(center+jp) + p(center-kp))
+    + (3.0/64) * (p(center-ip) + p(center-jp) + p(center+kp)
+                  + p(center-ip-jp) + p(center-jp+kp) + p(center-ip+kp));
+
+  const double p_mpm=p(center-ip+jp-kp)/64 + (63.0/64)*p(center)
+    - (3.0/32) * (p(center+ip) + p(center-jp) + p(center+kp))
+    + (3.0/64) * (p(center-ip) + p(center+jp) + p(center-kp)
+                  + p(center-ip+jp) + p(center+jp-kp) + p(center-ip-kp));
+
+  const double p_mpp=p(center-ip+jp+kp)/64 + (63.0/64)*p(center)
+    - (3.0/32) * (p(center+ip) + p(center-jp) + p(center-kp))
+    + (3.0/64) * (p(center-ip) + p(center+jp) + p(center+kp)
+                  + p(center-ip+jp) + p(center+jp+kp) + p(center-ip+kp));
+
+  /* If we are at an even index, update both of the elements in the cell */
+  if(j%2==0)
+    {
+      if(k%2==0)
+        {
+          p_fine(fine)=p_mmm;
+          if(j<j_max)
+            p_fine(fine+jp)=p_mpm;
+          if(k<k_max)
+            p_fine(fine+kp)=p_mmp;
+          if(j<j_max && k<k_max)
+            p_fine(fine+jp+kp)=p_mpp;
+        }
+      else
+        {
+          p_fine(fine)=p_mmp;
+          if(j<j_max)
+            p_fine(fine+jp)=p_mpp;
+        }
+    }
+  else
+    {
+      if(k%2==0)
+        {
+          p_fine(fine)=p_mpm;
+          if(k<k_max)
+            p_fine(fine+kp)=p_mpp;
+        }
+      else
+        {
+          p_fine(fine)=p_mpp;
+        }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Boundary_Refine/refine.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Boundary_Refine/refine.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,125 @@
+#include "Elastic/P_Boundary_Refine.h"
+#include "Elastic/set_boundary.h"
+#include "Constants.h"
+
+void SAMRAI::geom::P_Boundary_Refine::refine(hier::Patch& fine,
+                                             const hier::Patch& coarse,
+                                             const int dst_component,
+                                             const int src_component,
+                                             const hier::BoxOverlap& overlap,
+                                             const hier::IntVector& ratio)
+  const
+{
+  const pdat::CellOverlap* t_overlap =
+    dynamic_cast<const pdat::CellOverlap *>(&overlap);
+  const hier::BoxList& boxes = t_overlap->getDestinationBoxList();
+  const tbox::Dimension& dimension(getDim());
+  const int dim(dimension.getValue());
+
+  set_boundary(coarse,src_component,invalid_id,true);
+
+  for (hier::BoxList::Iterator b(boxes); b; b++)
+    {
+      hier::Box &overlap_box=b();
+      TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension,fine,coarse,overlap_box,ratio);
+
+      tbox::Pointer<pdat::CellData<double> >
+        p = coarse.getPatchData(src_component);
+      tbox::Pointer<pdat::CellData<double> >
+        p_fine = fine.getPatchData(dst_component);
+#ifdef DEBUG_CHECK_ASSERTIONS
+      TBOX_ASSERT(!p.isNull());
+      TBOX_ASSERT(!p_fine.isNull());
+      TBOX_ASSERT(p->getDepth() == p_fine->getDepth());
+      TBOX_ASSERT(p->getDepth() == 1);
+#endif
+
+      hier::Box fine_box=fine.getBox();
+      hier::Box gbox=p_fine->getGhostBox();
+
+      /* We have to infer where the boundary is from the boxes */
+      int boundary_direction;
+      bool boundary_positive;
+
+      for(int d=0;d<dim;++d)
+        {
+          if(overlap_box.lower(d)-overlap_box.upper(d)==0)
+            {
+              boundary_direction=d;
+              if(fine_box.upper(d)<overlap_box.lower(d))
+                boundary_positive=true;
+              else if(fine_box.lower(d)>overlap_box.upper(d))
+                boundary_positive=false;
+              else
+                abort();
+              break;
+            }
+        }
+
+      hier::Index p_min(dimension), p_max(dimension);
+      for(int d=0;d<dim;++d)
+        {
+          p_min[d]=std::max(overlap_box.lower(d),gbox.lower(d));
+          p_max[d]=std::min(overlap_box.upper(d),gbox.upper(d));
+        }
+
+      hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
+      ip[0]=1;
+      jp[1]=1;
+      if(dim>2)
+        kp[2]=1;
+
+      if(dim==2)
+        {
+          /* This odd stride is because we handle all of the fine
+           * boundary cells in a coarse cell at once.  However,
+           * sometimes there is only one fine cell in a coarse cell,
+           * so the starting point does not align with the coarse
+           * cell.  The stride ensures that, if we start not aligned,
+           * the next step will be aligned. */
+
+          for(int j=p_min[1]; j<=p_max[1]; j=(j/2)*2+2)
+            for(int i=p_min[0]; i<=p_max[0]; i=(i/2)*2+2)
+              {
+                pdat::CellIndex fine(hier::Index(i,j));
+        
+                switch(boundary_direction)
+                  {
+                  case 0:
+                    Update_P_2D(fine,boundary_positive ? ip : -ip,jp,j,p_max[1],
+                                *p,*p_fine);
+                    break;
+                  case 1:
+                    Update_P_2D(fine,boundary_positive ? jp : -jp,ip,i,p_max[0],
+                                *p,*p_fine);
+                    break;
+                  }
+              }
+        }
+      else
+        {
+          for(int k=p_min[2]; k<=p_max[2]; ++k)
+            for(int j=p_min[1]; j<=p_max[1]; ++j)
+              for(int i=p_min[0]; i<=p_max[0]; ++i)
+                {
+                  pdat::CellIndex fine(hier::Index(i,j,k));
+        
+                  switch(boundary_direction)
+                    {
+                    case 0:
+                      Update_P_3D(fine,boundary_positive ? ip : -ip,jp,kp,
+                                  j,k,p_max[1],p_max[2],*p,*p_fine);
+                      break;
+                    case 1:
+                      Update_P_3D(fine,boundary_positive ? jp : -jp,kp,ip,
+                                  k,i,p_max[2],p_max[0],*p,*p_fine);
+                      break;
+                    case 2:
+                      Update_P_3D(fine,boundary_positive ? kp : -kp,ip,jp,
+                                  i,j,p_max[0],p_max[1],*p,*p_fine);
+                      break;
+                    }
+                }
+        }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Refine.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Refine.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for cell-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_P_Refine_C
+#define included_geom_P_Refine_C
+
+#include "P_Refine.h"
+
+#include <float.h>
+#include <math.h>
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include "SAMRAI/tbox/Utilities.h"
+
+void SAMRAI::geom::P_Refine::refine(
+   hier::Patch& fine,
+   const hier::Patch& coarse,
+   const int dst_component,
+   const int src_component,
+   const hier::BoxOverlap& fine_overlap,
+   const hier::IntVector& ratio) const
+{
+   const pdat::CellOverlap* t_overlap =
+      dynamic_cast<const pdat::CellOverlap *>(&fine_overlap);
+
+   TBOX_ASSERT(t_overlap != NULL);
+
+   const hier::BoxList& boxes = t_overlap->getDestinationBoxList();
+   for (hier::BoxList::Iterator b(boxes); b; b++) {
+      refine(fine,
+         coarse,
+         dst_component,
+         src_component,
+         b(),
+         ratio);
+   }
+}
+
+void SAMRAI::geom::P_Refine::refine(
+   hier::Patch& fine_patch,
+   const hier::Patch& coarse_patch,
+   const int dst_component,
+   const int src_component,
+   const hier::Box& fine_box,
+   const hier::IntVector& ratio) const
+{
+   const tbox::Dimension& dim(getDim());
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dim, fine_patch, coarse_patch,
+                                   fine_box, ratio);
+
+   tbox::Pointer<pdat::CellData<double> >
+   p = coarse_patch.getPatchData(src_component);
+   tbox::Pointer<pdat::CellData<double> >
+   p_fine = fine_patch.getPatchData(dst_component);
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(!p.isNull());
+   TBOX_ASSERT(!p_fine.isNull());
+   TBOX_ASSERT(p->getDepth() == p_fine->getDepth());
+#endif
+
+   hier::Box coarse_box=coarse_patch.getBox();
+   tbox::Pointer<geom::CartesianPatchGeometry>
+     geom = coarse_patch.getPatchGeometry();
+
+   for(pdat::CellIterator ci(fine_box); ci; ci++)
+     {
+       pdat::CellIndex fine(*ci);
+
+       pdat::CellIndex
+         center(hier::Index::coarsen(fine,hier::Index::getOneIndex(dim)*2));
+
+       /* Pressure is cell-centered, so prolongation is a
+          linear interpolation from nearby cells. */
+
+       /* This assumes that the levels are always properly nested,
+          so that we always have an extra grid space for
+          interpolation.  So we only have to have a special case for
+          physical boundaries, where we do not have an extra grid
+          space. */
+
+       /* We could, in theory, use a refine_patch_strategy to fill
+          in the ghost zones with extrapolations, and then use
+          simple differences here. */
+
+       (*p_fine)(fine)=(*p)(center);
+       for(int d=0; d<dim.getValue(); ++d)
+         {
+           hier::Index ip(hier::Index::getZeroIndex(dim));
+           ip[d]=1;
+           double dp;
+           if(center[d]==coarse_box.lower(d)
+              && geom->getTouchesRegularBoundary(d,0))
+             {
+               dp=((*p)(center+ip)-(*p)(center))/4;
+             }
+           else if(center[d]==coarse_box.upper(d)
+                   && geom->getTouchesRegularBoundary(d,1))
+             {
+               dp=((*p)(center)-(*p)(center-ip))/4;
+             }
+           else
+             {
+               dp=((*p)(center+ip)-(*p)(center-ip))/8;
+             }
+           (*p_fine)(fine)+=((fine[d]%2==0) ? (-dp) : dp);
+         }           
+       }
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Refine.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Refine.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for cell-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_P_Refine
+#define included_geom_P_Refine
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/CellVariable.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class P_Refine implements linear
+ * interpolation for cell-centered double patch data defined over a Cartesian
+ * mesh.  It is derived from the xfer::RefineOperator base class.
+ * CartesianCellDoubleLinearRefine does not handle the lack of real
+ * boundaries for the pressure very well, so use this instead for
+ * pressure.
+ *
+ * The findRefineOperator() operator function returns true if the input
+ * variable is cell-centered double, and the std::string is "P_REFINE".
+ *
+ * @see xfer::RefineOperator
+ */
+
+class P_Refine:
+  public xfer::RefineOperator
+{
+public:
+  /**
+   * Uninteresting default constructor.
+   */
+  explicit P_Refine(const tbox::Dimension& dim):
+    xfer::RefineOperator(dim, "P_REFINE")
+  {
+    d_name_id = "P_REFINE";
+  }
+
+
+  /**
+   * Uninteresting virtual destructor.
+   */
+  virtual ~P_Refine(){}
+
+  /**
+   * Return true if the variable and name std::string match cell-centered
+   * double linear interpolation; otherwise, return false.
+   */
+  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
+                          const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /**
+   * Return name std::string identifier of this refinement operator.
+   */
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  /**
+   * The priority of cell-centered double linear interpolation is 0.
+   * It will be performed before any user-defined interpolation operations.
+   */
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  /**
+   * The stencil width of the linear interpolation operator is the vector
+   * of ones.  That is, its stencil extends one cell outside the fine box.
+   */
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getOne(getDim());
+  }
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the cell-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the boxes contained in fine_overlap
+   * It is assumed that the coarse patch contains sufficient data for the
+   * stencil width of the refinement operator.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::BoxOverlap& fine_overlap,
+              const hier::IntVector& ratio) const;
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the cell-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the fine box.   It is assumed that the
+   * coarse patch contains sufficient data for the stencil width of the
+   * refinement operator.  This differs from the above refine() method
+   * only in that it operates on a single fine box instead of a BoxOverlap.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::Box& fine_box,
+              const hier::IntVector& ratio) const;
+
+private:
+  std::string d_name_id;
+
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/P_Refine_Patch_Strategy.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/P_Refine_Patch_Strategy.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,408 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Robin boundary condition support on cartesian grids. 
+ *
+ ************************************************************************/
+#ifndef included_solv_P_Refine_Patch_Strategy
+#define included_solv_P_Refine_Patch_Strategy
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefinePatchStrategy.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/CellIndex.h"
+#include "Constants.h"
+#include "set_boundary.h"
+
+namespace SAMRAI {
+namespace solv {
+
+/*!
+ * @brief Helper utility for setting boundary conditions on P.
+ *
+ * This class inherits and implements virtual functions from
+ * xfer::RefinePatchStrategy so it may be used to help create
+ * communication schedules if desired.
+ */
+class P_Refine_Patch_Strategy:
+   public xfer::RefinePatchStrategy
+{
+
+public:
+   /*!
+    * @brief Constructor using.
+    *
+    * @param object_name Name of the object, for general referencing.
+    * @param coef_strategy Coefficients strategy being helped.
+    */
+   P_Refine_Patch_Strategy(
+      const tbox::Dimension& dim,
+      std::string object_name = std::string()):
+     xfer::RefinePatchStrategy(dim), d_dim(dim),d_object_name(object_name) {}
+
+   /*!
+    * @brief Destructor.
+    */
+   virtual ~P_Refine_Patch_Strategy(void) {}
+
+   //@{ @name xfer::RefinePatchStrategy virtuals
+
+   virtual void
+   setPhysicalBoundaryConditions(
+      hier::Patch& ,
+      const double ,
+      const hier::IntVector& ) {}
+   hier::IntVector
+   getRefineOpStencilWidth() const
+  { return hier::IntVector::getOne(d_dim); }
+   // virtual void
+   // preprocessRefineBoxes(
+   //    hier::Patch& fine,
+   //    const hier::Patch& coarse,
+   //    const hier::BoxList& fine_boxes,
+   //    const hier::IntVector& ratio) {}
+   virtual void
+   preprocessRefine(hier::Patch& ,
+                    const hier::Patch& coarse,
+                    const hier::Box& ,
+                    const hier::IntVector& )
+  {
+    set_boundary(coarse,p_id,invalid_id,true);
+  }
+
+   virtual void
+   postprocessRefineBoxes(
+      hier::Patch& ,
+      const hier::Patch& ,
+      const hier::BoxList& ,
+      const hier::IntVector& ) {}
+   virtual void
+   postprocessRefine(
+      hier::Patch& ,
+      const hier::Patch& ,
+      const hier::Box& ,
+      const hier::IntVector& ) {}
+
+   //@}
+
+   //@{
+
+   /*!
+    * @name Functions to set boundary condition values
+    */
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the first ghost cells.
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to cell-centered variables.
+    * -# Only one ghost cell width is filled.  Setting a Robin
+    *    boundary condition for cell-centered quantities requires
+    *    only one ghost cell to be set.
+    *    (More ghost cells can be filled by continuing the linear
+    *    distribution of data beyond the first cell, but that is
+    *    not implemented at this time.)
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to
+    * get the coefficients, then it sets the values in the first
+    * ghost cell on the boundary.
+    *
+    * To determine the value for the ghost cell,
+    * a @em linear approximation in the direction normal to the
+    * boundary is assumed.  We write the following discrete
+    * approximations:
+    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
+    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
+    * where the subscript b stands for the the boundary,
+    * i stands for the first cell inside the boundary and
+    * o stands for the first cell outside the boundary
+    * and h is the grid spacing normal to the boundary.
+    * Applying this to the Robin formula gives
+    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
+    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
+    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
+    *
+    * After setting the edge (face in 3D) boundary conditions,
+    * linear approximations are used to set the boundary conditions
+    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required in solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @internal To be more general to other data types,
+    * there could be versions for other data types also,
+    * such as ...InNodes, ...InFaces, etc.  However, I'm not
+    * sure exactly how to implement the Robin boundary condition
+    * on the faces and nodes when m != 1.  Should the boundary
+    * value be set or should the first ghost value be set?
+    *
+    * @internal I have not addressed possibility of differences
+    * in chosing the discrete formulation with which to compute
+    * the boundary value.  The above formulation is obviously
+    * one specific approximation, but there could be others.
+    * If anoter approximation is required, there should be
+    * another class like this or this class can offer a choice
+    * to be set by the user.  I favor another class.
+    *
+    * @internal Since the data alignment can be found through
+    * the target_data_id, these types of functions may be changed
+    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
+    * since it does assume boundary boxes.  This may have to be
+    * expanded to later include coarse-fine boundary boxes
+    * for more generality.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set ghost cells for an entire level.
+    *
+    * Loop through all patches on the given level and call
+    * setBoundaryValuesInCells(hier::Patch &patch,
+    *                          const double fill_time ,
+    *                          const hier::IntVector &ghost_width_to_fill ,
+    *                          int target_data_id ,
+    *                          bool homogeneous_bc=false )
+    * for each.
+    *
+    * @param level PatchLevel on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::PatchLevel& level,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the boundary nodes.
+    *
+    * This function is not yet implemented!
+    *
+    * There are some decisions that must be made before
+    * the implementation can be written.
+    * -# Do we set the values on the boundary or one cell
+    *    away from the boundary?
+    * -# What is the discrete formulation we should use
+    *    to compute the value to be set?
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to node-centered variables.
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to get the
+    * coefficients, then it sets the values at the boundary nodes.
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required to solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param target_data_id hier::Patch data index of data to be set.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesAtNodes(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   //@}
+
+   //@{
+   /*!
+    * @name Ways to provide the Robin bc coefficients
+    */
+
+   /*!
+    * @brief Provide an implementation of the RobinBcCoefStrategy
+    * for determining the boundary coefficients.
+    *
+    * Provide the implementation that can be used to set the
+    * Robin bc coefficients.
+    *
+    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
+    *        the coefficient strategy.
+    */
+   // void
+   // setCoefImplementation(
+   //    const RobinBcCoefStrategy* coef_strategy);
+
+   /*!
+    * @brief Set the data id that should be filled when setting
+    * physical boundary conditions.
+    *
+    * When setPhysicalBoundaryConditions is called, the data
+    * specified will be set.  This information is required because
+    * the it is not passed in through the argument list of
+    * setPhysicalBounaryConditions.
+    */
+  void setTargetDataId(int id)
+  {
+    p_id=id;
+  }
+
+   /*!
+    * @brief Set whether boundary filling should assume homogeneous
+    * conditions.
+    *
+    * In certain circumstances, only the value of a is needed, while
+    * the value of g is temporarily not required and taken to be zero.
+    * (An example is in setting the boundary condition for error
+    * value in an iterative method.)  In such cases, use this function
+    * to set a flag that will cause a null pointer to be given to
+    * setBcCoefs() to indicate that fact.
+    */
+   // void
+   // setHomogeneousBc(
+   //    bool homogeneous_bc);
+
+   //@}
+
+private:
+   /*!
+    * @brief Trim a boundary box so that it does not stick out
+    * past a given box.
+    *
+    * Certain boundary-related operations occur on patch data that
+    * do not or cannot extend past the edgr or corner of a patch.
+    * This function is used to trim down the parts of the boundary box
+    * that extend past those points so that a suitable index range
+    * is achieved.
+    *
+    * The boundary box trimmed must be of type 1 or 2.
+    *
+    * @param boundary_box Boundary box to be trimmed.
+    * @param limit_box hier::Box to not stick past
+    *
+    * @return New trimmed boundary box.
+    */
+   // hier::BoundaryBox
+   // trimBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box,
+   //    const hier::Box& limit_box) const;
+
+   /*!
+    * @brief Return box describing the index space of boundary nodes
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the nodes corresponding
+    * to the input boundary box.  These nodes lie on the boundary
+    * itself.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the node indices corresponding to
+    *   boundary_box
+    */
+   // hier::Box
+   // makeNodeBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   /*!
+    * @brief Return box describing the index space of faces
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the codimension 1
+    * surface corresponding to the input boundary box.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * This is a utility function for working with the
+    * indices coresponding to a boundary box but coincide
+    * with the patch boundary.
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the face indices corresponding to
+    *    boundary_box
+    */
+   // hier::Box
+   // makeFaceBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   const tbox::Dimension d_dim;
+
+   std::string d_object_name;
+
+   /*!
+    * @brief Coefficient strategy giving a way to get to
+    * Robin bc coefficients.
+    */
+   // const RobinBcCoefStrategy* d_coef_strategy;
+
+   /*!
+    * @brief hier::Index of target patch data when filling ghosts.
+    */
+   int p_id;
+
+   /*!
+    * @brief Whether to assumg g=0 when filling ghosts.
+    */
+   // bool d_homogeneous_bc;
+
+   /*!
+    * @brief Timers for performance measurement.
+    */
+   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
+   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
+};
+
+}
+}
+
+#endif  // included_solv_P_Refine_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/Resid_Coarsen.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/Resid_Coarsen.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,53 @@
+#include "Resid_Coarsen.h"
+
+/**
+ * Coarsens using the moduli as weights.  So in 2D
+   resid_coarse = (resid(i,j)*moduli(i,j)
+                   + resid(i,j+1)*moduli(i,j+1)
+                   + resid(i+1,j)*moduli(i+1,j)
+                   + resid(i+1,j+1)*moduli(i+1,j+1))/(4*moduli_coarse)
+ */
+
+void SAMRAI::geom::Resid_Coarsen::coarsen(hier::Patch& coarse,
+                                          const hier::Patch& fine,
+                                          const int dst_component,
+                                          const int src_component,
+                                          const hier::Box& coarse_box,
+                                          const hier::IntVector& ratio) const
+{
+  const tbox::Dimension& dimension(getDim());
+  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, coarse, fine, coarse_box, ratio);
+  
+  tbox::Pointer<pdat::CellData<double> >
+    r_fine_ptr = fine.getPatchData(src_component);
+  pdat::CellData<double> &r_fine(*r_fine_ptr);
+  tbox::Pointer<pdat::CellData<double> >
+    r_ptr = coarse.getPatchData(dst_component);
+  pdat::CellData<double> &r(*r_ptr);
+  tbox::Pointer<pdat::CellData<double> >
+    cell_moduli_fine_ptr = fine.getPatchData(cell_moduli_id);
+  pdat::CellData<double> &cell_moduli_fine(*cell_moduli_fine_ptr);
+
+  TBOX_ASSERT(!r_ptr.isNull());
+  TBOX_ASSERT(!r_fine_ptr.isNull());
+  TBOX_ASSERT(r_fine.getDepth() == r.getDepth());
+  TBOX_ASSERT(r.getDepth() == 1);
+
+  hier::Box cell_box(hier::Index::getZeroIndex(dimension),
+                     hier::Index::getOneIndex(dimension));
+
+  for(pdat::CellIterator ci(coarse.getBox()); ci; ci++)
+    {
+      pdat::CellIndex coarse(*ci);
+      pdat::CellIndex fine(coarse*2);
+      double temp(0), moduli_sum(0);
+
+      for(pdat::CellIterator ii(cell_box); ii; ii++)
+        {
+          pdat::CellIndex i(*ii);
+          temp+=r_fine(fine+i)*(cell_moduli_fine(fine+i,0)+cell_moduli_fine(fine+i,1));
+          moduli_sum+=(cell_moduli_fine(fine+i,0)+cell_moduli_fine(fine+i,1));
+        }
+      r(coarse)=temp/moduli_sum;
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/Resid_Coarsen.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/Resid_Coarsen.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,76 @@
+#ifndef included_geom_Resid_Coarsen
+#define included_geom_Resid_Coarsen
+
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/pdat/CellVariable.h"
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Coarsens using the moduli as weights.  So in 2D
+   resid_coarse = (resid(i,j)*moduli(i,j)
+                   + resid(i,j+1)*moduli(i,j+1)
+                   + resid(i+1,j)*moduli(i+1,j)
+                   + resid(i+1,j+1)*moduli(i+1,j+1))/(4*moduli_coarse)
+ * @see xfer::CoarsenOperator
+ */
+
+class Resid_Coarsen:
+   public xfer::CoarsenOperator
+{
+public:
+  explicit Resid_Coarsen(const tbox::Dimension& dim,
+                         const int &cell_moduli):
+    xfer::CoarsenOperator(dim, "RESID_COARSEN"),
+    cell_moduli_id(cell_moduli)
+  {
+    d_name_id = "RESID_COARSEN";
+  }
+
+  virtual ~Resid_Coarsen(){}
+
+  bool findCoarsenOperator(const tbox::Pointer<hier::Variable>& var,
+                           const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getZero(getDim());
+  }
+
+  void coarsen(hier::Patch& coarse,
+               const hier::Patch& fine,
+               const int dst_component,
+               const int src_component,
+               const hier::Box& coarse_box,
+               const hier::IntVector& ratio) const;
+
+private:
+  std::string d_name_id;
+  const int cell_moduli_id;
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Boundary_Refine.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Boundary_Refine.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Boundary_Refine
+#define included_geom_V_Boundary_Refine
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class V_Boundary_Refine implements the special interpolation needed
+ * for the boundary elements on the coarse-fine interface.
+ *
+ * The findRefineOperator() operator function returns true if the input
+ * variable is side-centered double, and the std::string is "V_BOUNDARY_REFINE".
+ *
+ * @see xfer::RefineOperator
+ */
+
+class V_Boundary_Refine:
+  public xfer::RefineOperator
+{
+public:
+  /**
+   * Uninteresting default constructor.
+   */
+  explicit V_Boundary_Refine(const tbox::Dimension& dim):
+    xfer::RefineOperator(dim, "V_BOUNDARY_REFINE")
+  {
+    d_name_id = "V_BOUNDARY_REFINE";
+  }
+
+
+  /**
+   * Uninteresting virtual destructor.
+   */
+  virtual ~V_Boundary_Refine(){}
+
+  /**
+   * Return true if the variable and name std::string match side-centered
+   * double linear interpolation; otherwise, return false.
+   */
+  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
+                          const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /**
+   * Return name std::string identifier of this refinement operator.
+   */
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  /**
+   * The priority of side-centered double linear interpolation is 0.
+   * It will be performed before any user-defined interpolation operations.
+   */
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  /**
+   * The stencil width of the linear interpolation operator is the vector
+   * of ones.  That is, its stencil extends one side outside the fine box.
+   */
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getOne(getDim());
+  }
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the side-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the boxes contained in fine_overlap
+   * It is assumed that the coarse patch contains sufficient data for the
+   * stencil width of the refinement operator.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::BoxOverlap& fine_overlap,
+              const hier::IntVector& ratio) const;
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the side-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the fine box.   It is assumed that the
+   * coarse patch contains sufficient data for the stencil width of the
+   * refinement operator.  This differs from the above refine() method
+   * only in that it operates on a single fine box instead of a BoxOverlap.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::Box& fine_box,
+              const hier::IntVector& ratio,
+              const int &axis) const;
+
+private:
+  std::string d_name_id;
+
+  void Update_V_2D
+  (const int &axis,
+   const int &boundary_direction,
+   const bool &boundary_positive,
+   const pdat::SideIndex &fine,
+   const hier::Index &ip, const hier::Index &jp,
+   int &i, int &j,
+   const int &i_max,
+   const int &j_min,
+   const int &j_max,
+   pdat::SideData<double> &v,
+   pdat::SideData<double> &v_fine) const;
+
+  void Update_V_3D
+  (const int &axis,
+   const int &boundary_direction,
+   const bool &boundary_positive,
+   const pdat::SideIndex &fine,
+   const hier::Index pp[],
+   const hier::Index &ijk,
+   const hier::Index &p_min, const hier::Index &p_max,
+   SAMRAI::pdat::SideData<double> &v,
+   SAMRAI::pdat::SideData<double> &v_fine) const;
+
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Boundary_Refine/Update_V_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Boundary_Refine/Update_V_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,155 @@
+#include "Elastic/V_Boundary_Refine.h"
+#include "quad_offset_interpolate.h"
+#include "Constants.h"
+
+/* This is written from the perspective of axis==x.  For axis==y, we
+   switch i and j and everything works out. */
+void SAMRAI::geom::V_Boundary_Refine::Update_V_2D
+(const int &axis,
+ const int &boundary_direction,
+ const bool &boundary_positive,
+ const pdat::SideIndex &fine,
+ const hier::Index &ip, const hier::Index &jp,
+ int &i, int &j,
+ const int &i_max,
+ const int &j_min,
+ const int &j_max,
+ SAMRAI::pdat::SideData<double> &v,
+ SAMRAI::pdat::SideData<double> &v_fine) const
+{
+  /* Set the derivative for the normal direction
+
+         i-1      i       i+1
+
+        ------- -------
+       |   f   f   F   |
+   j-1 C       C       C
+       |   f   f   F   |
+        ------- -------
+       |   f   f   F   |
+   j   C       C       C
+       |   f   f   F   |
+        ------- -------
+       |   f   f   F   |
+   j+1 C       C       C
+       |   f   f   F   |
+        ------- -------
+               |
+               |
+               |
+        Coarse-Fine Boundary
+
+    So we need to set F such that the derivative at the coarse-fine
+    boundary is coorrect.  We can compute the derivative at the coarse
+    points on the boundary, and then use quadratic interpolation to
+    get the derivative at the fine points on the boundary.
+
+ */
+  if(boundary_direction==axis)
+    {
+      /* Return early if we are at j==j_max, because that is a corner
+         that we do not care about.  We could also skip if j==j_min as
+         long as we do not have to do j_min+1. We do not really have
+         to skip these since we are guaranteed to have valid data for
+         those "past the end" points since they are needed for
+         pressure refinement.  */
+      if(j==j_max || (j==j_min && j%2!=0))
+        return;
+      /* Compute the derivative at the nearest three coarse points and
+         then interpolate */
+
+      hier::Index ip_s(boundary_positive ? ip : -ip);
+
+      pdat::SideIndex center(fine-ip_s);
+      center.coarsen(hier::Index(2,2));
+
+      const double dv_plus=v(center+jp+ip_s)-v(center+jp-ip_s);
+      const double dv_minus=v(center-jp+ip_s)-v(center-jp-ip_s);
+      const double dv_center=v(center+ip_s)-v(center-ip_s);
+
+      double dv_fine_minus, dv_fine_plus;
+
+      quad_offset_interpolate(dv_plus,dv_center,dv_minus,
+                              dv_fine_plus,dv_fine_minus);
+
+      hier::Index offset(ip_s*2);
+
+      if(j%2==0)
+        {
+          v_fine(fine)=v_fine(fine-offset) + dv_fine_minus/2;
+          v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_plus/2;
+          /* Since we update two points on j at once, we increment j
+             again.  This is ok, since the box in the 'i' direction is
+             defined to be only one cell wide */
+          ++j;
+        }
+      else
+        {
+          v_fine(fine)=v_fine(fine-offset) + dv_fine_plus/2;
+        }          
+    }
+  /* Set the value for the tangential direction
+
+         i-1      i       i+1
+
+        -f-C-f- -F-C---    C
+       |       |       |
+   j-1 |       |       |    
+       |       |       |
+        -f-C-f- -F-C---    C
+       |       |       |
+   j   |       |       |    
+       |       |       |
+        -f-C-f- -F-C---    C
+       |       |       |
+   j+1 |       |       |    
+       |       |       |
+        -f-C-f- -F-C---    C
+               |
+               |
+               |
+        Coarse-Fine Boundary
+
+    C are the coarse velocities, f are the interior fine velocities,
+    and F are the boundary fine velocities that we need to set.  So we
+    use quadratic interpolation from C to F.
+ */
+  else
+    {
+      pdat::SideIndex center(fine);
+      center.coarsen(hier::Index(2,2));
+
+      double v_center, v_plus;
+      hier::Index jp_s(boundary_positive ? jp : -jp);
+
+      v_center=
+        quad_offset_interpolate(v(center-jp_s),v(center),v(center+jp_s));
+
+      if(i%2==0)
+        {
+          v_fine(fine)=v_center;
+
+          if(i<i_max)
+            {
+              /* This is a bit inefficient, because we compute v_plus
+               * twice.  Once for the in-between point, and again
+               * later for the actual point. */
+
+              v_plus=quad_offset_interpolate(v(center+ip-jp_s),v(center+ip),
+                                             v(center+ip+jp_s));
+              v_fine(fine+ip)=(v_center+v_plus)/2;
+
+              /* Since we update two points on 'i' at once, we increment 'i' again.
+                 This is ok, since the box in the 'j' direction is defined to be
+                 only one cell wide */
+              ++i;
+            }
+        }
+      else
+        {
+          v_plus=quad_offset_interpolate(v(center+ip-jp_s),v(center+ip),
+                                         v(center+ip+jp_s));
+          v_fine(fine)=(v_center+v_plus)/2;
+        }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Boundary_Refine/Update_V_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Boundary_Refine/Update_V_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,251 @@
+#include "Elastic/V_Boundary_Refine.h"
+#include "Constants.h"
+
+/* This is written from the perspective of axis==x.  For axis==y, we
+   switch i and j and everything works out. */
+void SAMRAI::geom::V_Boundary_Refine::Update_V_3D
+(const int &axis,
+ const int &boundary_direction,
+ const bool &boundary_positive,
+ const pdat::SideIndex &fine,
+ const hier::Index pp[],
+ const hier::Index &ijk,
+ const hier::Index &p_min, const hier::Index &p_max,
+ SAMRAI::pdat::SideData<double> &v,
+ SAMRAI::pdat::SideData<double> &v_fine) const
+{
+  /* Set the derivative for the normal direction.
+
+     We set the derivative on the i=constant plane.  If we look at a
+     slice in that plane.
+
+         k-1      k       k+1
+
+        ------- -------
+       |       |       |
+   j-1 |   D   |   D   |   D
+       |       |       |
+        ------- -------
+       |       |d-- d+-|
+   j   |   D   |   D   |   D
+       |       |d-+ d++|
+        ------- -------
+       |       |       |
+   j+1 |   D   |   D   |   D
+       |       |       |
+        ------- -------
+               |
+               |
+               |
+        Coarse-Fine Boundary
+
+  where D are the coarse derivatives, and d are the fine derivatives.
+  This picture is the same as what is seen in P_Boundary_Refine in 2D.
+  So we can use the formula there to compute d--.
+
+   d(-,-) = a - b/4 + c/16 - d/4 + e/16 + f/16
+          = D(-,-)/16 + (15/16)*D(0,0)
+            + (3/32)*(-D(+,0) - D(0,+) + D(-,0) + D(0,-))
+
+  */
+
+  if(boundary_direction==axis)
+    {
+      /* Return early if we are at j==j_max, because that is a corner
+         that we do not care about.  We also skip if j==j_min as long
+         as we do not have to do j_min+1. We have to skip these even
+         though they are not used because otherwise we could end up
+         reading past the end of the array.  */
+      const int axis2((axis+1)%3), axis3((axis+2)%3);
+      if(ijk[axis2]==p_max[axis2] || (ijk[axis2]==p_min[axis2] && ijk[axis2]%2!=0)
+         || ijk[axis3]==p_max[axis3] 
+         || (ijk[axis3]==p_min[axis3] && ijk[axis3]%2!=0))
+        return;
+      /* Compute the derivative at all of the interpolation points.  */
+
+      const hier::Index ip(boundary_positive ? pp[axis] : -pp[axis]),
+        jp(pp[(axis+1)%3]), kp(pp[(axis+2)%3]);
+
+      pdat::SideIndex center(fine-ip);
+      center.coarsen(hier::Index(2,2,2));
+
+      const double dv_mm=v(center-jp-kp+ip) - v(center-jp-kp-ip);
+      const double dv_m0=v(center-jp+ip) - v(center-jp-ip);
+      const double dv_mp=v(center-jp+kp+ip) - v(center-jp+kp-ip);
+
+      const double dv_0m=v(center-kp+ip) - v(center-kp-ip);
+      const double dv_00=v(center+ip) - v(center-ip);
+      const double dv_0p=v(center+kp+ip) - v(center+kp-ip);
+
+      const double dv_pm=v(center+jp-kp+ip) - v(center+jp-kp-ip);
+      const double dv_p0=v(center+jp+ip) - v(center+jp-ip);
+      const double dv_pp=v(center+jp+kp+ip) - v(center+jp+kp-ip);
+
+      const double dv_fine_mm=dv_mm/16 + (15.0/16)*dv_00
+        + (3/32)*(-dv_p0 - dv_0p + dv_m0 + dv_0m);
+
+      const double dv_fine_mp=dv_mp/16 + (15.0/16)*dv_00
+        + (3/32)*(-dv_p0 - dv_0m + dv_m0 + dv_0p);
+
+      const double dv_fine_pm=dv_pm/16 + (15.0/16)*dv_00
+        + (3/32)*(-dv_m0 - dv_0p + dv_p0 + dv_0m);
+
+      const double dv_fine_pp=dv_pp/16 + (15.0/16)*dv_00
+        + (3/32)*(-dv_m0 - dv_0m + dv_p0 + dv_0p);
+
+      hier::Index offset(ip*2);
+
+      /* Be careful about using the right interpolation if the fine
+       * points are not aligned with the coarse points. */
+      if(ijk[axis2]%2==0)
+        {
+          if(ijk[axis3]%2==0)
+            {
+              v_fine(fine)=v_fine(fine-offset) + dv_fine_mm/2;
+              if(ijk[axis2]<p_max[axis2])
+                v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_pm/2;
+              if(ijk[axis3]<p_max[axis3])
+                v_fine(fine+kp)=v_fine(fine-offset+kp) + dv_fine_mp/2;
+              if(ijk[axis2]<p_max[axis2] && ijk[axis3]<p_max[axis3])
+                v_fine(fine+jp+kp)=v_fine(fine-offset+jp+kp) + dv_fine_pp/2;
+            }
+          else
+            {
+              v_fine(fine)=v_fine(fine-offset) + dv_fine_mp/2;
+              if(ijk[axis2]<p_max[axis2])
+                v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_pp/2;
+            }
+        }
+      else
+        {
+          if(ijk[axis3]%2==0)
+            {
+              v_fine(fine)=v_fine(fine-offset) + dv_fine_pm/2;
+              if(ijk[axis3]<p_max[axis3])
+                v_fine(fine+kp)=v_fine(fine-offset+kp) + dv_fine_pp/2;
+            }
+          else
+            {
+              v_fine(fine)=v_fine(fine-offset) + dv_fine_pp/2;
+            }
+        }          
+    }
+  /* Set the value for the tangential direction.
+
+     Again, if we look at a slice in the i=constant plane.
+
+          j-1      j      j+1
+
+        ------- -------
+       |       |       |
+   k-1 |   V   |   V   |   V
+       |       |       |
+        ------- -------
+       |       |v--    |
+   k   |   V   |   V   |   V
+       |       |v-+    |
+        ------- -------
+       |       |       |
+   k+1 |   V   |   V   |   V
+       |       |       |
+        ------- -------
+               |
+               |
+               |
+        Coarse-Fine Boundary
+
+  where V are the coarse velocities, and v are the fine velocities.
+  This picture is the same as what is seen in P_Boundary_Refine in 2D.
+  So we can use the formula there to compute v--.
+
+   v(-,-) = V(-,-)/16 + (15/16)*V(0,0)
+            + (3/32)*(-V(+,0) - V(0,+) + V(-,0) + V(0,-))
+
+ */
+  else
+    {
+      const int axis3((axis+1)%3 != boundary_direction ? (axis+1)%3 : (axis+2)%3);
+      const hier::Index ip(pp[axis]),
+        jp(boundary_positive ? pp[boundary_direction] : -pp[boundary_direction]),
+        kp(pp[axis3]);
+
+      pdat::SideIndex center(fine);
+      center.coarsen(hier::Index(2,2,2));
+
+      double v_minus=v(center-jp-kp)/16 + (15.0/16)*v(center)
+        + (3.0/32)*(-v(center+jp) - v(center+kp) + v(center-jp) + v(center-kp));
+      
+      double v_plus=v(center-jp+kp)/16 + (15.0/16)*v(center)
+        + (3.0/32)*(-v(center+jp) - v(center-kp) + v(center-jp) + v(center+kp));
+
+
+      /* Be careful about using the right interpolation if the fine
+       * points are not aligned with the coarse points. */
+      if(ijk[axis]%2==0)
+        {
+          if(ijk[axis3]%2==0)
+            {
+              v_fine(fine)=v_minus;
+              if(ijk[axis3]<p_max[axis3])
+                v_fine(fine+kp)=v_plus;
+              if(ijk[axis]<p_max[axis])
+                {
+                  double v_minus_off=v(center-jp-kp+ip)/16
+                    + (15.0/16)*v(center+ip)
+                    + (3.0/32)*(-v(center+jp+ip) - v(center+kp+ip)
+                                + v(center-jp+ip) + v(center-kp+ip));
+      
+                  double v_plus_off=v(center-jp+kp+ip)/16
+                    + (15.0/16)*v(center+ip)
+                    + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
+                                + v(center-jp+ip) + v(center+kp+ip));
+
+                  v_fine(fine+ip)=(v_minus+v_minus_off)/2;
+                  if(ijk[axis3]<p_max[axis3])
+                    v_fine(fine+ip+kp)=(v_plus+v_plus_off)/2;
+                }
+            }
+          else
+            {
+              v_fine(fine)=v_plus;
+              if(ijk[axis]<p_max[axis])
+                {
+                  double v_plus_off=v(center-jp+kp+ip)/16
+                    + (15.0/16)*v(center+ip)
+                    + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
+                                + v(center-jp+ip) + v(center+kp+ip));
+
+                  v_fine(fine+ip)=(v_plus+v_plus_off)/2;
+                }
+            }
+        }
+      else
+        {
+          if(ijk[axis3]%2==0)
+            {
+              double v_minus_off=v(center-jp-kp+ip)/16
+                + (15.0/16)*v(center+ip)
+                + (3.0/32)*(-v(center+jp+ip) - v(center+kp+ip)
+                            + v(center-jp+ip) + v(center-kp+ip));
+      
+              double v_plus_off=v(center-jp+kp+ip)/16
+                + (15.0/16)*v(center+ip)
+                + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
+                            + v(center-jp+ip) + v(center+kp+ip));
+
+              v_fine(fine)=(v_minus+v_minus_off)/2;
+              if(ijk[axis3]<p_max[axis3])
+                v_fine(fine+kp)=(v_plus+v_plus_off)/2;
+            }
+          else
+            {
+              double v_plus_off=v(center-jp+kp+ip)/16
+                + (15.0/16)*v(center+ip)
+                + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
+                            + v(center-jp+ip) + v(center+kp+ip));
+
+              v_fine(fine)=(v_plus+v_plus_off)/2;
+            }
+        }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Boundary_Refine/refine.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Boundary_Refine/refine.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#include "Elastic/V_Boundary_Refine.h"
+#include "Elastic/set_boundary.h"
+#include "Constants.h"
+
+void SAMRAI::geom::V_Boundary_Refine::refine(
+   hier::Patch& fine,
+   const hier::Patch& coarse,
+   const int dst_component,
+   const int src_component,
+   const hier::BoxOverlap& fine_overlap,
+   const hier::IntVector& ratio) const
+{
+   const pdat::SideOverlap* t_overlap =
+      dynamic_cast<const pdat::SideOverlap *>(&fine_overlap);
+
+   TBOX_ASSERT(t_overlap != NULL);
+
+   set_boundary(coarse,invalid_id,src_component,true);
+
+   for(int axis=0; axis<getDim().getValue(); ++axis)
+     {
+       const hier::BoxList& boxes = t_overlap->getDestinationBoxList(axis);
+       for (hier::BoxList::Iterator b(boxes); b; b++)
+         {
+           refine(fine,coarse,dst_component,src_component,b(),ratio,axis);
+         }
+     }
+}
+
+void SAMRAI::geom::V_Boundary_Refine::refine(hier::Patch& fine,
+                                             const hier::Patch& coarse,
+                                             const int dst_component,
+                                             const int src_component,
+                                             const hier::Box& overlap_box,
+                                             const hier::IntVector& ratio,
+                                             const int &axis) const
+{
+   const tbox::Dimension& dimension(getDim());
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, fine, coarse, overlap_box, ratio);
+   const int dim(dimension.getValue());
+
+   tbox::Pointer<pdat::SideData<double> >
+   v = coarse.getPatchData(src_component);
+   tbox::Pointer<pdat::SideData<double> >
+   v_fine = fine.getPatchData(dst_component);
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(!v.isNull());
+   TBOX_ASSERT(!v_fine.isNull());
+   TBOX_ASSERT(v->getDepth() == v_fine->getDepth());
+   TBOX_ASSERT(v->getDepth() == 1);
+#endif
+
+   hier::Box fine_box=fine.getBox();
+
+   /* We have to infer where the boundary is from the boxes */
+   int boundary_direction;
+   bool boundary_positive(false);
+
+   for(int d=0;d<dim;++d)
+     {
+       if(std::abs(overlap_box.lower(d)-overlap_box.upper(d))==(axis==d ? 1 : 0))
+         {
+           boundary_direction=d;
+           if(fine_box.upper(d)<=overlap_box.lower(d))
+             boundary_positive=true;
+           else if(fine_box.lower(d)>=overlap_box.upper(d))
+             boundary_positive=false;
+           else
+             abort();
+           break;
+         }
+     }
+
+   hier::Index p_min(overlap_box.lower()), p_max(overlap_box.upper());
+
+   if(boundary_direction==axis)
+     {
+       if(boundary_positive)
+         {
+           p_min[axis]=p_max[axis];
+         }
+       else
+         {
+           p_max[axis]=p_min[axis];
+         }
+     }
+
+   hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
+   ip[0]=1;
+   jp[1]=1;
+   if(dim>2)
+     kp[2]=1;
+
+   if(dim==2)
+     {
+       for(int j=p_min[1]; j<=p_max[1]; ++j)
+         for(int i=p_min[0]; i<=p_max[0]; ++i)
+           {
+             pdat::SideIndex fine(hier::Index(i,j),axis,pdat::SideIndex::Lower);
+             switch(axis)
+               {
+               case 0:
+                 Update_V_2D(axis,boundary_direction,boundary_positive,fine,
+                             ip,jp,i,j,p_max[0],p_min[1],p_max[1],*v,*v_fine);
+                 break;
+               case 1:
+                 Update_V_2D(axis,boundary_direction,boundary_positive,fine,
+                             jp,ip,j,i,p_max[1],p_min[0],p_max[0],*v,*v_fine);
+                 break;
+               default:
+                 abort();
+                 break;
+               }
+         }
+     }
+   else
+     {
+       hier::Index pp[]={ip,jp,kp};
+       hier::Index ijk(dimension);
+       for(ijk[2]=p_min[2]; ijk[2]<=p_max[2]; ijk[2]=(ijk[2]/2)*2+2)
+         for(ijk[1]=p_min[1]; ijk[1]<=p_max[1]; ijk[1]=(ijk[1]/2)*2+2)
+           for(ijk[0]=p_min[0]; ijk[0]<=p_max[0]; ijk[0]=(ijk[0]/2)*2+2)
+             {
+               pdat::SideIndex fine(ijk,axis,pdat::SideIndex::Lower);
+               Update_V_3D(axis,boundary_direction,boundary_positive,fine,
+                           pp,ijk,p_min,p_max,*v,*v_fine);
+             }
+     }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Weighted averaging operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Coarsen
+#define included_geom_V_Coarsen
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideVariable.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class V_Coarsen implements averaging 
+ * for side-centered double patch data defined over
+ * a Cartesian mesh.  It is derived from the xfer::CoarsenOperator base class.
+ * The numerical operations for theaveraging use FORTRAN numerical routines.
+ *
+ * CartesianSideDoubleWeightedAverage averages over the nearest two
+ * cells, which is not what we want for multigrid.  This averages over
+ * the nearest six points (in 2D).  The findCoarsenOperator() operator
+ * function returns true if the input variable is side-centered
+ * double, and the std::string is "V_COARSEN".
+ *
+ * @see xfer::CoarsenOperator
+ */
+
+class V_Coarsen:
+   public xfer::CoarsenOperator
+{
+public:
+  /**
+   * Uninteresting default constructor.
+   */
+  explicit V_Coarsen(const tbox::Dimension& dim):
+    xfer::CoarsenOperator(dim, "V_COARSEN")
+  {
+    d_name_id = "V_COARSEN";
+  }
+
+  /**
+   * Uninteresting virtual destructor.
+   */
+  virtual ~V_Coarsen(){}
+
+  /**
+   * Return true if the variable and name std::string match the side-centered
+   * double weighted averaging; otherwise, return false.
+   */
+  
+  bool findCoarsenOperator(const tbox::Pointer<hier::Variable>& var,
+                           const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Return name std::string identifier of this coarsening operator.
+   */
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  /**
+   * The priority of side-centered double weighted averaging is 0.
+   * It will be performed before any user-defined coarsen operations.
+   */
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getOne(getDim());
+  }
+
+  /**
+   * Coarsen the source component on the fine patch to the destination
+   * component on the coarse patch using the side-centered double weighted
+   * averaging operator.  Coarsening is performed on the intersection of
+   * the destination patch and the coarse box.  It is assumed that the
+   * fine patch contains sufficient data for the stencil width of the
+   * coarsening operator.
+   */
+  void
+  coarsen(hier::Patch& coarse,
+             const hier::Patch& fine,
+             const int dst_component,
+             const int src_component,
+             const hier::Box& coarse_box,
+             const hier::IntVector& ratio) const
+  {
+    if(getDim().getValue()==2)
+      coarsen_2D(coarse,fine,dst_component,src_component,coarse_box,ratio);
+    else
+      coarsen_3D(coarse,fine,dst_component,src_component,coarse_box,ratio);
+  }
+
+  void
+  coarsen_2D(hier::Patch& coarse,
+             const hier::Patch& fine,
+             const int dst_component,
+             const int src_component,
+             const hier::Box& coarse_box,
+             const hier::IntVector& ratio) const;
+
+  void
+  coarsen_3D(hier::Patch& coarse,
+             const hier::Patch& fine,
+             const int dst_component,
+             const int src_component,
+             const hier::Box& coarse_box,
+             const hier::IntVector& ratio) const;
+
+private:
+  std::string d_name_id;
+
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen/coarsen_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen/coarsen_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Weighted averaging operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Coarsen_C
+#define included_geom_V_Coarsen_C
+
+#include "Elastic/V_Coarsen.h"
+
+#include <float.h>
+#include <math.h>
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "Constants.h"
+
+#include "FTensor.hpp"
+
+using namespace SAMRAI;
+
+inline void coarsen_point_2D(const pdat::SideIndex &coarse,
+                             const hier::Index &ip, const hier::Index &jp,
+                             tbox::Pointer<pdat::SideData<double> > &v,
+                             tbox::Pointer<pdat::SideData<double> > &v_fine )
+{
+  pdat::SideIndex center(coarse*2);
+  (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/4
+    + ((*v_fine)(center-ip) + (*v_fine)(center-ip+jp)
+       + (*v_fine)(center+ip) + (*v_fine)(center+jp+ip))/8;
+}
+
+
+void SAMRAI::geom::V_Coarsen::coarsen_2D(hier::Patch& coarse,
+                                         const hier::Patch& fine,
+                                         const int dst_component,
+                                         const int src_component,
+                                         const hier::Box& coarse_box,
+                                         const hier::IntVector& ratio) const
+{
+  const tbox::Dimension& Dim(getDim());
+
+  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(Dim, coarse, fine, coarse_box, ratio);
+
+  tbox::Pointer<pdat::SideData<double> >
+    v_fine = fine.getPatchData(src_component);
+  tbox::Pointer<pdat::SideData<double> >
+    v = coarse.getPatchData(dst_component);
+
+  TBOX_ASSERT(!v.isNull());
+  TBOX_ASSERT(!v_fine.isNull());
+  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
+  TBOX_ASSERT(v->getDepth() == 1);
+
+  const hier::IntVector& directions(v->getDirectionVector());
+
+  TBOX_ASSERT(directions ==
+              hier::IntVector::min(directions, v_fine->getDirectionVector()));
+
+  const tbox::Pointer<CartesianPatchGeometry> cgeom =
+    coarse.getPatchGeometry();
+  const double *dx=cgeom->getDx();
+
+  /* Numbering of v nodes is
+
+     x--x--x--x--x  Fine
+     0  1  2  3  4
+
+     x-----x-----x Coarse
+     0     1     2
+
+     So the i'th coarse point is affected by the i*2-1,
+     i*2, and i*2+1 fine points.  So, for example, i_fine=3
+     affects both i_coarse=1 and i_coarse=2.
+
+     |---------------------------------------------------------------|
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     c               c               c               c               c
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     |---------------------------------------------------------------|
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     c               c               c               c               c
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     |---------------------------------------------------------------|
+
+     In 2D, a coarse point depends on six points.  In this
+     case, (i*2,j*2), (i*2,j*2+1), (i*2-1,j*2),
+     (i*2-1,j*2+1), (i*2+1,j*2), (i*2+1,j*2+1).
+
+     The coarse/fine boundaries get fixed up later in
+     V_Coarsen_Patch_Strategy::postprocessCoarsen.
+  */
+  hier::Index ip(1,0), jp(0,1);
+  for(int j=coarse_box.lower(1); j<=coarse_box.upper(1)+1; ++j)
+    for(int i=coarse_box.lower(0); i<=coarse_box.upper(0)+1; ++i)
+      {
+        if(directions(0) && j!=coarse_box.upper(1)+1)
+          {
+            pdat::SideIndex coarse(hier::Index(i,j),0,
+                                   pdat::SideIndex::Lower);
+            pdat::SideIndex fine(coarse*2);
+            if((i==coarse_box.lower(0)
+                && cgeom->getTouchesRegularBoundary(0,0))
+               || (i==coarse_box.upper(0)+1
+                   && cgeom->getTouchesRegularBoundary(0,1)))
+              {
+                (*v)(coarse)=((*v_fine)(fine) + (*v_fine)(fine+jp))/2;
+              }
+            else
+              {
+                const int axis=0;
+                FTensor::Tensor1<double,3> offset(0,0,0);
+                offset(axis)=dx[axis]/2;
+                FTensor::Tensor1<double,3> xyz(0,0,0);
+                for(int d=0;d<Dim.getValue();++d)
+                  xyz(d)=cgeom->getXLower()[d]
+                    + dx[d]*(coarse[d]-coarse_box.lower()[d] + 0.5) - offset(d);
+
+                coarsen_point_2D(coarse,ip,jp,v,v_fine);
+
+
+                // tbox::pout << "coarsen "
+                //            << coarse << " "
+                //            << xyz(0) << " "
+                //            << xyz(1) << " "
+                //            << dx[0] << " "
+                //            << fine << " "
+                //            << (*v)(coarse) << " "
+                //            << (*v_fine)(fine) << " "
+                //            << (*v_fine)(fine+ip) << " "
+                //            << (*v_fine)(fine-ip) << " "
+                //            << (*v_fine)(fine+jp) << " "
+                //            << (*v_fine)(fine+jp+ip) << " "
+                //            << (*v_fine)(fine+jp-ip) << " "
+                //            << "\n";
+              }
+          }
+        if(directions(1) && i!=coarse_box.upper(0)+1)
+          {
+            pdat::SideIndex coarse(hier::Index(i,j),1,
+                                   pdat::SideIndex::Lower);
+            pdat::SideIndex fine(coarse*2);
+            if((j==coarse_box.lower(1)
+                && cgeom->getTouchesRegularBoundary(1,0))
+               || (j==coarse_box.upper(1)+1
+                   && cgeom->getTouchesRegularBoundary(1,1)))
+              {
+                (*v)(coarse)=((*v_fine)(fine) + (*v_fine)(fine+ip))/2;
+              }
+            else
+              {
+                const int axis=1;
+                FTensor::Tensor1<double,3> offset(0,0,0);
+                offset(axis)=dx[axis]/2;
+                FTensor::Tensor1<double,3> xyz(0,0,0);
+                for(int d=0;d<Dim.getValue();++d)
+                  xyz(d)=cgeom->getXLower()[d]
+                    + dx[d]*(coarse[d]-coarse_box.lower()[d] + 0.5) - offset(d);
+
+                if(xyz(0)-dx[0]<0.5 && xyz(0)+dx[0]>0.5)
+                  {
+                    /* Interface between coarse and fine+1 */
+                    if((xyz(1)+dx[1]/2>0.6 && xyz(1)<0.6)
+                       || (xyz(1)+dx[1]/2>0.4 && xyz(1)<0.4))
+                      {
+                        // tbox::pout << "coarsen m ";
+                        (*v)(coarse)=(((*v_fine)(fine) + (*v_fine)(fine+ip))*2
+                                      + (*v_fine)(fine-jp) + (*v_fine)(fine+ip-jp))/3;
+                      }
+                    /* Interface between coarse and fine-1 */
+                    else if((xyz(1)-dx[1]/2<0.6 && xyz(1)>0.6)
+                            || (xyz(1)-dx[1]/2<0.4 && xyz(1)>0.4))
+                      {
+                        // tbox::pout << "coarsen p ";
+                        (*v)(coarse)=(((*v_fine)(fine) + (*v_fine)(fine+ip))*2
+                                      + (*v_fine)(fine+jp) + (*v_fine)(fine+ip+jp))/3;
+                      }
+                    else
+                      {
+                        // tbox::pout << "coarsen z ";
+                        coarsen_point_2D(coarse,jp,ip,v,v_fine);
+                      }
+                  }
+                else
+                  {
+                    // tbox::pout << "coarsen   ";
+                    coarsen_point_2D(coarse,jp,ip,v,v_fine);
+                  }
+
+                // /* Interface between coarse and fine-1 */
+                // if(xyz(0)+dx[0]/4>0.5 && xyz(0)<0.5)
+                //   {
+                //     tbox::pout << "coarsen m ";
+                //     (*v)(coarse)=(*v_fine)(fine)/2
+                //       + ((*v_fine)(fine-jp) + (*v_fine)(fine+jp))/4;
+                //   }
+                // /* Interface between coarse and fine+1 */
+                // else if(xyz(0)-dx[0]/4<0.5 && xyz(0)>0.5)
+                //   {
+                //     tbox::pout << "coarsen p ";
+                //     (*v)(coarse)=(*v_fine)(fine+ip)/2
+                //       + ((*v_fine)(fine-jp+ip) + (*v_fine)(fine+jp+ip))/4;
+                //   }
+                // else
+                //   {
+                //     tbox::pout << "coarsen   ";
+                //     coarsen_point_2D(coarse,jp,ip,v,v_fine);
+                //   }
+
+                // tbox::pout << coarse << " "
+                //            << xyz(0) << " "
+                //            << xyz(1) << " "
+                //            << dx[0] << " "
+                //            << fine << " "
+                //            << (*v)(coarse) << " "
+                //            << (*v_fine)(fine) << " "
+                //            << (*v_fine)(fine+jp) << " "
+                //            << (*v_fine)(fine-jp) << " "
+                //            << (*v_fine)(fine+ip) << " "
+                //            << (*v_fine)(fine+ip+jp) << " "
+                //            << (*v_fine)(fine+ip-jp) << " "
+                //            << "\n";
+              }
+          }
+      }
+}
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen/coarsen_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen/coarsen_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Weighted averaging operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Coarsen_C
+#define included_geom_V_Coarsen_C
+
+#include "Elastic/V_Coarsen.h"
+
+#include <float.h>
+#include <math.h>
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "Constants.h"
+
+using namespace SAMRAI;
+
+inline void coarsen_point_3D(const pdat::SideIndex &coarse,
+                             const hier::Index &ip, const hier::Index &jp,
+                             const hier::Index &kp,
+                             tbox::Pointer<pdat::SideData<double> > &v,
+                             tbox::Pointer<pdat::SideData<double> > &v_fine )
+{
+  pdat::SideIndex center(coarse*2);
+  (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp)
+                + (*v_fine)(center+kp) + (*v_fine)(center+jp+kp))/8
+    + ((*v_fine)(center-ip) + (*v_fine)(center-ip+jp)
+       + (*v_fine)(center-ip+kp) + (*v_fine)(center-ip+jp+kp)
+       + (*v_fine)(center+ip) + (*v_fine)(center+jp+ip)
+       + (*v_fine)(center+ip+kp) + (*v_fine)(center+jp+ip+kp))/16;
+}
+
+
+void SAMRAI::geom::V_Coarsen::coarsen_3D(hier::Patch& coarse,
+                                         const hier::Patch& fine,
+                                         const int dst_component,
+                                         const int src_component,
+                                         const hier::Box& coarse_box,
+                                         const hier::IntVector& ratio) const
+{
+  const tbox::Dimension& dim(getDim());
+
+  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dim, coarse, fine, coarse_box, ratio);
+
+  tbox::Pointer<pdat::SideData<double> >
+    v_fine = fine.getPatchData(src_component);
+  tbox::Pointer<pdat::SideData<double> >
+    v = coarse.getPatchData(dst_component);
+
+  TBOX_ASSERT(!v.isNull());
+  TBOX_ASSERT(!v_fine.isNull());
+  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
+  TBOX_ASSERT(v->getDepth() == 1);
+
+  const hier::IntVector& directions(v->getDirectionVector());
+
+  TBOX_ASSERT(directions ==
+              hier::IntVector::min(directions, v_fine->getDirectionVector()));
+
+  const tbox::Pointer<CartesianPatchGeometry> cgeom =
+    coarse.getPatchGeometry();
+
+  /* Numbering of v nodes is
+
+     x--x--x--x--x  Fine
+     0  1  2  3  4
+
+     x-----x-----x Coarse
+     0     1     2
+
+     So the i'th coarse point is affected by the i*2-1,
+     i*2, and i*2+1 fine points.  So, for example, i_fine=3
+     affects both i_coarse=1 and i_coarse=2.
+
+     |---------------------------------------------------------------|
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     c               c               c               c               c
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     |---------------------------------------------------------------|
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     c               c               c               c               c
+     |               |               |               |               |
+     f       f       f       f       f       f       f       f       f
+     |               |               |               |               |
+     |---------------------------------------------------------------|
+
+     In 2D, a coarse point depends on six points.  In this
+     case, (i*2,j*2), (i*2,j*2+1), (i*2-1,j*2),
+     (i*2-1,j*2+1), (i*2+1,j*2), (i*2+1,j*2+1).
+
+
+          --------------------
+         /                   /|
+        /                   / |
+       /                   /  |
+      /                   /   |
+      -------------------     |
+     |                   |    |
+     |    f        f     |    |
+     |                   |    |
+     |        C          |   /
+     |                   |  /
+     |    f        f     | /
+     |                   |/
+      -------------------
+
+     In 3D, a coarse point depend on 12 points
+     (i*2,j*2,k*2), (i*2,j*2+1,k*2), (i*2,j*2,k*2+1), (i*2,j*2+1,k*2+1),
+     (i*2+1,j*2,k*2), (i*2+1,j*2+1,k*2), (i*2+1,j*2,k*2+1), (i*2+1,j*2+1,k*2+1),
+     (i*2-1,j*2,k*2), (i*2-1,j*2+1,k*2), (i*2-1,j*2,k*2+1), (i*2-1,j*2+1,k*2+1)
+
+     The coarse/fine boundaries get fixed up later in
+     V_Coarsen_Patch_Strategy::postprocessCoarsen.
+  */
+  hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
+  for(int k=coarse_box.lower(2); k<=coarse_box.upper(2)+1; ++k)
+    for(int j=coarse_box.lower(1); j<=coarse_box.upper(1)+1; ++j)
+      for(int i=coarse_box.lower(0); i<=coarse_box.upper(0)+1; ++i)
+        {
+          if(directions(0) && j!=coarse_box.upper(1)+1
+              && k!=coarse_box.upper(2)+1)
+            {
+              pdat::SideIndex coarse(hier::Index(i,j,k),0,
+                                     pdat::SideIndex::Lower);
+              pdat::SideIndex center(coarse*2);
+              if((i==coarse_box.lower(0)
+                  && cgeom->getTouchesRegularBoundary(0,0))
+                 || (i==coarse_box.upper(0)+1
+                     && cgeom->getTouchesRegularBoundary(0,1)))
+                {
+                  (*v)(coarse)=
+                    ((*v_fine)(center) + (*v_fine)(center+jp)
+                     + (*v_fine)(center+kp) + (*v_fine)(center+jp+kp))/4;
+                }
+              else
+                {
+                  coarsen_point_3D(coarse,ip,jp,kp,v,v_fine);
+                }
+            }
+          if(directions(1) && i!=coarse_box.upper(0)+1
+             && k!=coarse_box.upper(2)+1)
+            {
+              pdat::SideIndex coarse(hier::Index(i,j,k),1,
+                                     pdat::SideIndex::Lower);
+              pdat::SideIndex center(coarse*2);
+              if((j==coarse_box.lower(1)
+                  && cgeom->getTouchesRegularBoundary(1,0))
+                 || (j==coarse_box.upper(1)+1
+                     && cgeom->getTouchesRegularBoundary(1,1)))
+                {
+                  (*v)(coarse)=
+                    ((*v_fine)(center) + (*v_fine)(center+ip)
+                     + (*v_fine)(center+kp) + (*v_fine)(center+ip+kp))/4;
+                }
+              else
+                {
+                  coarsen_point_3D(coarse,jp,kp,ip,v,v_fine);
+                }
+            }
+          if(directions(2) && i!=coarse_box.upper(0)+1
+              && j!=coarse_box.upper(1)+1)
+            {
+              pdat::SideIndex coarse(hier::Index(i,j,k),2,
+                                     pdat::SideIndex::Lower);
+              pdat::SideIndex center(coarse*2);
+              if((k==coarse_box.lower(2)
+                  && cgeom->getTouchesRegularBoundary(2,0))
+                 || (k==coarse_box.upper(2)+1
+                     && cgeom->getTouchesRegularBoundary(2,1)))
+                {
+                  (*v)(coarse)=
+                    ((*v_fine)(center) + (*v_fine)(center+ip)
+                     + (*v_fine)(center+jp) + (*v_fine)(center+ip+jp))/4;
+                }
+              else
+                {
+                  coarsen_point_3D(coarse,kp,ip,jp,v,v_fine);
+                }
+            }
+        }
+}
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen_Patch_Strategy.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen_Patch_Strategy.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Robin boundary condition support on cartesian grids. 
+ *
+ ************************************************************************/
+#ifndef included_solv_V_Coarsen_Patch_Strategy
+#define included_solv_V_Coarsen_Patch_Strategy
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/CoarsenPatchStrategy.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/CoarseFineBoundary.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/CellIndex.h"
+#include "Constants.h"
+#include "set_boundary.h"
+
+namespace SAMRAI {
+namespace solv {
+
+/*!
+ * @brief Helper utility for setting boundary conditions on V.
+ *
+ * This class inherits and implements virtual functions from
+ * xfer::CoarsenPatchStrategy so it may be used to help create
+ * communication schedules if desired.
+ */
+class V_Coarsen_Patch_Strategy:
+   public xfer::CoarsenPatchStrategy
+{
+
+public:
+   /*!
+    * @brief Constructor using.
+    *
+    * @param object_name Name of the object, for general referencing.
+    * @param coef_strategy Coefficients strategy being helped.
+    */
+   V_Coarsen_Patch_Strategy(
+      const tbox::Dimension& dim,
+      std::string object_name = std::string()):
+     xfer::CoarsenPatchStrategy(dim),
+     d_object_name(object_name) {}
+
+   /*!
+    * @brief Destructor.
+    */
+   virtual ~V_Coarsen_Patch_Strategy(void) {}
+
+   //@{ @name xfer::CoarsenPatchStrategy virtuals
+
+   virtual hier::IntVector
+   getCoarsenOpStencilWidth() const
+  { return hier::IntVector::getOne(getDim()); }
+
+   virtual void
+   preprocessCoarsen(hier::Patch& ,
+                    const hier::Patch& fine,
+                    const hier::Box& ,
+                    const hier::IntVector& )
+  {
+    set_boundary(fine,invalid_id,v_id,true);
+  }
+
+   virtual void
+   postprocessCoarsen(
+      hier::Patch& coarse,
+      const hier::Patch& fine,
+      const hier::Box& coarse_box,
+      const hier::IntVector& ratio)
+  {
+    if(getDim().getValue()==2)
+      postprocessCoarsen_2D(coarse,fine,coarse_box,ratio);
+    else
+      postprocessCoarsen_3D(coarse,fine,coarse_box,ratio);
+  }
+
+  void
+  postprocessCoarsen_2D(
+      hier::Patch& coarse,
+      const hier::Patch& fine,
+      const hier::Box& coarse_box,
+      const hier::IntVector& ratio);
+
+  void
+  postprocessCoarsen_3D(
+      hier::Patch& coarse,
+      const hier::Patch& fine,
+      const hier::Box& coarse_box,
+      const hier::IntVector& ratio);
+
+   //@}
+
+   //@{
+
+   /*!
+    * @name Functions to set boundary condition values
+    */
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the first ghost cells.
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::CoarsenPatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to cell-centered variables.
+    * -# Only one ghost cell width is filled.  Setting a Robin
+    *    boundary condition for cell-centered quantities requires
+    *    only one ghost cell to be set.
+    *    (More ghost cells can be filled by continuing the linear
+    *    distribution of data beyond the first cell, but that is
+    *    not implemented at this time.)
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to
+    * get the coefficients, then it sets the values in the first
+    * ghost cell on the boundary.
+    *
+    * To determine the value for the ghost cell,
+    * a @em linear approximation in the direction normal to the
+    * boundary is assumed.  We write the following discrete
+    * approximations:
+    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
+    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
+    * where the subscript b stands for the the boundary,
+    * i stands for the first cell inside the boundary and
+    * o stands for the first cell outside the boundary
+    * and h is the grid spacing normal to the boundary.
+    * Applying this to the Robin formula gives
+    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
+    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
+    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
+    *
+    * After setting the edge (face in 3D) boundary conditions,
+    * linear approximations are used to set the boundary conditions
+    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required in solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @internal To be more general to other data types,
+    * there could be versions for other data types also,
+    * such as ...InNodes, ...InFaces, etc.  However, I'm not
+    * sure exactly how to implement the Robin boundary condition
+    * on the faces and nodes when m != 1.  Should the boundary
+    * value be set or should the first ghost value be set?
+    *
+    * @internal I have not addressed possibility of differences
+    * in chosing the discrete formulation with which to compute
+    * the boundary value.  The above formulation is obviously
+    * one specific approximation, but there could be others.
+    * If anoter approximation is required, there should be
+    * another class like this or this class can offer a choice
+    * to be set by the user.  I favor another class.
+    *
+    * @internal Since the data alignment can be found through
+    * the target_data_id, these types of functions may be changed
+    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
+    * since it does assume boundary boxes.  This may have to be
+    * expanded to later include coarse-fine boundary boxes
+    * for more generality.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set ghost cells for an entire level.
+    *
+    * Loop through all patches on the given level and call
+    * setBoundaryValuesInCells(hier::Patch &patch,
+    *                          const double fill_time ,
+    *                          const hier::IntVector &ghost_width_to_fill ,
+    *                          int target_data_id ,
+    *                          bool homogeneous_bc=false )
+    * for each.
+    *
+    * @param level PatchLevel on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::PatchLevel& level,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the boundary nodes.
+    *
+    * This function is not yet implemented!
+    *
+    * There are some decisions that must be made before
+    * the implementation can be written.
+    * -# Do we set the values on the boundary or one cell
+    *    away from the boundary?
+    * -# What is the discrete formulation we should use
+    *    to compute the value to be set?
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::CoarsenPatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to node-centered variables.
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to get the
+    * coefficients, then it sets the values at the boundary nodes.
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required to solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param target_data_id hier::Patch data index of data to be set.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesAtNodes(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   //@}
+
+   //@{
+   /*!
+    * @name Ways to provide the Robin bc coefficients
+    */
+
+   /*!
+    * @brief Provide an implementation of the RobinBcCoefStrategy
+    * for determining the boundary coefficients.
+    *
+    * Provide the implementation that can be used to set the
+    * Robin bc coefficients.
+    *
+    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
+    *        the coefficient strategy.
+    */
+   // void
+   // setCoefImplementation(
+   //    const RobinBcCoefStrategy* coef_strategy);
+
+   /*!
+    * @brief Set the data id that should be filled when setting
+    * physical boundary conditions.
+    *
+    * When setPhysicalBoundaryConditions is called, the data
+    * specified will be set.  This information is required because
+    * the it is not passed in through the argument list of
+    * setPhysicalBounaryConditions.
+    */
+  void setSourceDataId(int id)
+  {
+    v_id=id;
+  }
+
+   /*!
+    * @brief Set whether boundary filling should assume homogeneous
+    * conditions.
+    *
+    * In certain circumstances, only the value of a is needed, while
+    * the value of g is temporarily not required and taken to be zero.
+    * (An example is in setting the boundary condition for error
+    * value in an iterative method.)  In such cases, use this function
+    * to set a flag that will cause a null pointer to be given to
+    * setBcCoefs() to indicate that fact.
+    */
+   // void
+   // setHomogeneousBc(
+   //    bool homogeneous_bc);
+
+   //@}
+
+  tbox::Array<tbox::Pointer<hier::CoarseFineBoundary> > coarse_fine;
+
+private:
+   /*!
+    * @brief Trim a boundary box so that it does not stick out
+    * past a given box.
+    *
+    * Certain boundary-related operations occur on patch data that
+    * do not or cannot extend past the edgr or corner of a patch.
+    * This function is used to trim down the parts of the boundary box
+    * that extend past those points so that a suitable index range
+    * is achieved.
+    *
+    * The boundary box trimmed must be of type 1 or 2.
+    *
+    * @param boundary_box Boundary box to be trimmed.
+    * @param limit_box hier::Box to not stick past
+    *
+    * @return New trimmed boundary box.
+    */
+   // hier::BoundaryBox
+   // trimBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box,
+   //    const hier::Box& limit_box) const;
+
+   /*!
+    * @brief Return box describing the index space of boundary nodes
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the nodes corresponding
+    * to the input boundary box.  These nodes lie on the boundary
+    * itself.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the node indices corresponding to
+    *   boundary_box
+    */
+   // hier::Box
+   // makeNodeBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   /*!
+    * @brief Return box describing the index space of faces
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the codimension 1
+    * surface corresponding to the input boundary box.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * This is a utility function for working with the
+    * indices coresponding to a boundary box but coincide
+    * with the patch boundary.
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the face indices corresponding to
+    *    boundary_box
+    */
+   // hier::Box
+   // makeFaceBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   std::string d_object_name;
+
+   /*!
+    * @brief Coefficient strategy giving a way to get to
+    * Robin bc coefficients.
+    */
+   // const RobinBcCoefStrategy* d_coef_strategy;
+
+   /*!
+    * @brief hier::Index of target patch data when filling ghosts.
+    */
+   int v_id;
+
+   /*!
+    * @brief Whether to assumg g=0 when filling ghosts.
+    */
+   // bool d_homogeneous_bc;
+
+   /*!
+    * @brief Timers for performance measurement.
+    */
+   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
+   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
+};
+
+}
+}
+
+#endif  // included_solv_V_Coarsen_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,89 @@
+#include "Elastic/V_Coarsen_Patch_Strategy.h"
+
+void
+SAMRAI::solv::V_Coarsen_Patch_Strategy::postprocessCoarsen_2D
+(hier::Patch& coarse,
+ const hier::Patch& fine,
+ const hier::Box& ,
+ const hier::IntVector& )
+{
+  /* Fix up the boundary elements by iterating through the boundary
+     boxes */
+
+  /* We only care about edges, not corners, so we only iterate over
+     edge boundary boxes. */
+  const tbox::Array<hier::BoundaryBox>
+    &boundaries=coarse_fine[fine.getPatchLevelNumber()]->getEdgeBoundaries(coarse.getGlobalId());
+     
+  tbox::Pointer<pdat::SideData<double> >
+    v_fine = fine.getPatchData(v_id);
+  tbox::Pointer<pdat::SideData<double> >
+    v = coarse.getPatchData(v_id);
+
+  TBOX_ASSERT(!v.isNull());
+  TBOX_ASSERT(!v_fine.isNull());
+  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
+  TBOX_ASSERT(v->getDepth() == 1);
+
+  hier::Box gbox(v_fine->getGhostBox());
+  hier::Index ip(1,0), jp(0,1);
+  for(int mm=0; mm<boundaries.size(); ++mm)
+    {
+      hier::Box bbox=boundaries[mm].getBox();
+      int location_index=boundaries[mm].getLocationIndex();
+
+      hier::Index lower=hier::Index::coarsen(bbox.lower(),hier::Index(2,2)),
+        upper=hier::Index::coarsen(bbox.upper(),hier::Index(2,2));
+
+      for(int j=lower(1); j<=upper(1); ++j)
+        for(int i=lower(0); i<=upper(0); ++i)
+          {
+            /* Fix vx */
+            if(location_index==0)
+              {
+                pdat::SideIndex coarse(hier::Index(i,j),0,
+                                       pdat::SideIndex::Upper);
+                pdat::SideIndex center(coarse*2);
+                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
+                  {
+                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
+                  }
+              }
+            else if(location_index==1)
+              {
+                pdat::SideIndex coarse(hier::Index(i,j),0,
+                                       pdat::SideIndex::Lower);
+                pdat::SideIndex center(coarse*2);
+                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
+                  {
+                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
+                  }
+              }
+            /* Fix vy */
+            else if(location_index==2)
+              {
+                pdat::SideIndex coarse(hier::Index(i,j),1,
+                                       pdat::SideIndex::Upper);
+                pdat::SideIndex center(coarse*2);
+                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
+                  {
+                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
+                  }
+              }
+            else if(location_index==3)
+              {
+                pdat::SideIndex coarse(hier::Index(i,j),1,
+                                       pdat::SideIndex::Lower);
+                pdat::SideIndex center(coarse*2);
+                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
+                  {
+                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
+                  }
+              }
+            else
+              {
+                abort();
+              }
+          }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,87 @@
+#include "Elastic/V_Coarsen_Patch_Strategy.h"
+
+void
+SAMRAI::solv::V_Coarsen_Patch_Strategy::postprocessCoarsen_3D
+(hier::Patch& coarse,
+ const hier::Patch& fine,
+ const hier::Box& ,
+ const hier::IntVector& )
+{
+  /* Fix up the boundary elements by iterating through the boundary
+     boxes */
+
+  /* We only care about faces, not edges or corners, so we only
+     iterate over face boundary boxes. */
+  const tbox::Array<hier::BoundaryBox> &boundaries
+    (coarse_fine[fine.getPatchLevelNumber()]
+     ->getFaceBoundaries(coarse.getGlobalId()));
+     
+  tbox::Pointer<pdat::SideData<double> >
+    v_fine = fine.getPatchData(v_id);
+  tbox::Pointer<pdat::SideData<double> >
+    v = coarse.getPatchData(v_id);
+
+  TBOX_ASSERT(!v.isNull());
+  TBOX_ASSERT(!v_fine.isNull());
+  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
+  TBOX_ASSERT(v->getDepth() == 1);
+
+  hier::Box gbox(v_fine->getGhostBox());
+  hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
+  for(int mm=0; mm<boundaries.size(); ++mm)
+    {
+      hier::Box bbox=boundaries[mm].getBox();
+      /* location_index tells where, in relation to the box, the boundary is.
+         0: x lower
+         1: x upper
+         2: y lower
+         3: y upper
+         4: z lower
+         5: z upper
+
+         Therefore, if location_index==3, then we need to set vy on
+         the __lower__ side of that boundary box. */
+         
+      int location_index=boundaries[mm].getLocationIndex();
+      int direction(location_index/2);
+      int side(location_index%2==0 ? pdat::SideIndex::Upper
+               : pdat::SideIndex::Lower);
+      int dir2((direction+1)%3), dir3((direction+2)%3);
+      hier::Index yp(ip), zp(ip);
+      switch(direction)
+        {
+        case 0:
+          yp=jp;
+          zp=kp;
+          break;
+        case 1:
+          yp=kp;
+          zp=ip;
+          break;
+        case 2:
+          yp=ip;
+          zp=jp;
+          break;
+        }      
+
+      hier::Index lower=hier::Index::coarsen(bbox.lower(),hier::Index(2,2,2)),
+        upper=hier::Index::coarsen(bbox.upper(),hier::Index(2,2,2));
+
+      for(int k=lower(2); k<=upper(2); ++k)
+        for(int j=lower(1); j<=upper(1); ++j)
+          for(int i=lower(0); i<=upper(0); ++i)
+            {
+              pdat::SideIndex coarse(hier::Index(i,j,k),direction,side);
+              pdat::SideIndex center(coarse*2);
+              if(center[dir2]>=gbox.lower(dir2)
+                 && center[dir2]<gbox.upper(dir2)
+                 && center[dir3]>=gbox.lower(dir3)
+                 && center[dir3]<gbox.upper(dir3))
+                {
+                  (*v)(coarse)=
+                    ((*v_fine)(center) + (*v_fine)(center+yp)
+                     + (*v_fine)(center+zp) + (*v_fine)(center+yp+zp))/4;
+                }
+            }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Refine.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Refine.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Refine
+#define included_geom_V_Refine
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefineOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+
+#include "FTensor.hpp"
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class V_Refine implements linear
+ * interpolation for side-centered double patch data defined over a Cartesian
+ * mesh.  It is derived from the xfer::RefineOperator base class.
+ * CartesianSideDoubleConservativeLinearRefine does not handle the 
+ * boundary for the velocity correctly, so use this instead for
+ * velocity.
+ *
+ * The findRefineOperator() operator function returns true if the input
+ * variable is side-centered double, and the std::string is "V_REFINE".
+ *
+ * @see xfer::RefineOperator
+ */
+
+class V_Refine:
+  public xfer::RefineOperator
+{
+public:
+  /**
+   * Uninteresting default constructor.
+   */
+  explicit V_Refine(const tbox::Dimension& dim):
+    xfer::RefineOperator(dim, "V_REFINE")
+  {
+    d_name_id = "V_REFINE";
+  }
+
+
+  /**
+   * Uninteresting virtual destructor.
+   */
+  virtual ~V_Refine(){}
+
+  /**
+   * Return true if the variable and name std::string match side-centered
+   * double linear interpolation; otherwise, return false.
+   */
+  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
+                          const std::string& op_name) const
+  {
+    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
+    if (!cast_var.isNull() && (op_name == d_name_id)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /**
+   * Return name std::string identifier of this refinement operator.
+   */
+  const std::string& getOperatorName() const
+  {
+    return d_name_id;
+  }
+
+  /**
+   * The priority of side-centered double linear interpolation is 0.
+   * It will be performed before any user-defined interpolation operations.
+   */
+  int getOperatorPriority() const
+  {
+    return 0;
+  }
+
+  /**
+   * The stencil width of the linear interpolation operator is the vector
+   * of ones.  That is, its stencil extends one side outside the fine box.
+   */
+  hier::IntVector getStencilWidth() const
+  {
+    return hier::IntVector::getOne(getDim());
+  }
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the side-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the boxes contained in fine_overlap
+   * It is assumed that the coarse patch contains sufficient data for the
+   * stencil width of the refinement operator.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::BoxOverlap& fine_overlap,
+              const hier::IntVector& ratio) const;
+
+  /**
+   * Refine the source component on the coarse patch to the destination
+   * component on the fine patch using the side-centered double linear
+   * interpolation operator.  Interpolation is performed on the intersection
+   * of the destination patch and the fine box.   It is assumed that the
+   * coarse patch contains sufficient data for the stencil width of the
+   * refinement operator.  This differs from the above refine() method
+   * only in that it operates on a single fine box instead of a BoxOverlap.
+   */
+  void refine(hier::Patch& fine,
+              const hier::Patch& coarse,
+              const int dst_component,
+              const int src_component,
+              const hier::Box& fine_box,
+              const hier::IntVector& ratio,
+              const int &axis) const;
+
+  double refine_along_line(pdat::SideData<double> &v,
+                           const int &axis,
+                           const int &dim,
+                           const hier::Index pp[],
+                           const pdat::SideIndex &fine,
+                           const pdat::SideIndex &coarse,
+                           const hier::Box &coarse_box,
+                           const CartesianPatchGeometry &coarse_geom,
+                           const FTensor::Tensor1<double,3> &xyz,
+                           const double *dx) const;
+
+private:
+  std::string d_name_id;
+
+};
+
+}
+}
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Refine/refine.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Refine/refine.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Linear refine operator for side-centered double data on
+ *                a Cartesian mesh. 
+ *
+ ************************************************************************/
+
+#include "Elastic/V_Refine.h"
+
+#include <float.h>
+#include <math.h>
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/tbox/Utilities.h"
+#include "SAMRAI/pdat/CellData.h"
+
+#include "FTensor.hpp"
+
+void SAMRAI::geom::V_Refine::refine(
+   hier::Patch& fine,
+   const hier::Patch& coarse,
+   const int dst_component,
+   const int src_component,
+   const hier::BoxOverlap& fine_overlap,
+   const hier::IntVector& ratio) const
+{
+   const pdat::SideOverlap* t_overlap =
+      dynamic_cast<const pdat::SideOverlap *>(&fine_overlap);
+
+   TBOX_ASSERT(t_overlap != NULL);
+
+   for(int axis=0; axis<getDim().getValue(); ++axis)
+     {
+       const hier::BoxList& boxes = t_overlap->getDestinationBoxList(axis);
+       for (hier::BoxList::Iterator b(boxes); b; b++)
+         {
+           refine(fine,coarse,dst_component,src_component,b(),ratio,axis);
+         }
+     }
+}
+
+void SAMRAI::geom::V_Refine::refine(hier::Patch& fine_patch,
+                                    const hier::Patch& coarse_patch,
+                                    const int dst_component,
+                                    const int src_component,
+                                    const hier::Box& fine_box,
+                                    const hier::IntVector& ratio,
+                                    const int &axis) const
+{
+   const tbox::Dimension& dimension(getDim());
+   const int dim(dimension.getValue());
+   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, fine_patch, coarse_patch, fine_box, ratio);
+
+   tbox::Pointer<pdat::SideData<double> >
+   v_ptr = coarse_patch.getPatchData(src_component);
+   pdat::SideData<double> &v(*v_ptr);
+   tbox::Pointer<pdat::SideData<double> >
+   v_fine_ptr = fine_patch.getPatchData(dst_component);
+   pdat::SideData<double> &v_fine(*v_fine_ptr);
+
+#ifdef DEBUG_CHECK_ASSERTIONS
+   TBOX_ASSERT(!v_ptr.isNull());
+   TBOX_ASSERT(!v_fine_ptr.isNull());
+   TBOX_ASSERT(v.getDepth() == v_fine.getDepth());
+   TBOX_ASSERT(v.getDepth() == 1);
+#endif
+
+   hier::Box coarse_box=coarse_patch.getBox();
+   tbox::Pointer<geom::CartesianPatchGeometry>
+     coarse_geom = coarse_patch.getPatchGeometry();
+
+   tbox::Pointer<geom::CartesianPatchGeometry>
+     fine_geom = fine_patch.getPatchGeometry();
+   const double *dx=fine_geom->getDx();
+
+   const hier::Box &fine_patch_box(fine_patch.getBox());
+
+   hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
+   ip[0]=1;
+   jp[1]=1;
+   if(dim>2)
+     kp[2]=1;
+   hier::Index pp[]={ip,jp,kp};
+
+   for(pdat::CellIterator ci(fine_box); ci; ci++)
+     {
+       pdat::SideIndex fine(*ci,axis,pdat::SideIndex::Lower);
+
+       pdat::SideIndex coarse(fine);
+       coarse.coarsen(hier::Index::getOneIndex(dimension)*2);
+
+       FTensor::Tensor1<double,3> offset(0,0,0);
+       offset(axis)=dx[axis]/2;
+       FTensor::Tensor1<double,3> xyz(0,0,0);
+       for(int d=0;d<dim;++d)
+         xyz(d)=fine_geom->getXLower()[d]
+           + dx[d]*(fine[d]-fine_patch_box.lower()[d] + 0.5) - offset(d);
+
+       if(fine[axis]%2==0)
+         {
+           v_fine(fine)=
+             refine_along_line(v,axis,dim,pp,fine,coarse,coarse_box,
+                               *coarse_geom,xyz,dx);
+         }
+       else
+         {
+           FTensor::Tensor1<double,3> xyz_low, xyz_high;
+           FTensor::Index<'a',3> a;
+
+           xyz_low(a)=xyz(a) - 2*offset(a);
+           xyz_high(a)=xyz(a) + 2*offset(a);
+
+           v_fine(fine)=
+             (refine_along_line(v,axis,dim,pp,fine,coarse,coarse_box,
+                                *coarse_geom,xyz_low,dx)
+              + refine_along_line(v,axis,dim,pp,fine,coarse+pp[axis],
+                                  coarse_box,*coarse_geom,xyz_high,dx))/2;
+         }
+     }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Refine/refine_along_line.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Refine/refine_along_line.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,280 @@
+#include "Elastic/V_Refine.h"
+
+/* This assumes that the levels are always properly nested, so that we
+   always have an extra grid space for interpolation.  So we only have
+   to have a special case for physical boundaries, where we do not
+   have an extra grid space. */
+
+/* Maybe this has to be fixed when dvx/dy != 0 on the outer boundary
+   because the approximation to the derivative is not accurate
+   enough? */
+
+/* Maybe in 3D we should include cross derivatives? */
+
+double SAMRAI::geom::V_Refine::refine_along_line
+(pdat::SideData<double> &v,
+ const int &axis,
+ const int &dim,
+ const hier::Index pp[],
+ const pdat::SideIndex &fine,
+ const pdat::SideIndex &coarse,
+ const hier::Box &coarse_box,
+ const CartesianPatchGeometry &coarse_geom,
+ const FTensor::Tensor1<double,3> &xyz,
+ const double *dx) const
+{
+  double result=v(coarse);
+
+  for(int d=(axis+1)%dim;d!=axis;d=(d+1)%dim)
+    {
+      const int sgn(fine[d]%2==0 ? -1 : 1);
+
+      double dvx_dy;
+      if(coarse[d]==coarse_box.lower(d)
+         && coarse_geom.getTouchesRegularBoundary(d,0))
+        {
+          dvx_dy=sgn*(v(coarse+pp[d])-v(coarse))/4;
+        }
+      else if(coarse[d]==coarse_box.upper(d)
+              && coarse_geom.getTouchesRegularBoundary(d,1))
+        {
+          dvx_dy=sgn*(v(coarse)-v(coarse-pp[d]))/4;
+        }
+      else
+        {
+          dvx_dy=sgn*(v(coarse+pp[d])-v(coarse-pp[d]))/8;
+
+          if(axis==0 && xyz(0)-dx[0]<0.5+1e-6 && xyz(0)+dx[0]>0.5+1e-6)
+            {
+              const double y_min(0.5-sgn*0.1), y_max(0.5+sgn*0.1);
+              /* Top tip */
+              /* Singularity in coarse+1 */
+              if(sgn*(xyz(1)+sgn*dx[1]*0.5-y_max)<0 && sgn*(xyz(1)+sgn*dx[1]*2.5-y_max)>0)
+                {
+                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
+                  // tbox::pout << "refine p cp1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+
+                }
+              /* Singularity in coarse */
+              else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_max)<0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_max)>0)
+                {
+                  dvx_dy=0;
+                  // tbox::pout << "refine p c "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+                }
+              /* Singularity in coarse-1 */
+              else if(sgn*(xyz(1)-sgn*dx[1]*3.5-y_max)<0 && sgn*(xyz(1)-sgn*dx[1]*1.5-y_max)>0)
+                {
+                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
+                  // tbox::pout << "refine p cm1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+                }
+
+              /* Bottom tip */
+              /* Singularity in coarse+1 */
+              else if(sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)<0 && sgn*(xyz(1)+sgn*dx[1]*2.5-y_min)>0)
+                {
+                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
+                  // tbox::pout << "refine m cp1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+                }
+              /* Singularity in coarse */
+              else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)<0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)>0)
+                {
+                  dvx_dy=0;
+                  // tbox::pout << "refine m c "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+                }
+              /* Singularity in coarse-1 */
+              else if(sgn*(xyz(1)-sgn*dx[1]*3.5-y_min)<0 && sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)>0)
+                {
+                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
+                  // tbox::pout << "refine m cm1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + dvx_dy << " "
+                  //            << "\n";
+                }
+
+              // /* Bottom tip */
+              // /* Singularity in coarse+1 */
+              // else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)<0 && sgn*(xyz(1)-sgn*dx[1]*3.5-y_min)>0)
+              //   {
+              //     dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
+              //     tbox::pout << "refine m cp1 "
+              //                << 1/dx[0] << " "
+              //                << xyz(0) << " "
+              //                << xyz(1) << " "
+              //                << fine << " "
+              //                << coarse << " "
+              //                << sgn << " "
+              //                << v(coarse+pp[d]*sgn) << " "
+              //                << v(coarse) << " "
+              //                << v(coarse-pp[d]*sgn) << " "
+              //                << result + dvx_dy << " "
+              //                << "\n";
+              //   }
+              // /* Jump in coarse */
+              // else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)>0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)<0)
+              //   {
+              //     dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
+              //     tbox::pout << "refine m c "
+              //                << 1/dx[0] << " "
+              //                << xyz(0) << " "
+              //                << xyz(1) << " "
+              //                << fine << " "
+              //                << coarse << " "
+              //                << sgn << " "
+              //                << v(coarse+pp[d]*sgn) << " "
+              //                << v(coarse) << " "
+              //                << v(coarse-pp[d]*sgn) << " "
+              //                << result + dvx_dy << " "
+              //                << "\n";
+              //   }
+
+            }
+
+          // if(coarse[1]==6)
+          //       {
+          //         tbox::pout << "refine "
+          //                    << 1/dx[0] << " "
+          //                    << xyz(0) << " "
+          //                    << xyz(1) << " "
+          //                    << fine << " "
+          //                    << coarse << " "
+          //                    << sgn << " "
+          //                    << v(coarse+pp[d]*sgn) << " "
+          //                    << v(coarse) << " "
+          //                    << v(coarse-pp[d]*sgn) << " "
+          //                    << result + dvx_dy << " "
+          //                    << "\n";
+
+          //       }
+
+
+
+          if(axis==1 && xyz(1)>=0.4 && xyz(1)<=0.6)
+            {
+              /* Interface between fine and coarse+1, do a one-sided
+                 interpolation. */
+              if(sgn*(xyz(0)-0.5)<0 && sgn*(xyz(0)+sgn*1.5*dx[0]-0.5)>0)
+                {
+                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
+
+                  // tbox::pout << "refine fcp1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + sgn*dvx_dy << " "
+                  //            << "\n";
+                }
+              /* Interface between fine and coarse, use derivative
+                 from the other side. */
+              else if(sgn*(xyz(0)-0.5)>0 && sgn*(xyz(0)-sgn*dx[0]/2-0.5)<0)
+                {
+                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse)
+                          - (v(coarse)-v(coarse-pp[d]*sgn))*0.75);
+
+                  // tbox::pout << "refine fc "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + sgn*dvx_dy << " "
+                  //            << "\n";
+                }
+              /* Interface between coarse and coarse-1, do a one-sided
+                 interpolation. */
+              else if(sgn*(xyz(0)-0.5)>0 && sgn*(xyz(0)-sgn*2.5*dx[0]-0.5)<0)
+                {
+                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
+
+                  // tbox::pout << "refine ccm1 "
+                  //            << 1/dx[0] << " "
+                  //            << xyz(0) << " "
+                  //            << xyz(1) << " "
+                  //            << fine << " "
+                  //            << coarse << " "
+                  //            << sgn << " "
+                  //            << v(coarse+pp[d]*sgn) << " "
+                  //            << v(coarse) << " "
+                  //            << v(coarse-pp[d]*sgn) << " "
+                  //            << result + sgn*dvx_dy << " "
+                  //            << "\n";
+                }
+            }
+        }
+      result+=dvx_dy;
+    }
+  return result;
+}
+
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/V_Refine_Patch_Strategy.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/V_Refine_Patch_Strategy.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,408 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution.  For full copyright 
+ * information, see COPYRIGHT and COPYING.LESSER. 
+ *
+ * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description:   Robin boundary condition support on cartesian grids. 
+ *
+ ************************************************************************/
+#ifndef included_solv_V_Refine_Patch_Strategy
+#define included_solv_V_Refine_Patch_Strategy
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/RefinePatchStrategy.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/CellIndex.h"
+#include "Constants.h"
+#include "set_boundary.h"
+
+namespace SAMRAI {
+namespace solv {
+
+/*!
+ * @brief Helper utility for setting boundary conditions on V.
+ *
+ * This class inherits and implements virtual functions from
+ * xfer::RefinePatchStrategy so it may be used to help create
+ * communication schedules if desired.
+ */
+class V_Refine_Patch_Strategy:
+   public xfer::RefinePatchStrategy
+{
+
+public:
+   /*!
+    * @brief Constructor using.
+    *
+    * @param object_name Name of the object, for general referencing.
+    * @param coef_strategy Coefficients strategy being helped.
+    */
+   V_Refine_Patch_Strategy(
+      const tbox::Dimension& dim,
+      std::string object_name = std::string()):
+     xfer::RefinePatchStrategy(dim), d_dim(dim),d_object_name(object_name) {}
+
+   /*!
+    * @brief Destructor.
+    */
+   virtual ~V_Refine_Patch_Strategy(void) {}
+
+   //@{ @name xfer::RefinePatchStrategy virtuals
+
+   virtual void
+   setPhysicalBoundaryConditions(
+      hier::Patch& ,
+      const double ,
+      const hier::IntVector& ) {}
+   hier::IntVector
+   getRefineOpStencilWidth() const
+  { return hier::IntVector::getOne(d_dim); }
+   // virtual void
+   // preprocessRefineBoxes(
+   //    hier::Patch& fine,
+   //    const hier::Patch& coarse,
+   //    const hier::BoxList& fine_boxes,
+   //    const hier::IntVector& ratio) {}
+   virtual void
+   preprocessRefine(hier::Patch& ,
+                    const hier::Patch& coarse,
+                    const hier::Box& ,
+                    const hier::IntVector& )
+  {
+    set_boundary(coarse,invalid_id,v_id,true);
+  }
+
+   virtual void
+   postprocessRefineBoxes(
+      hier::Patch& ,
+      const hier::Patch& ,
+      const hier::BoxList& ,
+      const hier::IntVector& ) {}
+   virtual void
+   postprocessRefine(
+      hier::Patch& ,
+      const hier::Patch& ,
+      const hier::Box& ,
+      const hier::IntVector& ) {}
+
+   //@}
+
+   //@{
+
+   /*!
+    * @name Functions to set boundary condition values
+    */
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the first ghost cells.
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to cell-centered variables.
+    * -# Only one ghost cell width is filled.  Setting a Robin
+    *    boundary condition for cell-centered quantities requires
+    *    only one ghost cell to be set.
+    *    (More ghost cells can be filled by continuing the linear
+    *    distribution of data beyond the first cell, but that is
+    *    not implemented at this time.)
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to
+    * get the coefficients, then it sets the values in the first
+    * ghost cell on the boundary.
+    *
+    * To determine the value for the ghost cell,
+    * a @em linear approximation in the direction normal to the
+    * boundary is assumed.  We write the following discrete
+    * approximations:
+    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
+    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
+    * where the subscript b stands for the the boundary,
+    * i stands for the first cell inside the boundary and
+    * o stands for the first cell outside the boundary
+    * and h is the grid spacing normal to the boundary.
+    * Applying this to the Robin formula gives
+    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
+    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
+    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
+    *
+    * After setting the edge (face in 3D) boundary conditions,
+    * linear approximations are used to set the boundary conditions
+    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required in solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @internal To be more general to other data types,
+    * there could be versions for other data types also,
+    * such as ...InNodes, ...InFaces, etc.  However, I'm not
+    * sure exactly how to implement the Robin boundary condition
+    * on the faces and nodes when m != 1.  Should the boundary
+    * value be set or should the first ghost value be set?
+    *
+    * @internal I have not addressed possibility of differences
+    * in chosing the discrete formulation with which to compute
+    * the boundary value.  The above formulation is obviously
+    * one specific approximation, but there could be others.
+    * If anoter approximation is required, there should be
+    * another class like this or this class can offer a choice
+    * to be set by the user.  I favor another class.
+    *
+    * @internal Since the data alignment can be found through
+    * the target_data_id, these types of functions may be changed
+    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
+    * since it does assume boundary boxes.  This may have to be
+    * expanded to later include coarse-fine boundary boxes
+    * for more generality.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set ghost cells for an entire level.
+    *
+    * Loop through all patches on the given level and call
+    * setBoundaryValuesInCells(hier::Patch &patch,
+    *                          const double fill_time ,
+    *                          const hier::IntVector &ghost_width_to_fill ,
+    *                          int target_data_id ,
+    *                          bool homogeneous_bc=false )
+    * for each.
+    *
+    * @param level PatchLevel on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param ghost_width_to_fill Max ghost width requiring fill
+    * @param target_data_id hier::Patch data index of data to be set.
+    *        This data must be a cell-centered double.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesInCells(
+   //    hier::PatchLevel& level,
+   //    const double fill_time,
+   //    const hier::IntVector& ghost_width_to_fill,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   /*!
+    * @brief Set the physical boundary condition by setting the
+    * value of the boundary nodes.
+    *
+    * This function is not yet implemented!
+    *
+    * There are some decisions that must be made before
+    * the implementation can be written.
+    * -# Do we set the values on the boundary or one cell
+    *    away from the boundary?
+    * -# What is the discrete formulation we should use
+    *    to compute the value to be set?
+    *
+    * This function has an interface similar to the virtual function
+    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
+    * and it may be used to help implement that function,
+    * but it does not serve the same purpose.  The primary
+    * differences are:
+    * -# It specializes to node-centered variables.
+    * -# User must specify the index of the data whose ghost
+    *    cells need to be filled.  This index is used to determine
+    *    the variable for which to set the boundary coefficients
+    *    and to get the data to be set.
+    *
+    * This function calls RobinBcStrategy::setBcCoefs() to get the
+    * coefficients, then it sets the values at the boundary nodes.
+    *
+    * In some cases, the calling function wants to set the
+    * boundary condition homogeneously, with g=0.
+    * This is useful in problems where the the solution of the
+    * homogeneous problem is required to solving the inhomogeneous
+    * problem.  This function respects such requests specified
+    * through the argument @c homogeneous_bc.
+    *
+    * @param patch hier::Patch on which to set boundary condition
+    * @param fill_time Solution time corresponding to filling
+    * @param target_data_id hier::Patch data index of data to be set.
+    * @param homogeneous_bc Set a homogeneous boundary condition.
+    *    This means g=0 for the boundary.
+    */
+   // void
+   // setBoundaryValuesAtNodes(
+   //    hier::Patch& patch,
+   //    const double fill_time,
+   //    int target_data_id,
+   //    bool homogeneous_bc = false) const;
+
+   //@}
+
+   //@{
+   /*!
+    * @name Ways to provide the Robin bc coefficients
+    */
+
+   /*!
+    * @brief Provide an implementation of the RobinBcCoefStrategy
+    * for determining the boundary coefficients.
+    *
+    * Provide the implementation that can be used to set the
+    * Robin bc coefficients.
+    *
+    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
+    *        the coefficient strategy.
+    */
+   // void
+   // setCoefImplementation(
+   //    const RobinBcCoefStrategy* coef_strategy);
+
+   /*!
+    * @brief Set the data id that should be filled when setting
+    * physical boundary conditions.
+    *
+    * When setPhysicalBoundaryConditions is called, the data
+    * specified will be set.  This information is required because
+    * the it is not passed in through the argument list of
+    * setPhysicalBounaryConditions.
+    */
+  void setTargetDataId(int id)
+  {
+    v_id=id;
+  }
+
+   /*!
+    * @brief Set whether boundary filling should assume homogeneous
+    * conditions.
+    *
+    * In certain circumstances, only the value of a is needed, while
+    * the value of g is temporarily not required and taken to be zero.
+    * (An example is in setting the boundary condition for error
+    * value in an iterative method.)  In such cases, use this function
+    * to set a flag that will cause a null pointer to be given to
+    * setBcCoefs() to indicate that fact.
+    */
+   // void
+   // setHomogeneousBc(
+   //    bool homogeneous_bc);
+
+   //@}
+
+private:
+   /*!
+    * @brief Trim a boundary box so that it does not stick out
+    * past a given box.
+    *
+    * Certain boundary-related operations occur on patch data that
+    * do not or cannot extend past the edgr or corner of a patch.
+    * This function is used to trim down the parts of the boundary box
+    * that extend past those points so that a suitable index range
+    * is achieved.
+    *
+    * The boundary box trimmed must be of type 1 or 2.
+    *
+    * @param boundary_box Boundary box to be trimmed.
+    * @param limit_box hier::Box to not stick past
+    *
+    * @return New trimmed boundary box.
+    */
+   // hier::BoundaryBox
+   // trimBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box,
+   //    const hier::Box& limit_box) const;
+
+   /*!
+    * @brief Return box describing the index space of boundary nodes
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the nodes corresponding
+    * to the input boundary box.  These nodes lie on the boundary
+    * itself.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the node indices corresponding to
+    *   boundary_box
+    */
+   // hier::Box
+   // makeNodeBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   /*!
+    * @brief Return box describing the index space of faces
+    * defined by a boundary box.
+    *
+    * Define a box describing the indices of the codimension 1
+    * surface corresponding to the input boundary box.
+    *
+    * The input boundary_box must be of type 1
+    * (see hier::BoundaryBox::getBoundaryType()).
+    *
+    * This is a utility function for working with the
+    * indices coresponding to a boundary box but coincide
+    * with the patch boundary.
+    *
+    * @param boundary_box input boundary box
+    * @return a box to define the face indices corresponding to
+    *    boundary_box
+    */
+   // hier::Box
+   // makeFaceBoundaryBox(
+   //    const hier::BoundaryBox& boundary_box) const;
+
+   const tbox::Dimension d_dim;
+
+   std::string d_object_name;
+
+   /*!
+    * @brief Coefficient strategy giving a way to get to
+    * Robin bc coefficients.
+    */
+   // const RobinBcCoefStrategy* d_coef_strategy;
+
+   /*!
+    * @brief hier::Index of target patch data when filling ghosts.
+    */
+   int v_id;
+
+   /*!
+    * @brief Whether to assumg g=0 when filling ghosts.
+    */
+   // bool d_homogeneous_bc;
+
+   /*!
+    * @brief Timers for performance measurement.
+    */
+   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
+   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
+};
+
+}
+}
+
+#endif  // included_solv_V_Refine_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/dRc_dp.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/dRc_dp.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,61 @@
+#ifndef GAMR_DRC_DP
+#define GAMR_DRC_DP
+
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/NodeData.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "dRm_dv.h"
+#include "Constants.h"
+
+/* These two functions should really have a more similar API */
+
+/* The derivative of the continuity equation with respect to
+   pressure.  Note that pressure does not appear in the continuity
+   equation, so we use Tackley's method to chain together
+   derivatives */
+
+inline double dRc_dp_2D(const SAMRAI::hier::Box &pbox,
+                        const SAMRAI::pdat::CellIndex &center,
+                        const SAMRAI::pdat::SideIndex &x,
+                        const SAMRAI::pdat::SideIndex &y,
+                        SAMRAI::pdat::CellData<double> &cell_moduli,
+                        SAMRAI::pdat::NodeData<double> &edge_moduli,
+                        SAMRAI::pdat::SideData<double> &v,
+                        const double &dx,
+                        const double &dy)
+{
+  const SAMRAI::hier::Index ip(1,0), jp(0,1);
+  const SAMRAI::pdat::NodeIndex
+    center_e(center,SAMRAI::pdat::NodeIndex::LowerLeft),
+    up_e(center_e+jp),right_e(center_e+ip);
+    
+  const double dRm_dp_xp(1/dx), dRm_dp_xm(-1/dx),
+    dRm_dp_yp(1/dy), dRm_dp_ym(-1/dy),
+    dRc_dvx_p(-1/dx), dRc_dvx_m(1/dx),
+    dRc_dvy_p(-1/dy), dRc_dvy_m(1/dy);
+
+  double result(0);
+
+  if(!(center[0]==pbox.lower(0) && v(x-ip)==boundary_value))
+    result+=dRc_dvx_m * dRm_dp_xm/dRm_dv_2D(cell_moduli,edge_moduli,
+                                            center,center-ip,up_e,center_e,
+                                            dx,dy);
+
+  if(!(center[0]==pbox.upper(0) && v(x+ip*2)==boundary_value))
+    result+=dRc_dvx_p * dRm_dp_xp/dRm_dv_2D(cell_moduli,edge_moduli,
+                                            center+ip,center,up_e+ip,
+                                            center_e+ip,dx,dy);
+  if(!(center[1]==pbox.lower(1) && v(y-jp)==boundary_value))
+    result+=dRc_dvy_m * dRm_dp_ym/dRm_dv_2D(cell_moduli,edge_moduli,
+                                            center,center-jp,right_e,center_e,
+                                            dy,dx);
+
+  if(!(center[1]==pbox.upper(1) && v(y+jp*2)==boundary_value))
+    result+=dRc_dvy_p * dRm_dp_yp/dRm_dv_2D(cell_moduli,edge_moduli,
+                                            center+jp,center,right_e+jp,
+                                            center_e+jp,dy,dx);
+                                            
+  return result;
+}
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/dRm_dv.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/dRm_dv.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,42 @@
+#ifndef GAMR_DRM_DV
+#define GAMR_DRM_DV
+
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/pdat/EdgeData.h"
+
+/* The derivative of the momentum equation w/respect to velocity. It
+   is written from the perspective of vx(center_x), but pass in
+   different values for center etc. to get vy or vx(!center_x). */
+
+template<class E_data, class E_index>
+double dRm_dv_2D(SAMRAI::pdat::CellData<double> &cell_moduli,
+                 E_data &edge_moduli,
+                 const SAMRAI::pdat::CellIndex &center,
+                 const SAMRAI::pdat::CellIndex &left,
+                 const E_index &up_e,
+                 const E_index &center_e,
+                 const double &dx,
+                 const double &dy)
+{
+  return -(   (cell_moduli(center,0) + cell_moduli(left,0))
+           +2*(cell_moduli(center,1) + cell_moduli(left,1)))/(dx*dx)
+         -(edge_moduli(up_e,1) + edge_moduli(center_e,1))/(dy*dy);
+}
+
+inline double dRm_dv_3D(SAMRAI::pdat::CellData<double> &cell_moduli,
+		        SAMRAI::pdat::EdgeData<double> &edge_moduli,
+			const SAMRAI::pdat::CellIndex &center,
+			const SAMRAI::pdat::CellIndex &left,
+			const SAMRAI::pdat::EdgeIndex &front_y,
+			const SAMRAI::pdat::EdgeIndex &center_y,
+			const SAMRAI::pdat::EdgeIndex &up_z,
+			const SAMRAI::pdat::EdgeIndex &center_z,
+			const double &dx,
+			const double &dy,
+			const double &dz)
+{
+	  return dRm_dv_2D(cell_moduli,edge_moduli,center,left,front_y,center_y,dx,dy)
+		      - (edge_moduli(up_z,1) + edge_moduli(center_z,1))/(dz*dz);
+}
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/set_boundary.C
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/set_boundary.C	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,168 @@
+#include "set_boundary.h"
+#include "Constants.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/CellData.h"
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+
+using namespace SAMRAI;
+
+void set_boundary(const SAMRAI::hier::Patch& patch, const int &p_id,
+                    const int &v_id, const bool &rhs)
+{
+  hier::Box pbox=patch.getBox();
+
+  tbox::Pointer<geom::CartesianPatchGeometry> geom = patch.getPatchGeometry();
+  const tbox::Dimension Dim(patch.getDim());
+  const int dim(patch.getDim().getValue());
+
+  const hier::Index zero(hier::Index::getZeroIndex(Dim));
+  hier::Index pp[]={zero,zero,zero};
+  for(int i=0;i<dim;++i)
+    pp[i][i]=1;
+  /* This should really get read from the input file. */
+  double lower_boundary[]={0,0,0};
+  bool lower_dirichlet[]={true,true,true};
+
+  // double upper_boundary[]={-6.94444444444e4,0,0};
+  // bool upper_dirichlet[]={true,false,true};
+
+  // bool upper_dirichlet[]={true,true,true};
+  // double upper_boundary[]={-1,1,0};
+
+  double p_lower[]={0,0,0};
+  double p_upper[]={0,0,0};
+
+  bool upper_dirichlet[]={true,true,true};
+  double upper_boundary[]={0,0,0};
+
+  if(v_id!=invalid_id)
+    {
+      tbox::Pointer<pdat::SideData<double> > v_ptr = patch.getPatchData(v_id);
+      pdat::SideData<double> &v(*v_ptr);
+
+      hier::Box gbox=v.getGhostBox();
+      for(int ix=0; ix<dim; ++ix)
+        {
+          for(pdat::SideIterator si(gbox,ix); si; si++)
+            {
+              pdat::SideIndex x(*si);
+
+              /* Set a sentinel value for normal components */
+              if(x[ix]<pbox.lower(ix) && geom->getTouchesRegularBoundary(ix,0))
+                {
+                  if(lower_dirichlet[ix])
+                    v(x)=boundary_value;
+                  else
+                    v(x)=v(x+pp[ix]*2);
+                }
+              else if(x[ix]>pbox.upper(ix)+1
+                      && geom->getTouchesRegularBoundary(ix,1))
+                {
+                  if(upper_dirichlet[ix])
+                    v(x)=boundary_value;
+                  else
+                    v(x)=v(x-pp[ix]*2);
+                }
+              /* Set values for normal components */
+              else if(x[ix]==pbox.lower(ix)
+                      && geom->getTouchesRegularBoundary(ix,0)
+                      && !rhs && lower_dirichlet[ix])
+                {
+                  v(x)=lower_boundary[ix];
+                }
+              else if(x[ix]==pbox.upper(ix)+1
+                      && geom->getTouchesRegularBoundary(ix,1)
+                      && !rhs && upper_dirichlet[ix])
+                {
+                  v(x)=upper_boundary[ix];
+                }
+              /* Set derivatives for tangential component.  The edges
+                 and corners are incorrect for now.  */
+              else
+                {
+                  for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
+                    {
+                      if(x[iy]<pbox.lower(iy)
+                         && geom->getTouchesRegularBoundary(iy,0))
+                        {
+                          v(x)=v(x+pp[iy]);
+                        }
+                      else if(x[iy]>pbox.upper(iy)
+                              && geom->getTouchesRegularBoundary(iy,1))
+                        {
+                          v(x)=v(x-pp[iy]);
+                        }
+                    }
+                }
+            }
+          /* Fix up the edges.  This has to be done in a different
+             loop, because the values on the faces will be used to
+             compute values in the edges and corners.  In 2D, I am not
+             sure that this is needed.  It is certainly not needed if
+             we have dirichlet conditions on the boundary.  It is
+             definitely needed in 3D.  We use the d/dx conditions
+             here, though we could use the d/dy conditions and get the
+             same number, as long as we have pure Neumann boundary
+             conditions, and not Robin. */
+
+          for(pdat::SideIterator si(gbox,ix); si; si++)
+            {
+              pdat::SideIndex x(*si);
+              if((x[ix]<pbox.lower(ix)
+                  && geom->getTouchesRegularBoundary(ix,0)
+                  && !lower_dirichlet[ix])
+                 || (x[ix]>pbox.upper(ix)+1
+                     && geom->getTouchesRegularBoundary(ix,1)
+                     && !upper_dirichlet[ix]))
+                {
+                  for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
+                    {
+                      if(x[iy]<pbox.lower(iy) 
+                         && geom->getTouchesRegularBoundary(iy,0))
+                        {
+                          v(x)=v(x+pp[iy]);
+                        }
+                      else if(x[iy]>pbox.upper(iy) 
+                              && geom->getTouchesRegularBoundary(iy,1))
+                        {
+                          v(x)=v(x-pp[iy]);
+                        }
+                    }
+                }
+            }
+          /* In 3D, fix the corners.  I am not sure that this is
+             needed. */
+          if(dim==3)
+            {
+              const int iy((ix+1)%dim), iz((iy+1)%dim);
+              for(pdat::SideIterator si(gbox,ix); si; si++)
+                {
+                  pdat::SideIndex x(*si);
+                  if(((x[ix]<pbox.lower(ix)
+                       && geom->getTouchesRegularBoundary(ix,0)
+                       && !lower_dirichlet[ix])
+                      || (x[ix]>pbox.upper(ix)+1
+                          && geom->getTouchesRegularBoundary(ix,1)
+                          && !upper_dirichlet[ix]))
+                     && ((x[iy]<pbox.lower(iy)
+                          && geom->getTouchesRegularBoundary(iy,0))
+                         || (x[iy]>pbox.upper(iy) 
+                             && geom->getTouchesRegularBoundary(iy,1))))
+                    {
+                      if(x[iz]<pbox.lower(iz) 
+                         && geom->getTouchesRegularBoundary(iz,0))
+                        {
+                          v(x)=v(x+pp[iz]);
+                        }
+                      else if(x[iz]>pbox.upper(iz) 
+                              && geom->getTouchesRegularBoundary(iz,1))
+                        {
+                          v(x)=v(x-pp[iz]);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff -r daa8bb8aed75 -r dc04c13db402 src/Elastic/set_boundary.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Elastic/set_boundary.h	Wed Jun 06 15:05:55 2012 -0700
@@ -0,0 +1,9 @@
+#ifndef SET_V_BOUNDARY_H
+#define SET_V_BOUNDARY_H
+
+#include "SAMRAI/hier/Patch.h"
+
+void set_boundary(const SAMRAI::hier::Patch& patch,
+                  const int &p_id, const int &v_id, const bool &rhs);
+
+#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps.I
--- a/src/ElasticFACOps.I	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for solving scalar Elastic using FAC 
- *
- ************************************************************************/
-namespace SAMRAI {
-namespace solv {
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setPreconditioner(
-   const FACPreconditioner* preconditioner) {
-   d_preconditioner = preconditioner;
-}
-
-#ifdef HAVE_HYPRE
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setUseSMG(
-   bool use_smg)
-{
-   if (d_hierarchy) {
-      TBOX_ERROR(
-         d_object_name << ": setUseSMG(bool) may NOT be called\n"
-         <<
-         "while the solver state is initialized, as that\n"
-         << "would lead to a corrupted solver state.\n");
-   }
-   d_hypre_solver.setUseSMG(use_smg);
-}
-#endif
-
-/*
- ********************************************************************
- * Set the physical boundary condition object.                      *
- ********************************************************************
- */
-
-// SAMRAI_INLINE_KEYWORD
-// void ElasticFACOps::setPhysicalBcCoefObject(
-//    const RobinBcCoefStrategy* physical_bc_coef)
-// {
-//    d_physical_bc_coef = physical_bc_coef;
-//    // d_bc_helper.setCoefImplementation(physical_bc_coef);
-// #ifdef HAVE_HYPRE
-//    d_hypre_solver.setPhysicalBcCoefObject(d_physical_bc_coef);
-// #endif
-// }
-
-/*
- ********************************************************************
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::enableLogging(
-   bool enable_logging)
-{
-   d_enable_logging = enable_logging;
-}
-
-/*
- ********************************************************************
- * Set the choice for smoothing algorithm.                          *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setSmoothingChoice(
-   const std::string& smoothing_choice)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (smoothing_choice != "Tackley" && smoothing_choice != "Gerya") {
-      TBOX_ERROR(d_object_name << ": Bad smoothing choice '"
-                               << smoothing_choice
-                               << "' in ElasticFACOps::setSmoothingChoice.");
-   }
-#endif
-   d_smoothing_choice = smoothing_choice;
-}
-
-/*
- ********************************************************************
- * Set the choice for the coarse level solver.                      *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setCoarsestLevelSolverChoice(
-   const std::string& choice) {
-#ifdef DEBUG_CHECK_ASSERTIONS
-#ifndef HAVE_HYPRE
-   if (choice == "hypre") {
-      TBOX_ERROR(d_object_name << ": HYPRe library is not available.\n");
-   }
-#endif
-#endif
-   if (choice == "Tackley"
-       || choice == "Gerya"
-       || choice == "hypre") {
-      d_coarse_solver_choice = choice;
-   } else {
-      TBOX_ERROR(
-         d_object_name << ": Bad coarse level solver choice '"
-         << choice
-         <<
-         "' in scapElasticOpsX::setCoarseLevelSolver.");
-   }
-}
-
-/*
- ********************************************************************
- * Set the tolerance for the coarse level solver.                   *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setCoarsestLevelSolverTolerance(
-   double tol) {
-   d_coarse_solver_tolerance = tol;
-}
-
-/*
- ********************************************************************
- * Set the tolerance for the coarse level solver.                   *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setCoarsestLevelSolverMaxIterations(
-   int max_iterations) {
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (max_iterations < 0) {
-      TBOX_ERROR(d_object_name << ": Invalid number of max iterations\n");
-   }
-#endif
-   d_coarse_solver_max_iterations = max_iterations;
-}
-
-/*
- ********************************************************************
- * Set the coarse-fine discretization method.                       *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::setCoarseFineDiscretization(
-   const std::string& coarsefine_method) {
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (d_hierarchy) {
-      TBOX_ERROR(
-         d_object_name << ": Cannot change coarse-fine\n"
-         <<
-         "discretization method while operator state\n"
-         << "is initialized because that causes a\n"
-         << "corruption in the state.\n");
-   }
-#endif
-   d_cf_discretization = coarsefine_method;
-}
-
-/*
- ********************************************************************
- * Set the prolongation method                                      *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::set_P_ProlongationMethod(
-   const std::string& prolongation_method) {
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (d_hierarchy) {
-      TBOX_ERROR(
-         d_object_name << ": Cannot change p prolongation method\n"
-         <<
-         "while operator state is initialized because that\n"
-         << "causes a corruption in the state.\n");
-   }
-#endif
-   p_prolongation_method = prolongation_method;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACOps::set_V_ProlongationMethod(
-   const std::string& prolongation_method) {
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (d_hierarchy) {
-      TBOX_ERROR(
-         d_object_name << ": Cannot change v prolongation method\n"
-         <<
-         "while operator state is initialized because that\n"
-         << "causes a corruption in the state.\n");
-   }
-#endif
-   v_prolongation_method = prolongation_method;
-}
-
-}
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps.h
--- a/src/ElasticFACOps.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1077 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#ifndef included_solv_ElasticFACOps
-#define included_solv_ElasticFACOps
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "SAMRAI/solv/FACOperatorStrategy.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/solv/SAMRAIVectorReal.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/math/HierarchySideDataOpsReal.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/hier/CoarseFineBoundary.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/hier/PatchHierarchy.h"
-#include "SAMRAI/hier/PatchLevel.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/VariableContext.h"
-#include "SAMRAI/tbox/Database.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "P_Refine_Patch_Strategy.h"
-#include "V_Refine_Patch_Strategy.h"
-#include "V_Coarsen_Patch_Strategy.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief FAC operator class to solve Elastic's equation on a SAMR grid,
- * using cell-centered, second-order finite-volume method, with Robin
- * boundary conditions.
- *
- * This class provides operators that are used by the FAC
- * preconditioner FACPreconditioner.
- * It is used to solve the scalar Elastic's equation using a cell-centered
- * second-order finite-volume discretization.
- * It is designed to provide all operations specific to
- * the scalar Elastic's equation,
- * @f[ \nabla \cdot D \nabla u + C u = f @f]
- * (see ElasticSpecifications) where
- * - C, D and f are indpendent of u
- * - C is a cell-centered scalar field
- * - D is the @em diffusion @em coefficients, stored on faces
- * - f is a cell-centered scalar function
- *
- * You are left to provide the source function, initial guess, etc.,
- * by specifying them in specific forms.
- *
- * This class provides:
- * -# 5-point (second order), cell-centered stencil operations
- *    for the discrete Laplacian.
- * -# Red-black Gauss-Seidel smoothing.
- * -# Provisions for working Robin boundary conditions
- *    (see RobinBcCoefStrategy).
- *
- * This class is meant to provide the Elastic-specific operator
- * used by the FAC preconditioner, FACPreconditioner.
- * To use the preconditioner with this class, you will have to provide:
- * -# The solution vector SAMRAIVectorReal,
- *    with appropriate norm weighting for the cell-centered AMR mesh.
- *    This class provides the function computeVectorWeights()
- *    to help with computing the appropriate weights.
- *    Since this is for a scalar equation, only the first depth
- *    of the first component of the vectors are used.
- *    All other parts are ignored.
- * -# The source vector SAMRAIVectorReal for f.
- * -# A ElasticSpecifications objects to specify
- *    the cell-centered scalar field C and the side-centered
- *    diffusion coefficients D
- * -# The boundary condition specifications in terms of the coefficients
- *    @f$ \alpha @f$, @f$ \beta @f$ and @f$ \gamma @f$ in the
- *    Robin formula @f$  \alpha u + \beta u_n = \gamma @f$ applied on the
- *    boundary faces.  See RobinBcCoefStrategy.
- *
- * This class allocates and deallocates only its own scratch data.
- * Other data that it manipuates are passed in as function arguments.
- * Hence, it owns none of the solution vectors, error vectors,
- * diffusion coefficient data, or any such things.
- *
- * Input Examples
- * @verbatim
- * coarse_solver_choice = "hypre"    // see setCoarsestLevelSolverChoice()
- * coarse_solver_tolerance = 1e-14   // see setCoarsestLevelSolverTolerance()
- * coarse_solver_max_iterations = 10 // see setCoarsestLevelSolverMaxIterations()
- * smoothing_choice = "Tackley"     // see setSmoothingChoice()
- * cf_discretization = "Ewing"       // see setCoarseFineDiscretization()
- * prolongation_method = "P_REFINE" // see setProlongationMethod()
- * hypre_solver = { ... }            // tbox::Database for initializing Hypre solver
- * @endverbatim
- */
-class ElasticFACOps:
-   public FACOperatorStrategy
-{
-
-public:
-   /*!
-    * @brief Constructor.
-    *
-    * If you want standard output and logging,
-    * pass in valid pointers for those streams.
-    * @param object_name Ojbect name
-    * @param database Input database
-    */
-   ElasticFACOps(
-      const tbox::Dimension& dim,
-      const std::string& object_name = std::string(),
-      tbox::Pointer<tbox::Database> database =
-         tbox::Pointer<tbox::Database>(NULL));
-
-   /*!
-    * @brief Destructor.
-    *
-    * Deallocate internal data.
-    */
-   ~ElasticFACOps(void) {}
-
-   /*!
-    * @brief Enable logging.
-    *
-    * By default, logging is disabled.  The logging flag is
-    * propagated to the major components used by this class.
-    */
-   void
-   enableLogging(
-      bool enable_logging);
-
-   //@{
-   /*!
-    * @name Functions for setting solver mathematic algorithm controls
-    */
-
-   /*!
-    * @brief Set the choice of smoothing algorithms.
-    *
-    * Current smoothing choices are:
-    * - "Tackley"
-    * - "Gerya"
-    */
-   void
-   setSmoothingChoice(
-      const std::string& smoothing_choice);
-
-   /*!
-    * @brief Set coarse level solver.
-    *
-    * Select from these:
-    * - @c "Tackley" (red-black smoothing until convergence--very slow!)
-    * - @c "Gerya" (red-black smoothing until convergence--very slow!)
-    * - @c "hypre" (only if the HYPRE library is available).
-    */
-   void
-   setCoarsestLevelSolverChoice(
-      const std::string& choice);
-
-   /*!
-    * @brief Set tolerance for coarse level solve.
-    *
-    * If the coarse level solver requires a tolerance (currently, they all do),
-    * the specified value is used.
-    */
-   void
-   setCoarsestLevelSolverTolerance(
-      double tol);
-
-   /*!
-    * @brief Set max iterations for coarse level solve.
-    *
-    * If the coarse level solver requires a max iteration limit
-    * (currently, they all do), the specified value is used.
-    */
-   void
-   setCoarsestLevelSolverMaxIterations(
-      int max_iterations);
-
-   /*!
-    * @brief Set the coarse-fine boundary discretization method.
-    *
-    * Specify the @c op_name std::string which will be passed to
-    * xfer::Geometry::lookupRefineOperator() to get the operator
-    * for setting fine grid ghost cells from the coarse grid.
-    * Note that chosing this operator implicitly choses the
-    * discretization method at the coarse-fine boundary.
-    *
-    * There is one important instance where this std::string is
-    * @em not passed to xfer::Geometry::lookupRefineOperator.
-    * If this variable is set to "Ewing", Ewing's coarse-fine
-    * discretization is used (a constant refinement is performed,
-    * and the flux is later corrected to result in Ewing's scheme).
-    * For a reference to Ewing's discretization method, see
-    * "Local Refinement Techniques for Elliptic Problems on Cell-Centered
-    * Grids, I. Error Analysis", Mathematics of Computation, Vol. 56, No. 194,
-    * April 1991, pp. 437-461.
-    *
-    * @param coarsefine_method String selecting the coarse-fine discretization method.
-    */
-   void
-   setCoarseFineDiscretization(
-      const std::string& coarsefine_method);
-
-   /*!
-    * @brief Set the name of the prolongation method.
-    *
-    * Specify the @c op_name std::string which will be passed to
-    * xfer::Geometry::lookupRefineOperator() to get the operator
-    * for prolonging the coarse-grid correction.
-    *
-    * By default, "CONSTANT_REFINE" is used.  "LINEAR_REFINE" seems to
-    * to lead to faster convergence, but it does NOT satisfy the Galerkin
-    * condition.
-    *
-    * Prolonging using linear refinement requires a Robin bc
-    * coefficient implementation that is capable of delivering
-    * coefficients for non-hierarchy data, because linear refinement
-    * requires boundary conditions to be set on temporary levels.
-    *
-    * @param prolongation_method String selecting the coarse-fine
-    *        discretization method.
-    */
-   void
-   set_P_ProlongationMethod(
-      const std::string& prolongation_method);
-
-   void
-   set_V_ProlongationMethod(
-      const std::string& prolongation_method);
-
-#ifdef HAVE_HYPRE
-   /*!
-    * @brief Set whether to use Hypre's PFMG algorithm instead of the
-    * SMG algorithm.
-    *
-    * This flag affects the Hypre solver (used to solve the coarsest level).
-    * The flag is used to select which of HYPRE's linear solver algorithms
-    * to use if true, the semicoarsening multigrid algorithm is used, and if
-    * false, the ``PF'' multigrid algorithm is used.
-    * By default, the SMG algorithm is used.
-    *
-    * This setting has effect only when Hypre is chosen for the coarsest
-    * level solver.  See setCoarsestLevelSolverChoice().
-    *
-    * Changing the algorithm must be done before initializing the solver
-    * state and must NOT be done while the state is initialized
-    * (the program will exit), as that would corrupt the state.
-    */
-   void
-   setUseSMG(
-      bool use_smg);
-#endif
-
-   //@}
-
-   //@{
-   /*!
-    * @name Functions for setting patch data indices and coefficients
-    */
-
-   /*!
-    * @brief Set the scratch patch data index for the flux.
-    *
-    * The use of this function is optional.
-    * The patch data index should be a pdat::SideData<DIM> type of variable.
-    * If the flux id is -1 (the default initial value), scratch space
-    * for the flux is allocated as needed and immediately deallocated
-    * afterward, level by level.  If you have space preallocated for
-    * flux and you would like that to be used, set flux id to the
-    * patch data index of that space.
-    */
-  void set_moduli_id(const int &cell_moduli, const int &edge_moduli)
-  {
-    cell_moduli_id=cell_moduli;
-    edge_moduli_id=edge_moduli;
-  }
-   //@}
-
-   /*!
-    * @brief Provide an implementation for getting the
-    * physical bc coefficients
-    *
-    * If your solution is fixed at the physical boundary
-    * ghost cell centers AND those cells have the correct
-    * values before entering solveSystem(), you may use a
-    * GhostCellRobinBcCoefs object.
-    *
-    * If your solution is @b not fixed at the ghost cell centers,
-    * the ghost cell values will change as the interior
-    * cell values change.  In those cases, the flexible
-    * Robin boundary conditions are applied.  You must
-    * call this function to provide the implementation for
-    * determining the boundary condition coefficients.
-    *
-    * @param physical_bc_coef tbox::Pointer to an object that can
-    *        set the Robin bc coefficients.
-    */
-   // void
-   // setPhysicalBcCoefObject(
-   //    const RobinBcCoefStrategy* physical_bc_coef);
-
-   /*!
-    * @brief Set weight appropriate for computing vector norms.
-    *
-    * If you this function to set the weights used when you
-    * SAMRAIVectorReal::addComponent, you can use the
-    * vector norm functions of SAMRAIVectorReal, and
-    * the weights will be used to blank out coarse grid
-    * regions under fine grids.
-    *
-    * The weights computed are specific to the cell-centered
-    * discretization used by this class.  The weight is equal
-    * to the cell volume if the cell has not been refined,
-    * and zero if it has.
-    *
-    * This function is state-independent.  All inputs are in
-    * the argument list.
-    *
-    * @param hierarchy Hierarchy configuration to compute weights for
-    * @param weight_id hier::Patch data index of the weight
-    * @param coarsest_ln Coarsest level number.  Must be included
-    *        in hierarchy.  Must not be greater than @c finest_ln.
-    *        Default to 0.
-    * @param finest_ln Finest level number.  Must be included
-    *        in hierarchy.  Must not be less than @c coarsest_ln.
-    *        Default to finest level in @c hierarchy.
-    */
-   void
-   computeVectorWeights(
-      tbox::Pointer<hier::PatchHierarchy> hierarchy,
-      int weight_id,
-      int coarsest_ln = -1,
-      int finest_ln = -1) const;
-
-   /*!
-    * @brief Set the FAC preconditioner that will be using this object.
-    *
-    * The FAC preconditioner is accessed to get convergence data during
-    * the cycle postprocessing step.  It is optional.
-    */
-   void
-   setPreconditioner(
-      const FACPreconditioner* preconditioner);
-
-   //@{ @name FACOperatorStrategy virtuals
-
-   virtual void
-   restrictSolution(
-      const SAMRAIVectorReal<double>& source,
-      SAMRAIVectorReal<double>& dest,
-      int dest_ln);
-   virtual void
-   restrictResidual(
-      const SAMRAIVectorReal<double>& source,
-      SAMRAIVectorReal<double>& dest,
-      int dest_ln);
-
-   virtual void
-   prolongErrorAndCorrect(
-      const SAMRAIVectorReal<double>& source,
-      SAMRAIVectorReal<double>& dest,
-      int dest_ln);
-
-   virtual void
-   smoothError(
-      SAMRAIVectorReal<double>& error,
-      const SAMRAIVectorReal<double>& residual,
-      int ln,
-      int num_sweeps);
-
-   virtual int
-   solveCoarsestLevel(
-      SAMRAIVectorReal<double>& error,
-      const SAMRAIVectorReal<double>& residual,
-      int coarsest_ln);
-
-   virtual void
-   computeCompositeResidualOnLevel(
-      SAMRAIVectorReal<double>& residual,
-      const SAMRAIVectorReal<double>& solution,
-      const SAMRAIVectorReal<double>& rhs,
-      int ln,
-      bool error_equation_indicator);
-
-  void residual_2D
-  (pdat::CellData<double> &p,
-   pdat::SideData<double> &v,
-   pdat::CellData<double> &cell_moduli,
-   pdat::CellData<double> &p_rhs,
-   pdat::SideData<double> &v_rhs,
-   pdat::CellData<double> &p_resid,
-   pdat::SideData<double> &v_resid,
-   hier::Patch &patch,
-   const hier::Box &pbox,
-   const geom::CartesianPatchGeometry &geom);
-
-  void residual_3D
-  (pdat::CellData<double> &p,
-   pdat::SideData<double> &v,
-   pdat::CellData<double> &cell_moduli,
-   pdat::CellData<double> &p_rhs,
-   pdat::SideData<double> &v_rhs,
-   pdat::CellData<double> &p_resid,
-   pdat::SideData<double> &v_resid,
-   hier::Patch &patch,
-   const hier::Box &pbox,
-   const geom::CartesianPatchGeometry &geom);
-
-   virtual double
-   computeResidualNorm(
-      const SAMRAIVectorReal<double>& residual,
-      int fine_ln,
-      int coarse_ln);
-
-   virtual void
-   initializeOperatorState(
-      const SAMRAIVectorReal<double>& solution,
-      const SAMRAIVectorReal<double>& rhs);
-
-   virtual void
-   deallocateOperatorState();
-
-   virtual void
-   postprocessOneCycle(
-      int fac_cycle_num,
-      const SAMRAIVectorReal<double>& current_soln,
-      const SAMRAIVectorReal<double>& residual);
-
-  void set_boundaries(const int &p_id, const int &v_id, const int &l)
-  {
-    set_boundaries(p_id,v_id,l,true);
-  }
-  void set_boundaries(const int &p_id, const int &v_id, const int &l,
-                      const bool &rhs)
-  {
-    tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(l);
-    set_boundaries(p_id,v_id,level,rhs);
-  }
-  void set_boundaries(const int &p_id, const int &v_id,
-                      tbox::Pointer<hier::PatchLevel> &level)
-  {
-    set_boundaries(p_id,v_id,level,true);
-  }
-  void set_boundaries(const int &p_id, const int &v_id, 
-                      tbox::Pointer<hier::PatchLevel> &level,
-                      const bool &rhs);
-
-   //@}
-
-private:
-   //@{
-   /*!
-    * @name Private workhorse functions.
-    */
-
-   /*!
-    * @brief Red-black Gauss-Seidel error smoothing on a level.
-    *
-    * Smoothes on the residual equation @f$ Ae=r @f$ on a level.
-    *
-    * @param error error vector
-    * @param residual residual vector
-    * @param ln level number
-    * @param num_sweeps number of sweeps
-    * @param residual_tolerance the maximum residual considered to be
-    *        converged
-    */
-   void smooth_Tackley_2D(
-      SAMRAIVectorReal<double>& error,
-      const SAMRAIVectorReal<double>& residual,
-      int ln,
-      int num_sweeps,
-      double residual_tolerance = -1.0);
-
-   void smooth_Tackley_3D
-            (SAMRAIVectorReal<double>& solution,
-             const SAMRAIVectorReal<double>& residual,
-             int ln,
-             int num_sweeps,
-             double residual_tolerance = -1.0);
-
-void smooth_V_2D(const int &axis,
-	const hier::Box &pbox,
-	tbox::Pointer<geom::CartesianPatchGeometry> &geom,
-	const pdat::CellIndex &center,
-	const hier::Index &ip,
-	const hier::Index &jp,
-	pdat::SideData<double> &v,
-	pdat::SideData<double> &v_rhs,
-	double &maxres,
-	const double &dx,
-	const double &dy,
-	pdat::CellData<double> &cell_moduli,
-	pdat::NodeData<double> &edge_moduli,
-	const double &theta_momentum);
-
-void smooth_V_3D(const int &ix,
-  const hier::Box &pbox,
-  tbox::Pointer<geom::CartesianPatchGeometry> &geom,
-  pdat::SideData<double> &v,
-  pdat::SideData<double> &v_rhs,
-  pdat::CellData<double> &cell_moduli,
-  pdat::EdgeData<double> &edge_moduli,
-  const pdat::CellIndex &center,
-  const double Dx[3],
-  const double &theta_momentum,
-  const hier::Index pp[3],
-  double &maxres);
-
-  /* The mixed derivative of the stress.  We have to use a template
-     because 2D uses Node's for the edge moduli, while 3D uses
-     Edge's.  Written as if it is dtau_xy_dy. */
-
-  template<class E_data, class E_index>
-  double shear_noncell(const pdat::SideData<double> &v,
-                    const E_data &edge_moduli,
-                    const pdat::SideIndex &x,
-                    const pdat::SideIndex &y,
-                    const E_index &edge,
-                    const hier::Index &ip,
-                    const hier::Index &jp,
-                    const double &dx,
-                    const double &dy)
-  {
-    return 
-	     edge_moduli(edge+jp,1)*(v(x+jp)-v(x   ))/(dy*dy)
-            -edge_moduli(edge   ,1)*(v(x   )-v(x-jp))/(dy*dy)
-            +edge_moduli(edge+jp,1)*(v(y+jp)-v(y+jp-ip))/(dx*dy) 
-            -edge_moduli(edge   ,1)*(v(y   )-v(y-ip   ))/(dx*dy);
-  }
-
-  /* The action of the velocity operator. It is written from the
-     perspective of vx, but pass in different values for center_x
-     etc. to get vy. */
-
-  double aligned_terms(const pdat::SideData<double> &v,
-                       const pdat::CellData<double> &cell_moduli,
-                       const pdat::CellIndex &center,
-                       const pdat::SideIndex &x,
-                       const hier::Index &ip,
-                       const double &dx)
-  {
-    return ( (v(x+ip)-v(x   ))*(cell_moduli(center   ,0)+2*cell_moduli(center   ,1))
-            -(v(x   )-v(x-ip))*(cell_moduli(center-ip,0)+2*cell_moduli(center-ip,1)))/(dx*dx);
-  }
-
-  double lame_mixed(const pdat::SideData<double> &v,
-                       const pdat::CellData<double> &cell_moduli,
-                       const pdat::CellIndex &center,
-                       const pdat::SideIndex &y,
-                       const hier::Index &ip,
-                       const hier::Index &jp,
-                       const double &dx,
-                       const double &dy)
-  {
-    return (+ cell_moduli(center   ,0)*(v(y+jp   )-v(y   ))/dy
-            - cell_moduli(center-ip,0)*(v(y+jp-ip)-v(y-ip))/dy)/dx;
-  }
-
-  double v_operator_2D(const pdat::SideData<double> &v,
-                       const pdat::CellData<double> &cell_moduli,
-                       const pdat::NodeData<double> &edge_moduli,
-                       const pdat::CellIndex &center,
-                       const pdat::NodeIndex &edge,
-                       const pdat::SideIndex &x,
-                       const pdat::SideIndex &y,
-                       const hier::Index &ip,
-                       const hier::Index &jp,
-                       const double &dx,
-                       const double &dy)
- {
-    return aligned_terms(v,cell_moduli,center,x,ip,dx)
-	  +lame_mixed(v,cell_moduli,center,y,ip,jp,dx,dy)
-	  +shear_noncell(v,edge_moduli,x,y,edge,ip,jp,dx,dy);
-  }
-
-  double v_operator_3D(const pdat::SideData<double> &v,
-                       const pdat::CellData<double> &cell_moduli,
-                       const pdat::EdgeData<double> &edge_moduli,
-                       const pdat::CellIndex &center,
-                       const pdat::EdgeIndex &edge_y,
-                       const pdat::EdgeIndex &edge_z,
-                       const pdat::SideIndex &x,
-                       const pdat::SideIndex &y,
-                       const pdat::SideIndex &z,
-                       const hier::Index &ip,
-                       const hier::Index &jp,
-                       const hier::Index &kp,
-                       const double &dx,
-                       const double &dy,
-                       const double &dz)
-  {
-    return aligned_terms(v,cell_moduli,center,x,ip,dx)
-	  +lame_mixed(v,cell_moduli,center,y,ip,jp,dx,dy)
-	  +lame_mixed(v,cell_moduli,center,z,ip,kp,dx,dz)
-	  +shear_noncell(v,edge_moduli,x,y,edge_y,ip,jp,dx,dy)
-	  +shear_noncell(v,edge_moduli,x,z,edge_z,ip,kp,dx,dz);
-  }
-
-   /*!
-    * @brief Solve the coarsest level using HYPRE
-    */
-   int
-   solveCoarsestLevel_HYPRE(
-      SAMRAIVectorReal<double>& error,
-      const SAMRAIVectorReal<double>& residual,
-      int ln);
-
-   /*!
-    * @brief AMR-unaware function to red or black smoothing on a single patch,
-    * for variable diffusion coefficient and variable scalar field.
-    *
-    * @param patch patch
-    * @param flux_data side-centered flux data
-    * @param rhs_data cell-centered rhs data
-    * @param scalar_field_data
-    *        cell-centered scalar field data
-    * @param soln_data cell-centered solution data
-    * @param red_or_black red-black switch.  Set to 'r' or 'b'.
-    * @param p_maxres max residual output.  Set to NULL to avoid computing.
-    */
-   void
-   redOrBlackSmoothingOnPatch(
-      const hier::Patch& patch,
-      const pdat::SideData<double>& flux_data,
-      const pdat::CellData<double>& rhs_data,
-      pdat::CellData<double>& soln_data,
-      char red_or_black,
-      double* p_maxres = NULL) const;
-
-   //@}
-
-   //@{ @name For executing, caching and resetting communication schedules.
-
-   /*!
-    * @brief Execute a refinement schedule
-    * for prolonging cell data.
-    *
-    * General notes regarding internal objects for communication:
-    * We maintain objects to support caching schedules to improve
-    * efficiency.  Communication is needed in 5 distinct tasks.
-    *   -# Prolongation
-    *   -# Restriction
-    *   -# Flux coarsening.  Changing the coarse grid flux to the
-    *      composite grid flux by coarsening the fine grid flux
-    *      at the coarse-fine boundaries.
-    *   -# Fill boundary data from other patches in the same level
-    *      and physical boundary condition.
-    *   -# Fill boundary data from same level, coarser levels
-    *      and physical boundary condition.
-    *
-    * For each task, we maintain a refine or coarsen operator,
-    * and a array of communication schedules (one for each
-    * destination level).
-    *
-    * The 5 member functions named @c xeqSchedule... execute
-    * communication schedules appropriate for five specific tasks.
-    * They use a cached schedule if possible or create and cache
-    * a new schedule if needed.  These functions and the data
-    * they manipulate are as follows:
-    * <ol>
-    *   <li> xeqScheduleProlongation():
-    *        prolongation_refine_operator
-    *        prolongation_refine_schedules
-    *   <li> xeqScheduleURestriction():
-    *        d_restriction_coarsen_operator,
-    *        urestriction_coarsen_schedules.
-    *   <li> xeqScheduleRRestriction():
-    *        restriction_coarsen_operator,
-    *        rrestriction_coarsen_schedules.
-    *   <li> xeqScheduleFluxCoarsen():
-    *        d_flux_coarsen_operator,
-    *        d_flux_coarsen_schedules.
-    *   <li> xeqScheduleGhostFill():
-    *        ghostfill_refine_operator,
-    *        ghostfill_refine_schedules.
-    *   <li> xeqScheduleGhostFillNoCoarse():
-    *        ghostfill_nocoarse_refine_operator,
-    *        ghostfill_nocoarse_refine_schedules.
-    * </ol>
-    *
-    * @return refinement schedule for prolongation
-    */
-   void
-   xeqScheduleProlongation(int p_dst, int p_src, int p_scr,
-                           int v_dst, int v_src, int v_scr,
-                           int dest_ln);
-
-   /*!
-    * @brief Execute schedule for restricting solution to the specified
-    * level or reregister an existing one.
-    *
-    * See general notes for xeqScheduleProlongation().
-    *
-    * @return coarsening schedule for restriction
-    */
-   void
-   xeqScheduleURestriction(int p_dst, int p_src, int v_dst, int v_src,
-                           int dest_ln);
-
-   /*!
-    * @brief Execute schedule for restricting residual to the specified
-    * level or reregister an existing one.
-    *
-    * See general notes for xeqScheduleProlongation().
-    *
-    * @return coarsening schedule for restriction
-    */
-   void
-   xeqScheduleRRestriction(int p_dst, int p_src, int v_dst, int v_src,
-                           int dest_ln);
-
-   /*!
-    * @brief Execute schedule for coarsening flux to the specified
-    * level or reregister an existing one.
-    *
-    * See general notes for xeqScheduleProlongation().
-    *
-    * @return coarsening schedule for setting composite grid flux at
-    * coarse-fine boundaries.
-    */
-   void
-   xeqScheduleFluxCoarsen(
-      int dst_id,
-      int src_id,
-      int dest_ln);
-
-   /*!
-    * @brief Execute schedule for filling ghosts on the specified
-    * level or reregister an existing one.
-    *
-    * See general notes for xeqScheduleProlongation().
-    *
-    * @return refine schedule for filling ghost data from coarser level
-    * and physical bc.
-    */
-   void
-   xeqScheduleGhostFill(int p_id, int v_id, int dest_ln);
-
-   /*!
-    * @brief Execute schedule for filling ghosts on the specified
-    * level or reregister an existing one.
-    * This version does not get data from coarser levels.
-    *
-    * See general notes for xeqScheduleProlongation().
-    *
-    * This function is used for the bottom solve level, since it does
-    * not access data from any coarser level.  (Ghost data obtained
-    * from coarser level must have been placed there before solve begins!)
-    *
-    * @return refine schedule for filling ghost data from same level
-    * and physical bc.
-    */
-   void
-   xeqScheduleGhostFillNoCoarse(int p_id, int v_id, int dest_ln);
-
-   //@}
-
-   //! @brief Return the patch data index for cell scratch data.
-   int
-   registerCellScratch() const;
-   //! @brief Return the patch data index for flux scratch data.
-   int
-   registerFluxScratch() const;
-   //! @brief Return the patch data index for outerflux scratch data.
-   int
-   registerOfluxScratch() const;
-
-   //! @brief Free static variables at shutdown time.
-   static void
-   finalizeCallback();
-
-   /*!
-    * @brief Object dimension.
-    */
-   const tbox::Dimension d_dim;
-
-   /*!
-    * @brief Object name.
-    */
-   std::string d_object_name;
-
-   //@{ @name Hierarchy-dependent objects.
-
-   /*!
-    * @brief Reference hierarchy
-    *
-    * This variable is non-null between the initializeOperatorState()
-    * and deallocateOperatorState() calls.  It is not truly needed,
-    * because the hierarchy is obtainable through variables in most
-    * function argument lists.  We use it to enforce working on one
-    * hierarchy at a time.
-    */
-   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
-
-   /*!
-    * @brief Coarsest level for solve.
-    */
-   int d_ln_min;
-
-   /*!
-    * @brief Finest level for solve.
-    */
-   int d_ln_max;
-
-   /*!
-    * @brief Description of coarse-fine boundaries.
-    *
-    * There is one coarse-fine boundary object for each level.
-    * d_coarse_fine_boundary[i] is the description of
-    * the coarse-fine boundary between level i and level i-1.
-    * The coarse-fine boundary does not exist at the coarsest level,
-    * although the hier::CoarseFineBoundary object still exists (it
-    * should not contain any boxes).
-    *
-    * This array is initialized in initializeOperatorState() and
-    * deallocated in deallocateOperatorState().  When allocated,
-    * it is allocated for the index range [0,d_ln_max], though
-    * the range [0,d_ln_min-1] is not used.  This is okay because
-    * hier::CoarseFineBoundary is a light object before
-    * it is set for a level.
-    */
-   tbox::Array<tbox::Pointer<hier::CoarseFineBoundary> > d_cf_boundary;
-
-   //@}
-
-   //@{
-   /*!
-    * @name Private state variables for solution process.
-    */
-
-   /*!
-    * @brief Smoothing choice.
-    * @see setSmoothingChoice.
-    */
-   std::string d_smoothing_choice;
-
-   /*!
-    * @brief Coarse level solver.
-    * @see setCoarsestLevelSolverChoice
-    */
-   std::string d_coarse_solver_choice;
-
-   /*!
-    * @brief Coarse-fine discretization method.
-    * @see setCoarseFineDiscretization().
-    */
-   std::string d_cf_discretization;
-
-   /*!
-    * @brief Coarse-fine discretization method.
-    *
-    * The name of the refinement operator used to prolong the
-    * coarse grid correction.
-    *
-    * @see setProlongationMethod()
-    */
-   std::string p_prolongation_method;
-   std::string v_prolongation_method;
-   std::string p_rrestriction_method;
-
-   /*!
-    * @brief Tolerance specified to coarse solver
-    * @see setCoarsestLevelSolverTolerance()
-    */
-   double d_coarse_solver_tolerance;
-
-   /*!
-    * @brief Coarse level solver iteration limit.
-    * @see setCoarsestLevelSolverMaxIterations()
-    */
-   int d_coarse_solver_max_iterations;
-
-   /*!
-    * @brief Residual tolerance to govern smoothing.
-    *
-    * When we use one of the internal error smoothing functions
-    * and want to terminate the smoothing sweeps at a certain
-    * level of residual, this will be set to > 0.  If it is
-    * < 0, the smoothing function effectively ignores it.
-    *
-    * This variable is needed because some coarse-level solver
-    * simply runs the smoothing function until convergence.
-    * It sets this variable to > 0, calls the smoothing function,
-    * then resets it to < 0.
-    */
-   double d_residual_tolerance_during_smoothing;
-
-   /*!
-    * @brief Id of moduli and dp.
-    *
-    * @see set_moduli_dp_id.
-    */
-  int cell_moduli_id, edge_moduli_id, dp_id;
-
-#ifdef HAVE_HYPRE
-   /*!
-    * @brief HYPRE coarse-level solver object.
-    */
-   ElasticHypreSolver d_hypre_solver;
-#endif
-
-   /*!
-    * @brief Externally provided physical boundary condition object.
-    *
-    * see setPhysicalBcCoefObject()
-    */
-   // const RobinBcCoefStrategy* d_physical_bc_coef;
-
-   //@}
-
-   //@{ @name Internal context and scratch data
-
-   static tbox::Pointer<pdat::CellVariable<double> >
-   s_cell_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-   static tbox::Pointer<pdat::SideVariable<double> >
-   s_side_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-   /*!
-    * @brief Default context of internally maintained hierarchy data.
-    */
-   tbox::Pointer<hier::VariableContext> d_context;
-
-   /*!
-    * @brief ID of the solution-like scratch data.
-    *
-    * Set in constructor and never changed.
-    * Corresponds to a pdat::CellVariable<double> named
-    * @c d_object_name+"::cell_scratch".
-    * Scratch data is allocated and removed as needed
-    * to reduce memory usage.
-    */
-  int d_cell_scratch_id, d_side_scratch_id;
-
-   //@}
-
-   //@{
-   /*!
-    * @name Various refine and coarsen objects used internally.
-    */
-
-   //! @brief Error prolongation (refinement) operator.
-   tbox::Pointer<xfer::RefineOperator> p_prolongation_refine_operator;
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   p_prolongation_refine_schedules;
-
-   tbox::Pointer<xfer::RefineOperator> v_prolongation_refine_operator;
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   v_prolongation_refine_schedules;
-
-   //! @brief Solution restriction (coarsening) operator.
-   tbox::Pointer<xfer::CoarsenOperator> p_urestriction_coarsen_operator;
-   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
-   p_urestriction_coarsen_schedules;
-
-   tbox::Pointer<xfer::CoarsenOperator> v_urestriction_coarsen_operator;
-   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
-   v_urestriction_coarsen_schedules;
-
-   //! @brief Residual restriction (coarsening) operator.
-   tbox::Pointer<xfer::CoarsenOperator> p_rrestriction_coarsen_operator;
-   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
-   p_rrestriction_coarsen_schedules;
-
-   tbox::Pointer<xfer::CoarsenOperator> v_rrestriction_coarsen_operator;
-   tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
-   v_rrestriction_coarsen_schedules;
-
-   //! @brief Refine operator for data from coarser level.
-   tbox::Pointer<xfer::RefineOperator> p_ghostfill_refine_operator;
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   p_ghostfill_refine_schedules;
-
-   tbox::Pointer<xfer::RefineOperator> v_ghostfill_refine_operator;
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   v_ghostfill_refine_schedules;
-
-   //! @brief Refine operator for data from same level.
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   p_nocoarse_refine_schedules;
-
-   tbox::Array<tbox::Pointer<xfer::RefineSchedule> >
-   v_nocoarse_refine_schedules;
-
-   //@}
-
-   /*!
-    * @brief Utility object employed in setting ghost cells and providing
-    * xfer::RefinePatchStrategy implementation.
-    *
-    * Since this class deals only in scalar variables having
-    * Robin boundary conditions, we take advantage of the corresponding
-    * implementation in CartesianRobinBcHelper.  Whenever
-    * we need an implementation of xfer::RefinePatchStrategy,
-    * this object is used.  Note that in the code, before we
-    * use this object to set ghost cell values, directly or
-    * indirectly by calling xfer::RefineSchedule::fillData(),
-    * we must tell the patch strategies the patch data index we want
-    * to set and whether we are setting data with homogeneous
-    * boundary condition.
-    */
-   P_Refine_Patch_Strategy p_refine_patch_strategy;
-   V_Refine_Patch_Strategy v_refine_patch_strategy;
-   V_Coarsen_Patch_Strategy v_coarsen_patch_strategy;
-
-   //@{
-   /*!
-    * @name Non-essential objects used in outputs and debugging.
-    */
-
-   /*!
-    * @brief Logging flag.
-    */
-   bool d_enable_logging;
-
-   /*!
-    * @brief Preconditioner using this object.
-    *
-    * See setPreconditioner().
-    */
-   const FACPreconditioner* d_preconditioner;
-
-   /*!
-    * @brief Hierarchy cell operator used in debugging.
-    */
-   tbox::Pointer<math::HierarchyCellDataOpsReal<double> > d_hopscell;
-
-   /*!
-    * @brief Hierarchy side operator used in debugging.
-    */
-   tbox::Pointer<math::HierarchySideDataOpsReal<double> > d_hopsside;
-
-   /*!
-    * @brief Timers for performance measurement.
-    */
-   tbox::Pointer<tbox::Timer> t_restrict_solution;
-   tbox::Pointer<tbox::Timer> t_restrict_residual;
-   tbox::Pointer<tbox::Timer> t_prolong;
-   tbox::Pointer<tbox::Timer> t_smooth_error;
-   tbox::Pointer<tbox::Timer> t_solve_coarsest;
-   tbox::Pointer<tbox::Timer> t_compute_composite_residual;
-   tbox::Pointer<tbox::Timer> t_compute_residual_norm;
-
-   static tbox::StartupShutdownManager::Handler
-   s_finalize_handler;
-};
-
-}
-}
-
-#ifdef SAMRAI_INLINE
-#include "ElasticFACOps.I"
-#endif
-
-#endif // included_solv_ElasticFACOps
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/ElasticFACOps.C
--- a/src/ElasticFACOps/ElasticFACOps.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#ifndef SAMRAI_INLINE
-#include "ElasticFACOps.I"
-#endif
-
-namespace SAMRAI {
-  namespace solv {
-
-    tbox::Pointer<pdat::CellVariable<double> >
-    ElasticFACOps::s_cell_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-    tbox::Pointer<pdat::SideVariable<double> >
-    ElasticFACOps::s_side_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-    tbox::StartupShutdownManager::Handler
-    ElasticFACOps::s_finalize_handler(
-                                     0,
-                                     0,
-                                     0,
-                                     ElasticFACOps::finalizeCallback,
-                                     tbox::StartupShutdownManager::priorityVariables);
-
-    /*
-********************************************************************
-* Constructor.                                                     *
-********************************************************************
-*/
-    ElasticFACOps::ElasticFACOps(const tbox::Dimension& dim,
-                               const std::string& object_name,
-                               tbox::Pointer<tbox::Database> database):
-      d_dim(dim),
-      d_object_name(object_name),
-      d_hierarchy(),
-      d_ln_min(-1),
-      d_ln_max(-1),
-      d_cf_boundary(),
-      d_smoothing_choice("Tackley"),
-      d_coarse_solver_choice(
-#ifdef HAVE_HYPRE
-                             "hypre"
-#else
-                             "Tackley"
-#endif
-
-                             ),
-      d_cf_discretization("Ewing"),
-      p_prolongation_method("P_REFINE"),
-      v_prolongation_method("V_REFINE"),
-      p_rrestriction_method("CONSERVATIVE_COARSEN"),
-      d_coarse_solver_tolerance(1.e-8),
-      d_coarse_solver_max_iterations(10),
-      d_residual_tolerance_during_smoothing(-1.0),
-      cell_moduli_id(invalid_id),
-      edge_moduli_id(invalid_id),
-      dp_id(invalid_id),
-#ifdef HAVE_HYPRE
-      d_hypre_solver(dim,
-                     object_name + "::hypre_solver",
-                     database && database->isDatabase("hypre_solver") ?
-                     database->getDatabase("hypre_solver"):
-                     tbox::Pointer<tbox::Database>(NULL)),
-#endif
-      // d_physical_bc_coef(NULL),
-      d_context(hier::VariableDatabase::getDatabase()
-                ->getContext(object_name + "::PRIVATE_CONTEXT")),
-      d_cell_scratch_id(invalid_id),
-      d_side_scratch_id(invalid_id),
-      p_prolongation_refine_operator(),
-      p_prolongation_refine_schedules(),
-      v_prolongation_refine_operator(),
-      v_prolongation_refine_schedules(),
-      p_urestriction_coarsen_operator(),
-      p_urestriction_coarsen_schedules(),
-      v_urestriction_coarsen_operator(),
-      v_urestriction_coarsen_schedules(),
-      p_rrestriction_coarsen_operator(),
-      p_rrestriction_coarsen_schedules(),
-      v_rrestriction_coarsen_operator(),
-      v_rrestriction_coarsen_schedules(),
-      p_ghostfill_refine_operator(),
-      p_ghostfill_refine_schedules(),
-      v_ghostfill_refine_operator(),
-      v_ghostfill_refine_schedules(),
-      p_nocoarse_refine_schedules(),
-      v_nocoarse_refine_schedules(),
-      p_refine_patch_strategy(dim,
-                              d_object_name + "::refine patch strategy"),
-      v_refine_patch_strategy(dim,
-                              d_object_name + "::refine patch strategy"),
-      v_coarsen_patch_strategy(dim,
-                               d_object_name + "::coarsen patch strategy"),
-      d_enable_logging(false),
-      d_preconditioner(NULL),
-      d_hopscell(),
-      d_hopsside()
-    {
-
-      t_restrict_solution = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::restrictSolution()");
-      t_restrict_residual = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::restrictResidual()");
-      t_prolong = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::prolongErrorAndCorrect()");
-      t_smooth_error = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::smoothError()");
-      t_solve_coarsest = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::solveCoarsestLevel()");
-      t_compute_composite_residual = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::computeCompositeResidualOnLevel()");
-      t_compute_residual_norm = tbox::TimerManager::getManager()->
-        getTimer("solv::ElasticFACOps::computeResidualNorm()");
-
-      if (d_dim == tbox::Dimension(1) || d_dim > tbox::Dimension(3)) {
-        TBOX_ERROR("ElasticFACOps : DIM == 1 or > 3 not implemented yet.\n");
-      }
-
-      if (s_cell_scratch_var[dim.getValue() - 1].isNull()) {
-        TBOX_ASSERT(s_cell_scratch_var[dim.getValue() - 1].isNull());
-        TBOX_ASSERT(s_cell_scratch_var[dim.getValue() - 1].isNull());
-
-        std::ostringstream ss;
-        ss << "ElasticFACOps::private_cell_scratch" << dim.getValue();
-        s_cell_scratch_var[dim.getValue() - 1] = new pdat::CellVariable<double>
-          (dim, ss.str());
-        ss.str("");
-        ss << "ElasticFACOps::private_side_scratch" << dim.getValue();
-        s_side_scratch_var[dim.getValue() - 1] = new pdat::SideVariable<double>
-          (dim, ss.str());
-      }
-
-      hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
-      d_cell_scratch_id = vdb->
-        registerVariableAndContext(s_cell_scratch_var[dim.getValue() - 1],
-                                   d_context,
-                                   hier::IntVector::getOne(dim));
-      d_side_scratch_id = vdb->
-        registerVariableAndContext(s_side_scratch_var[dim.getValue() - 1],
-                                   d_context,
-                                   hier::IntVector::getOne(d_dim));
-
-      /*
-       * Some variables initialized by default are overriden by input.
-       */
-
-      if (database) {
-        d_coarse_solver_choice =
-          database->getStringWithDefault("coarse_solver_choice",
-                                         d_coarse_solver_choice);
-        d_coarse_solver_tolerance =
-          database->getDoubleWithDefault("coarse_solver_tolerance",
-                                         d_coarse_solver_tolerance);
-        d_coarse_solver_max_iterations =
-          database->getIntegerWithDefault("coarse_solver_max_iterations",
-                                          d_coarse_solver_max_iterations);
-        d_smoothing_choice =
-          database->getStringWithDefault("smoothing_choice",
-                                         d_smoothing_choice);
-
-        d_cf_discretization =
-          database->getStringWithDefault("cf_discretization",
-                                         d_cf_discretization);
-
-        p_prolongation_method =
-          database->getStringWithDefault("p_prolongation_method",
-                                         p_prolongation_method);
-
-        v_prolongation_method =
-          database->getStringWithDefault("v_prolongation_method",
-                                         v_prolongation_method);
-
-        p_rrestriction_method =
-          database->getStringWithDefault("p_rrestriction_method",
-                                         p_rrestriction_method);
-
-        d_enable_logging =
-          database->getBoolWithDefault("enable_logging",
-                                       d_enable_logging);
-
-      }
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/computeCompositeResidualOnLevel.C
--- a/src/ElasticFACOps/computeCompositeResidualOnLevel.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::computeCompositeResidualOnLevel
-(SAMRAIVectorReal<double>& residual,
- const SAMRAIVectorReal<double>& solution,
- const SAMRAIVectorReal<double>& rhs,
- int ln,
- bool error_equation_indicator) {
-
-  t_compute_composite_residual->start();
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (residual.getPatchHierarchy() != d_hierarchy
-      || solution.getPatchHierarchy() != d_hierarchy
-      || rhs.getPatchHierarchy() != d_hierarchy) {
-    TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
-               "internal hierarchy.");
-  }
-#endif
-  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
-
-  /*
-   * Set up the bc helper so that when we use a refine schedule
-   * to fill ghosts, the correct data is operated on.
-   */
-  const int p_id = solution.getComponentDescriptorIndex(0);
-  const int v_id = solution.getComponentDescriptorIndex(1);
-  p_refine_patch_strategy.setTargetDataId(p_id);
-  v_refine_patch_strategy.setTargetDataId(v_id);
-  // v_refine_patch_strategy.setHomogeneousBc(error_equation_indicator);
-
-  /*
-   * Assumptions:
-   * 1. Data does not yet exist in ghost boundaries.
-   * 2. Residual data on next finer grid (if any)
-   *    has been computed already.
-   * 3. Flux data from next finer grid (if any) has
-   *    been computed but has not been coarsened to
-   *    this level.
-   *
-   * Steps:
-   * S1. Fill solution ghost data by refinement
-   *     or setting physical boundary conditions.
-   *     This also brings in information from coarser
-   *     to form the composite grid flux.
-   * S2. Compute flux on ln.
-   * S3. If next finer is available,
-   *     Coarsen flux data on next finer level,
-   *     overwriting flux computed from coarse data.
-   * S4. Compute residual data from flux.
-   */
-
-  /* S1. Fill solution ghost data. */
-
-  set_boundaries(p_id,v_id,ln,error_equation_indicator);
-  if (ln > d_ln_min) {
-    /* Fill from current, next coarser level and physical boundary */
-    xeqScheduleGhostFill(p_id, v_id, ln);
-  } else {
-    /* Fill from current and physical boundary */
-    xeqScheduleGhostFillNoCoarse(p_id, v_id, ln);
-  }
-
-  /*
-   * S4. Compute residual on patches in level.
-   */
-
-  for (hier::PatchLevel::Iterator pi(*level); pi; pi++) {
-    tbox::Pointer<hier::Patch> patch = *pi;
-    tbox::Pointer<pdat::CellData<double> >
-      p_ptr = solution.getComponentPatchData(0, *patch);
-    tbox::Pointer<pdat::SideData<double> >
-      v_ptr = solution.getComponentPatchData(1, *patch);
-    tbox::Pointer<pdat::CellData<double> >
-      cell_moduli_ptr = patch->getPatchData(cell_moduli_id);
-    tbox::Pointer<pdat::CellData<double> >
-      p_rhs_ptr = rhs.getComponentPatchData(0, *patch);
-    tbox::Pointer<pdat::SideData<double> >
-      v_rhs_ptr = rhs.getComponentPatchData(1, *patch);
-    tbox::Pointer<pdat::CellData<double> >
-      p_resid_ptr = residual.getComponentPatchData(0, *patch);
-    tbox::Pointer<pdat::SideData<double> >
-      v_resid_ptr = residual.getComponentPatchData(1, *patch);
-
-    hier::Box pbox=patch->getBox();
-    pbox.growUpper(hier::IntVector::getOne(d_dim));
-    tbox::Pointer<geom::CartesianPatchGeometry>
-      geom = patch->getPatchGeometry();
-
-    switch(d_dim.getValue())
-      {
-      case 2:
-        residual_2D(*p_ptr,*v_ptr,*cell_moduli_ptr,*p_rhs_ptr,*v_rhs_ptr,
-                    *p_resid_ptr,*v_resid_ptr,*patch,pbox,*geom);
-        break;
-      case 3:
-        residual_3D(*p_ptr,*v_ptr,*cell_moduli_ptr,*p_rhs_ptr,*v_rhs_ptr,
-                    *p_resid_ptr,*v_resid_ptr,*patch,pbox,*geom);
-        break;
-      default:
-        abort();
-      }
-  }
-
-  t_compute_composite_residual->stop();
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/computeResidualNorm.C
--- a/src/ElasticFACOps/computeResidualNorm.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#include "ElasticFACOps.h"
-
-double SAMRAI::solv::ElasticFACOps::computeResidualNorm
-(const SAMRAIVectorReal<double>& residual,
- int fine_ln,
- int coarse_ln)
-{
-  if (coarse_ln != residual.getCoarsestLevelNumber() ||
-      fine_ln != residual.getFinestLevelNumber()) {
-    TBOX_ERROR("ElasticFACOps::computeResidualNorm() is not\n"
-               << "set up to compute residual except on the range of\n"
-               << "levels defining the vector.\n");
-  }
-  t_compute_residual_norm->start();
-  /*
-   * The residual vector was cloned from vectors that has
-   * the proper weights associated with them, so we do not
-   * have to explicitly weight the residuals.
-   *
-   * maxNorm: not good to use because Hypre's norm does not
-   *   correspond to it.  Also maybe too sensitive to spikes.
-   * L2Norm: maybe good.  But does not correspond to the
-   *   scale of the quantity.
-   * L1Norm: maybe good.  Correspond to scale of quantity,
-   *   but may be too insensitive to spikes.
-   * RMSNorm: maybe good.
-   *
-   * We use maxNorm because it is a definite upper bound on the error.
-   */
-  double norm = residual.maxNorm();
-  t_compute_residual_norm->stop();
-  return norm;
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/computeVectorWeights.C
--- a/src/ElasticFACOps/computeVectorWeights.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-namespace SAMRAI {
-  namespace solv {
-
-    /*
-********************************************************************
-* Compute the vector weight and put it at a specified patch data   *
-* index.                                                           *
-********************************************************************
-*/
-
-    void ElasticFACOps::computeVectorWeights(
-                                            tbox::Pointer<hier::PatchHierarchy> hierarchy,
-                                            int weight_id,
-                                            int coarsest_ln,
-                                            int finest_ln) const
-    {
-      TBOX_ASSERT(!hierarchy.isNull());
-      TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
-
-      if (coarsest_ln == -1) coarsest_ln = 0;
-      if (finest_ln == -1) finest_ln = hierarchy->getFinestLevelNumber();
-      if (finest_ln < coarsest_ln) {
-        TBOX_ERROR(d_object_name
-                   << ": Illegal level number range.  finest_ln < coarsest_ln.");
-      }
-
-      int ln;
-      for (ln = finest_ln; ln >= coarsest_ln; --ln) {
-
-        /*
-         * On every level, first assign cell volume to vector weight.
-         */
-
-        tbox::Pointer<hier::PatchLevel> level =
-          hierarchy->getPatchLevel(ln);
-        for (hier::PatchLevel::Iterator p(level); p; p++) {
-          tbox::Pointer<hier::Patch> patch = *p;
-          tbox::Pointer<geom::CartesianPatchGeometry> patch_geometry =
-            patch->getPatchGeometry();
-          const double* dx = patch_geometry->getDx();
-          double cell_vol = dx[0];
-          if (d_dim > tbox::Dimension(1)) {
-            cell_vol *= dx[1];
-          }
-
-          if (d_dim > tbox::Dimension(2)) {
-            cell_vol *= dx[2];
-          }
-
-          tbox::Pointer<pdat::CellData<double> > w =
-            patch->getPatchData(weight_id);
-          if (!w) {
-            TBOX_ERROR(d_object_name
-                       << ": weight id must refer to a pdat::CellVariable");
-          }
-          w->fillAll(cell_vol);
-        }
-
-        /*
-         * On all but the finest level, assign 0 to vector
-         * weight to cells covered by finer cells.
-         */
-
-        if (ln < finest_ln) {
-
-          /*
-           * First get the boxes that describe index space of the next finer
-           * level and coarsen them to describe corresponding index space
-           * at this level.
-           */
-
-          tbox::Pointer<hier::PatchLevel> next_finer_level =
-            hierarchy->getPatchLevel(ln + 1);
-          hier::BoxArray coarsened_boxes = next_finer_level->getBoxes();
-          hier::IntVector coarsen_ratio(next_finer_level->getRatioToLevelZero());
-          coarsen_ratio /= level->getRatioToLevelZero();
-          coarsened_boxes.coarsen(coarsen_ratio);
-
-          /*
-           * Then set vector weight to 0 wherever there is
-           * a nonempty intersection with the next finer level.
-           * Note that all assignments are local.
-           */
-
-          for (hier::PatchLevel::Iterator p(level); p; p++) {
-
-            tbox::Pointer<hier::Patch> patch = *p;
-            for (int i = 0; i < coarsened_boxes.getNumberOfBoxes(); i++) {
-
-              hier::Box coarse_box = coarsened_boxes[i];
-              hier::Box intersection = coarse_box * (patch->getBox());
-              if (!intersection.empty()) {
-                tbox::Pointer<pdat::CellData<double> > w =
-                  patch->getPatchData(weight_id);
-                w->fillAll(0.0, intersection);
-
-              }  // assignment only in non-empty intersection
-            }  // loop over coarsened boxes from finer level
-          }  // loop over patches in level
-        }  // all levels except finest
-      }  // loop over levels
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/deallocateOperatorState.C
--- a/src/ElasticFACOps/deallocateOperatorState.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-namespace SAMRAI {
-  namespace solv {
-
-    /*
-********************************************************************
-* FACOperatorStrategy virtual deallocateOperatorState        *
-* function.  Deallocate internal hierarchy-dependent data.         *
-* State is allocated iff hierarchy is set.                         *
-********************************************************************
-*/
-
-    void ElasticFACOps::deallocateOperatorState()
-    {
-      if (d_hierarchy) {
-        d_cf_boundary.resizeArray(0);
-#ifdef HAVE_HYPRE
-        d_hypre_solver.deallocateSolverState();
-#endif
-        d_hierarchy.setNull();
-        d_ln_min = -1;
-        d_ln_max = -1;
-
-        p_prolongation_refine_schedules.setNull();
-        v_prolongation_refine_schedules.setNull();
-        p_urestriction_coarsen_schedules.setNull();
-        v_urestriction_coarsen_schedules.setNull();
-        p_rrestriction_coarsen_schedules.setNull();
-        v_rrestriction_coarsen_schedules.setNull();
-        p_ghostfill_refine_schedules.setNull();
-        v_ghostfill_refine_schedules.setNull();
-        p_nocoarse_refine_schedules.setNull();
-        v_nocoarse_refine_schedules.setNull();
-      }
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/finalizeCallback.C
--- a/src/ElasticFACOps/finalizeCallback.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-namespace SAMRAI {
-  namespace solv {
-
-    void
-    ElasticFACOps::finalizeCallback()
-    {
-      for (int d = 0; d < tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
-        s_cell_scratch_var[d].setNull();
-        s_side_scratch_var[d].setNull();
-      }
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/initializeOperatorState.C
--- a/src/ElasticFACOps/initializeOperatorState.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,469 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-/*
-************************************************************************
-* FACOperatorStrategy virtual initializeOperatorState function.  *
-*                                                                      *
-* Set internal variables to correspond to the solution passed in.      *
-* Look up transfer operators.                                          *
-************************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::initializeOperatorState
-(const SAMRAIVectorReal<double>& solution,
- const SAMRAIVectorReal<double>& rhs)
-{
-  deallocateOperatorState();
-  int ln;
-  hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
-
-  d_hierarchy = solution.getPatchHierarchy();
-  d_ln_min = solution.getCoarsestLevelNumber();
-  d_ln_max = solution.getFinestLevelNumber();
-  d_hopscell = new math::HierarchyCellDataOpsReal<double>(d_hierarchy,
-                                                          d_ln_min,
-                                                          d_ln_max);
-  d_hopsside = new math::HierarchySideDataOpsReal<double>(d_hierarchy,
-                                                          d_ln_min,
-                                                          d_ln_max);
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-
-  // if (d_physical_bc_coef == NULL) {
-  //   /*
-  //    * It's an error not to have bc object set.
-  //    * Note that the bc object cannot be passed in through
-  //    * the argument because the interface is inherited.
-  //    */
-  //   TBOX_ERROR(
-  //              d_object_name << ": No physical bc object in\n"
-  //              <<
-  //              "ElasticFACOps::initializeOperatorState\n"
-  //              << "You must use "
-  //              <<
-  //              "ElasticFACOps::setPhysicalBcCoefObject\n"
-  //              <<
-  //              "to set one before calling initializeOperatorState\n");
-  // }
-
-  if (solution.getNumberOfComponents() != 1) {
-    TBOX_WARNING(d_object_name
-                 << ": Solution vector has multiple components.\n"
-                 << "Solver is for component 0 only.\n");
-  }
-  if (rhs.getNumberOfComponents() != 1) {
-    TBOX_WARNING(d_object_name
-                 << ": RHS vector has multiple components.\n"
-                 << "Solver is for component 0 only.\n");
-  }
-
-  /*
-   * Make sure that solution and rhs data
-   *   are of correct type
-   *   are allocated
-   *   has sufficient ghost width
-   */
-  tbox::Pointer<hier::Variable> var;
-  {
-    vdb->mapIndexToVariable(rhs.getComponentDescriptorIndex(0),
-                            var);
-    if (!var) {
-      TBOX_ERROR(d_object_name << ": RHS component does not\n"
-                 << "correspond to a variable.\n");
-    }
-    tbox::Pointer<pdat::CellVariable<double> > cell_var = var;
-    if (!cell_var) {
-      TBOX_ERROR(d_object_name
-                 << ": RHS variable is not cell-centered double\n");
-    }
-  }
-  {
-    vdb->mapIndexToVariable(solution.getComponentDescriptorIndex(0),
-                            var);
-    if (!var) {
-      TBOX_ERROR(d_object_name << ": Solution component does not\n"
-                 << "correspond to a variable.\n");
-    }
-    tbox::Pointer<pdat::CellVariable<double> > cell_var = var;
-    if (!cell_var) {
-      TBOX_ERROR(d_object_name
-                 << ": Solution variable is not cell-centered double\n");
-    }
-  }
-  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
-    tbox::Pointer<hier::PatchLevel> level_ptr =
-      d_hierarchy->getPatchLevel(ln);
-    hier::PatchLevel& level = *level_ptr;
-    for (hier::PatchLevel::Iterator pi(level); pi; pi++) {
-      hier::Patch& patch = **pi;
-      tbox::Pointer<hier::PatchData> fd =
-        patch.getPatchData(rhs.getComponentDescriptorIndex(0));
-      if (fd) {
-        /*
-         * Some data checks can only be done if the data already exists.
-         */
-        tbox::Pointer<pdat::CellData<double> > cd = fd;
-        if (!cd) {
-          TBOX_ERROR(d_object_name
-                     << ": RHS data is not cell-centered double\n");
-        }
-        if (cd->getDepth() > 1) {
-          TBOX_WARNING(d_object_name
-                       << ": RHS data has multiple depths.\n"
-                       << "Solver is for depth 0 only.\n");
-        }
-      }
-      tbox::Pointer<hier::PatchData> ud =
-        patch.getPatchData(solution.getComponentDescriptorIndex(0));
-      if (ud) {
-        /*
-         * Some data checks can only be done if the data already exists.
-         */
-        tbox::Pointer<pdat::CellData<double> > cd = ud;
-        if (!cd) {
-          TBOX_ERROR(d_object_name
-                     << ": Solution data is not cell-centered double\n");
-        }
-        if (cd->getDepth() > 1) {
-          TBOX_WARNING(d_object_name
-                       << ": Solution data has multiple depths.\n"
-                       << "Solver is for depth 0 only.\n");
-        }
-        if (cd->getGhostCellWidth() < hier::IntVector::getOne(d_dim)) {
-          TBOX_ERROR(d_object_name
-                     << ": Solution data has insufficient ghost width\n");
-        }
-      }
-    }
-  }
-
-  /*
-   * Solution and rhs must have some similar properties.
-   */
-  if (rhs.getPatchHierarchy() != d_hierarchy
-      || rhs.getCoarsestLevelNumber() != d_ln_min
-      || rhs.getFinestLevelNumber() != d_ln_max) {
-    TBOX_ERROR(d_object_name << ": solution and rhs do not have\n"
-               << "the same set of patch levels.\n");
-  }
-
-#endif
-
-  /*
-   * Initialize the coarse-fine boundary description for the
-   * hierarchy.
-   */
-  d_cf_boundary.resizeArray(d_hierarchy->getNumberOfLevels());
-
-  hier::IntVector max_gcw(d_dim, 1);
-  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
-    d_cf_boundary[ln] = new hier::CoarseFineBoundary(*d_hierarchy,
-                                                     ln,
-                                                     max_gcw);
-  }
-
-  v_coarsen_patch_strategy.coarse_fine=d_cf_boundary;
-// #ifdef HAVE_HYPRE
-//   if (d_coarse_solver_choice == "hypre") {
-//     d_hypre_solver.initializeSolverState(d_hierarchy, d_ln_min);
-//     /*
-//      * Share the boundary condition object with the hypre solver
-//      * to make sure that boundary condition settings are consistent
-//      * between the two objects.
-//      */
-//     d_hypre_solver.setPhysicalBcCoefObject(d_physical_bc_coef);
-//     d_hypre_solver.setMatrixCoefficients(d_elastic_spec);
-//   }
-// #endif
-
-  /*
-   * Get the transfer operators.
-   * Cell (solution, error, etc) coarsening is conservative.
-   */
-  tbox::Pointer<geom::CartesianGridGeometry> geometry =
-    d_hierarchy->getGridGeometry();
-  tbox::Pointer<hier::Variable> variable;
-
-  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
-  p_prolongation_refine_operator =
-    geometry->lookupRefineOperator(variable,
-                                   p_prolongation_method);
-
-  vdb->mapIndexToVariable(d_side_scratch_id, variable);
-  v_prolongation_refine_operator =
-    geometry->lookupRefineOperator(variable,
-                                   v_prolongation_method);
-
-  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
-  p_urestriction_coarsen_operator =
-    geometry->lookupCoarsenOperator(variable,
-                                    "CONSERVATIVE_COARSEN");
-  p_rrestriction_coarsen_operator =
-    geometry->lookupCoarsenOperator(variable,
-                                   p_rrestriction_method);
-
-  vdb->mapIndexToVariable(d_side_scratch_id, variable);
-  v_urestriction_coarsen_operator =
-    v_rrestriction_coarsen_operator =
-    geometry->lookupCoarsenOperator(variable,
-                                    "V_COARSEN");
-
-  vdb->mapIndexToVariable(d_cell_scratch_id, variable);
-  p_ghostfill_refine_operator =
-    geometry->lookupRefineOperator(variable,
-                                   "P_BOUNDARY_REFINE");
-
-  vdb->mapIndexToVariable(d_side_scratch_id, variable);
-  v_ghostfill_refine_operator =
-    geometry->lookupRefineOperator(variable,
-                                   "V_BOUNDARY_REFINE");
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (!p_prolongation_refine_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find p prolongation refine operator");
-  }
-  if (!v_prolongation_refine_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find v prolongation refine operator");
-  }
-  if (!p_urestriction_coarsen_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find p restriction coarsening operator");
-  }
-  if (!v_urestriction_coarsen_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find v restriction coarsening operator");
-  }
-  if (!p_rrestriction_coarsen_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find p restriction coarsening operator");
-  }
-  if (!v_rrestriction_coarsen_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find v restriction coarsening operator");
-  }
-  if (!p_ghostfill_refine_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find ghost filling refinement operator");
-  }
-  if (!v_ghostfill_refine_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find ghost filling refinement operator");
-  }
-#endif
-
-  /*
-   * Make space for saving communication schedules.
-   * There is no need to delete the old schedules first
-   * because we have deallocated the solver state above.
-   */
-  p_prolongation_refine_schedules.resizeArray(d_ln_max + 1);
-  v_prolongation_refine_schedules.resizeArray(d_ln_max + 1);
-  p_ghostfill_refine_schedules.resizeArray(d_ln_max + 1);
-  v_ghostfill_refine_schedules.resizeArray(d_ln_max + 1);
-  p_nocoarse_refine_schedules.resizeArray(d_ln_max + 1);
-  v_nocoarse_refine_schedules.resizeArray(d_ln_max + 1);
-  p_urestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
-  p_rrestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
-  v_urestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
-  v_rrestriction_coarsen_schedules.resizeArray(d_ln_max + 1);
-
-  xfer::RefineAlgorithm p_prolongation_refine_algorithm(d_dim),
-    v_prolongation_refine_algorithm(d_dim),
-    p_ghostfill_refine_algorithm(d_dim),
-    v_ghostfill_refine_algorithm(d_dim),
-    p_nocoarse_refine_algorithm(d_dim),
-    v_nocoarse_refine_algorithm(d_dim);
-  xfer::CoarsenAlgorithm p_urestriction_coarsen_algorithm(d_dim),
-    p_rrestriction_coarsen_algorithm(d_dim),
-    v_urestriction_coarsen_algorithm(d_dim),
-    v_rrestriction_coarsen_algorithm(d_dim);
-
-  /* This is a little confusing.  The only real purpose here is to
-     create a communication schedule.  That communication schedule is
-     then reused later when refining, though with a different source,
-     scratch, and destination.  So the arguments to registerRefine are
-     not all that important, because a different refineAlgorithm will
-     be used then. */
-
-  p_prolongation_refine_algorithm.
-    registerRefine(d_cell_scratch_id,
-                   solution.getComponentDescriptorIndex(0),
-                   d_cell_scratch_id,
-                   p_prolongation_refine_operator);
-  v_prolongation_refine_algorithm.
-    registerRefine(d_side_scratch_id,
-                   solution.getComponentDescriptorIndex(1),
-                   d_side_scratch_id,
-                   v_prolongation_refine_operator);
-  p_urestriction_coarsen_algorithm.
-    registerCoarsen(solution.getComponentDescriptorIndex(0),
-                    solution.getComponentDescriptorIndex(0),
-                    p_urestriction_coarsen_operator);
-  p_rrestriction_coarsen_algorithm.
-    registerCoarsen(rhs.getComponentDescriptorIndex(0),
-                    rhs.getComponentDescriptorIndex(0),
-                    p_rrestriction_coarsen_operator);
-  v_urestriction_coarsen_algorithm.
-    registerCoarsen(solution.getComponentDescriptorIndex(1),
-                    solution.getComponentDescriptorIndex(1),
-                    v_urestriction_coarsen_operator);
-  v_rrestriction_coarsen_algorithm.
-    registerCoarsen(rhs.getComponentDescriptorIndex(1),
-                    rhs.getComponentDescriptorIndex(1),
-                    v_rrestriction_coarsen_operator);
-  p_ghostfill_refine_algorithm.
-    registerRefine(solution.getComponentDescriptorIndex(0),
-                   solution.getComponentDescriptorIndex(0),
-                   solution.getComponentDescriptorIndex(0),
-                   p_ghostfill_refine_operator);
-  v_ghostfill_refine_algorithm.
-    registerRefine(solution.getComponentDescriptorIndex(1),
-                   solution.getComponentDescriptorIndex(1),
-                   solution.getComponentDescriptorIndex(1),
-                   v_ghostfill_refine_operator);
-  p_nocoarse_refine_algorithm.
-    registerRefine(solution.getComponentDescriptorIndex(0),
-                   solution.getComponentDescriptorIndex(0),
-                   solution.getComponentDescriptorIndex(0),
-                   tbox::Pointer<xfer::RefineOperator>(0));
-  v_nocoarse_refine_algorithm.
-    registerRefine(solution.getComponentDescriptorIndex(1),
-                   solution.getComponentDescriptorIndex(1),
-                   solution.getComponentDescriptorIndex(1),
-                   tbox::Pointer<xfer::RefineOperator>(0));
-
-  /* Refinement and ghost fill operators */
-  for (int dest_ln = d_ln_min + 1; dest_ln <= d_ln_max; ++dest_ln) {
-
-    tbox::Pointer<xfer::PatchLevelFullFillPattern>
-      fill_pattern(new xfer::PatchLevelFullFillPattern());
-    p_prolongation_refine_schedules[dest_ln] =
-      p_prolongation_refine_algorithm.
-      createSchedule(fill_pattern,
-                     d_hierarchy->getPatchLevel(dest_ln),
-                     tbox::Pointer<hier::PatchLevel>(),
-                     dest_ln - 1,
-                     d_hierarchy);
-    if (!p_prolongation_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for p prolongation!\n");
-    }
-    v_prolongation_refine_schedules[dest_ln] =
-      v_prolongation_refine_algorithm.
-      createSchedule(fill_pattern,
-                     d_hierarchy->getPatchLevel(dest_ln),
-                     tbox::Pointer<hier::PatchLevel>(),
-                     dest_ln - 1,
-                     d_hierarchy);
-    if (!v_prolongation_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for v prolongation!\n");
-    }
-    p_ghostfill_refine_schedules[dest_ln] =
-      p_ghostfill_refine_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     dest_ln - 1,
-                     d_hierarchy,
-                     &p_refine_patch_strategy);
-    if (!p_ghostfill_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for ghost filling!\n");
-    }
-    v_ghostfill_refine_schedules[dest_ln] =
-      v_ghostfill_refine_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     dest_ln - 1,
-                     d_hierarchy,
-                     &v_refine_patch_strategy);
-    if (!v_ghostfill_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for ghost filling!\n");
-    }
-    p_nocoarse_refine_schedules[dest_ln] =
-      p_nocoarse_refine_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln));
-    if (!p_nocoarse_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for ghost filling on bottom level!\n");
-    }
-    v_nocoarse_refine_schedules[dest_ln] =
-      v_nocoarse_refine_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln));
-    if (!v_nocoarse_refine_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a refine schedule for ghost filling on bottom level!\n");
-    }
-  }
-
-  /* Coarsening operators */
-  for (int dest_ln = d_ln_min; dest_ln < d_ln_max; ++dest_ln) {
-    p_urestriction_coarsen_schedules[dest_ln] =
-      p_urestriction_coarsen_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     d_hierarchy->getPatchLevel(dest_ln + 1));
-    if (!p_urestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a coarsen schedule for U p restriction!\n");
-    }
-    p_rrestriction_coarsen_schedules[dest_ln] =
-      p_rrestriction_coarsen_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     d_hierarchy->getPatchLevel(dest_ln + 1));
-    if (!p_rrestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a coarsen schedule for R p restriction!\n");
-    }
-
-    v_urestriction_coarsen_schedules[dest_ln] =
-      v_urestriction_coarsen_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     d_hierarchy->getPatchLevel(dest_ln + 1),
-                     &v_coarsen_patch_strategy);
-    if (!v_urestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a coarsen schedule for U v restriction!\n");
-    }
-    v_rrestriction_coarsen_schedules[dest_ln] =
-      v_rrestriction_coarsen_algorithm.
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     d_hierarchy->getPatchLevel(dest_ln + 1),
-                     &v_coarsen_patch_strategy);
-    if (!v_rrestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a coarsen schedule for R v restriction!\n");
-    }
-  }
-
-  /* Ordinary ghost fill operator on the coarsest level */
-  p_nocoarse_refine_schedules[d_ln_min] =
-    p_nocoarse_refine_algorithm.
-    createSchedule(d_hierarchy->getPatchLevel(d_ln_min));
-  if (!p_nocoarse_refine_schedules[d_ln_min]) {
-    TBOX_ERROR(
-               d_object_name
-               <<
-               ": Cannot create a refine schedule for p ghost filling on bottom level!\n");
-  }
-  v_nocoarse_refine_schedules[d_ln_min] =
-    v_nocoarse_refine_algorithm.
-    createSchedule(d_hierarchy->getPatchLevel(d_ln_min));
-  if (!v_nocoarse_refine_schedules[d_ln_min]) {
-    TBOX_ERROR(
-               d_object_name
-               <<
-               ": Cannot create a refine schedule for v ghost filling on bottom level!\n");
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/postprocessOneCycle.C
--- a/src/ElasticFACOps/postprocessOneCycle.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-********************************************************************
-* FACOperatorStrategy virtual postprocessOneCycle function.  *
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::postprocessOneCycle
-(int fac_cycle_num,
- const SAMRAIVectorReal<double>& current_soln,
- const SAMRAIVectorReal<double>& residual)
-{
-  NULL_USE(current_soln);
-  NULL_USE(residual);
-
-  if (d_enable_logging) {
-    if (d_preconditioner) {
-      /*
-       * Output convergence progress.  This is probably only appropriate
-       * if the solver is NOT being used as a preconditioner.
-       */
-      double avg_factor, final_factor;
-      d_preconditioner->getConvergenceFactors(avg_factor, final_factor);
-      tbox::plog
-        << "iter=" << std::setw(4) << fac_cycle_num
-        << " resid=" << d_preconditioner->getResidualNorm()
-        << " net conv=" << d_preconditioner->getNetConvergenceFactor()
-        << " final conv=" << d_preconditioner->getNetConvergenceFactor()
-        << " avg conv=" << d_preconditioner->getAvgConvergenceFactor()
-        << std::endl;
-    }
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/prolongErrorAndCorrect.C
--- a/src/ElasticFACOps/prolongErrorAndCorrect.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-***********************************************************************
-* FACOperatorStrategy virtual prolongErrorAndCorrect function.  *
-* After the prolongation, we set the physical boundary condition      *
-* for the correction, which is zero.  Other ghost cell values,        *
-* which are preset to zero, need not be set.                          *
-***********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::prolongErrorAndCorrect
-(const SAMRAIVectorReal<double>& s,
- SAMRAIVectorReal<double>& d,
- int dest_ln)
-{
-  t_prolong->start();
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (s.getPatchHierarchy() != d_hierarchy
-      || d.getPatchHierarchy() != d_hierarchy) {
-    TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
-               "internal state hierarchy.");
-  }
-#endif
-
-  tbox::Pointer<hier::PatchLevel> coarse_level =
-    d_hierarchy->getPatchLevel(dest_ln - 1);
-  tbox::Pointer<hier::PatchLevel> fine_level =
-    d_hierarchy->getPatchLevel(dest_ln);
-
-  /*
-   * Data is prolonged into the scratch space corresponding
-   * to index d_cell_scratch_id and allocated here.
-   */
-  fine_level->allocatePatchData(d_cell_scratch_id);
-  fine_level->allocatePatchData(d_side_scratch_id);
-
-  // int p_src(s.getComponentDescriptorIndex(0)),
-  //   v_src(s.getComponentDescriptorIndex(1)),
-  //   p_dst(d.getComponentDescriptorIndex(0)),
-  //   v_dst(d.getComponentDescriptorIndex(1));
-  // xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
-
-  /*
-   * Refine solution into scratch space to fill the fine level
-   * interior in the scratch space, then use that refined data
-   * to correct the fine level error.
-   */
-  p_refine_patch_strategy.setTargetDataId(d_cell_scratch_id);
-  v_refine_patch_strategy.setTargetDataId(d_side_scratch_id);
-  // v_refine_patch_strategy.setHomogeneousBc(true);
-  xeqScheduleProlongation(d_cell_scratch_id,
-                          s.getComponentDescriptorIndex(0),
-                          d_cell_scratch_id,
-                          d_side_scratch_id,
-                          s.getComponentDescriptorIndex(1),
-                          d_side_scratch_id,
-                          dest_ln);
-
-  set_boundaries(s.getComponentDescriptorIndex(0),
-                 s.getComponentDescriptorIndex(1),fine_level,true);
-  /*
-   * Add the refined error in the scratch space to the error currently
-   * residing in the destination level.
-   */
-  {
-    math::HierarchyCellDataOpsReal<double>
-      hierarchy_math_ops(d_hierarchy, dest_ln, dest_ln);
-    const int p_dst = d.getComponentDescriptorIndex(0);
-    hierarchy_math_ops.add(p_dst, p_dst, d_cell_scratch_id);
-  }
-  {
-    math::HierarchySideDataOpsReal<double>
-      hierarchy_math_ops(d_hierarchy, dest_ln, dest_ln);
-    const int v_dst = d.getComponentDescriptorIndex(1);
-    hierarchy_math_ops.add(v_dst, v_dst, d_side_scratch_id);
-  }
-  fine_level->deallocatePatchData(d_cell_scratch_id);
-  fine_level->deallocatePatchData(d_side_scratch_id);
-
-  t_prolong->stop();
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/residual_2D.C
--- a/src/ElasticFACOps/residual_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-
-void SAMRAI::solv::ElasticFACOps::residual_2D
-(pdat::CellData<double> &p,
- pdat::SideData<double> &v,
- pdat::CellData<double> &cell_moduli,
- pdat::CellData<double> &p_rhs,
- pdat::SideData<double> &v_rhs,
- pdat::CellData<double> &p_resid,
- pdat::SideData<double> &v_resid,
- hier::Patch &patch,
- const hier::Box &pbox,
- const geom::CartesianPatchGeometry &geom)
-{
-  const hier::Index ip(1,0), jp(0,1);
-
-  tbox::Pointer<pdat::NodeData<double> >
-    edge_moduli_ptr = patch.getPatchData(edge_moduli_id);
-  pdat::NodeData<double> &edge_moduli(*edge_moduli_ptr);
-
-  double dx = geom.getDx()[0];
-  double dy = geom.getDx()[1];
-
-  for(pdat::CellIterator ci(pbox); ci; ci++)
-    {
-      pdat::CellIndex center(*ci);
-      pdat::CellIndex up(center), down(center), right(center),
-        left(center);
-
-      ++up[1];
-      --down[1];
-      ++right[0];
-      --left[0];
-
-      const pdat::SideIndex
-        x(center,0,pdat::SideIndex::Lower),
-        y(center,1,pdat::SideIndex::Lower);
-      const pdat::NodeIndex
-        edge(center,pdat::NodeIndex::LowerLeft);
-
-      /* p */
-      if(center[0]!=pbox.upper(0) && center[1]!=pbox.upper(1))
-        {
-          p_resid(center)=0;
-        }
-
-      /* vx */
-      if(center[1]!=pbox.upper(1))
-        {
-          /* If x==0 */
-          if((center[0]==pbox.lower(0) && v(x-ip)==boundary_value)
-             || (center[0]==pbox.upper(0) && v(x+ip)==boundary_value))
-            {
-              v_resid(x)=0;
-            }
-          else
-            {
-              v_resid(x)=v_rhs(x)
-                - v_operator_2D(v,cell_moduli,edge_moduli,center,
-                                edge,x,y,ip,jp,dx,dy);
-            }
-        }
-
-      /* vy */
-      if(center[0]!=pbox.upper(0))
-        {
-          /* If y==0 */
-          if((center[1]==pbox.lower(1) && v(y-jp)==boundary_value)
-             || (center[1]==pbox.upper(1) && v(y+jp)==boundary_value))
-            {
-              v_resid(y)=0;
-            }
-          else
-            {
-              v_resid(y)=v_rhs(y)
-                - v_operator_2D(v,cell_moduli,edge_moduli,center,
-                                edge,y,x,jp,ip,dy,dx);
-            }
-        }
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/residual_3D.C
--- a/src/ElasticFACOps/residual_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-
-void SAMRAI::solv::ElasticFACOps::residual_3D
-(pdat::CellData<double> &p,
- pdat::SideData<double> &v,
- pdat::CellData<double> &cell_moduli,
- pdat::CellData<double> &p_rhs,
- pdat::SideData<double> &v_rhs,
- pdat::CellData<double> &p_resid,
- pdat::SideData<double> &v_resid,
- hier::Patch &patch,
- const hier::Box &pbox,
- const geom::CartesianPatchGeometry &geom)
-{
-  tbox::Pointer<pdat::EdgeData<double> >
-    edge_moduli_ptr = patch.getPatchData(edge_moduli_id);
-  pdat::EdgeData<double> &edge_moduli(*edge_moduli_ptr);
-
-  const double *Dx = geom.getDx();
-  const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
-  const hier::Index pp[]={ip,jp,kp};
-
-  for(pdat::CellIterator ci(pbox); ci; ci++)
-    {
-      pdat::CellIndex center(*ci);
-      pdat::CellIndex up(center), down(center), right(center),
-        left(center), front(center), back(center);
-
-      ++right[0];
-      --left[0];
-      ++up[1];
-      --down[1];
-      ++front[2];
-      --back[2];
-
-      /* p */
-      if(center[0]!=pbox.upper(0) && center[1]!=pbox.upper(1)
-         && center[2]!=pbox.upper(2))
-        {
-          p_resid(center)=0;
-        }
-
-      for(int ix=0;ix<3;++ix)
-        {
-          const int iy((ix+1)%3), iz((ix+2)%3);
-          const pdat::SideIndex
-            x(center,ix,pdat::SideIndex::Lower),
-            y(center,iy,pdat::SideIndex::Lower),
-            z(center,iz,pdat::SideIndex::Lower);
-          const pdat::EdgeIndex
-            edge_y(center,iy,pdat::EdgeIndex::LowerLeft),
-            edge_z(center,iz,pdat::EdgeIndex::LowerLeft);
-
-          if(center[iy]!=pbox.upper(iy) && center[iz]!=pbox.upper(iz))
-            {
-              if((center[ix]==pbox.lower(ix) && v(x-pp[ix])==boundary_value)
-                 || (center[ix]==pbox.upper(ix) && v(x+pp[ix])==boundary_value))
-                {
-                  v_resid(x)=0;
-                }
-              else
-                {
-                  v_resid(x)=v_rhs(x)
-                    - v_operator_3D(v,cell_moduli,edge_moduli,
-                                    center,edge_y,edge_z,x,y,z,
-                                    pp[ix],pp[iy],pp[iz],Dx[ix],Dx[iy],Dx[iz]);
-                }
-            }
-        }          
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/restrictResidual.C
--- a/src/ElasticFACOps/restrictResidual.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-********************************************************************
-* FACOperatorStrategy virtual restrictresidual function.     *
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::restrictResidual
-(const SAMRAIVectorReal<double>& s,
- SAMRAIVectorReal<double>& d,
- int dest_ln)
-{
-  t_restrict_residual->start();
-
-  int p_src(s.getComponentDescriptorIndex(0)),
-    p_dst(d.getComponentDescriptorIndex(0)),
-    v_src(s.getComponentDescriptorIndex(1)),
-    v_dst(d.getComponentDescriptorIndex(1));
-
-  /* Need to do a sync because the coarsening for v uses ghost zones */
-  v_coarsen_patch_strategy.setSourceDataId(v_src);
-  xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
-
-  xeqScheduleRRestriction(p_dst,p_src,v_dst,v_src,dest_ln);
-
-  t_restrict_residual->stop();
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/restrictSolution.C
--- a/src/ElasticFACOps/restrictSolution.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-********************************************************************
-* FACOperatorStrategy virtual restrictSolution function.     *
-* After restricting solution, update ghost cells of the affected   *
-* level.                                                           *
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::restrictSolution
-(const SAMRAIVectorReal<double>& s,
- SAMRAIVectorReal<double>& d,
- int dest_ln)
-{
-  t_restrict_solution->start();
-
-  int p_src(s.getComponentDescriptorIndex(0)),
-    p_dst(d.getComponentDescriptorIndex(0)),
-    v_src(s.getComponentDescriptorIndex(1)),
-    v_dst(d.getComponentDescriptorIndex(1));
-
-  /* Need to do a sync because the coarsening for v uses ghost zones. */
-  v_coarsen_patch_strategy.setSourceDataId(v_src);
-  xeqScheduleGhostFillNoCoarse(invalid_id,v_src,dest_ln+1);
-
-  xeqScheduleURestriction(p_dst,p_src,v_dst,v_src,dest_ln);
-
-  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(dest_ln);
-  set_boundaries(p_dst,v_dst,level,false);
-  // v_refine_patch_strategy.setHomogeneousBc(false);
-  p_refine_patch_strategy.setTargetDataId(d.getComponentDescriptorIndex(0));
-  v_refine_patch_strategy.setTargetDataId(d.getComponentDescriptorIndex(1));
-
-  if (dest_ln == d_ln_min) {
-    xeqScheduleGhostFillNoCoarse(p_dst,v_dst,dest_ln);
-  } else {
-    xeqScheduleGhostFill(p_dst,v_dst,dest_ln);
-  }
-
-  t_restrict_solution->stop();
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/set_boundaries.C
--- a/src/ElasticFACOps/set_boundaries.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-#include "Constants.h"
-#include "set_boundary.h"
-
-/* Set the physical boundaries for the velocity. */
-
-void SAMRAI::solv::ElasticFACOps::set_boundaries
-(const int &p_id, const int &v_id,
- tbox::Pointer<hier::PatchLevel> &level, const bool &rhs)
-{
-  for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
-    {
-      tbox::Pointer<hier::Patch> patch = *pi;
-      set_boundary(*patch,p_id,v_id,rhs);
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/smoothError.C
--- a/src/ElasticFACOps/smoothError.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-********************************************************************
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::smoothError
-(SAMRAIVectorReal<double>& data,
- const SAMRAIVectorReal<double>& residual,
- int ln,
- int num_sweeps)
-{
-  t_smooth_error->start();
-
-  if (d_smoothing_choice == "Tackley") {
-    if(d_dim.getValue()==2)
-      smooth_Tackley_2D(data,residual,ln,num_sweeps,
-                        d_residual_tolerance_during_smoothing);
-    else if(d_dim.getValue()==3)
-      smooth_Tackley_3D(data,residual,ln,num_sweeps,
-                        d_residual_tolerance_during_smoothing);
-    else
-	TBOX_ERROR(d_object_name << ": Invalid dimension in ElasticFACOps.");
-  } else {
-    TBOX_ERROR(d_object_name << ": Bad smoothing choice '"
-               << d_smoothing_choice
-               << "' in ElasticFACOps.");
-  }
-
-  t_smooth_error->stop();
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/smooth_Tackley_2D.C
--- a/src/ElasticFACOps/smooth_Tackley_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Workhorse function to smooth error using red-black               *
-* Gauss-Seidel iterations.                                         *
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::smooth_Tackley_2D
-(SAMRAIVectorReal<double>& solution,
- const SAMRAIVectorReal<double>& residual,
- int ln,
- int num_sweeps,
- double residual_tolerance)
-{
-  const int p_id(solution.getComponentDescriptorIndex(0)),
-    p_rhs_id(residual.getComponentDescriptorIndex(0)),
-    v_id(solution.getComponentDescriptorIndex(1)),
-    v_rhs_id(residual.getComponentDescriptorIndex(1));
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (solution.getPatchHierarchy() != d_hierarchy
-      || residual.getPatchHierarchy() != d_hierarchy)
-    {
-      TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
-                 "internal hierarchy.");
-    }
-#endif
-  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
-
-  /* Only need to sync the rhs once. This sync is needed because
-     calculating a new pressure update requires computing in the ghost
-     region so that the update for the velocity inside the box will be
-     correct. */
-  p_refine_patch_strategy.setTargetDataId(p_id);
-  v_refine_patch_strategy.setTargetDataId(v_id);
-  set_boundaries(p_id,v_id,level,true);
-  xeqScheduleGhostFillNoCoarse(p_rhs_id,v_rhs_id,ln);
-
-  if (ln > d_ln_min) {
-    /*
-     * Perform a one-time transfer of data from coarser level,
-     * to fill ghost boundaries that will not change through
-     * the smoothing loop.
-     */
-    xeqScheduleGhostFill(p_id, v_id, ln);
-  }
-
-  double theta_momentum=1.0;
-
-  /*
-   * Smooth the number of sweeps specified or until
-   * the convergence is satisfactory.
-   */
-  double maxres;
-  /*
-   * Instead of checking residual convergence globally, we check the
-   * converged flag.  This avoids possible round-off errors affecting
-   * different processes differently, leading to disagreement on
-   * whether to continue smoothing.
-   */
-  const hier::Index ip(1,0), jp(0,1);
-  bool converged = false;
-  for (int sweep=0; sweep < num_sweeps*(1<<(d_ln_max-ln)) && !converged;
-       ++sweep)
-    {
-      maxres=0;
-
-      /* vx sweep */
-      xeqScheduleGhostFillNoCoarse(p_id,invalid_id,ln);
-      for(int rb=0;rb<2;++rb)
-        {
-          xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
-          for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
-            {
-              tbox::Pointer<hier::Patch> patch = *pi;
-
-              tbox::Pointer<pdat::CellData<double> > p_ptr =
-                patch->getPatchData(p_id);
-              pdat::CellData<double> &p(*p_ptr);
-                
-              tbox::Pointer<pdat::SideData<double> > v_ptr =
-                patch->getPatchData(v_id);
-              pdat::SideData<double> &v(*v_ptr);
-              tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
-                patch->getPatchData(v_rhs_id);
-              pdat::SideData<double> &v_rhs(*v_rhs_ptr);
-                
-              tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
-                = patch->getPatchData(cell_moduli_id);
-              pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
-              tbox::Pointer<pdat::NodeData<double> > edge_visc_ptr
-                = patch->getPatchData(edge_moduli_id);
-              pdat::NodeData<double> &edge_moduli(*edge_visc_ptr);
-
-              hier::Box pbox=patch->getBox();
-              tbox::Pointer<geom::CartesianPatchGeometry>
-                geom = patch->getPatchGeometry();
-              double dx = geom->getDx()[0];
-              double dy = geom->getDx()[1];
-
-              for(int j=pbox.lower(1); j<=pbox.upper(1); ++j)
-                {
-                  /* Do the red-black skip */
-                  int i_min=pbox.lower(0) + (abs(pbox.lower(0) + j + rb))%2;
-                  for(int i=i_min; i<=pbox.upper(0)+1; i+=2)
-                    {
-                      pdat::CellIndex center(tbox::Dimension(2));
-                      center[0]=i;
-                      center[1]=j;
-
-                      /* Update v */
-                      smooth_V_2D(0,pbox,geom,center,ip,jp,
-                                  v,v_rhs,maxres,dx,dy,cell_moduli,
-                                  edge_moduli,theta_momentum);
-                    }
-                }
-            }
-          set_boundaries(invalid_id,v_id,level,true);
-        }
-
-
-      /* vy sweep */
-
-      for(int rb=0;rb<2;++rb)
-        {
-          xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
-          for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
-            {
-              tbox::Pointer<hier::Patch> patch = *pi;
-
-              tbox::Pointer<pdat::CellData<double> > p_ptr =
-                patch->getPatchData(p_id);
-              pdat::CellData<double> &p(*p_ptr);
-                
-              tbox::Pointer<pdat::SideData<double> > v_ptr =
-                patch->getPatchData(v_id);
-              pdat::SideData<double> &v(*v_ptr);
-              tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
-                patch->getPatchData(v_rhs_id);
-              pdat::SideData<double> &v_rhs(*v_rhs_ptr);
-                
-              tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
-                = patch->getPatchData(cell_moduli_id);
-              pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
-              tbox::Pointer<pdat::NodeData<double> > edge_visc_ptr
-                = patch->getPatchData(edge_moduli_id);
-              pdat::NodeData<double> &edge_moduli(*edge_visc_ptr);
-
-              hier::Box pbox=patch->getBox();
-              tbox::Pointer<geom::CartesianPatchGeometry>
-                geom = patch->getPatchGeometry();
-              double dx = geom->getDx()[0];
-              double dy = geom->getDx()[1];
-
-              for(int j=pbox.lower(1); j<=pbox.upper(1)+1; ++j)
-                {
-                  /* Do the red-black skip */
-                  int i_min=pbox.lower(0) + (abs(pbox.lower(0) + j + rb))%2;
-                  for(int i=i_min; i<=pbox.upper(0); i+=2)
-                    {
-                      pdat::CellIndex center(tbox::Dimension(2));
-                      center[0]=i;
-                      center[1]=j;
-
-                      /* Update v */
-                      smooth_V_2D(1,pbox,geom,center,jp,ip,
-                                  v,v_rhs,maxres,dy,dx,cell_moduli,
-                                  edge_moduli,theta_momentum);
-                    }
-                }
-            }
-          set_boundaries(invalid_id,v_id,level,true);
-        }
-
-      // if (residual_tolerance >= 0.0) {
-        /*
-         * Check for early end of sweeps due to convergence
-         * only if it is numerically possible (user gave a
-         * non negative value for residual tolerance).
-         */
-        converged = maxres < residual_tolerance;
-        const tbox::SAMRAI_MPI&
-          mpi(d_hierarchy->getDomainMappedBoxLevel().getMPI());
-        int tmp= converged ? 1 : 0;
-        if (mpi.getSize() > 1)
-          {
-            mpi.AllReduce(&tmp, 1, MPI_MIN);
-          }
-        converged=(tmp==1);
-        // if (d_enable_logging)
-        //   tbox::plog
-        //     // << d_object_name << "\n"
-        //     << "Tackley  " << ln << " " << sweep << " : " << maxres << "\n";
-      // }
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/smooth_Tackley_3D.C
--- a/src/ElasticFACOps/smooth_Tackley_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Workhorse function to smooth error using red-black               *
-* Gauss-Seidel iterations.                                         *
-********************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACOps::smooth_Tackley_3D
-(SAMRAIVectorReal<double>& solution,
- const SAMRAIVectorReal<double>& residual,
- int ln,
- int num_sweeps,
- double residual_tolerance)
-{
-  const int p_id(solution.getComponentDescriptorIndex(0)),
-    p_rhs_id(residual.getComponentDescriptorIndex(0)),
-    v_id(solution.getComponentDescriptorIndex(1)),
-    v_rhs_id(residual.getComponentDescriptorIndex(1));
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (solution.getPatchHierarchy() != d_hierarchy
-      || residual.getPatchHierarchy() != d_hierarchy)
-    {
-      TBOX_ERROR(d_object_name << ": Vector hierarchy does not match\n"
-                 "internal hierarchy.");
-    }
-#endif
-  tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
-
-  /* Only need to sync the rhs once. This sync is needed because
-     calculating a new pressure update requires computing in the ghost
-     region so that the update for the velocity inside the box will be
-     correct. */
-  p_refine_patch_strategy.setTargetDataId(p_id);
-  v_refine_patch_strategy.setTargetDataId(v_id);
-  set_boundaries(p_id,v_id,level,true);
-  xeqScheduleGhostFillNoCoarse(p_rhs_id,v_rhs_id,ln);
-
-  if (ln > d_ln_min) {
-    /*
-     * Perform a one-time transfer of data from coarser level,
-     * to fill ghost boundaries that will not change through
-     * the smoothing loop.
-     */
-    xeqScheduleGhostFill(p_id, v_id, ln);
-  }
-
-  double theta_momentum=1.0;
-
-  /*
-   * Smooth the number of sweeps specified or until
-   * the convergence is satisfactory.
-   */
-  double maxres;
-  /*
-   * Instead of checking residual convergence globally, we check the
-   * converged flag.  This avoids possible round-off errors affecting
-   * different processes differently, leading to disagreement on
-   * whether to continue smoothing.
-   */
-  const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
-  const hier::Index pp[]={ip,jp,kp};
-  bool converged = false;
-  for (int sweep=0; sweep < num_sweeps*(1<<(2*(d_ln_max-ln))) && !converged;
-       ++sweep)
-    {
-      maxres=0;
-
-      /* v sweeps */
-      xeqScheduleGhostFillNoCoarse(p_id,invalid_id,ln);
-
-      for(int ix=0;ix<3;++ix)
-        for(int rb=0;rb<2;++rb)
-          {
-            xeqScheduleGhostFillNoCoarse(invalid_id,v_id,ln);
-            for (hier::PatchLevel::Iterator pi(*level); pi; pi++)
-              {
-                tbox::Pointer<hier::Patch> patch = *pi;
-
-                tbox::Pointer<pdat::CellData<double> > p_ptr =
-                  patch->getPatchData(p_id);
-                pdat::CellData<double> &p(*p_ptr);
-                
-                tbox::Pointer<pdat::SideData<double> > v_ptr =
-                  patch->getPatchData(v_id);
-                pdat::SideData<double> &v(*v_ptr);
-                tbox::Pointer<pdat::SideData<double> > v_rhs_ptr =
-                  patch->getPatchData(v_rhs_id);
-                pdat::SideData<double> &v_rhs(*v_rhs_ptr);
-                
-                tbox::Pointer<pdat::CellData<double> > cell_visc_ptr
-                  = patch->getPatchData(cell_moduli_id);
-                pdat::CellData<double> &cell_moduli(*cell_visc_ptr);
-                tbox::Pointer<pdat::EdgeData<double> > edge_visc_ptr
-                  = patch->getPatchData(edge_moduli_id);
-                pdat::EdgeData<double> &edge_moduli(*edge_visc_ptr);
-
-                hier::Box pbox=patch->getBox();
-                tbox::Pointer<geom::CartesianPatchGeometry>
-                  geom = patch->getPatchGeometry();
-                const double *Dx = geom->getDx();
-
-                for(int k=pbox.lower(2); k<=pbox.upper(2)+pp[ix][2]; ++k)
-                  for(int j=pbox.lower(1); j<=pbox.upper(1)+pp[ix][1]; ++j)
-                    {
-                      /* Do the red-black skip */
-                      int i_min=pbox.lower(0)
-                        + (abs(pbox.lower(0) + j + k + rb))%2;
-                      for(int i=i_min; i<=pbox.upper(0)+pp[ix][0]; i+=2)
-                        {
-                          pdat::CellIndex center(hier::Index(i,j,k));
-
-                          /* Update v */
-                          smooth_V_3D(ix,pbox,geom,v,v_rhs,cell_moduli,
-                                      edge_moduli,center,
-                                      Dx,theta_momentum,pp,maxres);
-                        }
-                    }
-              }
-            set_boundaries(invalid_id,v_id,level,true);
-          }
-
-      // if (residual_tolerance >= 0.0) {
-        /*
-         * Check for early end of sweeps due to convergence
-         * only if it is numerically possible (user gave a
-         * non negative value for residual tolerance).
-         */
-        converged = maxres < residual_tolerance;
-        const tbox::SAMRAI_MPI&
-          mpi(d_hierarchy->getDomainMappedBoxLevel().getMPI());
-        int tmp= converged ? 1 : 0;
-        if (mpi.getSize() > 1)
-          {
-            mpi.AllReduce(&tmp, 1, MPI_MIN);
-          }
-        converged=(tmp==1);
-        // if (d_enable_logging)
-        //   tbox::plog
-        //     // << d_object_name << "\n"
-        //     << "Tackley  " << ln << " " << sweep << " : " << maxres << "\n";
-      // }
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/smooth_V_2D.C
--- a/src/ElasticFACOps/smooth_V_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-#include "dRm_dv.h"
-/*
-********************************************************************
-* Updates one component of the velocity during a red-black *
-* Gauss-Seidel iteration.  *
-********************************************************************
-*/
-void SAMRAI::solv::ElasticFACOps::smooth_V_2D
-(const int &axis,
- const hier::Box &pbox,
- tbox::Pointer<geom::CartesianPatchGeometry> &geom,
- const pdat::CellIndex &center,
- const hier::Index &ip,
- const hier::Index &jp,
- pdat::SideData<double> &v,
- pdat::SideData<double> &v_rhs,
- double &maxres,
- const double &dx,
- const double &dy,
- pdat::CellData<double> &cell_moduli,
- pdat::NodeData<double> &edge_moduli,
- const double &theta_momentum)
-{
-  const int off_axis=(axis==0) ? 1 : 0;
-
-  const pdat::SideIndex x(center,axis,pdat::SideIndex::Lower),
-    y(center,off_axis,pdat::SideIndex::Lower);
-  const pdat::NodeIndex edge(center,pdat::NodeIndex::LowerLeft);
-    
-  /* If at a Dirichlet 'x' boundary, leave vx as is */
-  if(!((center[axis]==pbox.lower(axis) && v(x-ip)==boundary_value)
-       || (center[axis]==pbox.upper(axis)+1 && v(x+ip)==boundary_value)))
-    {
-      /* If at the boundary, set things up so that the derivative does
-         not change. */
-      hier::Index offset(0,0);
-      offset[axis]=2;
-      bool set_lower_boundary(false), set_upper_boundary(false);
-      double dv_lower(0), dv_upper(0);
-      if(center[axis]==pbox.lower(axis)+1
-         && !geom->getTouchesRegularBoundary(axis,0))
-        {
-          set_lower_boundary=true;
-          dv_lower=v(x-offset) - v(x);
-        }
-      if(center[axis]==pbox.upper(axis)
-         && !geom->getTouchesRegularBoundary(axis,1))
-        {
-          set_upper_boundary=true;
-          dv_upper=v(x+offset) - v(x);
-        }
-
-      double C_vx=dRm_dv_2D(cell_moduli,edge_moduli,center,center-ip,
-                            edge+jp,edge,dx,dy);
-
-      double delta_Rx=v_rhs(x)
-        - v_operator_2D(v,cell_moduli,edge_moduli,center,
-                        edge,x,y,ip,jp,dx,dy);
-
-      /* No scaling here, though there should be. */
-      maxres=std::max(maxres,std::fabs(delta_Rx));
-
-      v(x)+=delta_Rx*theta_momentum/C_vx;
-
-      /* Set the boundary elements so that the derivative is
-         unchanged. */
-      if(set_lower_boundary)
-        {
-          v(x-offset)=v(x) + dv_lower;
-        }
-      if(set_upper_boundary)
-        {
-          v(x+offset)=v(x) + dv_upper;
-        }
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/smooth_V_3D.C
--- a/src/ElasticFACOps/smooth_V_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#include "ElasticFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Updates one component of the velocity during a red-black *
-* Gauss-Seidel iteration.  *
-********************************************************************
-*/
-void SAMRAI::solv::ElasticFACOps::smooth_V_3D
-(const int &ix,
- const hier::Box &pbox,
- tbox::Pointer<geom::CartesianPatchGeometry> &geom,
- pdat::SideData<double> &v,
- pdat::SideData<double> &v_rhs,
- pdat::CellData<double> &cell_moduli,
- pdat::EdgeData<double> &edge_moduli,
- const pdat::CellIndex &center,
- const double Dx[3],
- const double &theta_momentum,
- const hier::Index pp[3],
- double &maxres)
-{
-  const int iy((ix+1)%3), iz((ix+2)%3);
-  const pdat::SideIndex x(center,ix,pdat::SideIndex::Lower),
-    y(center,iy,pdat::SideIndex::Lower),
-    z(center,iz,pdat::SideIndex::Lower);
-  const pdat::EdgeIndex edge_y(center,iy,pdat::EdgeIndex::LowerLeft),
-    edge_z(center,iz,pdat::EdgeIndex::LowerLeft);
-    
-  /* If at a Dirichlet 'x' boundary, leave vx as is */
-  if(!((center[ix]==pbox.lower(ix) && v(x-pp[ix])==boundary_value)
-       || (center[ix]==pbox.upper(ix)+1 && v(x+pp[ix])==boundary_value)))
-    {
-      /* If at the boundary, set things up so that the derivative does
-         not change. */
-      hier::Index offset(0,0,0);
-      offset[ix]=2;
-      bool set_lower_boundary(false), set_upper_boundary(false);
-      double dv_lower(0), dv_upper(0);
-      if(center[ix]==pbox.lower(ix)+1
-         && !geom->getTouchesRegularBoundary(ix,0))
-        {
-          set_lower_boundary=true;
-          dv_lower=v(x-offset) - v(x);
-        }
-      if(center[ix]==pbox.upper(ix) && !geom->getTouchesRegularBoundary(ix,1))
-        {
-          set_upper_boundary=true;
-          dv_upper=v(x+offset) - v(x);
-        }
-
-      double C_vx=dRm_dv_3D(cell_moduli,edge_moduli,center,center-pp[ix],
-                            edge_y+pp[iz],edge_y,edge_z+pp[iy],edge_z,
-                            Dx[ix],Dx[iy],Dx[iz]);
-
-      double delta_Rx=v_rhs(x)
-        - v_operator_3D(v,cell_moduli,edge_moduli,center,edge_y,edge_z,
-                        x,y,z,pp[ix],pp[iy],pp[iz],Dx[ix],Dx[iy],Dx[iz]);
-
-      /* No scaling here, though there should be. */
-      maxres=std::max(maxres,std::fabs(delta_Rx));
-
-      v(x)+=delta_Rx*theta_momentum/C_vx;
-
-      /* Set the boundary elements so that the derivative is
-         unchanged. */
-      if(set_lower_boundary)
-        {
-          v(x-offset)=v(x) + dv_lower;
-        }
-      if(set_upper_boundary)
-        {
-          v(x+offset)=v(x) + dv_upper;
-        }
-    }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/solveCoarsestLevel.C
--- a/src/ElasticFACOps/solveCoarsestLevel.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-/*
-********************************************************************
-* FACOperatorStrategy virtual solveCoarsestLevel             *
-* function                                                         *
-********************************************************************
-*/
-
-int SAMRAI::solv::ElasticFACOps::solveCoarsestLevel
-(SAMRAIVectorReal<double>& data,
- const SAMRAIVectorReal<double>& residual,
- int coarsest_ln)
-{
-  t_solve_coarsest->start();
-
-  int return_value = 0;
-
-  if (d_coarse_solver_choice == "Tackley"
-      || d_coarse_solver_choice == "Gerya") {
-    d_residual_tolerance_during_smoothing = d_coarse_solver_tolerance;
-    smoothError(data,
-                residual,
-                coarsest_ln,
-                d_coarse_solver_max_iterations);
-    d_residual_tolerance_during_smoothing = -1.0;
-  } else if (d_coarse_solver_choice == "hypre") {
-#ifndef HAVE_HYPRE
-    TBOX_ERROR(d_object_name << ": Coarse level solver choice '"
-               << d_coarse_solver_choice
-               << "' unavailable in "
-               << "ElasticFACOps::solveCoarsestLevel.");
-#else
-    return_value = solveCoarsestLevel_HYPRE(data, residual, coarsest_ln);
-#endif
-  } else {
-    TBOX_ERROR(
-               d_object_name << ": Bad coarse level solver choice '"
-               << d_coarse_solver_choice
-               <<
-               "' in ElasticFACOps::solveCoarsestLevel.");
-  }
-
-  xeqScheduleGhostFillNoCoarse(data.getComponentDescriptorIndex(0),
-                               data.getComponentDescriptorIndex(1),
-                               coarsest_ln);
-  t_solve_coarsest->stop();
-
-  return return_value;
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/solveCoarsestLevel_HYPRE.C
--- a/src/ElasticFACOps/solveCoarsestLevel_HYPRE.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-#include IOMANIP_HEADER_FILE
-
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/pdat/CellDoubleConstantRefine.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/PatchData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticHypreSolver.h"
-#include "SAMRAI/tbox/Array.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/xfer/CoarsenAlgorithm.h"
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/xfer/CoarsenSchedule.h"
-#include "SAMRAI/xfer/RefineAlgorithm.h"
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/xfer/RefineSchedule.h"
-#include "SAMRAI/xfer/PatchLevelFullFillPattern.h"
-
-namespace SAMRAI {
-  namespace solv {
-
-#ifdef HAVE_HYPRE
-    /*
-********************************************************************
-* Solve coarsest level using Hypre                                 *
-* We only solve for the error, so we always use homogeneous bc.    *
-********************************************************************
-*/
-
-    int ElasticFACOps::solveCoarsestLevel_HYPRE(
-                                               SAMRAIVectorReal<double>& data,
-                                               const SAMRAIVectorReal<double>& residual,
-                                               int coarsest_ln) {
-
-      NULL_USE(coarsest_ln);
-
-#ifndef HAVE_HYPRE
-      TBOX_ERROR(d_object_name << ": Coarse level solver choice '"
-                 << d_coarse_solver_choice
-                 << "' unavailable in "
-                 << "ElasticFACOps::solveCoarsestLevel.");
-
-      return 0;
-
-#else
-
-      d_hypre_solver.setStoppingCriteria(d_coarse_solver_max_iterations,
-                                         d_coarse_solver_tolerance);
-      const int solver_ret =
-        d_hypre_solver.solveSystem(
-                                   data.getComponentDescriptorIndex(0),
-                                   residual.getComponentDescriptorIndex(0),
-                                   true);
-      /*
-       * Present data on the solve.
-       * The Hypre solver returns 0 if converged.
-       */
-      if (d_enable_logging) tbox::plog
-                              << d_object_name << " Hypre solve " << (solver_ret ? "" : "NOT ")
-                              << "converged\n"
-                              << "\titerations: " << d_hypre_solver.getNumberOfIterations() << "\n"
-                              << "\tresidual: " << d_hypre_solver.getRelativeResidualNorm() << "\n";
-
-      return !solver_ret;
-
-#endif
-
-    }
-#endif
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/xeqScheduleGhostFill.C
--- a/src/ElasticFACOps/xeqScheduleGhostFill.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::xeqScheduleGhostFill(int p_id, int v_id,
-                                                      int dest_ln)
-{
-  /* p */
-  {
-    if (!p_ghostfill_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(p_id,p_id,p_id,p_ghostfill_refine_operator);
-    refiner.resetSchedule(p_ghostfill_refine_schedules[dest_ln]);
-    p_ghostfill_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-
-  /* v */
-  {
-    if (!v_ghostfill_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-    set_boundaries(invalid_id,v_id,dest_ln-1);
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(v_id,v_id,v_id,v_ghostfill_refine_operator);
-    refiner.resetSchedule(v_ghostfill_refine_schedules[dest_ln]);
-    v_ghostfill_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C
--- a/src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::xeqScheduleGhostFillNoCoarse(int p_id,
-                                                              int v_id,
-                                                              int dest_ln)
-{
-  /* p */
-  if(p_id!=invalid_id)
-  {
-    if (!p_nocoarse_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected cell schedule not found.");
-    }
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(p_id,p_id,p_id,tbox::Pointer<xfer::RefineOperator>(0));
-    refiner.resetSchedule(p_nocoarse_refine_schedules[dest_ln]);
-    p_nocoarse_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-
-  /* v */
-  if(v_id!=invalid_id)
-  {
-    if (!v_nocoarse_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected side schedule not found.");
-    }
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(v_id,v_id,v_id,tbox::Pointer<xfer::RefineOperator>(0));
-    refiner.resetSchedule(v_nocoarse_refine_schedules[dest_ln]);
-    v_nocoarse_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/xeqScheduleProlongation.C
--- a/src/ElasticFACOps/xeqScheduleProlongation.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::xeqScheduleProlongation
-(int p_dst, int p_src, int p_scr, int v_dst, int v_src, int v_scr,
- int dest_ln)
-{
-  /* p */
-  {
-    if (!p_prolongation_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(p_dst, p_src, p_scr, p_prolongation_refine_operator);
-    refiner.resetSchedule(p_prolongation_refine_schedules[dest_ln]);
-    p_prolongation_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-
-  /* v */
-  {
-    if (!v_prolongation_refine_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-    xfer::RefineAlgorithm refiner(d_dim);
-    refiner.registerRefine(v_dst, v_src, v_scr, v_prolongation_refine_operator);
-    refiner.resetSchedule(v_prolongation_refine_schedules[dest_ln]);
-    v_prolongation_refine_schedules[dest_ln]->fillData(0.0,false);
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/xeqScheduleRRestriction.C
--- a/src/ElasticFACOps/xeqScheduleRRestriction.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::xeqScheduleRRestriction(int p_dst, int p_src,
-                                                         int v_dst, int v_src,
-                                                         int dest_ln)
-{
-  /* p */
-  {
-    if (!p_rrestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-
-    xfer::CoarsenAlgorithm coarsener(d_dim);
-    coarsener.registerCoarsen(p_dst,p_src,p_rrestriction_coarsen_operator);
-    coarsener.resetSchedule(p_rrestriction_coarsen_schedules[dest_ln]);
-    p_rrestriction_coarsen_schedules[dest_ln]->coarsenData();
-  }
-
-  /* v */
-  {
-    if (!v_rrestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-
-    xfer::CoarsenAlgorithm coarsener(d_dim);
-    coarsener.registerCoarsen(v_dst,v_src,v_rrestriction_coarsen_operator);
-    coarsener.resetSchedule(v_rrestriction_coarsen_schedules[dest_ln]);
-    v_rrestriction_coarsen_schedules[dest_ln]->coarsenData();
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACOps/xeqScheduleURestriction.C
--- a/src/ElasticFACOps/xeqScheduleURestriction.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Operator class for cell-centered scalar Elastic using FAC 
- *
- ************************************************************************/
-#include "ElasticFACOps.h"
-
-void SAMRAI::solv::ElasticFACOps::xeqScheduleURestriction(int p_dst, int p_src,
-                                                         int v_dst, int v_src,
-                                                         int dest_ln)
-{
-  /* p */
-  {
-    if (!p_urestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-
-    xfer::CoarsenAlgorithm coarsener(d_dim);
-    coarsener.registerCoarsen(p_dst, p_src, p_urestriction_coarsen_operator);
-    coarsener.resetSchedule(p_urestriction_coarsen_schedules[dest_ln]);
-    p_urestriction_coarsen_schedules[dest_ln]->coarsenData();
-  }
-
-  /* v */
-  {
-    if (!v_urestriction_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR("Expected schedule not found.");
-    }
-
-    xfer::CoarsenAlgorithm coarsener(d_dim);
-    coarsener.registerCoarsen(v_dst, v_src, v_urestriction_coarsen_operator);
-    coarsener.resetSchedule(v_urestriction_coarsen_schedules[dest_ln]);
-    v_urestriction_coarsen_schedules[dest_ln]->coarsenData();
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver.I
--- a/src/ElasticFACSolver.I	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar elastic equation. 
- *
- ************************************************************************/
-namespace SAMRAI {
-namespace solv {
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::set_P_ProlongationMethod(
-   const std::string& p_prolongation_method)
-{
-   d_fac_ops.set_P_ProlongationMethod(p_prolongation_method);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::set_V_ProlongationMethod(
-   const std::string& v_prolongation_method)
-{
-   d_fac_ops.set_V_ProlongationMethod(v_prolongation_method);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setCoarsestLevelSolverChoice(
-   const std::string& choice)
-{
-   d_fac_ops.setCoarsestLevelSolverChoice(choice);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setCoarsestLevelSolverTolerance(
-   double tol)
-{
-   d_fac_ops.setCoarsestLevelSolverTolerance(tol);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setCoarsestLevelSolverMaxIterations(
-   int max_iterations)
-{
-   d_fac_ops.setCoarsestLevelSolverMaxIterations(max_iterations);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setCoarseFineDiscretization(
-   const std::string& coarsefine_method)
-{
-   d_fac_ops.setCoarseFineDiscretization(coarsefine_method);
-}
-
-#ifdef HAVE_HYPRE
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setUseSMG(
-   bool use_smg)
-{
-   if (d_solver_is_initialized) {
-      TBOX_ERROR(
-         d_object_name << ": setUseSMG(bool) may NOT be called\n"
-         <<
-         "while the solver state is initialized, as that\n"
-         << "would lead to a corrupted solver state.\n");
-   }
-   d_fac_ops.setUseSMG(use_smg);
-}
-#endif
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setPresmoothingSweeps(
-   int num_pre_sweeps) {
-   d_fac_precond.setPresmoothingSweeps(num_pre_sweeps);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setPostsmoothingSweeps(
-   int num_post_sweeps) {
-   d_fac_precond.setPostsmoothingSweeps(num_post_sweeps);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setMaxCycles(
-   int max_cycles) {
-   d_fac_precond.setMaxCycles(max_cycles);
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::setResidualTolerance(
-   double residual_tol) {
-   d_fac_precond.setResidualTolerance(residual_tol);
-}
-
-SAMRAI_INLINE_KEYWORD
-int ElasticFACSolver::getNumberOfIterations() const
-{
-   return d_fac_precond.getNumberOfIterations();
-}
-
-SAMRAI_INLINE_KEYWORD
-double ElasticFACSolver::getResidualNorm() const
-{
-   return d_fac_precond.getResidualNorm();
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticFACSolver::getConvergenceFactors(
-   double& avg_factor,
-   double& final_factor)
-const
-{
-   d_fac_precond.getConvergenceFactors(avg_factor, final_factor);
-}
-
-}
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver.h
--- a/src/ElasticFACSolver.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,673 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#ifndef included_solv_ElasticFACSolver
-#define included_solv_ElasticFACSolver
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "ElasticFACOps.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/tbox/Database.h"
-#include "SAMRAI/tbox/Pointer.h"
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief Class for solving scalar Elastic's equation on SAMR grid,
- * wrapping up lower-level components (FAC cycling, Elastic equation
- * operations and boundary conditions) in a single high-level interface.
- *
- * Note: this class provides a backward-compatible interface to
- * the soon-to-be obsolete ElasticHierarchySolver<DIM> class.
- * Although this class hides the lower-level components (FAC cycling,
- * Elastic equation operations and boundary conditions), it is
- * perfectly acceptable to use those lower-level components directly.
- *
- * We solve the equation
- *    div(D grad(u)) + Cu = f
- * where D is a side-centered array and C is a cell-centered array.
- * u and f are also cell-centered.
- * Boundary conditions supported are Dirichlet, Neumann and mixed
- * (Dirichlet on some faces and Neumann on others).
- *
- * This class is a wrapper, providing a single class that coordinates
- * three major components: the FAC solver, the cell-centered Elastic
- * FAC operator and a default Robin bc coefficient implelemtation.
- * It is perfectly acceptable to use those classes outside of this
- * class.
- *
- * The underlying solver is an FAC solver using cell-centered
- * discretization.  The difference scheme is second-order
- * central-difference.  On coarse-fine boundaries within the
- * solution levels, the composite grid operator uses, by default,
- * the discretization method of Ewing, Lazarov and Vassilevski
- * ("Local Refinement Techniques for Elliptic Problems on
- * Cell-Centered Grids, I. Error Analysis", Mathematics of
- * Computation, Vol. 56, No. 194, April 1991, pp. 437-461).
- *
- * Typical use of this class is:
- * -# Construct a ElasticFACSolver object, providing it
- *    the hierarchy and range of levels participating in the solve.
- * -# Set the parameters C and D using the functions named @c setC...
- *    and @c setD...  By default, D=1 and C=0 everywhere.
- * -# Call setBoundaries() to state the types boundary conditions,
- *    along with supplemental data for setting those boundary
- *    conditions.
- * -# Call initializeSolverState() to set up information
- *    internal to the solver.  This is step is not required
- *    but will save setup costs if you are making multiple
- *    solves.  This commits the object to the current hierarchy state
- *    and the specific @em types of boundary conditions you selected,
- *    It does NOT commit to the specific @em values of the boundary
- *    condition.  A hierarchy change (through adaption or other means)
- *    invalidates the state, thus you must reinitialize or
- *    deallocateSolverState() the state before another solve.
- * -# Solve the equation with solveSystem().  You provide the
- *    patch data indices for the solution u and the right hand
- *    side f.  u must have at least one ghost cell and where
- *    a Dirichlet boundary condition applies, those cells
- *    must be set to the value on the boundary.  If only Neumann
- *    boundary conditions are used, the ghost cell values
- *    do not matter.
- * -# Call deallocateSolverState() to free up internal resources,
- *    if initializeSolverState() was called before the solve.
- *
- * After the solve, information on the solve can be obtained
- * by calling one of these functions:
- * - getNumberOfIterations() gives the number of FAC cycles used.
- * - getConvergenceFactors() gives the average and final convergence
- *   factors for the solve.
- * - getResidualNorm() gives the final residual
- *
- * Finer solver controls can be set using the functions in this class.
- *
- * Object of this class can be set using input databases.
- * The following parameters can be set.  Each is shown with its
- * default value in the case where hypre is used.
- * @verbatim
- * enable_logging = TRUE // Bool flag to switch logging on/off
- * max_cycles = 10       // Integer number of max FAC cycles to use
- * residual_tol = 1.e-6  // Residual tolerance to solve for
- * num_pre_sweeps = 1    // Number of presmoothing sweeps to use
- * num_post_sweeps = 1   // Number of postsmoothing sweeps to use
- * coarse_fine_discretization = "Ewing" // Name of coarse-fine discretization
- * prolongation_method = "CONSTANT_REFINE" // Name of prolongation method
- * coarse_solver_choice = "hypre"  // Name of coarse level solver
- * coarse_solver_tolerance = 1e-10 // Coarse level tolerance
- * coarse_solver_max_iterations = 20 // Coarse level max iterations
- * use_smg = "FALSE"     // Whether to use hypre's smg solver
- *                       // (alternative is the pfmg solver)
- * @endverbatim
- *
- */
-class ElasticFACSolver
-{
-
-public:
-   /*!
-    * @brief Construct a solver.
-    *
-    * If the database is not NULL, initial settings will be set
-    * using the database.
-    * The solver is uninitialized until initializeSolverState()
-    * is called.
-    *
-    * @param object_name Name of object used in outputs
-    * @param database tbox::Database for initialization (may be NULL)
-    */
-   ElasticFACSolver(
-      const tbox::Dimension& dim,
-      const std::string& object_name,
-      tbox::Pointer<tbox::Database> database =
-         tbox::Pointer<tbox::Database>());
-
-   /*!
-    * @brief Destructor.
-    */
-   ~ElasticFACSolver(
-      void);
-
-   /*!
-    * @brief Enable logging.
-    *
-    * To disable, pass in @c false.
-    */
-   void
-   enableLogging(
-      bool logging);
-
-   /*!
-    * @brief Solve Elastic's equation, assuming an uninitialized
-    * solver state.
-    *
-    * Here, u is the "solution" patch data index and f is the
-    * right hand side patch data index.
-    * The return value is true if the solver converged and false otherwise.
-    *
-    * This function is a wrapper.
-    * It simply initializes the solver state, call the
-    * solveSystem(const int,const int) for the initialized solver then
-    * deallocates the solver state.
-    *
-    * Upon return from this function,
-    * solution will contain the result of the solve.
-    *
-    * See initializeSolverState() for opportunities to save overhead
-    * when using multiple consecutive solves.
-    *
-    * @see solveSystem(const int,const int)
-    *
-    * @param solution hier::Patch data index for solution u
-    * @param rhs hier::Patch data index for right hand side f
-    * @param hierarchy The patch hierarchy to solve on
-    * @param coarse_ln The coarsest level in the solve.
-    * @param fine_ln The finest level in the solve.
-    *
-    * @return whether solver converged to specified level
-    *
-    * @see initializeSolverState
-    */
-   bool
-   solveSystem(
-      const int p,
-      const int cell_moduli,
-      const int edge_moduli,
-      const int dp,
-      const int p_rhs,
-      const int v,
-      const int v_rhs,
-      tbox::Pointer<hier::PatchHierarchy> hierarchy,
-      int coarse_ln = -1,
-      int fine_ln = -1);
-
-   /*!
-    * @brief Solve Elastic's equation using the current solver state
-    * set by initializeSolverState().
-    *
-    * When the solver state has been initialized, this function may
-    * be called repeadedly with different values on the rhs.
-    * There is some cost savings for multiple solves when this
-    * is done.
-    *
-    * Before calling this function, the solution and
-    * right-hand-side quantities should be set properly by the user
-    * on all patch interiors on the range of levels covered by the
-    * FAC iteration.  All data for these patch data index should be allocated.
-    * Thus, the user is responsible for managing the
-    * storage for the solution and right-hand-side.
-    *
-    * @return whether solver converged to specified level
-    *
-    * @see solveSystem( const int, const int, tbox::Pointer< hier::PatchHierarchy >, int, int);
-    */
-   bool
-   solveSystem(const int p, const int p_rhs,
-               const int v, const int v_rhs);
-
-   /*!
-    * @brief Specify the boundary conditions that are to be used at the
-    * physical domain boundary.
-    *
-    * This method is used to set up the default SimpleCellRobinBcCoefs
-    * object for specifying boundary conditions.  Note that you may
-    * alternatively provide your own implementation of the Robin
-    * boundary condition coefficients using the setBcObject() method.
-    *
-    * The boundary conditions specified as the
-    * std::string argument "boundary_type."  The boundary type argument can be
-    * "Dirichlet", "Neumann", or "Mixed".
-    *
-    * If using Dirichlet boundary conditions, then before the solver is
-    * called, the storage for the unknown u
-    * must have a mapped_box_level of ghost cells at least one cell wide that includes
-    * the Dirichlet boundary values.
-    *
-    * If using Neumann boundary conditions, then before the solver is called,
-    * the outerface boundary flux data must be set for the Neumann conditions.
-    * The fluxes argument gives the patch data index of this flux
-    * data.
-    *
-    * The mixed boundary type is for a mixture of Dirichlet and Neumann
-    * boundary conditions are used at the physical domain boundary.
-    * The fluxes argument gives the patch data index of the outerface data
-    * that specifies the flux data for the Neumann conditions.  The flags
-    * array is an outerface data array of integer flags that specifies whether
-    * Dirichlet (flag == zero) or Neumann (flag == one) conditions are to be
-    * used at a particular cell boundary face.  Note that the flag data must
-    * be set before the matrix entries can be computed and the flux data
-    * must be set before the solver is called.  The bdry_types argument can
-    * be used if the boundary conditions are mixed but one or more of the
-    * faces of the physical boundary are entirely either Dirichlet or
-    * Neumann boundaries.  The bdry_types argument should be an array of
-    * 2*DIM integers, specifying the boundary conditions on each side of
-    * the physical domain.  It should be ordered {x_lo, x_hi, y_lo, y_hi,
-    * z_lo, z_hi}, with the values for each face being 0 for Dirichlet
-    * conditions, 1 for Neumann conditions, and 2 for mixed boundary
-    * conditions.  The bdry_type argument is never required, but if used
-    * it can sometimes make the ElasticHYPRESolver class more efficient.
-    */
-
-   void
-   setBoundaries(
-      const std::string& boundary_type,
-      const int fluxes = -1,
-      const int flags = -1,
-      int* bdry_types = NULL);
-
-   /*!
-    * @brief Override internal implementation to set boundary condition
-    * coefficients with user-provided implementation.
-    *
-    * This function is used to override the default internal
-    * object for setting Robin boundary condition coefficients.
-    * You should override when you need to avoid the limitations
-    * of the SimpleCellRobinBcCoefs class or you prefer to
-    * use your own implementation.
-    *
-    * Note that an important limitation of the SimpleCellRobinBcCoefs
-    * class is the inability to support linear interpolation in
-    * the prolongation step.
-    *
-    * Once the boundary condition object is overwritten by this
-    * method, you must no longer call the setBoundaries() method.
-    */
-   void
-   setBcObject(
-      const RobinBcCoefStrategy* bc_object);
-
-   //!@{ @name Specifying PDE parameters
-
-   /*!
-    * @brief Set the patch data index for variable D.
-    *
-    * In addition, disregard any previous D
-    * specified by setDConstant().
-    */
-   void
-   setDPatchDataId(
-      int id);
-
-   /*!
-    * @brief Set the scalar value variable D.
-    *
-    * In addition, disregard any previous D
-    * specified by setDPatchDataId().
-    */
-   void
-   setDConstant(
-      double scalar);
-
-   /*!
-    * @brief Set the scalar value variable C.
-    *
-    * In addition, disregard any previous C
-    * specified by setCConstant().
-    */
-   void
-   setCPatchDataId(
-      int id);
-
-   /*!
-    * @brief Set the patch data index for variable C.
-    *
-    * In addition, disregard any previous C
-    * specified by setCConstant().
-    */
-   void
-   setCConstant(
-      double scalar);
-
-   //@}
-
-   //@{ @name Functions for setting solver mathematic algorithm controls
-
-   /*!
-    * @brief Set coarse level solver.
-    *
-    * Select from these:
-    * - @c "Tackley"
-    * - @c "Gerya"
-    * - @c "hypre" (only if the HYPRE library is available).
-    */
-   void
-   setCoarsestLevelSolverChoice(
-      const std::string& choice);
-
-   /*!
-    * @brief Set tolerance for coarse level solve.
-    *
-    * If the coarse level solver requires a tolerance
-    * (currently, they all do), the specified value is used.
-    */
-   void
-   setCoarsestLevelSolverTolerance(
-      double tol);
-
-   /*!
-    * @brief Set max iterations for coarse level solve.
-    *
-    * If the coarse level solver requires a max iteration limit
-    * (currently, they all do), the specified value is used.
-    */
-   void
-   setCoarsestLevelSolverMaxIterations(
-      int max_iterations);
-
-#ifdef HAVE_HYPRE
-   /*!
-    * @brief Set whether to use HYPRe's PFMG algorithm instead of the
-    * SMG algorithm.
-    *
-    * The flag is used to select which of HYPRE's linear solver algorithms
-    * to use if true, the semicoarsening multigrid algorithm is used, and if
-    * false, the ``PF'' multigrid algorithm is used.
-    * By default, the SMG algorithm is used.
-    *
-    * This setting has effect only when HYPRe is chosen for the coarsest
-    * level solver.  See setCoarsestLevelSolverChoice().
-    *
-    * Changing the algorithm must be done before setting up the matrix
-    * coefficients.
-    */
-   void
-   setUseSMG(
-      bool use_smg);
-#endif
-
-   /*!
-    * @brief Set the coarse-fine boundary discretization method.
-    *
-    * Specify the @c op_name std::string which will be passed to
-    * xfer::Geometry::lookupRefineOperator() to get the operator
-    * for setting fine grid ghost cells from the coarse grid.
-    * Note that chosing this operator implicitly choses the
-    * discretization method at the coarse-fine boundary.
-    *
-    * There is one important instance where this std::string is
-    * @em not passed to xfer::Geometry::lookupRefineOperator().
-    * If this variable is set to "Ewing", a constant refinement
-    * method is used along with Ewing's correction.
-    * For a reference to the correction method, see
-    * "Local Refinement Techniques for Elliptic Problems on Cell-Centered
-    * Grids, I. Error Analysis", Mathematics of Computation, Vol. 56, No. 194,
-    * April 1991, pp. 437-461.
-    *
-    * @param coarsefine_method String selecting the coarse-fine discretization method.
-    */
-   void
-   setCoarseFineDiscretization(
-      const std::string& coarsefine_method);
-
-   /*!
-    * @brief Set the name of the prolongation method.
-    *
-    * Specify the @c op_name std::string which will be passed to
-    * xfer::Geometry::lookupRefineOperator() to get the operator
-    * for prolonging the coarse-grid correction.
-    *
-    * By default, "CONSTANT_REFINE" is used.  "LINEAR_REFINE" seems to
-    * to lead to faster convergence, but it does NOT satisfy the Galerkin
-    * condition.
-    *
-    * Prolonging using linear refinement requires a Robin bc
-    * coefficient implementation that is capable of delivering
-    * coefficients for non-hierarchy data, because linear refinement
-    * requires boundary conditions to be set on temporary levels.
-    *
-    * @param prolongation_method String selecting the coarse-fine discretization method.
-    */
-   void
-   set_P_ProlongationMethod(
-      const std::string& prolongation_method);
-
-   void
-   set_V_ProlongationMethod(
-      const std::string& prolongation_method);
-
-   /*!
-    * @brief Set the number of pre-smoothing sweeps during
-    * FAC iteration process.
-    *
-    * Presmoothing is applied during the fine-to-coarse phase of the
-    * iteration.  The default is to use one sweep.
-    *
-    * @param num_pre_sweeps Number of presmoothing sweeps
-    */
-   void
-   setPresmoothingSweeps(
-      int num_pre_sweeps);
-
-   /*!
-    * @brief Set the number of post-smoothing sweeps during
-    * FAC iteration process.
-    *
-    * Postsmoothing is applied during the coarse-to-fine phase of the
-    * iteration.  The default is to use one sweep.
-    *
-    * @param num_post_sweeps Number of postsmoothing sweeps
-    */
-   void
-   setPostsmoothingSweeps(
-      int num_post_sweeps);
-
-   /*!
-    * @brief Set the max number of iterations (cycles) to use per solve.
-    */
-   void
-   setMaxCycles(
-      int max_cycles);
-
-   /*!
-    * @brief Set the residual tolerance for stopping.
-    *
-    * If you want the prescribed maximum number of cycles to always be taken,
-    * set the residual tolerance to a negative number.
-    */
-   void
-   setResidualTolerance(
-      double residual_tol);
-
-   //@}
-
-   /*!
-    * @brief Prepare the solver's internal state for solving
-    *
-    * In the interest of efficiency, this class may prepare and
-    * cache some hierarchy-dependent objects.  Though it is not required,
-    * initializing the solver state makes for greater efficiency
-    * when you are doing multiple solves on the same system of
-    * equation.  If you do not initialize the state, it is initialized
-    * and deallocated each time you call solveSystem(const int, const int).
-    * The state must be reinitialized if the hierarchy or a boundary
-    * condition type changes.
-    *
-    * To unset the data set in this function,
-    * see deallocateSolverState().
-    *
-    * The @c solution and @c rhs patch data indices in the argument
-    * list are used to determine the @em form of the data you
-    * plan to use in the solve.  They need not be the same data
-    * you solve on, but they should be similar.  Both must represent
-    * cell-centered double data.  The solution must have at least one
-    * ghost cell width, though this is not checked in the initialize
-    * phase, because data is not required yet.
-    *
-    * @param solution solution patch data index for u
-    * @param rhs right hand side patch data index for f
-    * @param hierarchy The patch hierarchy to solve on
-    * @param coarse_level The coarsest level in the solve
-    * @param fine_level The finest level in the solve
-    */
-   void
-   initializeSolverState(const int p,
-                         const int cell_moduli,
-                         const int edge_moduli,
-                         const int dp,
-                         const int p_rhs,
-                         const int v,
-                         const int v_rhs,
-                         tbox::Pointer<hier::PatchHierarchy> hierarchy,
-                         const int coarse_level = -1,
-                         const int fine_level = -1);
-
-   /*!
-    * @brief Remove the solver's internal state data
-    *
-    * Remove all hierarchy-dependent data set by initializeSolverState.
-    * It is safe to call deallocateSolverState() even state is already
-    * deallocated, but nothing is done in that case.
-    *
-    * @see initializeSolverState()
-    */
-   void
-   deallocateSolverState();
-
-   //@{
-   //! @name Functions to get data on last solve.
-
-   /*!
-    * @brief Return FAC iteration count from last (or current
-    * if there is one) FAC iteration process.
-    */
-   int
-   getNumberOfIterations() const;
-
-   /*!
-    * @brief Get average convergance rate and convergence rate of
-    * the last (or current if there is one) FAC solve.
-    *
-    * @param avg_factor average convergence factor over current FAC cycles
-    * @param final_factor convergence factor of the last FAC cycle
-    */
-   void
-   getConvergenceFactors(
-      double& avg_factor,
-      double& final_factor) const;
-
-   /*!
-    * @brief Return residual norm from the just-completed FAC iteration.
-    *
-    * The norm return value is computed as the maximum norm over all
-    * patch levels involved in the solve.  The value corresponds to the
-    * norm applied in the user-defined residual computation.
-    *
-    * The latest computed norm is the one returned.
-    */
-   double
-   getResidualNorm() const;
-
-  void set_boundaries(const int &p_id, const int &v_id,
-                      tbox::Pointer<hier::PatchLevel> &level,
-                      const bool &homogeneous)
-  {
-    d_fac_ops.set_boundaries(p_id,v_id,level,homogeneous);
-  }
-
-
-   //@}
-
-private:
-   /*!
-    * @brief Set state using database
-    *
-    * See the class description for the parameters that can be set
-    * from a database.
-    *
-    * @param database Input database.  If a NULL pointer is given,
-    * nothing is done.
-    */
-   void
-   getFromInput(
-      tbox::Pointer<tbox::Database> database);
-
-   /*
-    * @brief Set @c d_uv and @c d_fv to vectors wrapping the data
-    * specified by patch data indices u and f.
-    */
-   void
-   createVectorWrappers(int p, int p_rhs, int v, int v_rhs);
-
-   /*
-    * @brief Destroy vector wrappers referenced to by @c d_uv and @c d_fv.
-    */
-   void
-   destroyVectorWrappers();
-
-   /*
-    * @brief Initialize static members
-    */
-   static void
-   initializeStatics();
-
-   const tbox::Dimension d_dim;
-
-   /*!
-    * @brief Object name.
-    */
-   std::string d_object_name;
-
-   /*!
-    * @brief FAC operator implementation corresponding to cell-centered
-    * Elastic discretization.
-    */
-   ElasticFACOps d_fac_ops;
-
-   /*!
-    * @brief FAC preconditioner algorithm.
-    */
-   FACPreconditioner d_fac_precond;
-
-   /*!
-    * @brief Robin bc object in use.
-    */
-   const RobinBcCoefStrategy* d_bc_object;
-
-   /*
-    * @brief Default implementation of RobinBcCoefStrategy
-    */
-   SimpleCellRobinBcCoefs d_simple_bc;
-
-   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
-   int d_ln_min;
-   int d_ln_max;
-
-   /*!
-    * @brief Context for all internally maintained data.
-    */
-   tbox::Pointer<hier::VariableContext> d_context;
-   /*
-    * @brief Vector wrapper for solution.
-    * @see createVectorWrappers(), destroyVectorWrappers()
-    */
-   tbox::Pointer<SAMRAIVectorReal<double> > d_uv;
-   /*
-    * @brief Vector wrapper for source.
-    * @see createVectorWrappers(), destroyVectorWrappers()
-    */
-   tbox::Pointer<SAMRAIVectorReal<double> > d_fv;
-
-   bool d_solver_is_initialized;
-   bool d_enable_logging;
-
-   static bool s_initialized;
-   static int s_weight_id[SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-   static int s_instance_counter[SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-};
-
-}
-}
-
-#ifdef SAMRAI_INLINE
-#include "ElasticFACSolver.I"
-#endif
-
-#endif  // included_solv_ElasticFACSolver
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/ElasticFACSolver.C
--- a/src/ElasticFACSolver/ElasticFACSolver.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar elastic equation. 
- *
- ************************************************************************/
-#ifndef included_solv_ElasticFACSolver_C
-#define included_solv_ElasticFACSolver_C
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-#ifndef SAMRAI_INLINE
-#include "ElasticFACSolver.I"
-#endif
-
-namespace SAMRAI {
-  namespace solv {
-
-    /*
-*************************************************************************
-*                                                                       *
-* Initialize the static data members.                                   *
-*                                                                       *
-*************************************************************************
-*/
-
-    bool ElasticFACSolver::s_initialized = 0;
-    int ElasticFACSolver::s_weight_id[SAMRAI::tbox::Dimension::
-                                     MAXIMUM_DIMENSION_VALUE];
-    int ElasticFACSolver::s_instance_counter[SAMRAI::tbox::Dimension::
-                                            MAXIMUM_DIMENSION_VALUE];
-
-    /*
-*************************************************************************
-*                                                                       *
-* Constructor sets uninitialized solver state.                          *
-* Set default iteration and convergence parameters.                     *
-*                                                                       *
-* By default settings:                                                  *
-*   - Elastic equation specified has D=1, C=0.                          *
-*   - State is uninitialized                                            *
-*   - Logging is disabled                                               *
-*   - Context for internal data is set based on object name.            *
-*                                                                       *
-*************************************************************************
-*/
-
-    ElasticFACSolver::ElasticFACSolver(const tbox::Dimension& dim,
-                                       const std::string& object_name,
-                                       tbox::Pointer<tbox::Database> database):
-      d_dim(dim),
-      d_object_name(object_name),
-      d_fac_ops(d_dim, object_name + "::fac_ops",database),
-      d_fac_precond(object_name + "::fac_precond", d_fac_ops),
-      d_bc_object(NULL),
-      d_simple_bc(d_dim, object_name + "::bc"),
-      d_hierarchy(NULL),
-      d_ln_min(-1),
-      d_ln_max(-1),
-      d_context(hier::VariableDatabase::getDatabase()
-                ->getContext(object_name + "::CONTEXT")),
-      d_uv(NULL),
-      d_fv(NULL),
-      d_solver_is_initialized(false),
-      d_enable_logging(false)
-    {
-
-      if (!s_initialized) {
-        initializeStatics();
-      }
-
-      setMaxCycles(10);
-      setResidualTolerance(1e-6);
-      setPresmoothingSweeps(1);
-      setPostsmoothingSweeps(1);
-      setCoarseFineDiscretization("Ewing");
-// #ifdef HAVE_HYPRE
-//       setCoarsestLevelSolverChoice("hypre");
-//       setCoarsestLevelSolverTolerance(1e-10);
-//       setCoarsestLevelSolverMaxIterations(20);
-//       setUseSMG(true);
-// #else
-      setCoarsestLevelSolverChoice("Tackley");
-      setCoarsestLevelSolverTolerance(1e-8);
-      setCoarsestLevelSolverMaxIterations(10);
-// #endif
-
-      /*
-       * Construct integer tag variables and add to variable database.  Note that
-       * variables and patch data indices are shared among all instances.
-       * The VariableDatabase holds the variables, once contructed and
-       * registered via the VariableDatabase::registerInternalSAMRAIVariable()
-       * function call.  Note that variables are registered and patch data indices
-       * are made only for the first time through the constructor.
-       */
-      hier::VariableDatabase* var_db = hier::VariableDatabase::getDatabase();
-
-      {
-        static std::string cell_weight_name("ElasticFACSolver_cell_weight");
-
-        tbox::Pointer<pdat::CellVariable<double> >
-          weight = var_db->getVariable(cell_weight_name);
-        if (weight.isNull()) {
-          weight = new pdat::CellVariable<double>(d_dim, cell_weight_name, 1);
-        }
-
-        if (s_weight_id[d_dim.getValue() - 1] < 0) {
-          s_weight_id[d_dim.getValue() - 1] =
-            var_db->registerInternalSAMRAIVariable
-            (weight,hier::IntVector::getZero(d_dim));
-        }
-      }
-
-      {
-        static std::string side_weight_name("ElasticFACSolver_side_weight");
-
-        tbox::Pointer<pdat::SideVariable<double> >
-          weight = var_db->getVariable(side_weight_name);
-        if (weight.isNull()) {
-          weight = new pdat::SideVariable<double>(d_dim, side_weight_name, 1);
-        }
-
-        if (s_weight_id[d_dim.getValue() - 2] < 0) {
-          s_weight_id[d_dim.getValue() - 2] =
-            var_db->registerInternalSAMRAIVariable
-            (weight,hier::IntVector::getZero(d_dim));
-        }
-      }
-
-      // /*
-      //  * The default RobinBcCoefStrategy used,
-      //  * SimpleCellRobinBcCoefs only works with constant refine
-      //  * for prolongation.  So we use constant refinement
-      //  * for prolongation by default.
-      //  */
-      // setProlongationMethod("CONSTANT_REFINE");
-
-      /*
-       * The FAC operator optionally uses the preconditioner
-       * to get data for logging.
-       */
-      d_fac_ops.setPreconditioner((const FACPreconditioner *)(&d_fac_precond));
-
-      if (database) {
-        getFromInput(database);
-      }
-
-      s_instance_counter[d_dim.getValue() - 1]++;
-    }
-
-  }
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/ElasticFACSolver_Destructor.C
--- a/src/ElasticFACSolver/ElasticFACSolver_Destructor.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-    /*
-*************************************************************************
-*                                                                       *
-* Destructor for ElasticFACSolver.                            *
-* Deallocate internal data.                                             *
-*                                                                       *
-*************************************************************************
-*/
-    ElasticFACSolver::~ElasticFACSolver()
-    {
-      s_instance_counter[d_dim.getValue() - 1]--;
-      deallocateSolverState();
-      if (s_instance_counter[d_dim.getValue() - 1] == 0) {
-        hier::VariableDatabase::getDatabase()->
-          removeInternalSAMRAIVariablePatchDataIndex(s_weight_id[d_dim.getValue() - 1]);
-        s_weight_id[d_dim.getValue() - 1] = -1;
-      }
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/createVectorWrappers.C
--- a/src/ElasticFACSolver/createVectorWrappers.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-void SAMRAI::solv::ElasticFACSolver::createVectorWrappers(int p, int p_rhs,
-                                                         int v, int v_rhs) {
-
-  hier::VariableDatabase& vdb(*hier::VariableDatabase::getDatabase());
-  tbox::Pointer<hier::Variable> variable;
-
-  if (!d_uv || d_uv->getComponentDescriptorIndex(0) != p) {
-    d_uv.setNull();
-    d_uv = new SAMRAIVectorReal<double>(d_object_name + "::uv",
-                                        d_hierarchy,
-                                        d_ln_min,
-                                        d_ln_max);
-    /* Add p */
-    vdb.mapIndexToVariable(p, variable);
-#ifdef DEBUG_CHECK_ASSERTIONS
-    if (!variable) {
-      TBOX_ERROR(d_object_name << ": No variable for patch data index "
-                 << p << "\n");
-    }
-    tbox::Pointer<pdat::CellVariable<double> > cell_variable = variable;
-    if (!cell_variable) {
-      TBOX_ERROR(d_object_name << ": hier::Patch data index " << p
-                 << " is not a cell-double variable.\n");
-    }
-#endif
-    d_uv->addComponent(variable, p, s_weight_id[d_dim.getValue() - 1]);
-
-    /* Add v */
-    vdb.mapIndexToVariable(v, variable);
-#ifdef DEBUG_CHECK_ASSERTIONS
-    if (!variable) {
-      TBOX_ERROR(d_object_name << ": No variable for patch data index "
-                 << v << "\n");
-    }
-    tbox::Pointer<pdat::SideVariable<double> > side_variable = variable;
-    if (!side_variable) {
-      TBOX_ERROR(d_object_name << ": hier::Patch data index " << v
-                 << " is not a side-double variable.\n");
-    }
-#endif
-    d_uv->addComponent(variable, v);
-  }
-
-  if (!d_fv || d_fv->getComponentDescriptorIndex(0) != p_rhs) {
-    d_fv.setNull();
-    d_fv = new SAMRAIVectorReal<double>(d_object_name + "::fv",
-                                        d_hierarchy,
-                                        d_ln_min,
-                                        d_ln_max);
-    /* Add p_rhs */
-    vdb.mapIndexToVariable(p_rhs, variable);
-#ifdef DEBUG_CHECK_ASSERTIONS
-    if (!variable) {
-      TBOX_ERROR(d_object_name << ": No variable for patch data index "
-                 << p_rhs << "\n");
-    }
-    tbox::Pointer<pdat::CellVariable<double> > cell_variable = variable;
-    if (!cell_variable) {
-      TBOX_ERROR(d_object_name << ": hier::Patch data index " << p_rhs
-                 << " is not a cell-double variable.\n");
-    }
-#endif
-    d_fv->addComponent(variable, p_rhs, s_weight_id[d_dim.getValue() - 1]);
-
-    /* Add v_rhs */
-    vdb.mapIndexToVariable(v_rhs, variable);    
-#ifdef DEBUG_CHECK_ASSERTIONS
-    if (!variable) {
-      TBOX_ERROR(d_object_name << ": No variable for patch data index "
-                 << v_rhs << "\n");
-    }
-    tbox::Pointer<pdat::SideVariable<double> > side_variable = variable;
-    if (!side_variable) {
-      TBOX_ERROR(d_object_name << ": hier::Patch data index " << v_rhs
-                 << " is not a cell-double variable.\n");
-    }
-#endif
-    d_fv->addComponent(variable, v_rhs);
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/deallocateSolverState.C
--- a/src/ElasticFACSolver/deallocateSolverState.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-    void ElasticFACSolver::deallocateSolverState()
-    {
-      if (d_hierarchy) {
-
-        d_fac_precond.deallocateSolverState();
-
-        /*
-         * Delete internally managed data.
-         */
-        int ln;
-        for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
-          d_hierarchy->getPatchLevel(ln)->deallocatePatchData(s_weight_id[d_dim.getValue()
-                                                                          - 1]);
-        }
-
-        d_hierarchy.setNull();
-        d_ln_min = -1;
-        d_ln_max = -1;
-        d_solver_is_initialized = false;
-
-        destroyVectorWrappers();
-
-      }
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/destroyVectorWrappers.C
--- a/src/ElasticFACSolver/destroyVectorWrappers.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-    /*
-***********************************************************************
-* Delete the vector wrappers.  Do not freeVectorComponents because    *
-* we do not control their data allocation.  The user does that.       *
-***********************************************************************
-*/
-    void ElasticFACSolver::destroyVectorWrappers() {
-      d_uv.setNull();
-      d_fv.setNull();
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/enableLogging.C
--- a/src/ElasticFACSolver/enableLogging.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-
-    /*
-*************************************************************************
-* Enable logging and propagate logging flag to major components.        *
-*************************************************************************
-*/
-
-    void ElasticFACSolver::enableLogging(
-                                        bool logging)
-    {
-      d_enable_logging = logging;
-      d_fac_precond.enableLogging(d_enable_logging);
-      d_fac_ops.enableLogging(d_enable_logging);
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/getFromInput.C
--- a/src/ElasticFACSolver/getFromInput.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-
-    /*
-********************************************************************
-* Set state from database                                          *
-*                                                                  *
-* Do not allow FAC preconditioner and Elastic FAC operators to be  *
-* set from database, as that may cause them to be inconsistent     *
-* with this object if user does not coordinate the inputs          *
-* correctly.  This is also why we don't allow direct access to     *
-* those objects.  The responsibility for maintaining consistency   *
-* lies in the public functions to set parameters, so use them      *
-* instead of setting the parameters directly in this function.     *
-********************************************************************
-*/
-
-    void ElasticFACSolver::getFromInput(
-                                       tbox::Pointer<tbox::Database> database)
-    {
-      if (database) {
-        if (database->isBool("enable_logging")) {
-          bool logging = database->getBool("enable_logging");
-          enableLogging(logging);
-        }
-        if (database->isInteger("max_cycles")) {
-          int max_cycles = database->getInteger("max_cycles");
-          setMaxCycles(max_cycles);
-        }
-        if (database->isDouble("residual_tol")) {
-          double residual_tol = database->getDouble("residual_tol");
-          setResidualTolerance(residual_tol);
-        }
-        if (database->isInteger("num_pre_sweeps")) {
-          int num_pre_sweeps = database->getInteger("num_pre_sweeps");
-          setPresmoothingSweeps(num_pre_sweeps);
-        }
-        if (database->isInteger("num_post_sweeps")) {
-          int num_post_sweeps = database->getInteger("num_post_sweeps");
-          setPostsmoothingSweeps(num_post_sweeps);
-        }
-        if (database->isString("coarse_fine_discretization")) {
-          std::string s = database->getString("coarse_fine_discretization");
-          setCoarseFineDiscretization(s);
-        }
-        if (database->isString("p_prolongation_method")) {
-          std::string s = database->getString("p_prolongation_method");
-          set_P_ProlongationMethod(s);
-        }
-        if (database->isString("v_prolongation_method")) {
-          std::string s = database->getString("v_prolongation_method");
-          set_V_ProlongationMethod(s);
-        }
-        if (database->isString("coarse_solver_choice")) {
-          std::string s = database->getString("coarse_solver_choice");
-          setCoarsestLevelSolverChoice(s);
-        }
-        if (database->isDouble("coarse_solver_tolerance")) {
-          double tol = database->getDouble("coarse_solver_tolerance");
-          setCoarsestLevelSolverTolerance(tol);
-        }
-        if (database->isInteger("coarse_solver_max_iterations")) {
-          int itr = database->getInteger("coarse_solver_max_iterations");
-          setCoarsestLevelSolverMaxIterations(itr);
-        }
-#ifdef HAVE_HYPRE
-        if (database->isBool("use_smg")) {
-          bool smg = database->getBool("use_smg");
-          setUseSMG(smg);
-        }
-#endif
-      }
-    }
-
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/initializeSolverState.C
--- a/src/ElasticFACSolver/initializeSolverState.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-/*
-*************************************************************************
-*                                                                       *
-* Prepare internal data for solve.                                      *
-* Allocate scratch data.  Create vectors for u and f                    *
-* required by the FACPreconditioner interface.                    *
-* Set up internal boundary condition object.                            *
-* Share data to coordinate with FAC preconditioner and                  *
-* Elastic FAC operator.                                                 *
-*                                                                       *
-*************************************************************************
-*/
-
-void SAMRAI::solv::ElasticFACSolver::initializeSolverState
-(const int p,
- const int cell_moduli,
- const int edge_moduli,
- const int dp,
- const int p_rhs,
- const int v,
- const int v_rhs,
- tbox::Pointer<hier::PatchHierarchy> hierarchy,
- const int coarse_level,
- const int fine_level)
-{
-  TBOX_ASSERT(!hierarchy.isNull());
-  TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
-
-  if (d_bc_object == NULL) {
-    TBOX_ERROR(
-               d_object_name << ": No BC coefficient strategy object!\n"
-               <<
-               "Use either setBoundaries or setPhysicalBcCoefObject\n"
-               << "to specify the boundary conidition.\n");
-  }
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (p < 0 || p_rhs < 0) {
-    TBOX_ERROR(d_object_name << ": Bad patch data id.\n");
-  }
-#endif
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (!hierarchy) {
-    TBOX_ERROR(d_object_name << ": NULL hierarchy pointer not allowed\n"
-               << "in inititialization.");
-  }
-#endif
-  d_hierarchy = hierarchy;
-
-  d_ln_min = coarse_level;
-  d_ln_max = fine_level;
-  if (d_ln_min == -1) {
-    d_ln_min = 0;
-  }
-  if (d_ln_max == -1) {
-    d_ln_max = d_hierarchy->getFinestLevelNumber();
-  }
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (d_ln_min < 0 || d_ln_max < 0 || d_ln_min > d_ln_max) {
-    TBOX_ERROR(d_object_name << ": Bad range of levels in\n"
-               << "inititialization.\n");
-  }
-#endif
-
-  int ln;
-  for (ln = d_ln_min; ln <= d_ln_max; ++ln) {
-    d_hierarchy->getPatchLevel(ln)->allocatePatchData(s_weight_id[d_dim.getValue() - 1]);
-  }
-
-  d_fac_ops.computeVectorWeights(d_hierarchy,
-                                 s_weight_id[d_dim.getValue() - 1],
-                                 d_ln_min,
-                                 d_ln_max);
-
-  if (d_bc_object == &d_simple_bc) {
-    d_simple_bc.setHierarchy(d_hierarchy,
-                             d_ln_min,
-                             d_ln_max);
-  }
-
-  d_fac_ops.set_moduli_id(cell_moduli,edge_moduli);
-
-  createVectorWrappers(p, p_rhs, v, v_rhs);
-
-  d_fac_precond.initializeSolverState(*d_uv, *d_fv);
-
-  d_solver_is_initialized = true;
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/initializeStatics.C
--- a/src/ElasticFACSolver/initializeStatics.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-    void ElasticFACSolver::initializeStatics() {
-
-      for (int d = 0; d < SAMRAI::tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
-        s_weight_id[d] = -1;
-        s_instance_counter[d] = -1;
-      }
-
-      s_initialized = 1;
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/setBcObject.C
--- a/src/ElasticFACSolver/setBcObject.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-
-    void ElasticFACSolver::setBcObject(
-                                      const RobinBcCoefStrategy* bc_object)
-    {
-#ifdef DEBUG_CHECK_ASSERTIONS
-      if (!bc_object) {
-        TBOX_ERROR(d_object_name << ": NULL pointer for boundary condition\n"
-                   << "object.\n");
-      }
-#endif
-      d_bc_object = bc_object;
-      // d_fac_ops.setPhysicalBcCoefObject(d_bc_object);
-    }
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/setBoundaries.C
--- a/src/ElasticFACSolver/setBoundaries.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-namespace SAMRAI {
-  namespace solv {
-
-    void ElasticFACSolver::setBoundaries(
-                                        const std::string& boundary_type,
-                                        const int fluxes,
-                                        const int flags,
-                                        int* bdry_types)
-    {
-#ifdef DEBUG_CHECK_ASSERTIONS
-      if (d_bc_object != NULL && d_bc_object != &d_simple_bc) {
-        TBOX_ERROR(
-                   d_object_name << ": Bad attempt to set boundary condition\n"
-                   <<
-                   "by using default bc object after it has been overriden.\n");
-      }
-#endif
-      d_simple_bc.setBoundaries(boundary_type,
-                                fluxes,
-                                flags,
-                                bdry_types);
-      d_bc_object = &d_simple_bc;
-      // d_fac_ops.setPhysicalBcCoefObject(d_bc_object);
-    }
-
-
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticFACSolver/solveSystem.C
--- a/src/ElasticFACSolver/solveSystem.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   High-level solver (wrapper) for scalar Elastic equation. 
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "ElasticFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-/*
-*************************************************************************
-*                                                                       *
-* Solve the linear system and report whether iteration converged.       *
-*                                                                       *
-* This version is for an initialized solver state.                      *
-* Before solving, set the final piece of the boundary condition,        *
-* which is not known until now, and initialize some internal            *
-* solver quantities.                                                    *
-*                                                                       *
-*************************************************************************
-*/
-
-bool SAMRAI::solv::ElasticFACSolver::solveSystem(const int p,
-                                                const int p_rhs,
-                                                const int v, const int v_rhs)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (!d_solver_is_initialized) {
-    TBOX_ERROR(
-               d_object_name << ".solveSystem(int,int): uninitialized\n"
-               <<
-               "solver state.  You must call initializeSolverState()\n"
-               <<
-               "before using this function.  Or you can use\n"
-               <<
-               "solveSystem(int,int,...) to initialize the solver,\n"
-               << "solve and deallocate the solver.\n");
-  }
-  if (p < 0 || p_rhs < 0 || v < 0 || v_rhs < 0) {
-    TBOX_ERROR(d_object_name << ": Bad patch data id.\n");
-  }
-#endif
-  if (d_bc_object == &d_simple_bc) {
-    /*
-     * Knowing that we are using the SimpelCellRobinBcCoefsX
-     * implementation of RobinBcCoefStrategy, we must save
-     * the ghost data in u before solving.
-     * The solver overwrites it, but SimpleCellRobinBcCoefs
-     * needs to get to access it repeatedly.
-     */
-    d_simple_bc.cacheDirichletData(p);
-  }
-
-  createVectorWrappers(p, p_rhs, v, v_rhs);
-  bool solver_rval;
-
-  solver_rval = d_fac_precond.solveSystem(*d_uv, *d_fv);
-
-  return solver_rval;
-}
-
-/*
-*************************************************************************
-*                                                                       *
-* Solve the linear system and report whether iteration converged.       *
-*                                                                       *
-* This version is for an uninitialized solver state.                    *
-* 1. Initialize the (currently uninitialized) solver state.             *
-* 2. Solve.                                                             *
-* 3. Deallocate the solver state.                                       *
-*                                                                       *
-*************************************************************************
-*/
-
-bool SAMRAI::solv::ElasticFACSolver::solveSystem
-(const int p,
- const int cell_moduli,
- const int edge_moduli,
- const int dp,
- const int p_rhs,
- const int v,
- const int v_rhs,
- tbox::Pointer<hier::PatchHierarchy>
- hierarchy,
- int coarse_ln,
- int fine_ln)
-{
-  TBOX_ASSERT(!hierarchy.isNull());
-  TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
-
-  if (d_enable_logging) {
-    tbox::plog << "ElasticFACSolver::solveSystem (" << d_object_name
-               << ")\n";
-  }
-#ifdef DEBUG_CHECK_ASSERTIONS
-  if (d_solver_is_initialized) {
-    TBOX_ERROR(
-               d_object_name << ".solveSystem(int,int,...): initialized\n"
-               <<
-               "solver state.  This function can only used when the\n"
-               <<
-               "solver state is uninitialized.  You should deallocate\n"
-               <<
-               "the solver state or use solveSystem(int,int).\n");
-  }
-  if (!hierarchy) {
-    TBOX_ERROR(d_object_name << ".solveSystem(): Null hierarchy\n"
-               << "specified.\n");
-  }
-#endif
-  initializeSolverState(p, cell_moduli, edge_moduli, dp, p_rhs, v, v_rhs,
-                        hierarchy, coarse_ln, fine_ln);
-
-  bool solver_rval;
-  solver_rval = solveSystem(p, p_rhs, v, v_rhs);
-
-  deallocateSolverState();
-
-  return solver_rval;
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticHypreSolver.C
--- a/src/ElasticHypreSolver.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1549 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Hypre solver interface for diffusion-like elliptic problems. 
- *
- ************************************************************************/
-#ifndef included_solv_ElasticHypreSolver_C
-#define included_solv_ElasticHypreSolver_C
-
-#include "ElasticHypreSolver.h"
-
-#ifdef HAVE_HYPRE
-
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/math/ArrayDataBasicOps.h"
-#include "SAMRAI/math/PatchSideDataBasicOps.h"
-#include "SAMRAI/pdat/ArrayData.h"
-#include "SAMRAI/pdat/CellIndex.h"
-#include "SAMRAI/pdat/CellIterator.h"
-#include "SAMRAI/pdat/FaceIndex.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/SideIndex.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/pdat/OuterfaceData.h"
-#include "SAMRAI/pdat/OutersideData.h"
-#include "SAMRAI/hier/BoundaryBoxUtils.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-#include "SAMRAI/tbox/MathUtilities.h"
-#include "SAMRAI/tbox/SAMRAI_MPI.h"
-#include "SAMRAI/tbox/SAMRAIManager.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Timer.h"
-#include "SAMRAI/tbox/TimerManager.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-#include "SAMRAI/tbox/Utilities.h"
-
-#include <cstdlib>
-
-#ifndef SAMRAI_INLINE
-#include "ElasticHypreSolver.I"
-#endif
-
-extern "C" {
-
-#ifdef __INTEL_COMPILER
-#pragma warning (disable:1419)
-#endif
-
-void F77_FUNC(compdiagvariablec2d, COMPDIAGVARIABLEC2D) (
-   double* diag,
-   const double* c,
-   const double* offdiagi,
-   const double* offdiagj,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(compdiagscalarc2d, COMPDIAGSCALARC2D) (
-   double* diag,
-   const double* c,
-   const double* offdiagi,
-   const double* offdiagj,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(compdiagzeroc2d, COMPDIAGZEROC2D) (
-   double* diag,
-   const double* offdiagi,
-   const double* offdiagj,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(adjbdry2d, ADJBDRY2D) (
-   double* diag,
-   const double* offdiagi,
-   const double* offdiagj,
-   const int* pifirst, const int* pilast,
-   const int* pjfirst, const int* pjlast,
-   const double* acoef,
-   const double* bcoef,
-   const int* aifirst, const int* ailast,
-   const int* ajfirst, const int* ajlast,
-   const double* Ak0,
-   const int* kifirst, const int* kilast,
-   const int* kjfirst, const int* kjlast,
-   const int* lower, const int* upper,
-   const int* location,
-   const double* h);
-void F77_FUNC(adjbdryconstoffdiags2d, ADJBDRYCONSTOFFDIAGS2D) (
-   double* diag,
-   const double* offdiag,
-   const int* pifirst,
-   const int* pilast,
-   const int* pjfirst,
-   const int* pjlast,
-   const double* acoef,
-   const int* aifirst,
-   const int* ailast,
-   const int* ajfirst,
-   const int* ajlast,
-   const double* Ak0,
-   const int* kifirst,
-   const int* kilast,
-   const int* kjfirst,
-   const int* kjlast,
-   const int* lower, const int* upper,
-   const int* location,
-   const double* h);
-void F77_FUNC(adjustrhs2d, ADJUSTRHS2D) (double* rhs,
-   const int* rifirst,
-   const int* rilast,
-   const int* rjfirst,
-   const int* rjlast,
-   const double* Ak0,
-   const int* kifirst,
-   const int* kilast,
-   const int* kjfirst,
-   const int* kjlast,
-   const double* gcoef,
-   const int* aifirst,
-   const int* ailast,
-   const int* ajfirst,
-   const int* ajlast,
-   const int* lower, const int* upper,
-   const int* location);
-
-void F77_FUNC(compdiagvariablec3d, COMPDIAGVARIABLEC3D) (
-   double* diag,
-   const double* c,
-   const double* offdiagi,
-   const double* offdiagj,
-   const double* offdiagk,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const int* kfirst,
-   const int* klast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(compdiagscalarc3d, COMPDIAGSCALARC3D) (
-   double* diag,
-   const double* c,
-   const double* offdiagi,
-   const double* offdiagj,
-   const double* offdiagk,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const int* kfirst,
-   const int* klast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(compdiagzeroc3d, COMPDIAGZEROC3D) (
-   double* diag,
-   const double* offdiagi,
-   const double* offdiagj,
-   const double* offdiagk,
-   const int* ifirst,
-   const int* ilast,
-   const int* jfirst,
-   const int* jlast,
-   const int* kfirst,
-   const int* klast,
-   const double* cscale,
-   const double* dscale);
-void F77_FUNC(adjbdry3d, ADJBDRY3D) (
-   double* diag,
-   const double* offdiagi,
-   const double* offdiagj,
-   const double* offdiagk,
-   const int* pifirst,
-   const int* pilast,
-   const int* pjfirst,
-   const int* pjlast,
-   const int* pkfirst,
-   const int* pklast,
-   const double* acoef,
-   const double* bcoef,
-   const int* aifirst,
-   const int* ailast,
-   const int* ajfirst,
-   const int* ajlast,
-   const int* akfirst,
-   const int* aklast,
-   const double* Ak0,
-   const int* kifirst,
-   const int* kilast,
-   const int* kjfirst,
-   const int* kjlast,
-   const int* kkfirst,
-   const int* kklast,
-   const int* lower, const int* upper,
-   const int* location,
-   const double* h);
-void F77_FUNC(adjbdryconstoffdiags3d, ADJBDRYCONSTOFFDIAGS3D) (
-   double* diag,
-   const double* offdiag,
-   const int* pifirst,
-   const int* pilast,
-   const int* pjfirst,
-   const int* pjlast,
-   const int* pkfirst,
-   const int* pklast,
-   const double* acoef,
-   const int* aifirst,
-   const int* ailast,
-   const int* ajfirst,
-   const int* ajlast,
-   const int* akfirst,
-   const int* aklast,
-   const double* Ak0,
-   const int* kifirst,
-   const int* kilast,
-   const int* kjfirst,
-   const int* kjlast,
-   const int* kkfirst,
-   const int* kklast,
-   const int* lower, const int* upper,
-   const int* location,
-   const double* h);
-void F77_FUNC(adjustrhs3d, ADJUSTRHS3D) (double* rhs,
-   const int* rifirst,
-   const int* rilast,
-   const int* rjfirst,
-   const int* rjlast,
-   const int* rkfirst,
-   const int* rklast,
-   const double* Ak0,
-   const int* kifirst,
-   const int* kilast,
-   const int* kjfirst,
-   const int* kjlast,
-   const int* kkfirst,
-   const int* kklast,
-   const double* gcoef,
-   const int* aifirst,
-   const int* ailast,
-   const int* ajfirst,
-   const int* ajlast,
-   const int* akfirst,
-   const int* aklast,
-   const int* lower, const int* upper,
-   const int* location);
-
-}
-
-namespace SAMRAI {
-namespace solv {
-
-tbox::Pointer<pdat::OutersideVariable<double> >
-ElasticHypreSolver::s_Ak0_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-tbox::StartupShutdownManager::Handler ElasticHypreSolver::s_finalize_handler(
-   0,
-   0,
-   0,
-   ElasticHypreSolver::finalizeCallback,
-   tbox::StartupShutdownManager::priorityVariables);
-
-/*
- *************************************************************************
- * Constructor                                                           *
- *************************************************************************
- */
-
-ElasticHypreSolver::ElasticHypreSolver(
-   const tbox::Dimension& dim,
-   const std::string& object_name,
-   tbox::Pointer<tbox::Database> database):
-   d_dim(dim),
-   d_object_name(object_name),
-   d_hierarchy(NULL),
-   d_ln(-1),
-   d_context(hier::VariableDatabase::getDatabase()->
-             getContext(object_name + "::context")),
-   d_cf_boundary(),
-   d_physical_bc_coef_strategy(&d_physical_bc_simple_case),
-   d_physical_bc_variable(NULL),
-   d_physical_bc_simple_case(dim, d_object_name + "::simple bc"),
-   d_cf_bc_coef(dim, object_name + "::coarse-fine bc coefs"),
-   d_coarsefine_bc_variable(NULL),
-   d_Ak0_id(-1),
-   d_soln_depth(0),
-   d_rhs_depth(0),
-   d_max_iterations(10),
-   d_relative_residual_tol(1e-10),
-   d_number_iterations(-1),
-   d_num_pre_relax_steps(1),
-   d_num_post_relax_steps(1),
-   d_relative_residual_norm(-1.0),
-   d_use_smg(false),
-   d_grid(NULL),
-   d_stencil(NULL),
-   d_matrix(NULL),
-   d_linear_rhs(NULL),
-   d_linear_sol(NULL),
-   d_mg_data(NULL),
-   d_print_solver_info(false)
-{
-   if (d_dim == tbox::Dimension(1) || d_dim > tbox::Dimension(3)) {
-      TBOX_ERROR(" ElasticHypreSolver : DIM == 1 or > 3 not implemented");
-   }
-
-   t_solve_system = tbox::TimerManager::getManager()->
-      getTimer("solv::ElasticHypreSolver::solveSystem()");
-   t_set_matrix_coefficients = tbox::TimerManager::getManager()->
-      getTimer("solv::ElasticHypreSolver::setMatrixCoefficients()");
-
-   hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
-   if (s_Ak0_var[d_dim.getValue() - 1].isNull()) {
-      s_Ak0_var[d_dim.getValue() - 1] = new
-         pdat::OutersideVariable<double>(d_dim, d_object_name + "::Ak0", 1);
-   }
-   d_Ak0_id =
-      vdb->registerVariableAndContext(s_Ak0_var[d_dim.getValue() - 1],
-         d_context,
-         hier::IntVector::getZero(d_dim));
-   if (database) {
-      getFromInput(database);
-   }
-}
-
-/*
- ********************************************************************
- * Set state from database                                          *
- ********************************************************************
- */
-
-void ElasticHypreSolver::getFromInput(
-   tbox::Pointer<tbox::Database> database)
-{
-   if (database) {
-      d_print_solver_info = database->getBoolWithDefault("print_solver_info",
-            d_print_solver_info);
-      d_max_iterations = database->getIntegerWithDefault("max_iterations",
-            d_max_iterations);
-      d_relative_residual_tol = database->getDoubleWithDefault(
-            "relative_residual_tol",
-            d_relative_residual_tol);
-      if (database->isDouble("residual_tol")) {
-         TBOX_ERROR("ElasticHypreSolver input error.\n"
-            << "The parameter 'residual_tol' has been replaced\n"
-            << "by 'relative_residual_tol' to be more descriptive.\n"
-            << "Please change the parameter name in the input database.");
-      }
-      d_num_pre_relax_steps =
-         database->getIntegerWithDefault("num_pre_relax_steps",
-            d_num_pre_relax_steps);
-      if (d_num_pre_relax_steps < 0) {
-         TBOX_ERROR(d_object_name << ": Number of relaxation steps must be\n"
-                                  << "non-negative.\n");
-      }
-      d_num_post_relax_steps =
-         database->getIntegerWithDefault("num_post_relax_steps",
-            d_num_post_relax_steps);
-      if (d_num_post_relax_steps < 0) {
-         TBOX_ERROR(d_object_name << ": Number of relaxation steps must be\n"
-                                  << "non-negative.\n");
-      }
-      if (database->isBool("use_smg")) {
-         bool use_smg = database->getBool("use_smg");
-         if (use_smg != d_use_smg) {
-            setUseSMG(use_smg);
-         }
-      }
-   }
-}
-
-/*
- ********************************************************************
- * Initialize internal data for a given hierarchy level             *
- * After setting internal data, propagate the information           *
- * to the major algorithm objects.  Allocate data for               *
- * storing boundary condition-dependent quantities for              *
- * adding to souce term before solving.                             *
- ********************************************************************
- */
-
-void ElasticHypreSolver::initializeSolverState(
-   tbox::Pointer<hier::PatchHierarchy> hierarchy,
-   int ln)
-{
-   TBOX_ASSERT(!hierarchy.isNull());
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS1(d_dim, *hierarchy);
-
-   deallocateSolverState();
-
-   d_hierarchy = hierarchy;
-   d_ln = ln;
-
-   hier::IntVector max_gcw(d_dim, 1);
-   d_cf_boundary = new hier::CoarseFineBoundary(*d_hierarchy, d_ln, max_gcw);
-
-   d_physical_bc_simple_case.setHierarchy(d_hierarchy, d_ln, d_ln);
-
-   d_number_iterations = -1;
-   d_relative_residual_norm = -1.0;
-
-   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
-   level->allocatePatchData(d_Ak0_id);
-   allocateHypreData();
-}
-
-/*
- ********************************************************************
- * Deallocate data initialized by initializeSolverState             *
- ********************************************************************
- */
-
-void ElasticHypreSolver::deallocateSolverState()
-{
-   if (d_hierarchy.isNull()) return;
-
-   d_cf_boundary->clear();
-   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
-   level->deallocatePatchData(d_Ak0_id);
-   deallocateHypreData();
-   d_hierarchy.setNull();
-   d_ln = -1;
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Allocate the HYPRE data structures that depend only on the level      *
- * and will not change (grid, stencil, matrix, and vectors).             *
- *                                                                       *
- *************************************************************************
- */
-void ElasticHypreSolver::allocateHypreData()
-{
-   tbox::SAMRAI_MPI::Comm communicator = d_hierarchy->getDomainMappedBoxLevel().getMPI().getCommunicator();
-
-   /*
-    * Set up the grid data - only set grid data for local boxes
-    */
-
-   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
-   tbox::Pointer<geom::CartesianGridGeometry> grid_geometry =
-      d_hierarchy->getGridGeometry();
-   const hier::IntVector ratio = level->getRatioToLevelZero();
-   hier::IntVector periodic_shift =
-      grid_geometry->getPeriodicShift(ratio);
-
-   int periodic_flag[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-   int d;
-   bool is_periodic = false;
-   for (d = 0; d < d_dim.getValue(); ++d) {
-      periodic_flag[d] = periodic_shift[d] != 0;
-      is_periodic = is_periodic || periodic_flag[d];
-   }
-
-   HYPRE_StructGridCreate(communicator, d_dim.getValue(), &d_grid);
-   for (hier::PatchLevel::Iterator p(level); p; p++) {
-      const hier::Box& box = (*p)->getBox();
-      hier::Index lower = box.lower();
-      hier::Index upper = box.upper();
-      HYPRE_StructGridSetExtents(d_grid, &lower[0], &upper[0]);
-   }
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-   if (is_periodic) {
-      const hier::BoxArray& level_domain = level->getPhysicalDomain();
-      hier::Box domain_bound(level_domain[0]);
-      for (int i = 1; i < level_domain.size(); ++i) {
-         domain_bound.lower().min(level_domain[i].lower());
-         domain_bound.upper().max(level_domain[i].upper());
-      }
-      for (d = 0; d < d_dim.getValue(); ++d) {
-         if (periodic_flag[d] == true) {
-            int tmpi = 1;
-            unsigned int p_of_two;
-            for (p_of_two = 0; p_of_two < 8 * sizeof(p_of_two) - 1;
-                 ++p_of_two) {
-               if (tmpi == domain_bound.numberCells(d)) {
-                  break;
-               }
-               if (tmpi > domain_bound.numberCells(d)) {
-                  TBOX_ERROR(
-                     d_object_name << ": Hypre currently requires\n"
-                     <<
-                     "that grid size in periodic directions be\n"
-                     <<
-                     "powers of two.  (This requirement may go\n"
-                     <<
-                     "away in future versions of hypre.)\n"
-                     << "Size problem in direction "
-                     << d << "\n"
-                     << "Domain bound is "
-                     << domain_bound << ",\n"
-                     << "Size of "
-                     << domain_bound.numberCells() << "\n");
-               }
-               tmpi = tmpi ? tmpi << 1 : 1;
-            }
-         }
-      }
-   }
-#endif
-
-   HYPRE_StructGridSetPeriodic(d_grid, &periodic_shift[0]);
-   HYPRE_StructGridAssemble(d_grid);
-
-   {
-      /*
-       * Allocate stencil data and set stencil offsets
-       */
-
-      if (d_dim == tbox::Dimension(1)) {
-         const int stencil_size = 2;
-         int stencil_offsets[2][1] = {
-            { -1 }, { 0 }
-         };
-         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
-         for (int s = 0; s < stencil_size; s++) {
-            HYPRE_StructStencilSetElement(d_stencil, s,
-               stencil_offsets[s]);
-         }
-      } else if (d_dim == tbox::Dimension(2)) {
-         const int stencil_size = 3;
-         int stencil_offsets[3][2] = {
-            { -1, 0 }, { 0, -1 }, { 0, 0 }
-         };
-         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
-         for (int s = 0; s < stencil_size; s++) {
-            HYPRE_StructStencilSetElement(d_stencil, s,
-               stencil_offsets[s]);
-         }
-      } else if (d_dim == tbox::Dimension(3)) {
-         const int stencil_size = 4;
-         int stencil_offsets[4][3] = {
-            { -1, 0, 0 }, { 0, -1, 0 }, { 0, 0, -1 }, { 0, 0, 0 }
-         };
-         HYPRE_StructStencilCreate(d_dim.getValue(), stencil_size, &d_stencil);
-         for (int s = 0; s < stencil_size; s++) {
-            HYPRE_StructStencilSetElement(d_stencil, s,
-               stencil_offsets[s]);
-         }
-      }
-   }
-
-   {
-      int full_ghosts1[2 * 3] = { 1, 1, 0, 0, 0, 0 };
-      int no_ghosts1[2 * 3] = { 0, 0, 0, 0, 0, 0 };
-
-      int full_ghosts2[2 * 3] = { 1, 1, 1, 1, 0, 0 };
-      int no_ghosts2[2 * 3] = { 0, 0, 0, 0, 0, 0 };
-
-      int full_ghosts3[2 * 3] = { 1, 1, 1, 1, 1, 1 };
-      int no_ghosts3[2 * 3] = { 0, 0, 0, 0, 0, 0 };
-
-      /*
-       * Allocate the structured matrix
-       */
-
-      int* full_ghosts = NULL;
-      int* no_ghosts = NULL;
-
-      if (d_dim == tbox::Dimension(1)) {
-         full_ghosts = full_ghosts1;
-         no_ghosts = no_ghosts1;
-      } else if (d_dim == tbox::Dimension(2)) {
-         full_ghosts = full_ghosts2;
-         no_ghosts = no_ghosts2;
-      } else if (d_dim == tbox::Dimension(3)) {
-         full_ghosts = full_ghosts3;
-         no_ghosts = no_ghosts3;
-      } else {
-         TBOX_ERROR(
-            "ElasticHypreSolver does not yet support dimension " << d_dim);
-      }
-
-      HYPRE_StructMatrixCreate(communicator,
-         d_grid,
-         d_stencil,
-         &d_matrix);
-      HYPRE_StructMatrixSetNumGhost(d_matrix, full_ghosts);
-      HYPRE_StructMatrixSetSymmetric(d_matrix, 1);
-      HYPRE_StructMatrixInitialize(d_matrix);
-
-      HYPRE_StructVectorCreate(communicator,
-         d_grid,
-         &d_linear_rhs);
-      HYPRE_StructVectorSetNumGhost(d_linear_rhs, no_ghosts);
-      HYPRE_StructVectorInitialize(d_linear_rhs);
-
-      HYPRE_StructVectorCreate(communicator,
-         d_grid,
-         &d_linear_sol);
-      HYPRE_StructVectorSetNumGhost(d_linear_sol, full_ghosts);
-      HYPRE_StructVectorInitialize(d_linear_sol);
-   }
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * The destructor deallocates solver data.                               *
- *                                                                       *
- *************************************************************************
- */
-
-ElasticHypreSolver::~ElasticHypreSolver()
-{
-   deallocateHypreData();
-
-   if (!d_hierarchy.isNull()) {
-      tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(0);
-      level->deallocatePatchData(d_Ak0_id);
-   }
-   hier::VariableDatabase* vdb =
-      hier::VariableDatabase::getDatabase();
-   vdb->removePatchDataIndex(d_Ak0_id);
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Deallocate HYPRE data and solver.  HYPRE requires that we             *
- * check whether HYPRE has already deallocated this data.                *
- * Note that the HYPRE solver, d_mg_data, was created at                 *
- * the end of setMatrixCoefficients.                                     *
- *                                                                       *
- *************************************************************************
- */
-
-void ElasticHypreSolver::deallocateHypreData()
-{
-   if (d_stencil) {
-      HYPRE_StructStencilDestroy(d_stencil);
-      d_stencil = NULL;
-   }
-   if (d_grid) {
-      HYPRE_StructGridDestroy(d_grid);
-      d_grid = NULL;
-   }
-   if (d_matrix) {
-      HYPRE_StructMatrixDestroy(d_matrix);
-      d_matrix = NULL;
-   }
-   if (d_linear_rhs) {
-      HYPRE_StructVectorDestroy(d_linear_rhs);
-      d_linear_rhs = NULL;
-   }
-   if (d_linear_sol) {
-      HYPRE_StructVectorDestroy(d_linear_sol);
-      d_linear_sol = NULL;
-   }
-   destroyHypreSolver();
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Copy data into the HYPRE vector structures.                           *
- *                                                                       *
- *************************************************************************
- */
-
-void ElasticHypreSolver::copyToHypre(
-   HYPRE_StructVector vector,
-   pdat::CellData<double>& src,
-   int depth,
-   const hier::Box& box)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, src, box);
-
-   for (pdat::CellIterator c(box); c; c++) {
-      hier::IntVector ic = c();
-      HYPRE_StructVectorSetValues(vector, &ic[0], src(c(), depth));
-   }
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Copy data out of the HYPRE vector structures.                         *
- *                                                                       *
- *************************************************************************
- */
-
-void ElasticHypreSolver::copyFromHypre(
-   pdat::CellData<double>& dst,
-   int depth,
-   HYPRE_StructVector vector,
-   const hier::Box box)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, dst, box);
-
-   for (pdat::CellIterator c(box); c; c++) {
-      double value;
-      hier::IntVector ic = c();
-      HYPRE_StructVectorGetValues(vector, &ic[0], &value);
-      dst(c(), depth) = value;
-   }
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Set the matrix coefficients for the linear system.                    *
- * The matrix coefficients are dependent on the problem                  *
- * specification described by the ElasticSpecificiations            *
- * object and by the boundary condition.                                 *
- *                                                                       *
- *************************************************************************
- */
-
-void ElasticHypreSolver::setMatrixCoefficients()
-{
-   if (d_physical_bc_coef_strategy == NULL) {
-      TBOX_ERROR(
-         d_object_name << ": No BC coefficient strategy object!\n"
-         <<
-         "Use either setBoundaries or setPhysicalBcCoefObject\n"
-         <<
-         "to specify the boundary conidition.  Do it before\n"
-         << "calling setMatrixCoefficients.");
-   }
-
-   t_set_matrix_coefficients->start();
-
-   int i = 0;
-
-   tbox::Pointer<pdat::CellData<double> > C_data;
-   tbox::Pointer<pdat::SideData<double> > D_data;
-
-   /*
-    * Some computations can be done using high-level math objects.
-    * Define the math objects.
-    */
-   math::ArrayDataBasicOps<double> array_math;
-   math::PatchSideDataBasicOps<double> patch_side_math;
-
-   /*
-    * The value of the ghost cell based on the Robin boundary condition
-    * can be written as the sum of a constant, k0, plus a multiple of the
-    * internal cell value, k1*ui.  k1*ui depends on the value of u so it
-    * contributes to the product Au,
-    * while the constant k0 contributes the right hand side f.
-    * We save Ak0 = A*k0(a) to add to f when solving.
-    * We assume unit g here because we will multiply it in just before
-    * solving, thus allowing everything that does not affect A to change
-    * from solve to solve.
-    */
-   tbox::Pointer<pdat::OutersideData<double> > Ak0;
-
-   /*
-    * Loop over patches and set matrix entries for each patch.
-    */
-   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
-   const hier::IntVector no_ghosts(d_dim, 0);
-   for (hier::PatchLevel::Iterator pi(*level); pi; pi++) {
-
-      hier::Patch& patch = **pi;
-
-      tbox::Pointer<geom::CartesianPatchGeometry> pg =
-         patch.getPatchGeometry();
-
-      const double* h = pg->getDx();
-
-      const hier::Box patch_box = patch.getBox();
-      const hier::Index patch_lo = patch_box.lower();
-      const hier::Index patch_up = patch_box.upper();
-
-      Ak0 = patch.getPatchData(d_Ak0_id);
-
-      Ak0->fillAll(0.0);
-
-      pdat::CellData<double> diagonal(patch_box, 1, no_ghosts);
-
-      /*
-       * Set diagonals to zero so we can accumulate to it.
-       * Accumulation is used at boundaries to shift weights
-       * for ghost cells onto the diagonal.
-       */
-      diagonal.fillAll(0.0);
-
-      const tbox::Pointer<geom::CartesianPatchGeometry>
-      geometry = patch.getPatchGeometry();
-
-      const hier::Index ifirst = patch_box.lower();
-      const hier::Index ilast = patch_box.upper();
-
-      /*
-       * Storage for off-diagonal entries,
-       * which can be variable or constant.
-       */
-      pdat::SideData<double> off_diagonal(patch_box, 1, no_ghosts);
-
-      /*
-       * Compute all off-diagonal entries with no regard to BCs.
-       * These off-diagonal entries are simply D/(h*h), according
-       * to our central difference formula.
-       */
-      for (i = 0; i < d_dim.getValue(); ++i) {
-        hier::Box sbox(patch_box);
-        sbox.growUpper(i, 1);
-        array_math.scale(off_diagonal.getArrayData(i),
-                         1.0 / (h[i] * h[i]),
-                         D_data->getArrayData(i),
-                         sbox);
-      }
-
-      /*
-       * Compute diagonal entries using off-diagonal contributions.
-       */
-      computeDiagonalEntries(diagonal,
-                             *C_data,
-                             off_diagonal,
-                             patch_box);
-
-      /*
-       * Walk physical domain boundaries and adjust off-diagonals
-       * before computation of diagonal entries.
-       * The exterior cell's value is
-       * uo = ( h*gamma + ui*(beta-h*alpha/2) )/( beta+h*alpha/2 )
-       *   = k0 + k1*ui
-       * where k0 = h*gamma/( beta+h*alpha/2 )
-       * k1 = ( beta-h*alpha/2 )/( beta+h*alpha/2 )
-       * Split coupling between interior-exterior cells
-       * into two parts: interior-interior coupling (k1)
-       * and rhs contribution (k0).
-       */
-      {
-         const tbox::Array<hier::BoundaryBox>& surface_boxes =
-            pg->getCodimensionBoundaries(1);
-         const int n_bdry_boxes = surface_boxes.getSize();
-         for (int n = 0; n < n_bdry_boxes; ++n) {
-
-            const hier::BoundaryBox& boundary_box = surface_boxes[n];
-            if (boundary_box.getBoundaryType() != 1) {
-               TBOX_ERROR(
-                  d_object_name << ": Illegal boundary type in "
-                  <<
-                  "ElasticHypreSolver::setMatrixCoefficients\n");
-            }
-            const hier::BoundaryBoxUtils bbu(boundary_box);
-            const int location_index = boundary_box.getLocationIndex();
-            const hier::BoundaryBox trimmed_boundary_box =
-               bbu.trimBoundaryBox(patch.getBox());
-            const hier::Box bccoef_box =
-               bbu.getSurfaceBoxFromBoundaryBox();
-            tbox::Pointer<pdat::ArrayData<double> >
-            acoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
-            tbox::Pointer<pdat::ArrayData<double> >
-            bcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
-            tbox::Pointer<pdat::ArrayData<double> >
-            gcoef_data(NULL);
-            static const double fill_time = 0.0;
-            d_physical_bc_coef_strategy->setBcCoefs(acoef_data,
-               bcoef_data,
-               gcoef_data,
-               d_physical_bc_variable,
-               patch,
-               boundary_box,
-               fill_time);
-            pdat::ArrayData<double>& Ak0_data =
-               Ak0->getArrayData(location_index / 2,
-                  location_index % 2);
-            adjustBoundaryEntries(diagonal,
-               off_diagonal,
-               patch_box,
-               *acoef_data,
-               *bcoef_data,
-               bccoef_box,
-               Ak0_data,
-               trimmed_boundary_box,
-               h);
-         }
-      }
-
-      /*
-       * Walk coarse-fine boundaries and adjust off-diagonals
-       * according data in ghost cells.
-       */
-      if (d_ln > 0) {
-         /*
-          * There are potentially coarse-fine boundaries to deal with.
-          */
-
-         tbox::Array<hier::BoundaryBox> surface_boxes;
-
-         if (d_dim == tbox::Dimension(2)) {
-            surface_boxes = d_cf_boundary->getEdgeBoundaries(pi->getGlobalId());
-         } else if (d_dim == tbox::Dimension(3)) {
-            surface_boxes = d_cf_boundary->getFaceBoundaries(pi->getGlobalId());
-         }
-
-         const int n_bdry_boxes = surface_boxes.getSize();
-         for (int n = 0; n < n_bdry_boxes; ++n) {
-
-            const hier::BoundaryBox& boundary_box = surface_boxes[n];
-            if (boundary_box.getBoundaryType() != 1) {
-               TBOX_ERROR(
-                  d_object_name << ": Illegal boundary type in "
-                  <<
-                  "ElasticHypreSolver::setMatrixCoefficients\n");
-            }
-            const int location_index = boundary_box.getLocationIndex();
-            const hier::BoundaryBoxUtils bbu(boundary_box);
-            const hier::BoundaryBox trimmed_boundary_box =
-               bbu.trimBoundaryBox(patch.getBox());
-            const hier::Box bccoef_box =
-               bbu.getSurfaceBoxFromBoundaryBox();
-            tbox::Pointer<pdat::ArrayData<double> >
-            acoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
-            tbox::Pointer<pdat::ArrayData<double> >
-            bcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
-            tbox::Pointer<pdat::ArrayData<double> >
-            gcoef_data(NULL);
-            static const double fill_time = 0.0;
-            /*
-             * Reset invalid ghost data id to help detect use in setBcCoefs.
-             */
-            d_cf_bc_coef.setGhostDataId(-1, hier::IntVector::getZero(d_dim));
-            d_cf_bc_coef.setBcCoefs(acoef_data,
-               bcoef_data,
-               gcoef_data,
-               d_coarsefine_bc_variable,
-               patch,
-               boundary_box,
-               fill_time);
-            pdat::ArrayData<double>& Ak0_data =
-               Ak0->getArrayData(location_index / 2,
-                  location_index % 2);
-            adjustBoundaryEntries(diagonal,
-               off_diagonal,
-               patch_box,
-               *acoef_data,
-               *bcoef_data,
-               bccoef_box,
-               Ak0_data,
-               trimmed_boundary_box,
-               h);
-         }
-      }
-
-      /*
-       * Copy matrix entries to HYPRE matrix structure.  Note that
-       * we translate our temporary diagonal/off-diagonal storage into the
-       * HYPRE symmetric storage scheme for the stencil specified earlier.
-       */
-      const int stencil_size = d_dim.getValue() + 1;
-      int stencil_indices[stencil_size];
-      double mat_entries[stencil_size];
-
-      for (i = 0; i < stencil_size; i++) stencil_indices[i] = i;
-
-      pdat::CellIterator ic(patch_box);
-
-      /*
-       * To do: This loop uses inefficient high-level syntax.
-       * See if it can be replaced by a Fortran loop or if we
-       * can set matrix entries for an entire box at once.
-       */
-      for ( ; ic; ic++) {
-
-         hier::IntVector icell = ic();
-         pdat::SideIndex ixlower(ic(),
-                                 pdat::SideIndex::X,
-                                 pdat::SideIndex::Lower);
-         mat_entries[0] = (off_diagonal)(ixlower);
-
-         if (d_dim > tbox::Dimension(1)) {
-            pdat::SideIndex iylower(ic(),
-                                    pdat::SideIndex::Y,
-                                    pdat::SideIndex::Lower);
-            mat_entries[1] = (off_diagonal)(iylower);
-         }
-
-         if (d_dim > tbox::Dimension(2)) {
-            pdat::SideIndex izlower(ic(),
-                                    pdat::SideIndex::Z,
-                                    pdat::SideIndex::Lower);
-            // The "funny" indexing prevents a warning when compiling for
-            // DIM < 2.  This code is only reached if DIM > 2 when
-            // executing.
-            mat_entries[d_dim.getValue() > 2 ? 2 : 0] = (off_diagonal)(izlower);
-         }
-
-         mat_entries[d_dim.getValue()] = (diagonal)(ic());
-         HYPRE_StructMatrixSetValues(d_matrix, &icell[0],
-            stencil_size, stencil_indices,
-            mat_entries);
-      } // end cell loop
-
-   } // end patch loop
-
-   if (d_print_solver_info) {
-      HYPRE_StructMatrixPrint("mat_bA.out", d_matrix, 1);
-   }
-
-   HYPRE_StructMatrixAssemble(d_matrix);
-
-   if (d_print_solver_info) {
-      HYPRE_StructMatrixPrint("mat_aA.out", d_matrix, 1);
-   }
-
-   t_set_matrix_coefficients->stop();
-
-   setupHypreSolver();
-}
-
-/*
- **********************************************************************
- * Add g*A*k0(a) from physical boundaries to rhs.                     *
- * This operation is done for physical as well as cf boundaries,      *
- * so it is placed in a function.                                     *
- **********************************************************************
- */
-
-void ElasticHypreSolver::add_gAk0_toRhs(
-   const hier::Patch& patch,
-   const tbox::Array<hier::BoundaryBox>& bdry_boxes,
-   const RobinBcCoefStrategy* robin_bc_coef,
-   pdat::CellData<double>& rhs)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS2(d_dim, patch, rhs);
-
-   /*
-    * g*A*k0(a) is the storage for adjustments to be made to the rhs
-    * when we solve. This is the value of the weight of the ghost cell
-    * value for the interior cell, times k0.  It is independent of u,
-    * and so is moved to the rhs.  Before solving, g*A*k0(a) is added
-    * to rhs.
-    */
-   tbox::Pointer<pdat::OutersideData<double> > Ak0;
-
-   tbox::Pointer<geom::CartesianPatchGeometry> pg =
-      patch.getPatchGeometry();
-
-   Ak0 = patch.getPatchData(d_Ak0_id);
-
-   const int n_bdry_boxes = bdry_boxes.getSize();
-   for (int n = 0; n < n_bdry_boxes; ++n) {
-
-      const hier::BoundaryBox& boundary_box = bdry_boxes[n];
-#ifdef DEBUG_CHECK_ASSERTIONS
-      if (boundary_box.getBoundaryType() != 1) {
-         TBOX_ERROR(d_object_name << ": Illegal boundary type in "
-                                  << "ElasticHypreSolver::add_gAk0_toRhs\n");
-      }
-#endif
-      const int location_index = boundary_box.getLocationIndex();
-      const hier::BoundaryBoxUtils bbu(boundary_box);
-      const hier::BoundaryBox trimmed_boundary_box =
-         bbu.trimBoundaryBox(patch.getBox());
-      const hier::Index& lower = trimmed_boundary_box.getBox().lower();
-      const hier::Index& upper = trimmed_boundary_box.getBox().upper();
-      const hier::Box& rhsbox = rhs.getArrayData().getBox();
-      const hier::Box& Ak0box = Ak0->getArrayData(location_index / 2,
-            location_index % 2).getBox();
-      const hier::Box bccoef_box = bbu.getSurfaceBoxFromBoundaryBox();
-      tbox::Pointer<pdat::ArrayData<double> >
-      acoef_data(NULL);
-      tbox::Pointer<pdat::ArrayData<double> >
-      bcoef_data(NULL);
-      tbox::Pointer<pdat::ArrayData<double> >
-      gcoef_data(new pdat::ArrayData<double>(bccoef_box, 1));
-      static const double fill_time = 0.0;
-      robin_bc_coef->setBcCoefs(acoef_data,
-         bcoef_data,
-         gcoef_data,
-         d_physical_bc_variable,
-         patch,
-         boundary_box,
-         fill_time);
-      /*
-       * Nomenclature for indices: cel=first-cell, gho=ghost,
-       * beg=beginning, end=ending.
-       */
-      if (d_dim == tbox::Dimension(2)) {
-         F77_FUNC(adjustrhs2d, ADJUSTRHS2D) (rhs.getPointer(d_rhs_depth),
-            &rhsbox.lower()[0],
-            &rhsbox.upper()[0],
-            &rhsbox.lower()[1],
-            &rhsbox.upper()[1],
-            Ak0->getPointer(location_index / 2, location_index % 2),
-            &Ak0box.lower()[0],
-            &Ak0box.upper()[0],
-            &Ak0box.lower()[1],
-            &Ak0box.upper()[1],
-            gcoef_data->getPointer(),
-            &bccoef_box.lower()[0],
-            &bccoef_box.upper()[0],
-            &bccoef_box.lower()[1],
-            &bccoef_box.upper()[1],
-            &lower[0], &upper[0],
-            &location_index);
-      } else if (d_dim == tbox::Dimension(3)) {
-         F77_FUNC(adjustrhs3d, ADJUSTRHS3D) (rhs.getPointer(d_rhs_depth),
-            &rhsbox.lower()[0],
-            &rhsbox.upper()[0],
-            &rhsbox.lower()[1],
-            &rhsbox.upper()[1],
-            &rhsbox.lower()[2],
-            &rhsbox.upper()[2],
-            Ak0->getPointer(location_index / 2, location_index % 2),
-            &Ak0box.lower()[0],
-            &Ak0box.upper()[0],
-            &Ak0box.lower()[1],
-            &Ak0box.upper()[1],
-            &Ak0box.lower()[2],
-            &Ak0box.upper()[2],
-            gcoef_data->getPointer(),
-            &bccoef_box.lower()[0],
-            &bccoef_box.upper()[0],
-            &bccoef_box.lower()[1],
-            &bccoef_box.upper()[1],
-            &bccoef_box.lower()[2],
-            &bccoef_box.upper()[2],
-            &lower[0], &upper[0],
-            &location_index);
-      }
-   }
-}
-
-/*
- *************************************************************************
- * Create the hypre solver and set it according to the current state.    *
- *************************************************************************
- */
-void ElasticHypreSolver::setupHypreSolver()
-{
-   TBOX_ASSERT(d_mg_data == NULL);
-
-   tbox::SAMRAI_MPI::Comm communicator = d_hierarchy->getDomainMappedBoxLevel().getMPI().getCommunicator();
-
-   if (d_use_smg) {
-      HYPRE_StructSMGCreate(communicator, &d_mg_data);
-      HYPRE_StructSMGSetMemoryUse(d_mg_data, 0);
-      HYPRE_StructSMGSetMaxIter(d_mg_data, d_max_iterations);
-      HYPRE_StructSMGSetTol(d_mg_data, d_relative_residual_tol);
-      HYPRE_StructSMGSetLogging(d_mg_data, 1);
-      HYPRE_StructSMGSetNumPreRelax(d_mg_data,
-         d_num_pre_relax_steps);
-      HYPRE_StructSMGSetNumPostRelax(d_mg_data,
-         d_num_post_relax_steps);
-      HYPRE_StructSMGSetup(d_mg_data,
-         d_matrix,
-         d_linear_rhs,
-         d_linear_sol);
-   } else {
-      HYPRE_StructPFMGCreate(communicator, &d_mg_data);
-      HYPRE_StructPFMGSetMaxIter(d_mg_data, d_max_iterations);
-      HYPRE_StructPFMGSetTol(d_mg_data, d_relative_residual_tol);
-      HYPRE_StructPFMGSetLogging(d_mg_data, 1);
-      HYPRE_StructPFMGSetNumPreRelax(d_mg_data,
-         d_num_pre_relax_steps);
-      HYPRE_StructPFMGSetNumPostRelax(d_mg_data,
-         d_num_post_relax_steps);
-      HYPRE_StructPFMGSetup(d_mg_data,
-         d_matrix,
-         d_linear_rhs,
-         d_linear_sol);
-   }
-}
-
-void ElasticHypreSolver::destroyHypreSolver()
-{
-   if (d_mg_data != NULL) {
-      if (d_use_smg) {
-         HYPRE_StructSMGDestroy(d_mg_data);
-      } else {
-         HYPRE_StructPFMGDestroy(d_mg_data);
-      }
-      d_mg_data = NULL;
-   }
-}
-
-/*
- *************************************************************************
- *                                                                       *
- * Solve the linear system.  This routine assumes that the boundary      *
- * conditions and the matrix coefficients have been specified.           *
- *                                                                       *
- *************************************************************************
- */
-
-int ElasticHypreSolver::solveSystem(
-   const int u,
-   const int f,
-   bool homogeneous_bc)
-{
-   if (d_physical_bc_coef_strategy == NULL) {
-      TBOX_ERROR(
-         d_object_name << ": No BC coefficient strategy object!\n"
-         <<
-         "Use either setBoundaries or setPhysicalBcCoefObject\n"
-         <<
-         "to specify the boundary conidition.  Do it before\n"
-         << "calling solveSystem.");
-   }
-   // Tracer t("ElasticHypreSolver::solveSystem");
-
-   t_solve_system->start();
-
-   tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(d_ln);
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(u >= 0);
-   TBOX_ASSERT(
-      u < level->getPatchDescriptor()->getMaxNumberRegisteredComponents());
-   TBOX_ASSERT(f >= 0);
-   TBOX_ASSERT(
-      f < level->getPatchDescriptor()->getMaxNumberRegisteredComponents());
-#endif
-
-   if (d_physical_bc_coef_strategy == &d_physical_bc_simple_case) {
-      /*
-       * If we are using the simple bc implementation, the final piece
-       * of information it requires is the Dirichlet boundary value
-       * set in the ghost cells.  Now that we have the ghost cell data,
-       * we can complete the boundary condition setup.
-       */
-      d_physical_bc_simple_case.cacheDirichletData(u);
-   }
-
-   /*
-    * Modify right-hand-side to account for boundary conditions and
-    * copy solution and right-hand-side to HYPRE structures.
-    */
-
-   const hier::IntVector no_ghosts(d_dim, 0);
-   const hier::IntVector ghosts(d_dim, 1);
-
-   /*
-    * At coarse-fine boundaries, we expect ghost cells to have correct
-    * values to be used in our bc, so u provides the ghost cell data.
-    * Assume that the user only provided data for the immediate first
-    * ghost cell, so pass zero for the number of extensions fillable.
-    */
-   d_cf_bc_coef.setGhostDataId(u, hier::IntVector::getZero(d_dim));
-
-   for (hier::PatchLevel::Iterator p(level); p; p++) {
-      tbox::Pointer<hier::Patch> patch = *p;
-
-      const hier::Box box = patch->getBox();
-
-      /*
-       * Set up variable data needed to prepare linear system solver.
-       */
-      tbox::Pointer<pdat::CellData<double> > u_data_ = patch->getPatchData(u);
-#ifdef DEBUG_CHECK_ASSERTIONS
-      TBOX_ASSERT(!u_data_.isNull());
-#endif
-      pdat::CellData<double>& u_data = *u_data_;
-      pdat::CellData<double> rhs_data(box, 1, no_ghosts);
-
-      /*
-       * Copy rhs and solution from the hierarchy into HYPRE structures.
-       * For rhs, add in the contribution from boundary conditions, if
-       * needed.  If boundary condition is homogenous, this only adds
-       * zero, so we skip it.
-       */
-      copyToHypre(d_linear_sol, u_data, d_soln_depth, box);
-      rhs_data.copy(*(patch->getPatchData(f)));
-      if (!homogeneous_bc) {
-         /*
-          * Add g*A*k0(a) from physical and coarse-fine boundaries to rhs.
-          */
-         add_gAk0_toRhs(*patch,
-            patch->getPatchGeometry()->getCodimensionBoundaries(1),
-            d_physical_bc_coef_strategy,
-            rhs_data);
-         add_gAk0_toRhs(*patch,
-            d_cf_boundary->getBoundaries(patch->getGlobalId(), 1),
-            &d_cf_bc_coef,
-            rhs_data);
-      }
-      copyToHypre(d_linear_rhs, rhs_data, d_rhs_depth, box);
-
-   } // end patch loop
-
-   /*
-    * Reset invalid ghost data id to help detect erroneous further use.
-    */
-   d_cf_bc_coef.setGhostDataId(-1, hier::IntVector::getZero(d_dim));
-
-   /*
-    * Finish assembly of the vectors
-    */
-   HYPRE_StructVectorAssemble(d_linear_sol);
-
-   HYPRE_StructVectorAssemble(d_linear_rhs);
-
-   /*
-    * Solve the system - zero means convergence
-    * Solve takes the same arguments as Setup
-    */
-
-   if (d_print_solver_info) {
-      HYPRE_StructVectorPrint("sol0.out", d_linear_sol, 1);
-      HYPRE_StructMatrixPrint("mat0.out", d_matrix, 1);
-      HYPRE_StructVectorPrint("rhs.out", d_linear_rhs, 1);
-   }
-
-   if (d_use_smg) {
-      // HYPRE_StructSMGSetMaxIter(d_mg_data, d_max_iterations);
-      HYPRE_StructSMGSetTol(d_mg_data, d_relative_residual_tol);
-      /* converge = */ HYPRE_StructSMGSolve(d_mg_data,
-         d_matrix,
-         d_linear_rhs,
-         d_linear_sol);
-   } else {
-      // HYPRE_StructPFMGSetMaxIter(d_mg_data, d_max_iterations);
-      HYPRE_StructPFMGSetTol(d_mg_data, d_relative_residual_tol);
-      /* converge = */ HYPRE_StructPFMGSolve(d_mg_data,
-         d_matrix,
-         d_linear_rhs,
-         d_linear_sol);
-   }
-
-   if (d_print_solver_info) {
-      HYPRE_StructMatrixPrint("mat.out", d_matrix, 1);
-      HYPRE_StructVectorPrint("sol.out", d_linear_sol, 1);
-   }
-
-   if (d_use_smg) {
-      HYPRE_StructSMGGetNumIterations(d_mg_data,
-         &d_number_iterations);
-      HYPRE_StructSMGGetFinalRelativeResidualNorm(d_mg_data,
-         &d_relative_residual_norm);
-   } else {
-      HYPRE_StructPFMGGetNumIterations(d_mg_data,
-         &d_number_iterations);
-      HYPRE_StructPFMGGetFinalRelativeResidualNorm(d_mg_data,
-         &d_relative_residual_norm);
-   }
-
-   /*
-    * Pull the solution vector out of the HYPRE structures
-    */
-   for (hier::PatchLevel::Iterator ip(level); ip; ip++) {
-      tbox::Pointer<hier::Patch> patch = *ip;
-      tbox::Pointer<pdat::CellData<double> > u_data_ = patch->getPatchData(u);
-      pdat::CellData<double>& u_data = *u_data_;
-      copyFromHypre(u_data,
-         d_soln_depth,
-         d_linear_sol,
-         patch->getBox());
-   }
-
-   t_solve_system->stop();
-
-   return d_relative_residual_norm <= d_relative_residual_tol;
-}
-
-void ElasticHypreSolver::computeDiagonalEntries(
-   pdat::CellData<double>& diagonal,
-   const pdat::CellData<double>& C_data,
-   const pdat::SideData<double>& off_diagonal,
-   const hier::Box& patch_box)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(d_dim,
-      diagonal,
-      C_data,
-      off_diagonal,
-      patch_box);
-
-   const hier::Index patch_lo = patch_box.lower();
-   const hier::Index patch_up = patch_box.upper();
-   const double c = 1.0, d = 1.0;
-   if (d_dim == tbox::Dimension(2)) {
-      F77_FUNC(compdiagvariablec2d, COMPDIAGVARIABLEC2D) (diagonal.getPointer(),
-         C_data.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &c, &d);
-   } else if (d_dim == tbox::Dimension(3)) {
-      F77_FUNC(compdiagvariablec3d, COMPDIAGVARIABLEC3D) (diagonal.getPointer(),
-         C_data.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         off_diagonal.getPointer(2),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &patch_lo[2], &patch_up[2],
-         &c, &d);
-   }
-}
-
-void ElasticHypreSolver::computeDiagonalEntries(
-   pdat::CellData<double>& diagonal,
-   const double C,
-   const pdat::SideData<double>& off_diagonal,
-   const hier::Box& patch_box)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS3(d_dim, diagonal, off_diagonal, patch_box);
-
-   const hier::Index patch_lo = patch_box.lower();
-   const hier::Index patch_up = patch_box.upper();
-   const double c = 1.0, d = 1.0;
-   if (d_dim == tbox::Dimension(2)) {
-      F77_FUNC(compdiagscalarc2d, COMPDIAGSCALARC2D) (diagonal.getPointer(),
-         &C,
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &c, &d);
-   } else if (d_dim == tbox::Dimension(3)) {
-      F77_FUNC(compdiagscalarc3d, COMPDIAGSCALARC3D) (diagonal.getPointer(),
-         &C,
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         off_diagonal.getPointer(2),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &patch_lo[2], &patch_up[2],
-         &c, &d);
-   } else {
-      TBOX_ERROR("ElasticHypreSolver error...\n"
-         << "DIM > 3 not supported." << std::endl);
-   }
-}
-
-void ElasticHypreSolver::computeDiagonalEntries(
-   pdat::CellData<double>& diagonal,
-   const pdat::SideData<double>& off_diagonal,
-   const hier::Box& patch_box)
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS3(d_dim, diagonal, off_diagonal, patch_box);
-
-   const hier::Index patch_lo = patch_box.lower();
-   const hier::Index patch_up = patch_box.upper();
-   const double c = 1.0, d = 1.0;
-   if (d_dim == tbox::Dimension(2)) {
-      F77_FUNC(compdiagzeroc2d, COMPDIAGZEROC2D) (diagonal.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &c, &d);
-   } else if (d_dim == tbox::Dimension(3)) {
-      F77_FUNC(compdiagzeroc3d, COMPDIAGZEROC3D) (diagonal.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         off_diagonal.getPointer(2),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &patch_lo[2], &patch_up[2],
-         &c, &d);
-   } else {
-      TBOX_ERROR("ElasticHypreSolver error...\n"
-         << "DIM > 3 not supported." << std::endl);
-   }
-}
-
-void ElasticHypreSolver::adjustBoundaryEntries(
-   pdat::CellData<double>& diagonal,
-   const pdat::SideData<double>& off_diagonal,
-   const hier::Box& patch_box,
-   const pdat::ArrayData<double>& acoef_data,
-   const pdat::ArrayData<double>& bcoef_data,
-   const hier::Box bccoef_box,
-   pdat::ArrayData<double>& Ak0_data,
-   const hier::BoundaryBox& trimmed_boundary_box,
-   const double h[tbox::Dimension::MAXIMUM_DIMENSION_VALUE])
-{
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS8(d_dim, diagonal, off_diagonal, patch_box,
-      acoef_data, bcoef_data,
-      bccoef_box, Ak0_data, trimmed_boundary_box);
-
-   const hier::Index patch_lo = patch_box.lower();
-   const hier::Index patch_up = patch_box.upper();
-   const int location_index = trimmed_boundary_box.getLocationIndex();
-   const hier::Index& lower = trimmed_boundary_box.getBox().lower();
-   const hier::Index& upper = trimmed_boundary_box.getBox().upper();
-   const hier::Box& Ak0_box = Ak0_data.getBox();
-   if (d_dim == tbox::Dimension(2)) {
-      F77_FUNC(adjbdry2d, ADJBDRY2D) (diagonal.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         acoef_data.getPointer(),
-         bcoef_data.getPointer(),
-         &bccoef_box.lower()[0],
-         &bccoef_box.upper()[0],
-         &bccoef_box.lower()[1],
-         &bccoef_box.upper()[1],
-         Ak0_data.getPointer(),
-         &Ak0_box.lower()[0],
-         &Ak0_box.upper()[0],
-         &Ak0_box.lower()[1],
-         &Ak0_box.upper()[1],
-         &lower[0], &upper[0],
-         &location_index, h);
-   } else if (d_dim == tbox::Dimension(3)) {
-      F77_FUNC(adjbdry3d, ADJBDRY3D) (diagonal.getPointer(),
-         off_diagonal.getPointer(0),
-         off_diagonal.getPointer(1),
-         off_diagonal.getPointer(2),
-         &patch_lo[0], &patch_up[0],
-         &patch_lo[1], &patch_up[1],
-         &patch_lo[2], &patch_up[2],
-         acoef_data.getPointer(),
-         bcoef_data.getPointer(),
-         &bccoef_box.lower()[0],
-         &bccoef_box.upper()[0],
-         &bccoef_box.lower()[1],
-         &bccoef_box.upper()[1],
-         &bccoef_box.lower()[2],
-         &bccoef_box.upper()[2],
-         Ak0_data.getPointer(),
-         &Ak0_box.lower()[0],
-         &Ak0_box.upper()[0],
-         &Ak0_box.lower()[1],
-         &Ak0_box.upper()[1],
-         &Ak0_box.lower()[2],
-         &Ak0_box.upper()[2],
-         &lower[0], &upper[0],
-         &location_index, h);
-   } else {
-      TBOX_ERROR("ElasticHypreSolver error...\n"
-         << "DIM > 3 not supported." << std::endl);
-   }
-}
-
-void
-ElasticHypreSolver::finalizeCallback()
-{
-   for (int d = 0; d < tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
-      s_Ak0_var[d].setNull();
-   }
-}
-
-}
-}
-
-#endif
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticHypreSolver.I
--- a/src/ElasticHypreSolver.I	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Level solver for diffusion-like elliptic problems. 
- *
- ************************************************************************/
-namespace SAMRAI {
-namespace solv {
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setSolnIdDepth(
-   const int depth) {
-   d_soln_depth = depth;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setRhsIdDepth(
-   const int depth) {
-   d_rhs_depth = depth;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setUseSMG(
-   bool use_smg) {
-   d_use_smg = use_smg;
-}
-
-/*
- ********************************************************************
- * Specify bc using the default internal bc coefficient object.     *
- * Clear up data supporting external bc coefficient setter.         *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setBoundaries(
-   const std::string& boundary_type,
-   const int fluxes,
-   const int flags,
-   int* bdry_types)
-{
-   d_physical_bc_simple_case.setBoundaries(boundary_type,
-      fluxes,
-      flags,
-      bdry_types);
-   d_physical_bc_coef_strategy = &d_physical_bc_simple_case;
-   d_physical_bc_variable.setNull();
-}
-
-/*
- ********************************************************************
- * Set the physical boundary condition object.                      *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setPhysicalBcCoefObject(
-   const RobinBcCoefStrategy* physical_bc_coef_strategy,
-   const tbox::Pointer<hier::Variable> variable)
-{
-   d_physical_bc_coef_strategy = physical_bc_coef_strategy;
-   d_physical_bc_variable = variable;
-}
-
-SAMRAI_INLINE_KEYWORD
-int ElasticHypreSolver::getNumberOfIterations() const
-{
-   return d_number_iterations;
-}
-
-SAMRAI_INLINE_KEYWORD
-double ElasticHypreSolver::getRelativeResidualNorm() const
-{
-   return d_relative_residual_norm;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setNumPreRelaxSteps(
-   const int steps)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(!d_hierarchy.isNull());
-#endif
-   d_num_pre_relax_steps = steps;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setNumPostRelaxSteps(
-   const int steps)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(!d_hierarchy.isNull());
-#endif
-   d_num_post_relax_steps = steps;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setPrintSolverInfo(
-   const bool print)
-{
-   d_print_solver_info = print;
-}
-
-SAMRAI_INLINE_KEYWORD
-void ElasticHypreSolver::setStoppingCriteria(
-   const int max_iterations,
-   const double residual_tol)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(max_iterations >= 0);
-   TBOX_ASSERT(residual_tol >= 0.0);
-#endif
-   d_max_iterations = max_iterations;
-   d_relative_residual_tol = residual_tol;
-}
-
-}
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/ElasticHypreSolver.h
--- a/src/ElasticHypreSolver.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,615 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Hypre solver interface for diffusion-like elliptic problems. 
- *
- ************************************************************************/
-#ifndef included_solv_ElasticHypreSolver
-#define included_solv_ElasticHypreSolver
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#ifdef HAVE_HYPRE
-
-#ifndef included_HYPRE_struct_ls
-/*
- * This might break things if F77_FUNC_ is different for hypre vs
- * SAMRAI autoconf detection.  But then C/C++ macros are totally
- * broken due to namespace collision as this example highlights so
- * resorting to hacks are necessary.
- */
-#ifdef F77_FUNC_
-#undef F77_FUNC_
-#endif
-#include "HYPRE_struct_ls.h"
-#define included_HYPRE_struct_ls
-#endif
-
-#include "SAMRAI/solv/GhostCellRobinBcCoefs.h"
-#include "SAMRAI/solv/RobinBcCoefStrategy.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/OutersideVariable.h"
-#include "SAMRAI/hier/BoxList.h"
-#include "SAMRAI/hier/CoarseFineBoundary.h"
-#include "SAMRAI/hier/PatchHierarchy.h"
-#include "SAMRAI/hier/PatchLevel.h"
-#include "SAMRAI/hier/VariableContext.h"
-#include "SAMRAI/tbox/Database.h"
-#include "SAMRAI/tbox/Pointer.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief Use the HYPRE preconditioner library to solve (the cell-centered)
- * Elastic's equation on a single level in a hierarchy.
- *
- * Class ElasticHypreSolver uses the HYPRE preconditioner library
- * to solve linear equations of the form
- * @f$ \nabla ( D \nabla u ) + C u = f @f$, where
- * C is a cell-centered array, D is a face-centered array,
- * and u and f are cell-centered arrays
- * (see ElasticSpecifications).
- * The discretization is the standard second order
- * finite difference stencil.
- *
- * Robin boundary conditions are used through the
- * interface class RobinBcCoefStrategy.
- * Periodic boundary conditions are not supported yet.
- *
- * The user must perform the following steps to use
- * ElasticHypreSolver:
- * - Create a ElasticHypreSolver object.
- * - Initialize ElasticHypreSolver object with a patch hierarchy,
- *   using the function initializeSolverState().
- * - Use the functions setPhysicalBcCoefObject()
- *   to provide implementations of RobinBcCoefStrategy.
- *   (For most problems you can probably find a suitable
- *   implementation to use without implementing the
- *   strategy yourself.  See for example
- *   SimpleCellRobinBcCoefs and GhostCellRobinBcCoefs.)
- * - Set the matrix coefficients in the linear system,
- *   using the function setMatrixCoefficients().
- * - Specify the stopping criteria using setStoppingCriteria().
- * - Solve the linear system, passing in u and f as the patch
- *   indices of the solution and the right hand side, respectively.
- *
- * Sample parameters for initialization from database (and their
- * default values):
- * @verbatim
- *     print_solver_info = FALSE      // Whether to print some data for debugging
- *     max_iterations = 10            // Max iterations used by Hypre
- *     relative_residual_tol = 1.0e-8 // Residual tolerance used by Hypre
- *     num_pre_relax_steps = 1        // # of presmoothing steps used by Hypre
- *     num_post_relax_steps = 1       // # of postsmoothing steps used by Hypre
- *     use_smg = FALSE                // Whether to use hypre's smg solver
- *                                    // (alternative is the pfmg solver)
- * @endverbatim
- */
-
-class ElasticHypreSolver
-{
-public:
-   /*!
-    * @brief Constructor.
-    *
-    * @param object_name Name of object.
-    * @param database tbox::Database for input.
-    */
-   ElasticHypreSolver(
-      const tbox::Dimension& dim,
-      const std::string& object_name,
-      tbox::Pointer<tbox::Database> database =
-         tbox::Pointer<tbox::Database>(NULL));
-
-   /*!
-    * The Elastic destructor releases all internally managed data.
-    */
-   ~ElasticHypreSolver();
-
-   /*!
-    * @brief Initialize to a given hierarchy.
-    *
-    * Initializer Elastic solver for a patch level in a hierarchy.
-    *
-    * @param hierarchy Hierarchy
-    * @param ln Level number
-    */
-   void
-   initializeSolverState(
-      tbox::Pointer<hier::PatchHierarchy> hierarchy,
-      int ln = 0);
-
-   /*!
-    * @brief Reset to an uninitialized state.
-    */
-   void
-   deallocateSolverState();
-
-   /*!
-    * @brief Set the matrix coefficients
-    *
-    * For information describing the Elastic equation parameters,
-    * see the light-weight ElasticSpecifications class where
-    * you set the values of C and D.
-    *
-    * This method must be called before solveSystem().
-    */
-   void
-   setMatrixCoefficients();
-
-   /*!
-    * @brief Set default depth of the solution data involved in the solve.
-    *
-    * If the solution data has multiple depths,
-    * the solver uses just one depth at a time.
-    * The default depth is the first depth.
-    * Use this function to change it.
-    * This is not used to set the depth of the data (which is not
-    * controled by this class) but the depth used in the solve.
-    *
-    * Changing the depth after setting up the matrix is permissible,
-    * as the solution data does not affect the matrix.
-    */
-   void
-   setSolnIdDepth(
-      const int depth);
-
-   /*!
-    * @brief Set default depth of the rhs data involved in the solve.
-    *
-    * If the rhs data has multiple depths,
-    * the solver uses just one depth at a time.
-    * The default depth is the first depth.
-    * Use this function to change it.
-    * This is not used to set the depth of the data (which is not
-    * controled by this class) but the depth used in the solve.
-    *
-    * Changing the depth after setting up the matrix is permissible,
-    * as the rhs data does not affect the matrix.
-    */
-   void
-   setRhsIdDepth(
-      const int depth);
-
-   /*!
-    * @brief Set the stopping criteria (max iterations and residual
-    * tolerance) for the linear solver.
-    *
-    * @param max_iterations gives the maximum number of iterations
-    * @param relative_residual_tol the maximum error tolerance
-    */
-   void
-   setStoppingCriteria(
-      const int max_iterations = 10,
-      const double relative_residual_tol = 1.0e-6);
-
-   /*!
-    * @brief Solve the linear system Au=f.
-    *
-    * The solution u and the right hand side f are
-    * specified via patch indices on the patch hierarchy.
-    *
-    * Member functions getNumberOfIterations() return the iterations
-    * from the solver.
-    * Note that the matrix coefficients and boundary condition object
-    * must have been set up before this function is called.
-    * As long as the matrix coefficients do not change,
-    * this routine may be called repeatedly to solve any number of linear
-    * systems (with the right-hand side varying).
-    * If the boundary conditions or matrix coefficients are changed
-    * then function setMatrixCoefficients() must be called again.
-    *
-    * When computing the matrix coefficients in setMatrixCoefficients(),
-    * the inhomogeneous portion of the boundary condition (constant
-    * terms, independent of u and thus having no effect on the matrix)
-    * are saved and added to the source term, f,
-    * before performing the matrix solve.  In some situations, it may be
-    * useful to not add the inhomogeneous portion to f.  The flag argument
-    * @c homoegneous_bc is used for this.  (This is a sort of optimization,
-    * to avoid having to re-call setMatrixCoefficients() to change the
-    * inhomogeneous portion.)
-    *
-    * @param u Descriptor of cell-centered unknown variable.
-    * @param f Descriptor of cell-centered source variable.
-    * @param homogeneous_bc Whether homogeneous boundary conditions
-    *        are assumed.
-    *
-    * @return whether solver converged to specified level
-    */
-   int
-   solveSystem(
-      const int u,
-      const int f,
-      bool homogeneous_bc = false);
-
-   /*!
-    * @brief Return the number of iterations taken by the solver to converge.
-    *
-    * @return number of iterations taken by the solver to converge
-    */
-   int
-   getNumberOfIterations() const;
-
-   /*!
-    * @brief Set the number of pre-relax steps used by the Hypre solve.
-    */
-   void
-   setNumPreRelaxSteps(
-      const int steps);
-
-   /*!
-    * @brief Set the number of post-relax steps used by the Hypre solve.
-    */
-   void
-   setNumPostRelaxSteps(
-      const int steps);
-
-   /*!
-    * @brief Return the final residual norm returned by the Hypre solve.
-    * @return final residual norm returned by the Hypre solve.
-    */
-   double
-   getRelativeResidualNorm() const;
-
-   /*!
-    * @brief Set whether to use Hypre's PFMG algorithm instead of the
-    * SMG algorithm.
-    *
-    * The flag is used to select which of HYPRE's linear solver algorithms
-    * to use if true, the semicoarsening multigrid algorithm is used, and if
-    * false, the "PF" multigrid algorithm is used.
-    * By default, the SMG algorithm is used.
-    *
-    * Changing the algorithm must be done before setting up the matrix
-    * coefficients.
-    */
-   void
-   setUseSMG(
-      bool use_smg);
-
-   /*!
-    * @brief Specify boundary condition directly, without using
-    * a RobinBcCoefStrategy object.
-    *
-    * Use @em either setBoundaries() @em or setPhysicalBcCoefObject(),
-    * but not both.
-    *
-    * A SimpleCelBcCoef object is used to interpret and implement
-    * the specified boundary conditions.
-    * See SimpleCellRobinBcCoefs::setBoundaries()
-    * for an explanation of the arguments.
-    */
-   void
-   setBoundaries(
-      const std::string& boundary_type,
-      const int fluxes = -1,
-      const int flags = -1,
-      int* bdry_types = NULL);
-
-   /*!
-    * @brief Specify boundary condition through the use of a
-    * Robin boundary condition object.
-    *
-    * Use @em either setBoundaries() @em or setPhysicalBcCoefObject(),
-    * but not both.
-    *
-    * The Robin boundary condition object is used when setting
-    * the matrix coefficient and when solving the system.
-    * If your boundary conditions are fixed values at ghost
-    * cell centers, use the GhostCellRobinBcCoefs
-    * implementation of the RobinBcCoefStrategy strategy.
-    *
-    * @param physical_bc_coef_strategy tbox::Pointer a concrete
-    *        implementation of the Robin bc strategy.
-    * @param variable hier::Variable pointer to be passed
-    *        to RobinBcCoefStrategy::setBcCoefs(),
-    *        but otherwise unused by this class.
-    */
-   void
-   setPhysicalBcCoefObject(
-      const RobinBcCoefStrategy* physical_bc_coef_strategy,
-      const tbox::Pointer<hier::Variable> variable =
-         tbox::Pointer<hier::Variable>(NULL));
-
-   /*!
-    * @brief Set the flag for printing solver information.
-    *
-    * This optional function is used primarily for debugging.
-    *
-    * If set true, it will print the HYPRE matrix information
-    * to the following files:
-    *
-    * - mat_bA.out - before setting matrix coefficients in matrix assemble
-    * - mat_aA.out - after setting matrix coefficients in matrix assemble
-    * - sol0.out   - u before solve (i.e. for system Au = b)
-    * - sol.out    - u after solve
-    * - mat0.out   - A before solve
-    * - mat.out    - A after solve
-    * - rhs.out    - b before and after solve
-    *
-    * If this method is not called, or the flag is set false, no printing
-    * will occur.
-    */
-   void
-   setPrintSolverInfo(
-      const bool print);
-
-private:
-   /*!
-    * @brief Set state using database
-    *
-    * See the class description for the parameters that can be set
-    * from a database.
-    *
-    * @param database Input database.  If a NULL pointer is given,
-    * nothing is done.
-    */
-   void
-   getFromInput(
-      tbox::Pointer<tbox::Database> database);
-
-   void
-   setupHypreSolver();
-   void
-   destroyHypreSolver();
-   void
-   allocateHypreData();
-   void
-   deallocateHypreData();
-
-   void
-   copyToHypre(
-      HYPRE_StructVector vector,
-      pdat::CellData<double>& src,
-      int depth,
-      const hier::Box& box);
-   void
-   copyFromHypre(
-      pdat::CellData<double>& dst,
-      int depth,
-      HYPRE_StructVector vector,
-      const hier::Box box);
-
-   /*!
-    * @brief Add g*A*k0(a) from boundaries to rhs.
-    *
-    * Move the constant portion of the boundary condition
-    * contribution to the right hand side and add it to the existing rhs.
-    * This operation is done for physical as well as cf boundaries,
-    * so it is placed in a function.
-    *
-    * The boundary boxes given must be to either the physical
-    * boundary or coarse-fine boundary for the patch.  The
-    * bc coefficient implementation should correspond to the
-    * boundary being worked on.
-    */
-   void
-   add_gAk0_toRhs(
-      const hier::Patch& patch,
-      const tbox::Array<hier::BoundaryBox>& bdry_boxes,
-      const RobinBcCoefStrategy* robin_bc_coef,
-      pdat::CellData<double>& rhs);
-
-   //@{
-
-   /*!
-    * @name Dimension-independent functions to organize Fortran interface.
-    */
-
-   //! @brief Compute diagonal entries of the matrix when C is variable.
-   void
-   computeDiagonalEntries(
-      pdat::CellData<double>& diagonal,
-      const pdat::CellData<double>& C_data,
-      const pdat::SideData<double>& variable_off_diagonal,
-      const hier::Box& patch_box);
-   //! @brief Compute diagonal entries of the matrix when C is constant.
-   void
-   computeDiagonalEntries(
-      pdat::CellData<double>& diagonal,
-      const double C,
-      const pdat::SideData<double>& variable_off_diagonal,
-      const hier::Box& patch_box);
-   //! @brief Compute diagonal entries of the matrix when C is zero.
-   void
-   computeDiagonalEntries(
-      pdat::CellData<double>& diagonal,
-      const pdat::SideData<double>& variable_off_diagonal,
-      const hier::Box& patch_box);
-   /*!
-    * @brief Adjust boundary entries for variable off-diagonals.
-    *
-    * At the same time, save information that are needed to adjust
-    * the rhs.
-    */
-   void
-   adjustBoundaryEntries(
-      pdat::CellData<double>& diagonal,
-      const pdat::SideData<double>& variable_off_diagonal,
-      const hier::Box& patch_box,
-      const pdat::ArrayData<double>& acoef_data,
-      const pdat::ArrayData<double>& bcoef_data,
-      const hier::Box bccoef_box,
-      pdat::ArrayData<double>& Ak0_data,
-      const hier::BoundaryBox& trimmed_boundary_box,
-      const double h[tbox::Dimension::MAXIMUM_DIMENSION_VALUE]);
-
-   //@}
-
-   //! @brief Free static variables at shutdown time.
-   static void
-   finalizeCallback();
-
-   /*!
-    * @brief Object dimension.
-    */
-   const tbox::Dimension d_dim;
-
-   /*!
-    * @brief Object name.
-    */
-   std::string d_object_name;
-
-   /*!
-    * @brief Associated hierarchy.
-    */
-   tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
-
-   /*!
-    * @brief Associated level number.
-    *
-    * Currently, this must be level number 0.
-    */
-   int d_ln;
-
-   /*!
-    * @brief Scratch context for this object.
-    */
-   tbox::Pointer<hier::VariableContext> d_context;
-
-   //@{ @name Boundary condition handling
-
-   /*!
-    * @brief The coarse-fine boundary description for level d_ln.
-    *
-    * The coarse-fine boundary is computed when the operator
-    * state is initialized.  It is used to allow solves on
-    * levels that are not the coarsest in the hierarchy.
-    */
-   tbox::Pointer<hier::CoarseFineBoundary> d_cf_boundary;
-
-   /*!
-    * @brief Robin boundary coefficient object for physical
-    * boundaries.
-    *
-    * If d_physical_bc_coef_strategy is set, use it, otherwise,
-    * use d_physical_bc_simple_case.
-    */
-   const RobinBcCoefStrategy* d_physical_bc_coef_strategy;
-   tbox::Pointer<hier::Variable> d_physical_bc_variable;
-
-   /*!
-    * @brief Implementation of Robin boundary conefficients
-    * for the case of simple boundary conditions.
-    */
-   SimpleCellRobinBcCoefs d_physical_bc_simple_case;
-
-   /*!
-    * @brief Robin boundary coefficient object for coarse-fine
-    * boundaries.
-    *
-    * This is a GhostCellRobinBcCoefs object because we
-    * expect the users to have the correct ghost cell values
-    * in the coarse-fine boundaries before solving.
-    */
-   GhostCellRobinBcCoefs d_cf_bc_coef;
-   tbox::Pointer<hier::Variable> d_coarsefine_bc_variable;
-
-   //@}
-
-   /*!
-    * @brief hier::Patch index of A*k0(a) quantity
-    *
-    * A*k0(a) is the quantity that is saved for
-    * later adding to the rhs.
-    *
-    * The Robin bc is expressed by the coefficients a and g
-    * on the boundary (see RobinBcCoefStrategy).
-    * This class uses a central difference approximation of
-    * the Robin bc, which results in the value at a ghost cell,
-    * uo, being writen as uo = g*k0(a) + k1(a)*ui, where ui is
-    * the first interior cell value, k0 and k1 depend on a as
-    * indicated.
-    *
-    * In setting up the Au=f system, the contribution of k1(a)*ui
-    * is incorporated into the product Au.  The contribution of
-    * A*g*k0(a) should be moved to the right hand side and saved for
-    * later adding to f.  However, the value of g is not provided
-    * until solve time.  Therefore, we save just A*k0(a) at the
-    * patch data index d_Ak0_id.
-    */
-   int d_Ak0_id;
-
-   static tbox::Pointer<pdat::OutersideVariable<double> > s_Ak0_var[tbox::
-                                                                    Dimension::
-                                                                    MAXIMUM_DIMENSION_VALUE];
-
-   /*!
-    * @brief Depth of the solution variable.
-    */
-   int d_soln_depth;
-
-   /*!
-    * @brief Depth of the rhs variable.
-    */
-   int d_rhs_depth;
-
-   int d_max_iterations;
-   double d_relative_residual_tol;
-
-   int d_number_iterations; // iterations in solver
-   int d_num_pre_relax_steps;  // pre-relax steps in solver
-   int d_num_post_relax_steps; // post-relax steps in solver
-   double d_relative_residual_norm;  // norm from solver
-
-   /*@
-    * @brief Flag to use SMG or PFMG (default)
-    */
-   bool d_use_smg;
-
-   //@{
-   //! @name Hypre object
-   //! @brief HYPRE grid
-   HYPRE_StructGrid d_grid;
-   //! @brief HYPRE stencil
-   HYPRE_StructStencil d_stencil;
-   //! @brief HYPRE structured matrix
-   HYPRE_StructMatrix d_matrix;
-   //! @brief Hypre RHS vector for linear solves
-   HYPRE_StructVector d_linear_rhs;
-   //! @brief Hypre solution vector
-   HYPRE_StructVector d_linear_sol;
-   //! @brief Hypre SMG solver data
-   HYPRE_StructSolver d_mg_data;
-   //@}
-
-   //@{
-
-   //! @name Variables for debugging and analysis.
-
-   /*!
-    * @brief Flag to print solver info
-    *
-    * See setPrintSolverInfo().
-    */
-   bool d_print_solver_info;
-
-   //@}
-
-   /*!
-    * @brief Timers for performance measurement.
-    */
-   tbox::Pointer<tbox::Timer> t_solve_system;
-   tbox::Pointer<tbox::Timer> t_set_matrix_coefficients;
-
-   static tbox::StartupShutdownManager::Handler s_finalize_handler;
-};
-
-}
-} // namespace SAMRAI
-
-#ifdef SAMRAI_INLINE
-#include "ElasticHypreSolver.I"
-#endif
-
-#endif
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic.h
--- a/src/FACElastic.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#ifndef included_FACElastic
-#define included_FACElastic
-
-#include "ElasticFACSolver.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/tbox/Database.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/solv/LocationIndexRobinBcCoefs.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/hier/PatchHierarchy.h"
-#include "SAMRAI/hier/PatchLevel.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/mesh/StandardTagAndInitStrategy.h"
-#include "SAMRAI/hier/VariableContext.h"
-#include "SAMRAI/appu/VisDerivedDataStrategy.h"
-#include "SAMRAI/appu/VisItDataWriter.h"
-
-namespace SAMRAI {
-
-  /*!
-   * @brief Class to solve a sample Elastic equation on a SAMR grid.
-   */
-  class FACElastic:
-    public mesh::StandardTagAndInitStrategy,
-    public appu::VisDerivedDataStrategy
-  {
-
-  public:
-    /*!
-     * @brief Constructor.
-     *
-     * If you want standard output and logging,
-     * pass in valid pointers for those streams.
-     *
-     * @param object_name Ojbect name
-     * @param database Input database (may be NULL)
-     */
-    FACElastic(const std::string& object_name,
-              const tbox::Dimension& dim,
-              tbox::Pointer<tbox::Database> database =
-              tbox::Pointer<tbox::Database>(NULL));
-
-    virtual ~FACElastic() {}
-
-    //@{ @name mesh::StandardTagAndInitStrategy virtuals
-
-    /*!
-     * @brief Allocate and initialize data for a new level
-     * in the patch hierarchy.
-     *
-     * This is where you implement the code for initialize data on
-     * the grid.  All the information needed to initialize the grid
-     * are in the arguments.
-     *
-     * @see mesh::StandardTagAndInitStrategy::initializeLevelData()
-     */
-    virtual void
-    initializeLevelData(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy,
-                        const int level_number,
-                        const double init_data_time,
-                        const bool can_be_refined,
-                        const bool initial_time,
-                        const tbox::Pointer<hier::BasePatchLevel> old_level,
-                        const bool allocate_data);
-
-    /*!
-     * @brief Reset any internal hierarchy-dependent information.
-     */
-    virtual void
-    resetHierarchyConfiguration(tbox::Pointer<hier::BasePatchHierarchy> new_hierarchy,
-                                int coarsest_level,
-                                int finest_level);
-
-    //@}
-
-    virtual void
-    applyGradientDetector(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy,
-                          const int level_number,
-                          const double error_data_time,
-                          const int tag_index,
-                          const bool initial_time,
-                          const bool uses_richardson_extrapolation);
-
-    void computeAdaptionEstimate(pdat::CellData<double>& estimate_data,
-                                 const pdat::CellData<double>& soln_cell_data)
-      const;
-
-    //@{ @name appu::VisDerivedDataStrategy virtuals
-
-    virtual bool
-    packDerivedDataIntoDoubleBuffer(double* buffer,
-                                    const hier::Patch& patch,
-                                    const hier::Box& region,
-                                    const std::string& variable_name,
-                                    int depth_id) const;
-
-    //@}
-
-    /*!
-     * @brief Solve using HYPRE Elastic solver
-     *
-     * Set up the linear algebra problem and use a
-     * solv::ElasticFACSolver object to solve it.
-     * -# Set initial guess
-     * -# Set boundary conditions
-     * -# Specify Elastic equation parameters
-     * -# Call solver
-     */
-    int
-    solveElastic();
-
-#ifdef HAVE_HDF5
-    /*!
-     * @brief Set up external plotter to plot internal
-     * data from this class.
-     *
-     * After calling this function, the external
-     * data writer may be used to write the
-     * viz file for this object.
-     *
-     * The internal hierarchy is used and must be
-     * established before calling this function.
-     * (This is commonly done by building a hierarchy
-     * with the mesh::StandardTagAndInitStrategy virtual
-     * functions implemented by this class.)
-     *
-     * @param viz_writer VisIt writer
-     */
-    int
-    setupPlotter(appu::VisItDataWriter& plotter) const;
-#endif
-
-  private:
-    void fix_moduli();
-    std::string d_object_name;
-
-    const tbox::Dimension d_dim;
-
-    tbox::Pointer<hier::PatchHierarchy> d_hierarchy;
-
-    //@{
-    /*!
-     * @name Major algorithm objects.
-     */
-
-    /*!
-     * @brief FAC Elastic solver.
-     */
-    solv::ElasticFACSolver d_elastic_fac_solver;
-
-    /*!
-     * @brief Boundary condition coefficient implementation.
-     */
-    solv::LocationIndexRobinBcCoefs d_bc_coefs;
-
-    //@}
-
-    //@{
-
-    /*!
-     * @name Private state variables for solution.
-     */
-
-    /*!
-     * @brief Context owned by this object.
-     */
-    tbox::Pointer<hier::VariableContext> d_context;
-  
-    /*!
-     * @brief Descriptor indices of internal data.
-     *
-     * These are initialized in the constructor and never change.
-     */
-
-    double d_adaption_threshold;
-    int min_full_refinement_level;
-  public:
-    int p_id, cell_moduli_id, edge_moduli_id, dp_id, p_exact_id,
-      p_rhs_id, v_id, v_rhs_id;
-
-    tbox::Array<double> lambda, lambda_xyz_max, lambda_xyz_min;
-    tbox::Array<int> lambda_ijk;
-
-    tbox::Array<double> mu, mu_xyz_max, mu_xyz_min;
-    tbox::Array<int> mu_ijk;
-
-    tbox::Array<double> v_rhs, v_rhs_xyz_max, v_rhs_xyz_min;
-    tbox::Array<int> v_rhs_ijk;
-
-    tbox::Array<double> p_initial, p_initial_xyz_max, p_initial_xyz_min;
-    tbox::Array<int> p_initial_ijk;
-    //@}
-
-  };
-
-}
-
-#endif  // included_FACElastic
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/FACElastic.C
--- a/src/FACElastic/FACElastic.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-
-namespace SAMRAI {
-
-  /* A little utility routine to validate the sizes of input arrays */
-  void check_array_sizes(const tbox::Array<int> ijk,
-                         const tbox::Array<double> min,
-                         const tbox::Array<double> max,
-                         const tbox::Array<double> data,
-                         const int dim, const std::string &name,
-                         const int num_components=1)
-  {
-    if(ijk.size()!=dim)
-      TBOX_ERROR("Bad number of elements in " << name << "_ijk.  Expected "
-                 << dim << " but got " << ijk.size());
-    if(min.size()!=dim)
-      TBOX_ERROR("Bad number of elements in "
-                 << name << "_coord_min.  Expected "
-                 << dim << " but got " << min.size());
-    if(max.size()!=dim)
-      TBOX_ERROR("Bad number of elements in "
-                 << name << "_coord_max.  Expected "
-                 << dim << " but got " << max.size());
-    int data_size(1);
-    for(int d=0; d<dim; ++d)
-      data_size*=ijk[d];
-    if(data.size()!=data_size*num_components)
-      TBOX_ERROR("Bad number of elements in "
-                 << name << "_data.  Expected "
-                 << data_size << " but got " << data.size());
-  }
-  /*
-*************************************************************************
-* Constructor creates a unique context for the object and register      *
-* all its internal variables with the variable database.                *
-*************************************************************************
-*/
-  FACElastic::FACElastic(const std::string& object_name,
-                         const tbox::Dimension& dimension,
-                         tbox::Pointer<tbox::Database> database):
-    d_object_name(object_name),
-    d_dim(dimension),
-    d_hierarchy(NULL),
-    d_elastic_fac_solver((d_dim),
-                        object_name + "::elastic_hypre",
-                        (!database.isNull() &&
-                         database->isDatabase("fac_solver")) ?
-                        database->getDatabase("fac_solver"):
-                        tbox::Pointer<tbox::Database>(NULL)),
-    d_bc_coefs(d_dim,
-               object_name + "::bc_coefs",
-               (!database.isNull() &&
-                database->isDatabase("bc_coefs")) ?
-               database->getDatabase("bc_coefs"):
-               tbox::Pointer<tbox::Database>(NULL)),
-    d_context()
-  {
-    const int dim(d_dim.getValue());
-    hier::VariableDatabase* vdb =
-      hier::VariableDatabase::getDatabase();
-
-    /*
-     * Get a unique context for variables owned by this object.
-     */
-    d_context = vdb->getContext(d_object_name + ":Context");
-
-    /*
-     * Register variables with hier::VariableDatabase
-     * and get the descriptor indices for those variables.
-     */
-
-    tbox::Pointer<pdat::CellVariable<double> >
-      p_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":p", 1));
-    p_id = vdb->registerVariableAndContext(p_ptr, d_context,
-                                           hier::IntVector(d_dim, 1)
-                                           /* ghost cell width is 1 for
-                                              stencil widths */);
-
-	int depth=2;
-    tbox::Pointer<pdat::CellVariable<double> >
-      cell_moduli_ptr(new pdat::CellVariable<double>(d_dim,
-                                                        object_name
-                                                        + ":cell_moduli",depth));
-    cell_moduli_id = vdb->registerVariableAndContext(cell_moduli_ptr,
-                                                        d_context,
-                                                        hier::IntVector(d_dim, 1)
-                                                        /* ghost cell width is
-                                                           1 in case needed */);
-
-    if(dim==2)
-      {
-        tbox::Pointer<pdat::NodeVariable<double> >
-          edge_moduli_ptr(new pdat::NodeVariable<double>(d_dim,
-                                                            object_name
-                                                            + ":edge_moduli",depth));
-        edge_moduli_id =
-          vdb->registerVariableAndContext(edge_moduli_ptr,d_context,
-                                          hier::IntVector(d_dim,1)
-                                          /* ghost cell width is 1 in
-                                             case needed */);
-      }
-    else if(dim==3)
-      {
-        tbox::Pointer<pdat::EdgeVariable<double> >
-          edge_moduli_ptr(new pdat::EdgeVariable<double>(d_dim,
-                                                            object_name
-                                                            + ":edge_moduli",depth));
-        edge_moduli_id =
-          vdb->registerVariableAndContext(edge_moduli_ptr,d_context,
-                                          hier::IntVector(d_dim,1)
-                                          /* ghost cell width is 1 in
-                                             case needed */);
-      }
-
-    tbox::Pointer<pdat::CellVariable<double> >
-      dp_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":dp"));
-    dp_id = vdb->registerVariableAndContext(dp_ptr,d_context,
-                                            hier::IntVector(d_dim, 1)
-                                            /* ghost cell width is
-                                                    1 in case needed */);
-
-    tbox::Pointer<pdat::CellVariable<double> >
-      p_exact_ptr(new pdat::CellVariable<double>(d_dim, object_name + ":p exact"));
-    p_exact_id = vdb->registerVariableAndContext(p_exact_ptr,d_context,
-                                                 hier::IntVector(d_dim, 1)
-                                                 /* ghost cell width is
-                                                    1 in case needed */);
-
-    tbox::Pointer<pdat::CellVariable<double> >
-      p_rhs_ptr(new pdat::CellVariable<double>(d_dim,object_name
-                                               + ":p right hand side"));
-    p_rhs_id = vdb->registerVariableAndContext(p_rhs_ptr,d_context,
-                                               hier::IntVector(d_dim, 1));
-
-    tbox::Pointer<pdat::SideVariable<double> >
-      v_ptr(new pdat::SideVariable<double>(d_dim, object_name + ":v", 1));
-    v_id = vdb->registerVariableAndContext(v_ptr, d_context,
-                                           hier::IntVector(d_dim, 1)
-                                           /* ghost cell width is 1 for
-                                              stencil widths */);
-
-    tbox::Pointer<pdat::SideVariable<double> >
-      v_rhs_ptr(new pdat::SideVariable<double>(d_dim,object_name
-                                               + ":v right hand side"));
-    v_rhs_id = vdb->registerVariableAndContext(v_rhs_ptr,d_context,
-                                               hier::IntVector(d_dim, 1)
-                                               /* ghost cell width is
-                                                  1 for coarsening
-                                                  operator */);
-
-    d_adaption_threshold=database->getDoubleWithDefault("adaption_threshold",
-                                                        1.0e-15);
-    min_full_refinement_level
-      =database->getIntegerWithDefault("min_full_refinement_level",0);
-
-    if(database->keyExists("lambda_data"))
-      {
-        lambda_ijk=database->getIntegerArray("lambda_ijk");
-        lambda_xyz_min=database->getDoubleArray("lambda_coord_min");
-        lambda_xyz_max=database->getDoubleArray("lambda_coord_max");
-        lambda=database->getDoubleArray("lambda_data");
-        check_array_sizes(lambda_ijk,lambda_xyz_min,lambda_xyz_max,
-                          lambda,dim,"lambda");
-      }
-
-    if(database->keyExists("mu_data"))
-      {
-        mu_ijk=database->getIntegerArray("mu_ijk");
-        mu_xyz_min=database->getDoubleArray("mu_coord_min");
-        mu_xyz_max=database->getDoubleArray("mu_coord_max");
-        mu=database->getDoubleArray("mu_data");
-        check_array_sizes(mu_ijk,mu_xyz_min,mu_xyz_max,
-                          mu,dim,"mu");
-      }
-
-    if(database->keyExists("v_rhs_data"))
-      {
-        v_rhs_ijk=database->getIntegerArray("v_rhs_ijk");
-        v_rhs_xyz_min=database->getDoubleArray("v_rhs_coord_min");
-        v_rhs_xyz_max=database->getDoubleArray("v_rhs_coord_max");
-        v_rhs=database->getDoubleArray("v_rhs_data");
-        check_array_sizes(v_rhs_ijk,v_rhs_xyz_min,v_rhs_xyz_max,
-                          v_rhs,dim,"v_rhs",dim);
-      }
-
-    if(database->keyExists("p_initial_data"))
-      {
-        p_initial_ijk=database->getIntegerArray("p_initial_ijk");
-        p_initial_xyz_min=database->getDoubleArray("p_initial_coord_min");
-        p_initial_xyz_max=database->getDoubleArray("p_initial_coord_max");
-        p_initial=database->getDoubleArray("p_initial_data");
-        check_array_sizes(p_initial_ijk,p_initial_xyz_min,p_initial_xyz_max,
-                          p_initial,dim,"p_initial");
-      }
-
-    /*
-     * Specify an implementation of solv::RobinBcCoefStrategy for the
-     * solver to use.  We use the implementation
-     * solv::LocationIndexRobinBcCoefs, but other implementations are
-     * possible, including user-implemented.
-     */
-    d_elastic_fac_solver.setBcObject(&d_bc_coefs);
-  }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/applyGradientDetector.C
--- a/src/FACElastic/applyGradientDetector.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#include "FACElastic.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/pdat/MDA_Access.h"
-#include "SAMRAI/pdat/ArrayDataAccess.h"
-
-void SAMRAI::FACElastic::applyGradientDetector
-(const tbox::Pointer<hier::BasePatchHierarchy> hierarchy_,
- const int ln,
- const double ,
- const int tag_index,
- const bool ,
- const bool )
-{
-  const tbox::Pointer<hier::PatchHierarchy> hierarchy__ = hierarchy_;
-  hier::PatchHierarchy& hierarchy = *hierarchy__;
-  hier::PatchLevel& level =
-    (hier::PatchLevel &) * hierarchy.getPatchLevel(ln);
-  
-  int ntag = 0, ntotal = 0;
-  double maxestimate = 0;
-  for(hier::PatchLevel::Iterator pi(level); pi; pi++)
-    {
-      hier::Patch& patch = **pi;
-      tbox::Pointer<hier::PatchData>
-        tag_data = patch.getPatchData(tag_index);
-      ntotal += patch.getBox().numberCells().getProduct();
-      if (tag_data.isNull())
-        {
-          TBOX_ERROR("Data index "
-                     << tag_index << " does not exist for patch.\n");
-        }
-      tbox::Pointer<pdat::CellData<int> > tag_cell_data_ = tag_data;
-      if (tag_cell_data_.isNull())
-        {
-          TBOX_ERROR("Data index " << tag_index << " is not cell int data.\n");
-        }
-      tbox::Pointer<hier::PatchData> soln_data = patch.getPatchData(v_id);
-      if (soln_data.isNull())
-        {
-          TBOX_ERROR("Data index " << v_id << " does not exist for patch.\n");
-        }
-      tbox::Pointer<pdat::SideData<double> > soln_side_data_ = soln_data;
-      if (soln_side_data_.isNull())
-        {
-          TBOX_ERROR("Data index " << v_id << " is not side data.\n");
-        }
-      pdat::SideData<double>& v = *soln_side_data_;
-      pdat::CellData<int>& tag_cell_data = *tag_cell_data_;
-                              
-      tbox::Pointer<geom::CartesianPatchGeometry> geom = patch.getPatchGeometry();
-
-      tag_cell_data.fill(0);
-      for (pdat::CellIterator ci(patch.getBox()); ci; ci++)
-        {
-          const pdat::CellIndex cell_index(*ci);
-
-	  double curve(0.);
-	  for (int ix=0; ix<d_dim.getValue(); ++ix)
-	  {
-            const pdat::SideIndex x(cell_index,ix,pdat::SideIndex::Lower);
-	    for (int d=0; d<d_dim.getValue(); ++d){
-		    hier::Index ip(d_dim,0),
-			        jp(d_dim,0),
-			        kp(d_dim,0);
-		    ip(0)=1;
-		    jp(1)=1;
-		    if (3==d_dim.getValue())
-		    {
-			kp(2)=1;
-		    }
-              const hier::Index pp[]={ip,jp,kp};
-
-              if(cell_index[ix]==patch.getBox().lower(ix)
-                 && geom->getTouchesRegularBoundary(ix,0))
-	      {
-	      curve=std::max(curve,std::abs(v(x+pp[ix]+pp[ix])-2*v(x+pp[ix])+v(x)));
-	      } else if(cell_index[ix]==patch.getBox().upper(ix)
-                 && geom->getTouchesRegularBoundary(ix,1))
-	      {
-	      curve=std::max(curve,std::abs(v(x+pp[ix])-2*v(x)+v(x-pp[ix])));
-	      }
-	      else
-	      {
-	      curve=std::max(curve,std::abs(v(x+pp[ix]+pp[ix])-v(x+pp[ix])-v(x)+v(x-pp[ix])));
-	      }
-	    }
-	  }
-          /*
-	   * tbox::plog << "estimate "
-                     << cell_index << " "
-                     << d_adaption_threshold << " "
-                     << curve << " "
-                     << std::boolalpha
-                     << (curve > d_adaption_threshold)
-                     << " "
-                     << "\n";
-		     */
-
-          if (maxestimate < curve)
-               maxestimate=curve;
-          if (curve > d_adaption_threshold || ln<min_full_refinement_level)
-            {
-              tag_cell_data(cell_index) = 1;
-              ++ntag;
-            }
-        }
-    }
-  tbox::plog << "Adaption threshold is " << d_adaption_threshold << "\n";
-  tbox::plog << "Number of cells tagged on level " << ln << " is "
-             << ntag << "/" << ntotal << "\n";
-  tbox::plog << "Max estimate is " << maxestimate << "\n";
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/fix_moduli.C
--- a/src/FACElastic/fix_moduli.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-#include "FACElastic.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-
-/* Fix the moduli on the coarse grids by coarsening from the finer
-   grids. */
-
-void SAMRAI::FACElastic::fix_moduli()
-{
-  const int ln_max(d_hierarchy->getFinestLevelNumber());
-
-  tbox::Pointer<xfer::CoarsenOperator> cell_moduli_coarsen_operator;
-  tbox::Pointer<xfer::CoarsenAlgorithm> cell_moduli_coarsen_algorithm;
-  tbox::Array<tbox::Pointer<xfer::CoarsenSchedule> >
-    cell_moduli_coarsen_schedules;
-
-  hier::VariableDatabase* vdb = hier::VariableDatabase::getDatabase();
-  tbox::Pointer<geom::CartesianGridGeometry> geometry =
-    d_hierarchy->getGridGeometry();
-  tbox::Pointer<hier::Variable> variable;
-  vdb->mapIndexToVariable(cell_moduli_id, variable);
-  cell_moduli_coarsen_operator =
-    geometry->lookupCoarsenOperator(variable,
-                                    "CONSERVATIVE_COARSEN");
-                                    // "CELL_VISCOSITY_COARSEN");
-
-  if (!cell_moduli_coarsen_operator) {
-    TBOX_ERROR(d_object_name
-               << ": Cannot find cell moduli coarsening operator");
-  }
-
-  cell_moduli_coarsen_schedules.resizeArray(ln_max + 1);
-  cell_moduli_coarsen_algorithm = new xfer::CoarsenAlgorithm(d_dim);
-  cell_moduli_coarsen_algorithm->
-    registerCoarsen(cell_moduli_id,cell_moduli_id,
-                    cell_moduli_coarsen_operator);
-
-  for (int dest_ln = 0; dest_ln < ln_max; ++dest_ln) {
-    cell_moduli_coarsen_schedules[dest_ln] =
-      cell_moduli_coarsen_algorithm->
-      createSchedule(d_hierarchy->getPatchLevel(dest_ln),
-                     d_hierarchy->getPatchLevel(dest_ln + 1));
-    if (!cell_moduli_coarsen_schedules[dest_ln]) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot create a coarsen schedule for cell moduli restriction!\n");
-    }
-  }
-
-  for(int dest_ln=ln_max-1; dest_ln>=0; --dest_ln)
-    {
-      xfer::CoarsenAlgorithm coarsener(d_dim);
-      coarsener.registerCoarsen(cell_moduli_id, cell_moduli_id,
-                                cell_moduli_coarsen_operator);
-      coarsener.resetSchedule(cell_moduli_coarsen_schedules[dest_ln]);
-      cell_moduli_coarsen_schedules[dest_ln]->coarsenData();
-      cell_moduli_coarsen_algorithm->
-        resetSchedule(cell_moduli_coarsen_schedules[dest_ln]);
-    }
-
-  cell_moduli_coarsen_algorithm.setNull();
-  cell_moduli_coarsen_schedules.setNull();
-
-  /* Compute edge_moduli by averaging the cell moduli. */
-
-  hier::Index ip(hier::Index::getZeroIndex(d_dim)), jp(ip), kp(ip);
-  ip[0]=1;
-  jp[1]=1;
-  if(d_dim.getValue()>2)
-    kp[2]=1;
-  hier::Index pp[]={ip,jp,kp};
-
-  for (int ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln)
-    {
-      tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
-      hier::PatchLevel::Iterator i_p(*level);
-      for ( ; i_p; i_p++)
-        {
-          tbox::Pointer<hier::Patch> patch = *i_p;
-          tbox::Pointer<pdat::CellData<double> >
-            cell_moduli_ptr = patch->getPatchData(cell_moduli_id);
-          pdat::CellData<double> &cell_moduli(*cell_moduli_ptr);
-          if(2==d_dim.getValue())
-            {
-              tbox::Pointer<pdat::NodeData<double> >
-                edge_moduli_ptr = patch->getPatchData(edge_moduli_id);
-              pdat::NodeData<double> &edge_moduli(*edge_moduli_ptr);
-
-              for(pdat::NodeIterator ni(edge_moduli.getBox()); ni; ni++)
-                {
-                  for (int m=0;m<2;++m)
-                    {
-                      pdat::NodeIndex e=ni();
-                      pdat::CellIndex c(e);
-                      cell_moduli(c,m);
-                      cell_moduli(c-ip,m);
-                      cell_moduli(c-jp,m);
-                      cell_moduli(c-ip-jp,m);
-                      edge_moduli(e,m)=
-                        pow(cell_moduli(c,m)*cell_moduli(c-ip,m)
-                            *cell_moduli(c-jp,m)*cell_moduli(c-ip-jp,m),0.25);
-                    }
-		}
-            }
-          else
-            {
-              tbox::Pointer<pdat::EdgeData<double> >
-                edge_moduli_ptr = patch->getPatchData(edge_moduli_id);
-              pdat::EdgeData<double> &edge_moduli(*edge_moduli_ptr);
-              for(int axis=0;axis<3;++axis)
-                {
-                  const int axis2((axis+1)%3), axis3((axis+2)%3);
-                  hier::Box pbox=patch->getBox();
-                  pbox.grow(axis,edge_moduli.getGhostCellWidth()[axis]);
-
-                  for(pdat::EdgeIterator ni(pbox,axis); ni; ni++)
-                    {
-                      pdat::EdgeIndex e=ni();
-                      pdat::CellIndex c(e);
-		      for (int m=0;m<2;++m)
-                        {
-                          edge_moduli(e,m)=
-                            pow(cell_moduli(c,m)*cell_moduli(c-pp[axis2],m)
-                                *cell_moduli(c-pp[axis3],m)
-                                *cell_moduli(c-pp[axis2]-pp[axis3],m),0.25);
-                        }
-                    }
-                }
-            }
-        }
-
-      /* Ghost fill */
-      xfer::RefineAlgorithm refiner(d_dim);
-      refiner.registerRefine(edge_moduli_id,edge_moduli_id,
-                             edge_moduli_id,
-                             tbox::Pointer<xfer::RefineOperator>(0));
-
-      tbox::Pointer<xfer::RefineSchedule> schedule=
-        refiner.createSchedule(d_hierarchy->getPatchLevel(ln));
-        
-      schedule->fillData(0.0,false);
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/initializeLevelData.C
--- a/src/FACElastic/initializeLevelData.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,477 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "FTensor.hpp"
-
-bool intersect_fault(const int &dim,
-                     const FTensor::Tensor1<double,3> &c0,
-                     const FTensor::Tensor1<double,3> &c1,
-                     const double fault[])
-{
-  bool result(true);
-  for(int d=1;d<dim;++d)
-    {
-      double y((c1(d)*c0(0) -  c1(0)*c0(d))/(c1(0) - c0(0)));
-      result=result && (y<=fault[d-1]/2 && y>-fault[d-1]/2);
-    }
-  return result;
-}
-
-void rotate(double cstrike, double sstrike, double cdip, double sdip, 
-            double x1, double x2, double x3, 
-            double * x1s, double * x1i, double * x2s, double * x3s, double * x3i)
-{
-
-  double x2r(cstrike*x1-sstrike*x2);
-
-  (*x1s)= cdip*x2r-sdip*x3;
-  (*x1i)= cdip*x2r+sdip*x3;
-  (*x2s)= sstrike*x1+cstrike*x2;
-  (*x3s)= sdip*x2r+cdip*x3;
-  (*x3i)=-sdip*x2r+cdip*x3;
-
-}
-
-double gauss(double x, double sigma)
-{
-  const double pi2 = atan(1.0)*8;
-  return exp(-0.5*(x/sigma)*(x/sigma))/sqrt(pi2)/sigma;
-}
-
-double omega(double x, double beta)
-{
-  const double pi=4*atan(1);
-
-  if (fabs(x) <= (1-2*beta)/(1-beta)/2)
-    {
-      return 1;
-    }
-  else
-    {
-      if (fabs(x) < 1./(2.*(1.-beta)))
-        {
-          return pow(cos(pi*((1.-beta)*fabs(x)-0.5+beta)/(2.*beta)),2.);
-        }
-      else
-        {
-          return 0;
-        }
-    }
-}
-
-/*
-*************************************************************************
-* Initialize data on a level.                                           *
-*                                                                       *
-* Allocate the solution, exact solution and rhs memory.                 *
-* Fill the rhs and exact solution.                                      *
-*************************************************************************
-*/
-void SAMRAI::FACElastic::initializeLevelData
-(const tbox::Pointer<hier::BasePatchHierarchy> patch_hierarchy,
- const int level_number,
- const double ,
- const bool ,
- const bool ,
- const tbox::Pointer<hier::BasePatchLevel> ,
- const bool allocate_data)
-{
-  tbox::Pointer<hier::PatchHierarchy> hierarchy = patch_hierarchy;
-  tbox::Pointer<geom::CartesianGridGeometry> grid_geom =
-    hierarchy->getGridGeometry();
-
-  tbox::Pointer<hier::PatchLevel> level =
-    hierarchy->getPatchLevel(level_number);
-  const int dim=d_dim.getValue();
-
-  if (allocate_data) {
-    level->allocatePatchData(p_id);
-    level->allocatePatchData(cell_moduli_id);
-    level->allocatePatchData(edge_moduli_id);
-    level->allocatePatchData(dp_id);
-    level->allocatePatchData(p_rhs_id);
-    level->allocatePatchData(p_exact_id);
-    level->allocatePatchData(v_id);
-    level->allocatePatchData(v_rhs_id);
-  }
-
-  /*
-   * Initialize data in all patches in the level.
-   */
-  hier::PatchLevel::Iterator p_i(*level);
-  for (p_i.initialize(*level); p_i; p_i++) {
-
-    tbox::Pointer<hier::Patch> patch = *p_i;
-    if (patch.isNull()) {
-      TBOX_ERROR(d_object_name
-                 << ": Cannot find patch.  Null patch pointer.");
-    }
-    tbox::Pointer<geom::CartesianPatchGeometry>
-      geom = patch->getPatchGeometry();
-    const double *dx=geom->getDx();
-
-    /* Initialize cell moduli */
-    tbox::Pointer<pdat::CellData<double> > cell_moduli =
-      patch->getPatchData(cell_moduli_id);
-
-    hier::Box cell_moduli_box = cell_moduli->getBox();
-
-    for(pdat::CellIterator ci(cell_moduli->getGhostBox()); ci; ci++)
-      {
-        pdat::CellIndex c=ci();
-        double xyz[dim];
-        for(int d=0;d<dim;++d)
-          xyz[d]=geom->getXLower()[d]
-            + dx[d]*(c[d]-cell_moduli_box.lower()[d] + 0.5);
-
-        int ijk(0), factor(1);
-        for(int d=0;d<dim;++d)
-          {
-            int i=static_cast<int>(xyz[d]*(lambda_ijk[d]-1)
-                                   /(lambda_xyz_max[d]-lambda_xyz_min[d]));
-            i=std::max(0,std::min(lambda_ijk[d]-1,i));
-            ijk+=i*factor;
-            factor*=lambda_ijk[d];
-          }
-        (*cell_moduli)(c,0)=lambda[ijk];
-      }
-
-    for(pdat::CellIterator ci(cell_moduli->getGhostBox()); ci; ci++)
-      {
-        pdat::CellIndex c=ci();
-        double xyz[dim];
-        for(int d=0;d<dim;++d)
-          xyz[d]=geom->getXLower()[d]
-            + dx[d]*(c[d]-cell_moduli_box.lower()[d] + 0.5);
-
-        int ijk(0), factor(1);
-        for(int d=0;d<dim;++d)
-          {
-            int i=static_cast<int>(xyz[d]*(mu_ijk[d]-1)
-                                   /(mu_xyz_max[d]-mu_xyz_min[d]));
-            i=std::max(0,std::min(mu_ijk[d]-1,i));
-            ijk+=i*factor;
-            factor*=mu_ijk[d];
-          }
-        (*cell_moduli)(c,1)=mu[ijk];
-      }
-
-    /* I do not think this is actually necessary. */
-    tbox::Pointer<pdat::CellData<double> > dp_data =
-      patch->getPatchData(dp_id);
-    dp_data->fill(0.0);
-
-    tbox::Pointer<pdat::CellData<double> > p_rhs_data =
-      patch->getPatchData(p_rhs_id);
-    p_rhs_data->fill(0.0);
-
-    /* v_rhs */
-    tbox::Pointer<pdat::SideData<double> > v_rhs_data =
-      patch->getPatchData(v_rhs_id);
-
-    if(v_rhs.empty())
-      {
-        v_rhs_data->fill(0,0);
-      }
-    else
-      {
-        double L(0.2),W(0.25);
-        double cdip(0.707107),sdip(0.707107);
-        //double cdip(0.),sdip(1.);
-        double cstrike(0.),sstrike(1.);
-        double cr(0.),sr(1.);
-        double delta(0.003);
-        double x(0.500001),y(0.5),z(0.5);
-        double beta(0.2);
-	double scale(-10.);
-
-        const double pi=4*atan(1);
-        const double theta(0);
-        // const double theta(pi/4);
-        const FTensor::Tensor1<double,3> center(x,y,z);
-        const FTensor::Tensor2<double,3,3> rot(std::cos(theta),std::sin(theta),0,
-                                               -std::sin(theta),cos(theta),0,
-                                               0,0,1);
-        FTensor::Tensor1<double,3> Dx[dim];
-        for(int d0=0;d0<dim;++d0)
-          {
-            for(int d1=0;d1<dim;++d1)
-              Dx[d0](d1)=0;
-            
-            Dx[d0](d0)=dx[d0];
-          }
-        FTensor::Tensor1<double,3> slip(0,scale,0);
-        FTensor::Index<'a',3> a;
-        FTensor::Index<'b',3> b;
-        FTensor::Tensor1<double,3> jump;
-        jump(a)=slip(b)*rot(b,a);
-
-        double fault[]={L,W};
-
-        hier::Box pbox = v_rhs_data->getBox();
-        for(int ix=0;ix<dim;++ix)
-          {
-            double offset[]={0.5,0.5,0.5};
-            offset[ix]=0;
-
-            for(pdat::SideIterator si(pbox,ix); si; si++)
-              {
-                pdat::SideIndex s=si();
-                (*v_rhs_data)(s)=0;
-
-                FTensor::Tensor1<double,3> xyz(0,0,0);
-                for(int d=0;d<dim;++d)
-                  xyz(d)=geom->getXLower()[d]
-                    + dx[d]*(s[d]-pbox.lower()[d]+offset[d]);
-
-                /* Rotate the coordinates into the coordinates of the
-                   fault.  So in those coordinates, if x<0, you are on
-                   the left, and if x>0, you are on the right. */
-                FTensor::Tensor1<double,3> ntt;
-                FTensor::Tensor1<double,3> ntt_dp[dim], ntt_dm[dim];
-                ntt(a)=rot(a,b)*(xyz(b)-center(b));
-                for(int d=0;d<dim;++d)
-                  {
-                    ntt_dp[d](a)=rot(a,b)*(xyz(b)+Dx[d](b)-center(b));
-                    ntt_dm[d](a)=rot(a,b)*(xyz(b)-Dx[d](b)-center(b));
-                  }
-
-                /* d/dx^2, d/dy^2, d/dz^2 */
-                for(int d=0;d<dim;++d)
-                  {
-                    int sign(0);
-                    if(ntt(0)<=0 && ntt_dp[d](0)>0
-                       && intersect_fault(dim,ntt,ntt_dp[d],fault))
-                      sign=1;
-                    else if(ntt(0)>0 && ntt_dp[d](0)<=0
-                            && intersect_fault(dim,ntt,ntt_dp[d],fault))
-                      sign=-1;
-                    else if(ntt(0)<=0 && ntt_dm[d](0)>0
-                            && intersect_fault(dim,ntt,ntt_dm[d],fault))
-                      sign=1;
-                    else if(ntt(0)>0 && ntt_dm[d](0)<=0
-                            && intersect_fault(dim,ntt,ntt_dm[d],fault))
-                      sign=-1;
-
-                    if(sign!=0)
-                      {
-                        const double lambda_here(1), mu_here(1);
-                        double factor(mu_here);
-                        if(ix==d)
-                          factor=lambda_here+2*mu_here;
-                        (*v_rhs_data)(s)+=sign*factor*jump(ix)/(dx[d]*dx[d]);
-                      }
-                  }
-
-                /* d/dxy */
-
-                for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
-                  {
-                    FTensor::Tensor1<double,3> ntt_dxy[2][2];
-                    ntt_dxy[0][0](a)=
-                      rot(a,b)*(xyz(b)+Dx[ix](b)/2+Dx[iy](b)/2-center(b));
-                    ntt_dxy[0][1](a)=
-                      rot(a,b)*(xyz(b)+Dx[ix](b)/2-Dx[iy](b)/2-center(b));
-                    ntt_dxy[1][0](a)=
-                      rot(a,b)*(xyz(b)-Dx[ix](b)/2+Dx[iy](b)/2-center(b));
-                    ntt_dxy[1][1](a)=
-                      rot(a,b)*(xyz(b)-Dx[ix](b)/2-Dx[iy](b)/2-center(b));
-
-                    const double lambda_here(1), mu_here(1);
-                    int l(0), m(0);
-                    double j(0);
-
-                    if(ntt_dxy[0][0](0)<=0 && ntt_dxy[1][0](0)>0
-                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[1][0],fault))
-                      m-=1;
-                    if(ntt_dxy[0][0](0)>0 && ntt_dxy[1][0](0)<=0
-                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[1][0],fault))
-                      m+=1;
-                    if(ntt_dxy[0][1](0)<=0 && ntt_dxy[1][1](0)>0
-                       && intersect_fault(dim,ntt_dxy[0][1],ntt_dxy[1][1],fault))
-                      m+=1;
-                    if(ntt_dxy[0][1](0)>0 && ntt_dxy[1][1](0)<=0
-                       && intersect_fault(dim,ntt_dxy[0][1],ntt_dxy[1][1],fault))
-                      m-=1;
-
-                    if(ntt_dxy[0][0](0)<=0 && ntt_dxy[0][1](0)>0
-                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[0][1],fault))
-                      l-=1;
-                    if(ntt_dxy[0][0](0)>0 && ntt_dxy[0][1](0)<=0
-                       && intersect_fault(dim,ntt_dxy[0][0],ntt_dxy[0][1],fault))
-                      l+=1;
-                    if(ntt_dxy[1][0](0)<=0 && ntt_dxy[1][1](0)>0
-                       && intersect_fault(dim,ntt_dxy[1][0],ntt_dxy[1][1],fault))
-                      l+=1;
-                    if(ntt_dxy[1][0](0)>0 && ntt_dxy[1][1](0)<=0
-                       && intersect_fault(dim,ntt_dxy[1][0],ntt_dxy[1][1],fault))
-                      l-=1;
-
-                    j=l*lambda_here + m*mu_here;
-
-                    if(j!=0)
-                      (*v_rhs_data)(s)+=j*jump(iy) / (dx[0]*dx[1]);
-                  }
-              }
-          }
-        // if(0)
-        //   {
-
-	// typedef struct {
-	// 	double x1s,x1i,x2s,x3s,x3i;
-	// } rpoint;
-
-	// rpoint xp00,xm00,x0p0,x0m0,x00p,x00m;
-	// double xr,yr,zr;
-        // double x2r;
-
-	// x2r= cstrike*x  -sstrike*y;
-	// xr = cdip   *x2r-sdip   *z;
-	// yr = sstrike*x  +cstrike*y;
-	// zr = sdip   *x2r+cdip   *z;
-
-        // hier::Box pbox = v_rhs_data->getBox();
-        // for(int ix=0;ix<dim;++ix)
-        //   {
-        //     double offset[]={0.5,0.5,0.5};
-        //     offset[ix]=0;
-
-        //     for(pdat::SideIterator si(pbox,ix); si; si++)
-        //       {
-        //         pdat::SideIndex s=si();
-        //         double xyz[dim];
-        //         for(int d=0;d<dim;++d)
-        //           xyz[d]=geom->getXLower()[d]
-        //             + dx[d]*(s[d]-pbox.lower()[d]+offset[d]);
-            
-	// 	double x1,x2,x3;
-	// 	double dx1,dx2,dx3;
-
-	// 	if (2==d_dim.getValue())
-	// 	{
-	// 		x1=0;
-	// 		x2=xyz[0];
-	// 		x3=xyz[1];
-	// 		dx1=dx[0];
-	// 		dx2=dx[0];
-	// 		dx3=dx[1];
-	// 	} else if (3==d_dim.getValue())
-	// 	{
-        //                 x1=xyz[0];
-	// 		x2=xyz[1];
-	// 		x3=xyz[2];
-	// 		dx1=dx[0];
-	// 		dx2=dx[1];
-	// 		dx3=dx[2];
-	// 	}
-
-	// 	double g0m0(1.),g0p0(1.),g00p(1.),g00m(1.),gm00(1.),gp00(1.);
-	// 	double x1s,x1i,x2s,x3s,x3i;
-
-        //         x2r= cstrike*x1-sstrike*x2;
-        //         x1s= cdip*x2r-sdip*x3;
-        //         x1i= cdip*x2r+sdip*x3;
-        //         x2s= sstrike*x1+cstrike*x2;
-        //         x3s= sdip*x2r+cdip*x3;
-        //         x3i=-sdip*x2r+cdip*x3;
-
-	// 	double n[]={cdip*cstrike,-cdip*sstrike,-sdip};
-	// 	double b[]={sstrike*cr+cstrike*sdip*sr,cstrike*cr-sstrike*sdip*sr,+cdip*sr};
-
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1+dx1/2.,x2,x3,&(xp00.x1s),&(xp00.x1i),&(xp00.x2s),&(xp00.x3s),&(xp00.x3i));
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1-dx1/2.,x2,x3,&(xm00.x1s),&(xm00.x1i),&(xm00.x2s),&(xm00.x3s),&(xm00.x3i));
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2+dx2/2.,x3,&(x0p0.x1s),&(x0p0.x1i),&(x0p0.x2s),&(x0p0.x3s),&(x0p0.x3i));
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2-dx2/2.,x3,&(x0m0.x1s),&(x0m0.x1i),&(x0m0.x2s),&(x0m0.x3s),&(x0m0.x3i));
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2,x3+dx3/2.,&(x00p.x1s),&(x00p.x1i),&(x00p.x2s),&(x00p.x3s),&(x00p.x3i));
-	// 	rotate(cstrike,sstrike,cdip,sdip,x1,x2,x3-dx3/2.,&(x00m.x1s),&(x00m.x1i),&(x00m.x2s),&(x00m.x3s),&(x00m.x3i));
-
-	// 	double temp1=gauss(x1s-xr,delta);
-	// 	double temp2(1.0);
-	// 	if (3==d_dim.getValue())
-	// 	{
-	// 		temp2=omega((x2s-yr)/L,beta);
-	// 	}
-	// 	double temp3=omega((x3s-zr)/W,beta);
-	// 	double sourc=(+(gp00*gauss(xp00.x1s-xr,delta)-gm00*gauss(xm00.x1s-xr,delta))*n[0]/dx1
-        //                       +(g0p0*gauss(x0p0.x1s-xr,delta)-g0m0*gauss(x0m0.x1s-xr,delta))*n[1]/dx2
-        //                       +(g00p*gauss(x00p.x1s-xr,delta)-g00m*gauss(x00m.x1s-xr,delta))*n[2]/dx3 )
-	// 		*temp2 
-	// 		*temp3;
-
-        //         double dblcp=temp1 
-        //                *( (gp00*omega((xp00.x2s-yr)/L,beta)-gm00*omega((xm00.x2s-yr)/L,beta))*b[0]/dx1
-        //                  +(g0p0*omega((x0p0.x2s-yr)/L,beta)-g0m0*omega((x0m0.x2s-yr)/L,beta))*b[1]/dx2
-        //                  +(g00p*omega((x00p.x2s-yr)/L,beta)-g00m*omega((x00m.x2s-yr)/L,beta))*b[2]/dx3 ) 
-        //                *temp3;
-
-	// 	double dipcs=temp1 
-	// 		*temp2 
-	// 		*(+(gp00*omega((xp00.x3s-zr)/W,beta)-gm00*omega((xm00.x3s-zr)/W,beta))*b[0]/dx1
-	// 		  +(g0p0*omega((x0p0.x3s-zr)/W,beta)-g0m0*omega((x0m0.x3s-zr)/W,beta))*b[1]/dx2
-	// 		  +(g00p*omega((x00p.x3s-zr)/W,beta)-g00m*omega((x00m.x3s-zr)/W,beta))*b[2]/dx3 );
-
-        //         temp1=gauss(x1i-xr,delta);
-        //         temp3=omega((x3i+zr)/W,beta);
-        //         // double image=( (gp00*gauss(xp00.x1i-xr,delta)-gm00*gauss(xm00.x1i-xr,delta))*n[0]/dx1
-        //         //               +(g0p0*gauss(x0p0.x1i-xr,delta)-g0m0*gauss(x0m0.x1i-xr,delta))*n[1]/dx2
-        //         //               +(g00p*gauss(x00p.x1i-xr,delta)-g00m*gauss(x00m.x1i-xr,delta))*n[2]/dx3 )
-        //         //      *temp2 
-        //         //      *temp3;
-        //         // double cplei=temp1 
-        //         //             *( (gp00*omega((xp00.x2s-yr)/L,beta)-gm00*omega((xp00.x2s-yr)/L,beta))*b[0]/dx1
-        //         //               +(g0p0*omega((x0p0.x2s-yr)/L,beta)-g0m0*omega((x0p0.x2s-yr)/L,beta))*b[1]/dx2
-        //         //               +(g00p*omega((x00p.x2s-yr)/L,beta)-g00m*omega((x00p.x2s-yr)/L,beta))*b[2]/dx3 ) 
-        //         //             *temp3;
-        //         // double dipci=temp1 
-        //         //             *temp2 
-        //         //             *( (gp00*omega((xp00.x3i+zr)/W,beta)-gm00*omega((xm00.x3i+zr)/W,beta))*b[0]/dx1
-        //         //               +(g0p0*omega((x0p0.x3i+zr)/W,beta)-g0m0*omega((x0m0.x3i+zr)/W,beta))*b[1]/dx2
-        //         //               +(g00p*omega((x00p.x3i+zr)/W,beta)-g00m*omega((x00m.x3i+zr)/W,beta))*b[2]/dx3 );
- 
-       	// 	// force update
-	// 	switch (d_dim.getValue()-ix-1)
-	// 	{
-	// 		case 2:{
-	// 			// f_1
-	// 			double f1=+cr*sstrike*sourc
-	// 				  +cr*cdip*cstrike*dblcp
-	// 				  +sr*cdip*cstrike*dipcs
-	// 				  +sr*sdip*cstrike*sourc;
-        //         		(*v_rhs_data)(s)=-f1*scale;
-	// 			break;
-	// 		       }
-	// 		case 1:{
-	// 		       // f_2
-	// 			double f2=+cr*cstrike*sourc
-	// 				  -cr*cdip*sstrike*dblcp
-	// 				  -sr*cdip*sstrike*dipcs
-	// 				  -sr*sdip*sstrike*sourc;
-        //         		(*v_rhs_data)(s)=-f2*scale;
-	// 			break;
-	// 		       }
-	// 		case 0:{
-	// 			// f_3
-	// 			double f3=-cr*sdip*dblcp
-	// 				  +sr*cdip*sourc
-	// 				  -sr*sdip*dipcs;
-	// 			(*v_rhs_data)(s)=-f3*scale;
-	// 		       }
-	// 	}
-
-        //       }
-        //     int i=1;
-        //     for(int d=0;d<dim;++d)
-        //       i*=v_rhs_ijk[d];
-        //   }
-        //   }
-      }
-  }    // End patch loop.
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/packDerivedDataIntoDoubleBuffer.C
--- a/src/FACElastic/packDerivedDataIntoDoubleBuffer.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-
-namespace SAMRAI {
-
-  /*
-*************************************************************************
-* Write derived data to the given stream.                               *
-*************************************************************************
-*/
-  bool FACElastic::packDerivedDataIntoDoubleBuffer(
-                                                  double* buffer,
-                                                  const hier::Patch& patch,
-                                                  const hier::Box& region,
-                                                  const std::string&
-                                                  variable_name,
-                                                  int depth_id) const
-  {
-	pdat::CellData<double>::Iterator icell(region);
-
-	tbox::Pointer<pdat::SideData<double> > v_ptr;
-	if (variable_name == "Displacement") {
-		v_ptr = patch.getPatchData(v_id);
-	}
-	else if ("Equivalent body force" == variable_name)
-	{
-		v_ptr = patch.getPatchData(v_rhs_id);
-	}
-	else
-	{
-		// Did not register this name.
-		TBOX_ERROR(
-		"Unregistered variable name '" << variable_name << "' in\n"
-		<<
-		"FACElasticX::packDerivedDataIntoDoubleBuffer");
-	}
-
-	pdat::SideData<double>& v = *v_ptr;
-        if(d_dim.getValue()==2)
-          {
-            const hier::Index ip(1,0), jp(0,1);
-            for ( ; icell; icell++) {
-
-              pdat::CellIndex center(*icell);
-              const pdat::SideIndex
-		x(center,0,pdat::SideIndex::Lower),
-		y(center,1,pdat::SideIndex::Lower);
-	
-              double vx=(v(x+ip) + v(x))/2.;
-              double vy=(v(y+jp) + v(y))/2.;
-
-              if (0==depth_id)
-		{
-                  *buffer = vx;
-		}
-              else
-		{
-                  *buffer = vy;
-		}
-              buffer = buffer + 1;
-            }
-          }
-        else
-          {
-            const hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
-            for ( ; icell; icell++) {
-
-              pdat::CellIndex center(*icell);
-              const pdat::SideIndex
-		x(center,0,pdat::SideIndex::Lower),
-		y(center,1,pdat::SideIndex::Lower),
-		z(center,2,pdat::SideIndex::Lower);
-	
-              double vx=(v(x+ip) + v(x))/2.;
-              double vy=(v(y+jp) + v(y))/2.;
-              double vz=(v(z+kp) + v(z))/2.;
-
-              if (0==depth_id)
-		{
-                  *buffer = vx;
-		}
-              else if (1==depth_id)
-		{
-                  *buffer = vy;
-		}
-              else
-                {
-                  *buffer = vz;
-                }
-              buffer = buffer + 1;
-            }
-          }
-    // Return true if this patch has derived data on it.
-    // False otherwise.
-    return true;
-  }
-
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/resetHierarchyConfiguration.C
--- a/src/FACElastic/resetHierarchyConfiguration.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-
-namespace SAMRAI {
-
-  /*
-*************************************************************************
-* Reset the hierarchy-dependent internal information.                   *
-*************************************************************************
-*/
-  void FACElastic::resetHierarchyConfiguration
-  (tbox::Pointer<hier::BasePatchHierarchy> new_hierarchy,
-   int coarsest_level,
-   int finest_level)
-  {
-    (void)coarsest_level;
-    (void)finest_level;
-
-    d_hierarchy = new_hierarchy;
-  }
-
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/setupPlotter.C
--- a/src/FACElastic/setupPlotter.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-
-namespace SAMRAI {
-
-#ifdef HAVE_HDF5
-  /*
-*************************************************************************
-* Set up external plotter to plot internal data from this class.        *
-* Register variables appropriate for plotting.                          *
-*************************************************************************
-*/
-  int FACElastic::setupPlotter(appu::VisItDataWriter& plotter) const {
-    if (d_hierarchy.isNull()) {
-      TBOX_ERROR(d_object_name << ": No hierarchy in\n"
-                 << " FACElastic::setupPlotter\n"
-                 << "The hierarchy must be set before calling\n"
-                 << "this function.\n");
-    }
-    plotter.registerPlotQuantity("Pressure",
-                                 "SCALAR",
-                                 p_id);
-    plotter.registerDerivedPlotQuantity("Displacement",
-                                        "VECTOR",
-                                        (appu::VisDerivedDataStrategy *)this);
-    plotter.registerDerivedPlotQuantity("Equivalent body force",
-                                        "VECTOR",
-                                        (appu::VisDerivedDataStrategy *)this);
-    plotter.registerPlotQuantity("Exact solution",
-                                 "SCALAR",
-                                 p_exact_id);
-    plotter.registerPlotQuantity("Cell lambda",
-                                 "SCALAR",
-                                 cell_moduli_id,0);
-		// this, below, doesn't seem to work.
-    plotter.registerPlotQuantity("Cell mu",
-                                 "SCALAR",
-                                 cell_moduli_id,1);
-    plotter.registerPlotQuantity("Elastic source",
-                                 "SCALAR",
-                                 p_rhs_id);
-
-    return 0;
-  }
-#endif
-
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/FACElastic/solveElastic.C
--- a/src/FACElastic/solveElastic.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Numerical routines for example FAC Elastic solver 
- *
- ************************************************************************/
-#include "FACElastic.h"
-
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/solv/SimpleCellRobinBcCoefs.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/math/HierarchyCellDataOpsReal.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/hier/Variable.h"
-#include "SAMRAI/hier/VariableDatabase.h"
-
-/*
-*************************************************************************
-* Set up the initial guess and problem parameters                       *
-* and solve the Elastic problem.  We explicitly initialize and          *
-* deallocate the solver state in this example.                          *
-*************************************************************************
-*/
-int SAMRAI::FACElastic::solveElastic()
-{
-
-  if (d_hierarchy.isNull()) {
-    TBOX_ERROR(d_object_name
-               << "Cannot solve using an uninitialized object.\n");
-  }
-
-  int ln;
-  /*
-   * Fill in the initial guess.
-   */
-  for (ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln) {
-    tbox::Pointer<hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
-    hier::PatchLevel::Iterator ip(*level);
-    for ( ; ip; ip++) {
-      tbox::Pointer<hier::Patch> patch = *ip;
-      tbox::Pointer<pdat::CellData<double> >
-        p = patch->getPatchData(p_id);
-
-      tbox::Pointer<geom::CartesianPatchGeometry>
-        geom = patch->getPatchGeometry();
-
-      if(p_initial.empty())
-        {
-          p->fill(0.0);
-        }
-      else
-        {
-          const int dim=d_dim.getValue();
-          const double *dx=geom->getDx();
-          double dx_p[dim];
-          for(int d=0;d<dim;++d)
-            dx_p[d]=(p_initial_xyz_max[d]
-                     - p_initial_xyz_min[d])/(p_initial_ijk[d]-1);
-          int di[dim];
-          di[0]=1;
-          for(int d=1;d<dim;++d)
-            di[d]=di[d-1]*p_initial_ijk[d-1];
-
-          hier::Box pbox = p->getBox();
-          for(pdat::CellIterator ci(p->getGhostBox()); ci; ci++)
-            {
-              pdat::CellIndex c=ci();
-              double xyz[dim], weight[dim][2];
-              for(int d=0;d<dim;++d)
-                xyz[d]=geom->getXLower()[d]
-                  + dx[d]*(c[d]-pbox.lower()[d] + 0.5);
-
-              int ijk(0);
-              int ddi[dim];
-              for(int d=0;d<dim;++d)
-                {
-                  int i=static_cast<int>(xyz[d]*(p_initial_ijk[d]-1)
-                                         /(p_initial_xyz_max[d]
-                                           - p_initial_xyz_min[d]));
-                  i=std::max(0,std::min(p_initial_ijk[d]-1,i));
-                  ijk+=i*di[d];
-
-                  if(i==p_initial_ijk[d]-1)
-                    {
-                      weight[d][0]=1;
-                      weight[d][1]=0;
-                      ddi[d]=0;
-                    }
-                  else
-                    {
-                      weight[d][1]=
-                        (xyz[d]-(i*dx_p[d] + p_initial_xyz_min[d]))/dx_p[d];
-                      weight[d][0]=1-weight[d][1];
-                      ddi[d]=di[d];
-                    }
-                }
-
-              if(dim==2)
-                {
-                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]
-                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]
-                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]
-                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1];
-                }
-              else
-                {
-                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]*weight[2][0]
-                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]*weight[2][0]
-                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]*weight[2][0]
-                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1]*weight[2][0]
-                    
-                    + p_initial[ijk+ddi[2]]*weight[0][0]*weight[1][0]*weight[2][1]
-                    + p_initial[ijk+ddi[0]+ddi[2]]*weight[0][1]*weight[1][0]*weight[2][1]
-                    + p_initial[ijk+ddi[1]+ddi[2]]*weight[0][0]*weight[1][1]*weight[2][1]
-                    + p_initial[ijk+ddi[0]+ddi[1]+ddi[2]]*weight[0][1]*weight[1][1]*weight[2][1];
-                }
-            }
-        }
-
-      tbox::Pointer<pdat::SideData<double> >
-        v = patch->getPatchData(v_id);
-      v->fill(0.0);
-    }
-    d_elastic_fac_solver.set_boundaries(p_id,v_id,level,false);
-  }
-
-  fix_moduli();
-
-  d_elastic_fac_solver.initializeSolverState
-    (p_id,cell_moduli_id,edge_moduli_id,dp_id,p_rhs_id,v_id,v_rhs_id,
-     d_hierarchy,0,d_hierarchy->getFinestLevelNumber());
-
-  tbox::plog << "solving..." << std::endl;
-  int solver_ret;
-  solver_ret = d_elastic_fac_solver.solveSystem(p_id,p_rhs_id,v_id,v_rhs_id);
-  /*
-   * Present data on the solve.
-   */
-  // double avg_factor, final_factor;
-  // d_elastic_fac_solver.getConvergenceFactors(avg_factor, final_factor);
-  // tbox::plog << "\t" << (solver_ret ? "" : "NOT ") << "converged " << "\n"
-  //            << "	iterations: "
-  //            << d_elastic_fac_solver.getNumberOfIterations() << "\n"
-  //            << "	residual: "<< d_elastic_fac_solver.getResidualNorm()
-  //            << "\n"
-  //            << "	average convergence: "<< avg_factor << "\n"
-  //            << "	final convergence: "<< final_factor << "\n"
-  //            << std::flush;
-
-  d_elastic_fac_solver.deallocateSolverState();
-
-  return 0;
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Boundary_Refine.h
--- a/src/P_Boundary_Refine.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for cell-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_P_Boundary_Refine
-#define included_geom_P_Boundary_Refine
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Class P_Boundary_Refine implements the special interpolation needed
- * for the boundary elements on the coarse-fine interface.
- *
- * The findRefineOperator() operator function returns true if the input
- * variable is cell-centered double, and the std::string is "P_BOUNDARY_REFINE".
- *
- * @see xfer::RefineOperator
- */
-
-class P_Boundary_Refine:
-  public xfer::RefineOperator
-{
-public:
-  /**
-   * Uninteresting default constructor.
-   */
-  explicit P_Boundary_Refine(const tbox::Dimension& dim):
-    xfer::RefineOperator(dim, "P_BOUNDARY_REFINE")
-  {
-    d_name_id = "P_BOUNDARY_REFINE";
-  }
-
-
-  /**
-   * Uninteresting virtual destructor.
-   */
-  virtual ~P_Boundary_Refine(){}
-
-  /**
-   * Return true if the variable and name std::string match cell-centered
-   * double linear interpolation; otherwise, return false.
-   */
-  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
-                          const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  /**
-   * Return name std::string identifier of this refinement operator.
-   */
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  /**
-   * The priority of cell-centered double linear interpolation is 0.
-   * It will be performed before any user-defined interpolation operations.
-   */
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  /**
-   * The stencil width of the linear interpolation operator is the vector
-   * of ones.  That is, its stencil extends one cell outside the fine box.
-   */
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getOne(getDim());
-  }
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the cell-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the boxes contained in fine_overlap
-   * It is assumed that the coarse patch contains sufficient data for the
-   * stencil width of the refinement operator.
-   */
-  virtual void refine(hier::Patch& fine,
-                      const hier::Patch& coarse,
-                      const int dst_component,
-                      const int src_component,
-                      const hier::BoxOverlap& fine_overlap,
-                      const hier::IntVector& ratio) const;
-
-
-private:
-  std::string d_name_id;
-
-  void Update_P_2D(const pdat::CellIndex &fine,
-                   const hier::Index &ip, const hier::Index &jp,
-                   const int &j, const int &j_max,
-                   SAMRAI::pdat::CellData<double> &p,
-                   SAMRAI::pdat::CellData<double> &p_fine)
-    const;
-
-  void Update_P_3D(const pdat::CellIndex &fine,
-                   const hier::Index &ip, const hier::Index &jp,
-                   const hier::Index &kp,
-                   const int &j, const int &k, const int &j_max, const int &k_max,
-                   SAMRAI::pdat::CellData<double> &p,
-                   SAMRAI::pdat::CellData<double> &p_fine)
-    const;
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Boundary_Refine/Update_P_2D.C
--- a/src/P_Boundary_Refine/Update_P_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#include "P_Boundary_Refine.h"
-
-/* Interpolate the pressure from the coarse (C) to the fine (f+/-)
-   coordinates using the intermediate fine points (F+/-, F_).
-
-         i-1      i       i+1
-
-        ------- -------
-       |       |       |
-   j-1 |   C   |   C   |   C
-       |       |       |
-        ------- -------
-       |       |f- F-  |
-   j   |   C   |F_ C   |   C
-       |       |f+ F+  |
-        ------- -------
-       |       |       |
-   j+1 |   C   |   C   |   C
-       |       |       |
-        ------- -------
-
-   C= a + b*x + c*x^2 + d*y + e*y^2 + f*x*y
-
-   C(0,0)=a
-   C(+,0)=a+b+c
-   C(-,0)=a-b+c
-   C(0,+)=a+d+e
-   C(0,-)=a-d+e
-   C(-,-)=a-b+c-d+e+f
-
-   f(-,-) = a - b/4 + c/16 - d/4 + e/16 + f/16
-          = C(-,-)/16 + (15/16)*C(0,0)
-            + (3/32)*(-C(+,0) - C(0,+) + C(-,0) + C(0,-))
-   
-   This example show a boundary in the positive x direction.  To reverse
-   the direction, pass in ip -> -ip.  To do the y direction, switch ip
-   and jp, and replace j with i.
-
-*/
-     
-
-void SAMRAI::geom::P_Boundary_Refine::Update_P_2D
-(const pdat::CellIndex &fine,
- const hier::Index &ip, const hier::Index &jp,
- const int &j, const int &j_max,
- SAMRAI::pdat::CellData<double> &p,
- SAMRAI::pdat::CellData<double> &p_fine) const
-{
-  pdat::CellIndex center(fine);
-  center.coarsen(hier::Index(2,2));
-
-    
-  /* If we are at an even index, update both of the elements in the cell */
-  if(j%2==0)
-    {
-      const double p_low=p(center-ip-jp)/16 + (15.0/16)*p(center)
-        + (3.0/32)*(-p(center+ip) - p(center+jp) + p(center-ip) + p(center-jp));
-      p_fine(fine)=p_low;
-      if(j<j_max)
-        {
-          const double p_high=p(center-ip+jp)/16 + (15.0/16)*p(center)
-            + (3.0/32)*(-p(center+ip) - p(center-jp)
-                        + p(center-ip) + p(center+jp));
-          p_fine(fine+jp)=p_high;
-        }
-    }
-  else
-    {
-      const double p_high=p(center-ip+jp)/16 + (15.0/16)*p(center)
-        + (3.0/32)*(-p(center+ip) - p(center-jp)
-                    + p(center-ip) + p(center+jp));
-      p_fine(fine)=p_high;
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Boundary_Refine/Update_P_3D.C
--- a/src/P_Boundary_Refine/Update_P_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#include "P_Boundary_Refine.h"
-
-/* Interpolate the pressure from the coarse (C) to the fine (f+/-)
-   coordinates using the intermediate fine points (F+/-, F_).
-
-          i-1      i       i+1
-
-        ------- -------
-       |       |       |
-   j-1 |  C    |   C   |   C
-       |       |       |
-       ------- -------
-       |       |f- Y-  |
-   j   |   C   |X_ C   |   C
-       |       |f+ Y+  |
-       ------- -------
-       |       |       |
-   j+1 |   C   |   C   |   C
-       |       |       |
-       ------- -------
-
-
-   C= a + b*x + c*x^2 + d*y + e*y^2 + f*z + g*z^2
-        + h*x*y + i*x*z + j*y*z + k*x*y*z
-
-   C(0,0,0)=a
-   C(+,0,0)=a+b+c
-   C(-,0,0)=a-b+c
-   C(0,+,0)=a+d+e
-   C(0,-,0)=a-d+e
-   C(-,-,0)=a-b+c-d+e+h
-   C(-,-,-)=a-b+c-d+e-f+g+h+i+j-k
-
-   f(-,-) = a - b/4 + c/16 - d/4 + e/16 - f/4 + g/16 + h/16 + i/16 + j/16 - k/64
-          = C(-,-)/64 + (63/64)*C(0,0)
-            - (6/64)*(C(+,0,0) + C(0,+,0) + C(0,0,+))
-            + (3/64)*(C(-,0,0) + C(0,-,0) + C(0,0,-)
-                      + C(-,-,0) + C(-,0,-) + C(0,-,-))
-
-   Note that if, for example, C is constant in the Z direction, then
-   this formula reduces to the one used in Update_P_2D.
-
-   This example show a boundary in the positive x direction.  To
-   reverse the direction, pass in ip -> -ip.  To do the y direction,
-   rotate [ip,jp,kp], and switch j with k.  To do z, rotate again and
-   switch k with i.
-*/
-     
-
-void SAMRAI::geom::P_Boundary_Refine::Update_P_3D
-(const pdat::CellIndex &fine,
- const hier::Index &ip, const hier::Index &jp, const hier::Index &kp,
- const int &j, const int &k, const int &j_max, const int &k_max,
- SAMRAI::pdat::CellData<double> &p,
- SAMRAI::pdat::CellData<double> &p_fine) const
-{
-  pdat::CellIndex center(fine);
-  center.coarsen(hier::Index(2,2,2));
-
-  const double p_mmm=p(center-ip-jp-kp)/64 + (63.0/64)*p(center)
-    - (3.0/32) * (p(center+ip) + p(center+jp) + p(center+kp))
-    + (3.0/64) * (p(center-ip) + p(center-jp) + p(center-kp)
-                  + p(center-ip-jp) + p(center-jp-kp) + p(center-ip-kp));
-
-  const double p_mmp=p(center-ip-jp+kp)/64 + (63.0/64)*p(center)
-    - (3.0/32) * (p(center+ip) + p(center+jp) + p(center-kp))
-    + (3.0/64) * (p(center-ip) + p(center-jp) + p(center+kp)
-                  + p(center-ip-jp) + p(center-jp+kp) + p(center-ip+kp));
-
-  const double p_mpm=p(center-ip+jp-kp)/64 + (63.0/64)*p(center)
-    - (3.0/32) * (p(center+ip) + p(center-jp) + p(center+kp))
-    + (3.0/64) * (p(center-ip) + p(center+jp) + p(center-kp)
-                  + p(center-ip+jp) + p(center+jp-kp) + p(center-ip-kp));
-
-  const double p_mpp=p(center-ip+jp+kp)/64 + (63.0/64)*p(center)
-    - (3.0/32) * (p(center+ip) + p(center-jp) + p(center-kp))
-    + (3.0/64) * (p(center-ip) + p(center+jp) + p(center+kp)
-                  + p(center-ip+jp) + p(center+jp+kp) + p(center-ip+kp));
-
-  /* If we are at an even index, update both of the elements in the cell */
-  if(j%2==0)
-    {
-      if(k%2==0)
-        {
-          p_fine(fine)=p_mmm;
-          if(j<j_max)
-            p_fine(fine+jp)=p_mpm;
-          if(k<k_max)
-            p_fine(fine+kp)=p_mmp;
-          if(j<j_max && k<k_max)
-            p_fine(fine+jp+kp)=p_mpp;
-        }
-      else
-        {
-          p_fine(fine)=p_mmp;
-          if(j<j_max)
-            p_fine(fine+jp)=p_mpp;
-        }
-    }
-  else
-    {
-      if(k%2==0)
-        {
-          p_fine(fine)=p_mpm;
-          if(k<k_max)
-            p_fine(fine+kp)=p_mpp;
-        }
-      else
-        {
-          p_fine(fine)=p_mpp;
-        }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Boundary_Refine/refine.C
--- a/src/P_Boundary_Refine/refine.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-#include "P_Boundary_Refine.h"
-#include "set_boundary.h"
-#include "Constants.h"
-
-void SAMRAI::geom::P_Boundary_Refine::refine(hier::Patch& fine,
-                                             const hier::Patch& coarse,
-                                             const int dst_component,
-                                             const int src_component,
-                                             const hier::BoxOverlap& overlap,
-                                             const hier::IntVector& ratio)
-  const
-{
-  const pdat::CellOverlap* t_overlap =
-    dynamic_cast<const pdat::CellOverlap *>(&overlap);
-  const hier::BoxList& boxes = t_overlap->getDestinationBoxList();
-  const tbox::Dimension& dimension(getDim());
-  const int dim(dimension.getValue());
-
-  set_boundary(coarse,src_component,invalid_id,true);
-
-  for (hier::BoxList::Iterator b(boxes); b; b++)
-    {
-      hier::Box &overlap_box=b();
-      TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension,fine,coarse,overlap_box,ratio);
-
-      tbox::Pointer<pdat::CellData<double> >
-        p = coarse.getPatchData(src_component);
-      tbox::Pointer<pdat::CellData<double> >
-        p_fine = fine.getPatchData(dst_component);
-#ifdef DEBUG_CHECK_ASSERTIONS
-      TBOX_ASSERT(!p.isNull());
-      TBOX_ASSERT(!p_fine.isNull());
-      TBOX_ASSERT(p->getDepth() == p_fine->getDepth());
-      TBOX_ASSERT(p->getDepth() == 1);
-#endif
-
-      hier::Box fine_box=fine.getBox();
-      hier::Box gbox=p_fine->getGhostBox();
-
-      /* We have to infer where the boundary is from the boxes */
-      int boundary_direction;
-      bool boundary_positive;
-
-      for(int d=0;d<dim;++d)
-        {
-          if(overlap_box.lower(d)-overlap_box.upper(d)==0)
-            {
-              boundary_direction=d;
-              if(fine_box.upper(d)<overlap_box.lower(d))
-                boundary_positive=true;
-              else if(fine_box.lower(d)>overlap_box.upper(d))
-                boundary_positive=false;
-              else
-                abort();
-              break;
-            }
-        }
-
-      hier::Index p_min(dimension), p_max(dimension);
-      for(int d=0;d<dim;++d)
-        {
-          p_min[d]=std::max(overlap_box.lower(d),gbox.lower(d));
-          p_max[d]=std::min(overlap_box.upper(d),gbox.upper(d));
-        }
-
-      hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
-      ip[0]=1;
-      jp[1]=1;
-      if(dim>2)
-        kp[2]=1;
-
-      if(dim==2)
-        {
-          /* This odd stride is because we handle all of the fine
-           * boundary cells in a coarse cell at once.  However,
-           * sometimes there is only one fine cell in a coarse cell,
-           * so the starting point does not align with the coarse
-           * cell.  The stride ensures that, if we start not aligned,
-           * the next step will be aligned. */
-
-          for(int j=p_min[1]; j<=p_max[1]; j=(j/2)*2+2)
-            for(int i=p_min[0]; i<=p_max[0]; i=(i/2)*2+2)
-              {
-                pdat::CellIndex fine(hier::Index(i,j));
-        
-                switch(boundary_direction)
-                  {
-                  case 0:
-                    Update_P_2D(fine,boundary_positive ? ip : -ip,jp,j,p_max[1],
-                                *p,*p_fine);
-                    break;
-                  case 1:
-                    Update_P_2D(fine,boundary_positive ? jp : -jp,ip,i,p_max[0],
-                                *p,*p_fine);
-                    break;
-                  }
-              }
-        }
-      else
-        {
-          for(int k=p_min[2]; k<=p_max[2]; ++k)
-            for(int j=p_min[1]; j<=p_max[1]; ++j)
-              for(int i=p_min[0]; i<=p_max[0]; ++i)
-                {
-                  pdat::CellIndex fine(hier::Index(i,j,k));
-        
-                  switch(boundary_direction)
-                    {
-                    case 0:
-                      Update_P_3D(fine,boundary_positive ? ip : -ip,jp,kp,
-                                  j,k,p_max[1],p_max[2],*p,*p_fine);
-                      break;
-                    case 1:
-                      Update_P_3D(fine,boundary_positive ? jp : -jp,kp,ip,
-                                  k,i,p_max[2],p_max[0],*p,*p_fine);
-                      break;
-                    case 2:
-                      Update_P_3D(fine,boundary_positive ? kp : -kp,ip,jp,
-                                  i,j,p_max[0],p_max[1],*p,*p_fine);
-                      break;
-                    }
-                }
-        }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Refine.C
--- a/src/P_Refine.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for cell-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_P_Refine_C
-#define included_geom_P_Refine_C
-
-#include "P_Refine.h"
-
-#include <float.h>
-#include <math.h>
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include "SAMRAI/tbox/Utilities.h"
-
-void SAMRAI::geom::P_Refine::refine(
-   hier::Patch& fine,
-   const hier::Patch& coarse,
-   const int dst_component,
-   const int src_component,
-   const hier::BoxOverlap& fine_overlap,
-   const hier::IntVector& ratio) const
-{
-   const pdat::CellOverlap* t_overlap =
-      dynamic_cast<const pdat::CellOverlap *>(&fine_overlap);
-
-   TBOX_ASSERT(t_overlap != NULL);
-
-   const hier::BoxList& boxes = t_overlap->getDestinationBoxList();
-   for (hier::BoxList::Iterator b(boxes); b; b++) {
-      refine(fine,
-         coarse,
-         dst_component,
-         src_component,
-         b(),
-         ratio);
-   }
-}
-
-void SAMRAI::geom::P_Refine::refine(
-   hier::Patch& fine_patch,
-   const hier::Patch& coarse_patch,
-   const int dst_component,
-   const int src_component,
-   const hier::Box& fine_box,
-   const hier::IntVector& ratio) const
-{
-   const tbox::Dimension& dim(getDim());
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dim, fine_patch, coarse_patch,
-                                   fine_box, ratio);
-
-   tbox::Pointer<pdat::CellData<double> >
-   p = coarse_patch.getPatchData(src_component);
-   tbox::Pointer<pdat::CellData<double> >
-   p_fine = fine_patch.getPatchData(dst_component);
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(!p.isNull());
-   TBOX_ASSERT(!p_fine.isNull());
-   TBOX_ASSERT(p->getDepth() == p_fine->getDepth());
-#endif
-
-   hier::Box coarse_box=coarse_patch.getBox();
-   tbox::Pointer<geom::CartesianPatchGeometry>
-     geom = coarse_patch.getPatchGeometry();
-
-   for(pdat::CellIterator ci(fine_box); ci; ci++)
-     {
-       pdat::CellIndex fine(*ci);
-
-       pdat::CellIndex
-         center(hier::Index::coarsen(fine,hier::Index::getOneIndex(dim)*2));
-
-       /* Pressure is cell-centered, so prolongation is a
-          linear interpolation from nearby cells. */
-
-       /* This assumes that the levels are always properly nested,
-          so that we always have an extra grid space for
-          interpolation.  So we only have to have a special case for
-          physical boundaries, where we do not have an extra grid
-          space. */
-
-       /* We could, in theory, use a refine_patch_strategy to fill
-          in the ghost zones with extrapolations, and then use
-          simple differences here. */
-
-       (*p_fine)(fine)=(*p)(center);
-       for(int d=0; d<dim.getValue(); ++d)
-         {
-           hier::Index ip(hier::Index::getZeroIndex(dim));
-           ip[d]=1;
-           double dp;
-           if(center[d]==coarse_box.lower(d)
-              && geom->getTouchesRegularBoundary(d,0))
-             {
-               dp=((*p)(center+ip)-(*p)(center))/4;
-             }
-           else if(center[d]==coarse_box.upper(d)
-                   && geom->getTouchesRegularBoundary(d,1))
-             {
-               dp=((*p)(center)-(*p)(center-ip))/4;
-             }
-           else
-             {
-               dp=((*p)(center+ip)-(*p)(center-ip))/8;
-             }
-           (*p_fine)(fine)+=((fine[d]%2==0) ? (-dp) : dp);
-         }           
-       }
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Refine.h
--- a/src/P_Refine.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for cell-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_P_Refine
-#define included_geom_P_Refine
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/CellVariable.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Class P_Refine implements linear
- * interpolation for cell-centered double patch data defined over a Cartesian
- * mesh.  It is derived from the xfer::RefineOperator base class.
- * CartesianCellDoubleLinearRefine does not handle the lack of real
- * boundaries for the pressure very well, so use this instead for
- * pressure.
- *
- * The findRefineOperator() operator function returns true if the input
- * variable is cell-centered double, and the std::string is "P_REFINE".
- *
- * @see xfer::RefineOperator
- */
-
-class P_Refine:
-  public xfer::RefineOperator
-{
-public:
-  /**
-   * Uninteresting default constructor.
-   */
-  explicit P_Refine(const tbox::Dimension& dim):
-    xfer::RefineOperator(dim, "P_REFINE")
-  {
-    d_name_id = "P_REFINE";
-  }
-
-
-  /**
-   * Uninteresting virtual destructor.
-   */
-  virtual ~P_Refine(){}
-
-  /**
-   * Return true if the variable and name std::string match cell-centered
-   * double linear interpolation; otherwise, return false.
-   */
-  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
-                          const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  /**
-   * Return name std::string identifier of this refinement operator.
-   */
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  /**
-   * The priority of cell-centered double linear interpolation is 0.
-   * It will be performed before any user-defined interpolation operations.
-   */
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  /**
-   * The stencil width of the linear interpolation operator is the vector
-   * of ones.  That is, its stencil extends one cell outside the fine box.
-   */
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getOne(getDim());
-  }
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the cell-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the boxes contained in fine_overlap
-   * It is assumed that the coarse patch contains sufficient data for the
-   * stencil width of the refinement operator.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::BoxOverlap& fine_overlap,
-              const hier::IntVector& ratio) const;
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the cell-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the fine box.   It is assumed that the
-   * coarse patch contains sufficient data for the stencil width of the
-   * refinement operator.  This differs from the above refine() method
-   * only in that it operates on a single fine box instead of a BoxOverlap.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::Box& fine_box,
-              const hier::IntVector& ratio) const;
-
-private:
-  std::string d_name_id;
-
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/P_Refine_Patch_Strategy.h
--- a/src/P_Refine_Patch_Strategy.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Robin boundary condition support on cartesian grids. 
- *
- ************************************************************************/
-#ifndef included_solv_P_Refine_Patch_Strategy
-#define included_solv_P_Refine_Patch_Strategy
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefinePatchStrategy.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/CellIndex.h"
-#include "Constants.h"
-#include "set_boundary.h"
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief Helper utility for setting boundary conditions on P.
- *
- * This class inherits and implements virtual functions from
- * xfer::RefinePatchStrategy so it may be used to help create
- * communication schedules if desired.
- */
-class P_Refine_Patch_Strategy:
-   public xfer::RefinePatchStrategy
-{
-
-public:
-   /*!
-    * @brief Constructor using.
-    *
-    * @param object_name Name of the object, for general referencing.
-    * @param coef_strategy Coefficients strategy being helped.
-    */
-   P_Refine_Patch_Strategy(
-      const tbox::Dimension& dim,
-      std::string object_name = std::string()):
-     xfer::RefinePatchStrategy(dim), d_dim(dim),d_object_name(object_name) {}
-
-   /*!
-    * @brief Destructor.
-    */
-   virtual ~P_Refine_Patch_Strategy(void) {}
-
-   //@{ @name xfer::RefinePatchStrategy virtuals
-
-   virtual void
-   setPhysicalBoundaryConditions(
-      hier::Patch& ,
-      const double ,
-      const hier::IntVector& ) {}
-   hier::IntVector
-   getRefineOpStencilWidth() const
-  { return hier::IntVector::getOne(d_dim); }
-   // virtual void
-   // preprocessRefineBoxes(
-   //    hier::Patch& fine,
-   //    const hier::Patch& coarse,
-   //    const hier::BoxList& fine_boxes,
-   //    const hier::IntVector& ratio) {}
-   virtual void
-   preprocessRefine(hier::Patch& ,
-                    const hier::Patch& coarse,
-                    const hier::Box& ,
-                    const hier::IntVector& )
-  {
-    set_boundary(coarse,p_id,invalid_id,true);
-  }
-
-   virtual void
-   postprocessRefineBoxes(
-      hier::Patch& ,
-      const hier::Patch& ,
-      const hier::BoxList& ,
-      const hier::IntVector& ) {}
-   virtual void
-   postprocessRefine(
-      hier::Patch& ,
-      const hier::Patch& ,
-      const hier::Box& ,
-      const hier::IntVector& ) {}
-
-   //@}
-
-   //@{
-
-   /*!
-    * @name Functions to set boundary condition values
-    */
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the first ghost cells.
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to cell-centered variables.
-    * -# Only one ghost cell width is filled.  Setting a Robin
-    *    boundary condition for cell-centered quantities requires
-    *    only one ghost cell to be set.
-    *    (More ghost cells can be filled by continuing the linear
-    *    distribution of data beyond the first cell, but that is
-    *    not implemented at this time.)
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to
-    * get the coefficients, then it sets the values in the first
-    * ghost cell on the boundary.
-    *
-    * To determine the value for the ghost cell,
-    * a @em linear approximation in the direction normal to the
-    * boundary is assumed.  We write the following discrete
-    * approximations:
-    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
-    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
-    * where the subscript b stands for the the boundary,
-    * i stands for the first cell inside the boundary and
-    * o stands for the first cell outside the boundary
-    * and h is the grid spacing normal to the boundary.
-    * Applying this to the Robin formula gives
-    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
-    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
-    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
-    *
-    * After setting the edge (face in 3D) boundary conditions,
-    * linear approximations are used to set the boundary conditions
-    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required in solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @internal To be more general to other data types,
-    * there could be versions for other data types also,
-    * such as ...InNodes, ...InFaces, etc.  However, I'm not
-    * sure exactly how to implement the Robin boundary condition
-    * on the faces and nodes when m != 1.  Should the boundary
-    * value be set or should the first ghost value be set?
-    *
-    * @internal I have not addressed possibility of differences
-    * in chosing the discrete formulation with which to compute
-    * the boundary value.  The above formulation is obviously
-    * one specific approximation, but there could be others.
-    * If anoter approximation is required, there should be
-    * another class like this or this class can offer a choice
-    * to be set by the user.  I favor another class.
-    *
-    * @internal Since the data alignment can be found through
-    * the target_data_id, these types of functions may be changed
-    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
-    * since it does assume boundary boxes.  This may have to be
-    * expanded to later include coarse-fine boundary boxes
-    * for more generality.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set ghost cells for an entire level.
-    *
-    * Loop through all patches on the given level and call
-    * setBoundaryValuesInCells(hier::Patch &patch,
-    *                          const double fill_time ,
-    *                          const hier::IntVector &ghost_width_to_fill ,
-    *                          int target_data_id ,
-    *                          bool homogeneous_bc=false )
-    * for each.
-    *
-    * @param level PatchLevel on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::PatchLevel& level,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the boundary nodes.
-    *
-    * This function is not yet implemented!
-    *
-    * There are some decisions that must be made before
-    * the implementation can be written.
-    * -# Do we set the values on the boundary or one cell
-    *    away from the boundary?
-    * -# What is the discrete formulation we should use
-    *    to compute the value to be set?
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to node-centered variables.
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to get the
-    * coefficients, then it sets the values at the boundary nodes.
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required to solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param target_data_id hier::Patch data index of data to be set.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesAtNodes(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   //@}
-
-   //@{
-   /*!
-    * @name Ways to provide the Robin bc coefficients
-    */
-
-   /*!
-    * @brief Provide an implementation of the RobinBcCoefStrategy
-    * for determining the boundary coefficients.
-    *
-    * Provide the implementation that can be used to set the
-    * Robin bc coefficients.
-    *
-    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
-    *        the coefficient strategy.
-    */
-   // void
-   // setCoefImplementation(
-   //    const RobinBcCoefStrategy* coef_strategy);
-
-   /*!
-    * @brief Set the data id that should be filled when setting
-    * physical boundary conditions.
-    *
-    * When setPhysicalBoundaryConditions is called, the data
-    * specified will be set.  This information is required because
-    * the it is not passed in through the argument list of
-    * setPhysicalBounaryConditions.
-    */
-  void setTargetDataId(int id)
-  {
-    p_id=id;
-  }
-
-   /*!
-    * @brief Set whether boundary filling should assume homogeneous
-    * conditions.
-    *
-    * In certain circumstances, only the value of a is needed, while
-    * the value of g is temporarily not required and taken to be zero.
-    * (An example is in setting the boundary condition for error
-    * value in an iterative method.)  In such cases, use this function
-    * to set a flag that will cause a null pointer to be given to
-    * setBcCoefs() to indicate that fact.
-    */
-   // void
-   // setHomogeneousBc(
-   //    bool homogeneous_bc);
-
-   //@}
-
-private:
-   /*!
-    * @brief Trim a boundary box so that it does not stick out
-    * past a given box.
-    *
-    * Certain boundary-related operations occur on patch data that
-    * do not or cannot extend past the edgr or corner of a patch.
-    * This function is used to trim down the parts of the boundary box
-    * that extend past those points so that a suitable index range
-    * is achieved.
-    *
-    * The boundary box trimmed must be of type 1 or 2.
-    *
-    * @param boundary_box Boundary box to be trimmed.
-    * @param limit_box hier::Box to not stick past
-    *
-    * @return New trimmed boundary box.
-    */
-   // hier::BoundaryBox
-   // trimBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box,
-   //    const hier::Box& limit_box) const;
-
-   /*!
-    * @brief Return box describing the index space of boundary nodes
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the nodes corresponding
-    * to the input boundary box.  These nodes lie on the boundary
-    * itself.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the node indices corresponding to
-    *   boundary_box
-    */
-   // hier::Box
-   // makeNodeBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   /*!
-    * @brief Return box describing the index space of faces
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the codimension 1
-    * surface corresponding to the input boundary box.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * This is a utility function for working with the
-    * indices coresponding to a boundary box but coincide
-    * with the patch boundary.
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the face indices corresponding to
-    *    boundary_box
-    */
-   // hier::Box
-   // makeFaceBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   const tbox::Dimension d_dim;
-
-   std::string d_object_name;
-
-   /*!
-    * @brief Coefficient strategy giving a way to get to
-    * Robin bc coefficients.
-    */
-   // const RobinBcCoefStrategy* d_coef_strategy;
-
-   /*!
-    * @brief hier::Index of target patch data when filling ghosts.
-    */
-   int p_id;
-
-   /*!
-    * @brief Whether to assumg g=0 when filling ghosts.
-    */
-   // bool d_homogeneous_bc;
-
-   /*!
-    * @brief Timers for performance measurement.
-    */
-   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
-   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
-};
-
-}
-}
-
-#endif  // included_solv_P_Refine_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/Resid_Coarsen.C
--- a/src/Resid_Coarsen.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-#include "Resid_Coarsen.h"
-
-/**
- * Coarsens using the moduli as weights.  So in 2D
-   resid_coarse = (resid(i,j)*moduli(i,j)
-                   + resid(i,j+1)*moduli(i,j+1)
-                   + resid(i+1,j)*moduli(i+1,j)
-                   + resid(i+1,j+1)*moduli(i+1,j+1))/(4*moduli_coarse)
- */
-
-void SAMRAI::geom::Resid_Coarsen::coarsen(hier::Patch& coarse,
-                                          const hier::Patch& fine,
-                                          const int dst_component,
-                                          const int src_component,
-                                          const hier::Box& coarse_box,
-                                          const hier::IntVector& ratio) const
-{
-  const tbox::Dimension& dimension(getDim());
-  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, coarse, fine, coarse_box, ratio);
-  
-  tbox::Pointer<pdat::CellData<double> >
-    r_fine_ptr = fine.getPatchData(src_component);
-  pdat::CellData<double> &r_fine(*r_fine_ptr);
-  tbox::Pointer<pdat::CellData<double> >
-    r_ptr = coarse.getPatchData(dst_component);
-  pdat::CellData<double> &r(*r_ptr);
-  tbox::Pointer<pdat::CellData<double> >
-    cell_moduli_fine_ptr = fine.getPatchData(cell_moduli_id);
-  pdat::CellData<double> &cell_moduli_fine(*cell_moduli_fine_ptr);
-
-  TBOX_ASSERT(!r_ptr.isNull());
-  TBOX_ASSERT(!r_fine_ptr.isNull());
-  TBOX_ASSERT(r_fine.getDepth() == r.getDepth());
-  TBOX_ASSERT(r.getDepth() == 1);
-
-  hier::Box cell_box(hier::Index::getZeroIndex(dimension),
-                     hier::Index::getOneIndex(dimension));
-
-  for(pdat::CellIterator ci(coarse.getBox()); ci; ci++)
-    {
-      pdat::CellIndex coarse(*ci);
-      pdat::CellIndex fine(coarse*2);
-      double temp(0), moduli_sum(0);
-
-      for(pdat::CellIterator ii(cell_box); ii; ii++)
-        {
-          pdat::CellIndex i(*ii);
-          temp+=r_fine(fine+i)*(cell_moduli_fine(fine+i,0)+cell_moduli_fine(fine+i,1));
-          moduli_sum+=(cell_moduli_fine(fine+i,0)+cell_moduli_fine(fine+i,1));
-        }
-      r(coarse)=temp/moduli_sum;
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/Resid_Coarsen.h
--- a/src/Resid_Coarsen.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#ifndef included_geom_Resid_Coarsen
-#define included_geom_Resid_Coarsen
-
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/pdat/CellVariable.h"
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Coarsens using the moduli as weights.  So in 2D
-   resid_coarse = (resid(i,j)*moduli(i,j)
-                   + resid(i,j+1)*moduli(i,j+1)
-                   + resid(i+1,j)*moduli(i+1,j)
-                   + resid(i+1,j+1)*moduli(i+1,j+1))/(4*moduli_coarse)
- * @see xfer::CoarsenOperator
- */
-
-class Resid_Coarsen:
-   public xfer::CoarsenOperator
-{
-public:
-  explicit Resid_Coarsen(const tbox::Dimension& dim,
-                         const int &cell_moduli):
-    xfer::CoarsenOperator(dim, "RESID_COARSEN"),
-    cell_moduli_id(cell_moduli)
-  {
-    d_name_id = "RESID_COARSEN";
-  }
-
-  virtual ~Resid_Coarsen(){}
-
-  bool findCoarsenOperator(const tbox::Pointer<hier::Variable>& var,
-                           const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::CellVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getZero(getDim());
-  }
-
-  void coarsen(hier::Patch& coarse,
-               const hier::Patch& fine,
-               const int dst_component,
-               const int src_component,
-               const hier::Box& coarse_box,
-               const hier::IntVector& ratio) const;
-
-private:
-  std::string d_name_id;
-  const int cell_moduli_id;
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Boundary_Refine.h
--- a/src/V_Boundary_Refine.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_V_Boundary_Refine
-#define included_geom_V_Boundary_Refine
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Class V_Boundary_Refine implements the special interpolation needed
- * for the boundary elements on the coarse-fine interface.
- *
- * The findRefineOperator() operator function returns true if the input
- * variable is side-centered double, and the std::string is "V_BOUNDARY_REFINE".
- *
- * @see xfer::RefineOperator
- */
-
-class V_Boundary_Refine:
-  public xfer::RefineOperator
-{
-public:
-  /**
-   * Uninteresting default constructor.
-   */
-  explicit V_Boundary_Refine(const tbox::Dimension& dim):
-    xfer::RefineOperator(dim, "V_BOUNDARY_REFINE")
-  {
-    d_name_id = "V_BOUNDARY_REFINE";
-  }
-
-
-  /**
-   * Uninteresting virtual destructor.
-   */
-  virtual ~V_Boundary_Refine(){}
-
-  /**
-   * Return true if the variable and name std::string match side-centered
-   * double linear interpolation; otherwise, return false.
-   */
-  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
-                          const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  /**
-   * Return name std::string identifier of this refinement operator.
-   */
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  /**
-   * The priority of side-centered double linear interpolation is 0.
-   * It will be performed before any user-defined interpolation operations.
-   */
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  /**
-   * The stencil width of the linear interpolation operator is the vector
-   * of ones.  That is, its stencil extends one side outside the fine box.
-   */
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getOne(getDim());
-  }
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the side-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the boxes contained in fine_overlap
-   * It is assumed that the coarse patch contains sufficient data for the
-   * stencil width of the refinement operator.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::BoxOverlap& fine_overlap,
-              const hier::IntVector& ratio) const;
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the side-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the fine box.   It is assumed that the
-   * coarse patch contains sufficient data for the stencil width of the
-   * refinement operator.  This differs from the above refine() method
-   * only in that it operates on a single fine box instead of a BoxOverlap.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::Box& fine_box,
-              const hier::IntVector& ratio,
-              const int &axis) const;
-
-private:
-  std::string d_name_id;
-
-  void Update_V_2D
-  (const int &axis,
-   const int &boundary_direction,
-   const bool &boundary_positive,
-   const pdat::SideIndex &fine,
-   const hier::Index &ip, const hier::Index &jp,
-   int &i, int &j,
-   const int &i_max,
-   const int &j_min,
-   const int &j_max,
-   pdat::SideData<double> &v,
-   pdat::SideData<double> &v_fine) const;
-
-  void Update_V_3D
-  (const int &axis,
-   const int &boundary_direction,
-   const bool &boundary_positive,
-   const pdat::SideIndex &fine,
-   const hier::Index pp[],
-   const hier::Index &ijk,
-   const hier::Index &p_min, const hier::Index &p_max,
-   SAMRAI::pdat::SideData<double> &v,
-   SAMRAI::pdat::SideData<double> &v_fine) const;
-
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Boundary_Refine/Update_V_2D.C
--- a/src/V_Boundary_Refine/Update_V_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-#include "V_Boundary_Refine.h"
-#include "quad_offset_interpolate.h"
-#include "Constants.h"
-
-/* This is written from the perspective of axis==x.  For axis==y, we
-   switch i and j and everything works out. */
-void SAMRAI::geom::V_Boundary_Refine::Update_V_2D
-(const int &axis,
- const int &boundary_direction,
- const bool &boundary_positive,
- const pdat::SideIndex &fine,
- const hier::Index &ip, const hier::Index &jp,
- int &i, int &j,
- const int &i_max,
- const int &j_min,
- const int &j_max,
- SAMRAI::pdat::SideData<double> &v,
- SAMRAI::pdat::SideData<double> &v_fine) const
-{
-  /* Set the derivative for the normal direction
-
-         i-1      i       i+1
-
-        ------- -------
-       |   f   f   F   |
-   j-1 C       C       C
-       |   f   f   F   |
-        ------- -------
-       |   f   f   F   |
-   j   C       C       C
-       |   f   f   F   |
-        ------- -------
-       |   f   f   F   |
-   j+1 C       C       C
-       |   f   f   F   |
-        ------- -------
-               |
-               |
-               |
-        Coarse-Fine Boundary
-
-    So we need to set F such that the derivative at the coarse-fine
-    boundary is coorrect.  We can compute the derivative at the coarse
-    points on the boundary, and then use quadratic interpolation to
-    get the derivative at the fine points on the boundary.
-
- */
-  if(boundary_direction==axis)
-    {
-      /* Return early if we are at j==j_max, because that is a corner
-         that we do not care about.  We could also skip if j==j_min as
-         long as we do not have to do j_min+1. We do not really have
-         to skip these since we are guaranteed to have valid data for
-         those "past the end" points since they are needed for
-         pressure refinement.  */
-      if(j==j_max || (j==j_min && j%2!=0))
-        return;
-      /* Compute the derivative at the nearest three coarse points and
-         then interpolate */
-
-      hier::Index ip_s(boundary_positive ? ip : -ip);
-
-      pdat::SideIndex center(fine-ip_s);
-      center.coarsen(hier::Index(2,2));
-
-      const double dv_plus=v(center+jp+ip_s)-v(center+jp-ip_s);
-      const double dv_minus=v(center-jp+ip_s)-v(center-jp-ip_s);
-      const double dv_center=v(center+ip_s)-v(center-ip_s);
-
-      double dv_fine_minus, dv_fine_plus;
-
-      quad_offset_interpolate(dv_plus,dv_center,dv_minus,
-                              dv_fine_plus,dv_fine_minus);
-
-      hier::Index offset(ip_s*2);
-
-      if(j%2==0)
-        {
-          v_fine(fine)=v_fine(fine-offset) + dv_fine_minus/2;
-          v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_plus/2;
-          /* Since we update two points on j at once, we increment j
-             again.  This is ok, since the box in the 'i' direction is
-             defined to be only one cell wide */
-          ++j;
-        }
-      else
-        {
-          v_fine(fine)=v_fine(fine-offset) + dv_fine_plus/2;
-        }          
-    }
-  /* Set the value for the tangential direction
-
-         i-1      i       i+1
-
-        -f-C-f- -F-C---    C
-       |       |       |
-   j-1 |       |       |    
-       |       |       |
-        -f-C-f- -F-C---    C
-       |       |       |
-   j   |       |       |    
-       |       |       |
-        -f-C-f- -F-C---    C
-       |       |       |
-   j+1 |       |       |    
-       |       |       |
-        -f-C-f- -F-C---    C
-               |
-               |
-               |
-        Coarse-Fine Boundary
-
-    C are the coarse velocities, f are the interior fine velocities,
-    and F are the boundary fine velocities that we need to set.  So we
-    use quadratic interpolation from C to F.
- */
-  else
-    {
-      pdat::SideIndex center(fine);
-      center.coarsen(hier::Index(2,2));
-
-      double v_center, v_plus;
-      hier::Index jp_s(boundary_positive ? jp : -jp);
-
-      v_center=
-        quad_offset_interpolate(v(center-jp_s),v(center),v(center+jp_s));
-
-      if(i%2==0)
-        {
-          v_fine(fine)=v_center;
-
-          if(i<i_max)
-            {
-              /* This is a bit inefficient, because we compute v_plus
-               * twice.  Once for the in-between point, and again
-               * later for the actual point. */
-
-              v_plus=quad_offset_interpolate(v(center+ip-jp_s),v(center+ip),
-                                             v(center+ip+jp_s));
-              v_fine(fine+ip)=(v_center+v_plus)/2;
-
-              /* Since we update two points on 'i' at once, we increment 'i' again.
-                 This is ok, since the box in the 'j' direction is defined to be
-                 only one cell wide */
-              ++i;
-            }
-        }
-      else
-        {
-          v_plus=quad_offset_interpolate(v(center+ip-jp_s),v(center+ip),
-                                         v(center+ip+jp_s));
-          v_fine(fine)=(v_center+v_plus)/2;
-        }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Boundary_Refine/Update_V_3D.C
--- a/src/V_Boundary_Refine/Update_V_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-#include "V_Boundary_Refine.h"
-#include "Constants.h"
-
-/* This is written from the perspective of axis==x.  For axis==y, we
-   switch i and j and everything works out. */
-void SAMRAI::geom::V_Boundary_Refine::Update_V_3D
-(const int &axis,
- const int &boundary_direction,
- const bool &boundary_positive,
- const pdat::SideIndex &fine,
- const hier::Index pp[],
- const hier::Index &ijk,
- const hier::Index &p_min, const hier::Index &p_max,
- SAMRAI::pdat::SideData<double> &v,
- SAMRAI::pdat::SideData<double> &v_fine) const
-{
-  /* Set the derivative for the normal direction.
-
-     We set the derivative on the i=constant plane.  If we look at a
-     slice in that plane.
-
-         k-1      k       k+1
-
-        ------- -------
-       |       |       |
-   j-1 |   D   |   D   |   D
-       |       |       |
-        ------- -------
-       |       |d-- d+-|
-   j   |   D   |   D   |   D
-       |       |d-+ d++|
-        ------- -------
-       |       |       |
-   j+1 |   D   |   D   |   D
-       |       |       |
-        ------- -------
-               |
-               |
-               |
-        Coarse-Fine Boundary
-
-  where D are the coarse derivatives, and d are the fine derivatives.
-  This picture is the same as what is seen in P_Boundary_Refine in 2D.
-  So we can use the formula there to compute d--.
-
-   d(-,-) = a - b/4 + c/16 - d/4 + e/16 + f/16
-          = D(-,-)/16 + (15/16)*D(0,0)
-            + (3/32)*(-D(+,0) - D(0,+) + D(-,0) + D(0,-))
-
-  */
-
-  if(boundary_direction==axis)
-    {
-      /* Return early if we are at j==j_max, because that is a corner
-         that we do not care about.  We also skip if j==j_min as long
-         as we do not have to do j_min+1. We have to skip these even
-         though they are not used because otherwise we could end up
-         reading past the end of the array.  */
-      const int axis2((axis+1)%3), axis3((axis+2)%3);
-      if(ijk[axis2]==p_max[axis2] || (ijk[axis2]==p_min[axis2] && ijk[axis2]%2!=0)
-         || ijk[axis3]==p_max[axis3] 
-         || (ijk[axis3]==p_min[axis3] && ijk[axis3]%2!=0))
-        return;
-      /* Compute the derivative at all of the interpolation points.  */
-
-      const hier::Index ip(boundary_positive ? pp[axis] : -pp[axis]),
-        jp(pp[(axis+1)%3]), kp(pp[(axis+2)%3]);
-
-      pdat::SideIndex center(fine-ip);
-      center.coarsen(hier::Index(2,2,2));
-
-      const double dv_mm=v(center-jp-kp+ip) - v(center-jp-kp-ip);
-      const double dv_m0=v(center-jp+ip) - v(center-jp-ip);
-      const double dv_mp=v(center-jp+kp+ip) - v(center-jp+kp-ip);
-
-      const double dv_0m=v(center-kp+ip) - v(center-kp-ip);
-      const double dv_00=v(center+ip) - v(center-ip);
-      const double dv_0p=v(center+kp+ip) - v(center+kp-ip);
-
-      const double dv_pm=v(center+jp-kp+ip) - v(center+jp-kp-ip);
-      const double dv_p0=v(center+jp+ip) - v(center+jp-ip);
-      const double dv_pp=v(center+jp+kp+ip) - v(center+jp+kp-ip);
-
-      const double dv_fine_mm=dv_mm/16 + (15.0/16)*dv_00
-        + (3/32)*(-dv_p0 - dv_0p + dv_m0 + dv_0m);
-
-      const double dv_fine_mp=dv_mp/16 + (15.0/16)*dv_00
-        + (3/32)*(-dv_p0 - dv_0m + dv_m0 + dv_0p);
-
-      const double dv_fine_pm=dv_pm/16 + (15.0/16)*dv_00
-        + (3/32)*(-dv_m0 - dv_0p + dv_p0 + dv_0m);
-
-      const double dv_fine_pp=dv_pp/16 + (15.0/16)*dv_00
-        + (3/32)*(-dv_m0 - dv_0m + dv_p0 + dv_0p);
-
-      hier::Index offset(ip*2);
-
-      /* Be careful about using the right interpolation if the fine
-       * points are not aligned with the coarse points. */
-      if(ijk[axis2]%2==0)
-        {
-          if(ijk[axis3]%2==0)
-            {
-              v_fine(fine)=v_fine(fine-offset) + dv_fine_mm/2;
-              if(ijk[axis2]<p_max[axis2])
-                v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_pm/2;
-              if(ijk[axis3]<p_max[axis3])
-                v_fine(fine+kp)=v_fine(fine-offset+kp) + dv_fine_mp/2;
-              if(ijk[axis2]<p_max[axis2] && ijk[axis3]<p_max[axis3])
-                v_fine(fine+jp+kp)=v_fine(fine-offset+jp+kp) + dv_fine_pp/2;
-            }
-          else
-            {
-              v_fine(fine)=v_fine(fine-offset) + dv_fine_mp/2;
-              if(ijk[axis2]<p_max[axis2])
-                v_fine(fine+jp)=v_fine(fine-offset+jp) + dv_fine_pp/2;
-            }
-        }
-      else
-        {
-          if(ijk[axis3]%2==0)
-            {
-              v_fine(fine)=v_fine(fine-offset) + dv_fine_pm/2;
-              if(ijk[axis3]<p_max[axis3])
-                v_fine(fine+kp)=v_fine(fine-offset+kp) + dv_fine_pp/2;
-            }
-          else
-            {
-              v_fine(fine)=v_fine(fine-offset) + dv_fine_pp/2;
-            }
-        }          
-    }
-  /* Set the value for the tangential direction.
-
-     Again, if we look at a slice in the i=constant plane.
-
-          j-1      j      j+1
-
-        ------- -------
-       |       |       |
-   k-1 |   V   |   V   |   V
-       |       |       |
-        ------- -------
-       |       |v--    |
-   k   |   V   |   V   |   V
-       |       |v-+    |
-        ------- -------
-       |       |       |
-   k+1 |   V   |   V   |   V
-       |       |       |
-        ------- -------
-               |
-               |
-               |
-        Coarse-Fine Boundary
-
-  where V are the coarse velocities, and v are the fine velocities.
-  This picture is the same as what is seen in P_Boundary_Refine in 2D.
-  So we can use the formula there to compute v--.
-
-   v(-,-) = V(-,-)/16 + (15/16)*V(0,0)
-            + (3/32)*(-V(+,0) - V(0,+) + V(-,0) + V(0,-))
-
- */
-  else
-    {
-      const int axis3((axis+1)%3 != boundary_direction ? (axis+1)%3 : (axis+2)%3);
-      const hier::Index ip(pp[axis]),
-        jp(boundary_positive ? pp[boundary_direction] : -pp[boundary_direction]),
-        kp(pp[axis3]);
-
-      pdat::SideIndex center(fine);
-      center.coarsen(hier::Index(2,2,2));
-
-      double v_minus=v(center-jp-kp)/16 + (15.0/16)*v(center)
-        + (3.0/32)*(-v(center+jp) - v(center+kp) + v(center-jp) + v(center-kp));
-      
-      double v_plus=v(center-jp+kp)/16 + (15.0/16)*v(center)
-        + (3.0/32)*(-v(center+jp) - v(center-kp) + v(center-jp) + v(center+kp));
-
-
-      /* Be careful about using the right interpolation if the fine
-       * points are not aligned with the coarse points. */
-      if(ijk[axis]%2==0)
-        {
-          if(ijk[axis3]%2==0)
-            {
-              v_fine(fine)=v_minus;
-              if(ijk[axis3]<p_max[axis3])
-                v_fine(fine+kp)=v_plus;
-              if(ijk[axis]<p_max[axis])
-                {
-                  double v_minus_off=v(center-jp-kp+ip)/16
-                    + (15.0/16)*v(center+ip)
-                    + (3.0/32)*(-v(center+jp+ip) - v(center+kp+ip)
-                                + v(center-jp+ip) + v(center-kp+ip));
-      
-                  double v_plus_off=v(center-jp+kp+ip)/16
-                    + (15.0/16)*v(center+ip)
-                    + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
-                                + v(center-jp+ip) + v(center+kp+ip));
-
-                  v_fine(fine+ip)=(v_minus+v_minus_off)/2;
-                  if(ijk[axis3]<p_max[axis3])
-                    v_fine(fine+ip+kp)=(v_plus+v_plus_off)/2;
-                }
-            }
-          else
-            {
-              v_fine(fine)=v_plus;
-              if(ijk[axis]<p_max[axis])
-                {
-                  double v_plus_off=v(center-jp+kp+ip)/16
-                    + (15.0/16)*v(center+ip)
-                    + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
-                                + v(center-jp+ip) + v(center+kp+ip));
-
-                  v_fine(fine+ip)=(v_plus+v_plus_off)/2;
-                }
-            }
-        }
-      else
-        {
-          if(ijk[axis3]%2==0)
-            {
-              double v_minus_off=v(center-jp-kp+ip)/16
-                + (15.0/16)*v(center+ip)
-                + (3.0/32)*(-v(center+jp+ip) - v(center+kp+ip)
-                            + v(center-jp+ip) + v(center-kp+ip));
-      
-              double v_plus_off=v(center-jp+kp+ip)/16
-                + (15.0/16)*v(center+ip)
-                + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
-                            + v(center-jp+ip) + v(center+kp+ip));
-
-              v_fine(fine)=(v_minus+v_minus_off)/2;
-              if(ijk[axis3]<p_max[axis3])
-                v_fine(fine+kp)=(v_plus+v_plus_off)/2;
-            }
-          else
-            {
-              double v_plus_off=v(center-jp+kp+ip)/16
-                + (15.0/16)*v(center+ip)
-                + (3.0/32)*(-v(center+jp+ip) - v(center-kp+ip)
-                            + v(center-jp+ip) + v(center+kp+ip));
-
-              v_fine(fine)=(v_plus+v_plus_off)/2;
-            }
-        }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Boundary_Refine/refine.C
--- a/src/V_Boundary_Refine/refine.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#include "V_Boundary_Refine.h"
-#include "set_boundary.h"
-#include "Constants.h"
-
-void SAMRAI::geom::V_Boundary_Refine::refine(
-   hier::Patch& fine,
-   const hier::Patch& coarse,
-   const int dst_component,
-   const int src_component,
-   const hier::BoxOverlap& fine_overlap,
-   const hier::IntVector& ratio) const
-{
-   const pdat::SideOverlap* t_overlap =
-      dynamic_cast<const pdat::SideOverlap *>(&fine_overlap);
-
-   TBOX_ASSERT(t_overlap != NULL);
-
-   set_boundary(coarse,invalid_id,src_component,true);
-
-   for(int axis=0; axis<getDim().getValue(); ++axis)
-     {
-       const hier::BoxList& boxes = t_overlap->getDestinationBoxList(axis);
-       for (hier::BoxList::Iterator b(boxes); b; b++)
-         {
-           refine(fine,coarse,dst_component,src_component,b(),ratio,axis);
-         }
-     }
-}
-
-void SAMRAI::geom::V_Boundary_Refine::refine(hier::Patch& fine,
-                                             const hier::Patch& coarse,
-                                             const int dst_component,
-                                             const int src_component,
-                                             const hier::Box& overlap_box,
-                                             const hier::IntVector& ratio,
-                                             const int &axis) const
-{
-   const tbox::Dimension& dimension(getDim());
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, fine, coarse, overlap_box, ratio);
-   const int dim(dimension.getValue());
-
-   tbox::Pointer<pdat::SideData<double> >
-   v = coarse.getPatchData(src_component);
-   tbox::Pointer<pdat::SideData<double> >
-   v_fine = fine.getPatchData(dst_component);
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(!v.isNull());
-   TBOX_ASSERT(!v_fine.isNull());
-   TBOX_ASSERT(v->getDepth() == v_fine->getDepth());
-   TBOX_ASSERT(v->getDepth() == 1);
-#endif
-
-   hier::Box fine_box=fine.getBox();
-
-   /* We have to infer where the boundary is from the boxes */
-   int boundary_direction;
-   bool boundary_positive(false);
-
-   for(int d=0;d<dim;++d)
-     {
-       if(std::abs(overlap_box.lower(d)-overlap_box.upper(d))==(axis==d ? 1 : 0))
-         {
-           boundary_direction=d;
-           if(fine_box.upper(d)<=overlap_box.lower(d))
-             boundary_positive=true;
-           else if(fine_box.lower(d)>=overlap_box.upper(d))
-             boundary_positive=false;
-           else
-             abort();
-           break;
-         }
-     }
-
-   hier::Index p_min(overlap_box.lower()), p_max(overlap_box.upper());
-
-   if(boundary_direction==axis)
-     {
-       if(boundary_positive)
-         {
-           p_min[axis]=p_max[axis];
-         }
-       else
-         {
-           p_max[axis]=p_min[axis];
-         }
-     }
-
-   hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
-   ip[0]=1;
-   jp[1]=1;
-   if(dim>2)
-     kp[2]=1;
-
-   if(dim==2)
-     {
-       for(int j=p_min[1]; j<=p_max[1]; ++j)
-         for(int i=p_min[0]; i<=p_max[0]; ++i)
-           {
-             pdat::SideIndex fine(hier::Index(i,j),axis,pdat::SideIndex::Lower);
-             switch(axis)
-               {
-               case 0:
-                 Update_V_2D(axis,boundary_direction,boundary_positive,fine,
-                             ip,jp,i,j,p_max[0],p_min[1],p_max[1],*v,*v_fine);
-                 break;
-               case 1:
-                 Update_V_2D(axis,boundary_direction,boundary_positive,fine,
-                             jp,ip,j,i,p_max[1],p_min[0],p_max[0],*v,*v_fine);
-                 break;
-               default:
-                 abort();
-                 break;
-               }
-         }
-     }
-   else
-     {
-       hier::Index pp[]={ip,jp,kp};
-       hier::Index ijk(dimension);
-       for(ijk[2]=p_min[2]; ijk[2]<=p_max[2]; ijk[2]=(ijk[2]/2)*2+2)
-         for(ijk[1]=p_min[1]; ijk[1]<=p_max[1]; ijk[1]=(ijk[1]/2)*2+2)
-           for(ijk[0]=p_min[0]; ijk[0]<=p_max[0]; ijk[0]=(ijk[0]/2)*2+2)
-             {
-               pdat::SideIndex fine(ijk,axis,pdat::SideIndex::Lower);
-               Update_V_3D(axis,boundary_direction,boundary_positive,fine,
-                           pp,ijk,p_min,p_max,*v,*v_fine);
-             }
-     }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen.h
--- a/src/V_Coarsen.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Weighted averaging operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_V_Coarsen
-#define included_geom_V_Coarsen
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/CoarsenOperator.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/SideVariable.h"
-
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Class V_Coarsen implements averaging 
- * for side-centered double patch data defined over
- * a Cartesian mesh.  It is derived from the xfer::CoarsenOperator base class.
- * The numerical operations for theaveraging use FORTRAN numerical routines.
- *
- * CartesianSideDoubleWeightedAverage averages over the nearest two
- * cells, which is not what we want for multigrid.  This averages over
- * the nearest six points (in 2D).  The findCoarsenOperator() operator
- * function returns true if the input variable is side-centered
- * double, and the std::string is "V_COARSEN".
- *
- * @see xfer::CoarsenOperator
- */
-
-class V_Coarsen:
-   public xfer::CoarsenOperator
-{
-public:
-  /**
-   * Uninteresting default constructor.
-   */
-  explicit V_Coarsen(const tbox::Dimension& dim):
-    xfer::CoarsenOperator(dim, "V_COARSEN")
-  {
-    d_name_id = "V_COARSEN";
-  }
-
-  /**
-   * Uninteresting virtual destructor.
-   */
-  virtual ~V_Coarsen(){}
-
-  /**
-   * Return true if the variable and name std::string match the side-centered
-   * double weighted averaging; otherwise, return false.
-   */
-  
-  bool findCoarsenOperator(const tbox::Pointer<hier::Variable>& var,
-                           const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  /**
-   * Return name std::string identifier of this coarsening operator.
-   */
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  /**
-   * The priority of side-centered double weighted averaging is 0.
-   * It will be performed before any user-defined coarsen operations.
-   */
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getOne(getDim());
-  }
-
-  /**
-   * Coarsen the source component on the fine patch to the destination
-   * component on the coarse patch using the side-centered double weighted
-   * averaging operator.  Coarsening is performed on the intersection of
-   * the destination patch and the coarse box.  It is assumed that the
-   * fine patch contains sufficient data for the stencil width of the
-   * coarsening operator.
-   */
-  void
-  coarsen(hier::Patch& coarse,
-             const hier::Patch& fine,
-             const int dst_component,
-             const int src_component,
-             const hier::Box& coarse_box,
-             const hier::IntVector& ratio) const
-  {
-    if(getDim().getValue()==2)
-      coarsen_2D(coarse,fine,dst_component,src_component,coarse_box,ratio);
-    else
-      coarsen_3D(coarse,fine,dst_component,src_component,coarse_box,ratio);
-  }
-
-  void
-  coarsen_2D(hier::Patch& coarse,
-             const hier::Patch& fine,
-             const int dst_component,
-             const int src_component,
-             const hier::Box& coarse_box,
-             const hier::IntVector& ratio) const;
-
-  void
-  coarsen_3D(hier::Patch& coarse,
-             const hier::Patch& fine,
-             const int dst_component,
-             const int src_component,
-             const hier::Box& coarse_box,
-             const hier::IntVector& ratio) const;
-
-private:
-  std::string d_name_id;
-
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen/coarsen_2D.C
--- a/src/V_Coarsen/coarsen_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,244 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Weighted averaging operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_V_Coarsen_C
-#define included_geom_V_Coarsen_C
-
-#include "V_Coarsen.h"
-
-#include <float.h>
-#include <math.h>
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "Constants.h"
-
-#include "FTensor.hpp"
-
-using namespace SAMRAI;
-
-inline void coarsen_point_2D(const pdat::SideIndex &coarse,
-                             const hier::Index &ip, const hier::Index &jp,
-                             tbox::Pointer<pdat::SideData<double> > &v,
-                             tbox::Pointer<pdat::SideData<double> > &v_fine )
-{
-  pdat::SideIndex center(coarse*2);
-  (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/4
-    + ((*v_fine)(center-ip) + (*v_fine)(center-ip+jp)
-       + (*v_fine)(center+ip) + (*v_fine)(center+jp+ip))/8;
-}
-
-
-void SAMRAI::geom::V_Coarsen::coarsen_2D(hier::Patch& coarse,
-                                         const hier::Patch& fine,
-                                         const int dst_component,
-                                         const int src_component,
-                                         const hier::Box& coarse_box,
-                                         const hier::IntVector& ratio) const
-{
-  const tbox::Dimension& Dim(getDim());
-
-  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(Dim, coarse, fine, coarse_box, ratio);
-
-  tbox::Pointer<pdat::SideData<double> >
-    v_fine = fine.getPatchData(src_component);
-  tbox::Pointer<pdat::SideData<double> >
-    v = coarse.getPatchData(dst_component);
-
-  TBOX_ASSERT(!v.isNull());
-  TBOX_ASSERT(!v_fine.isNull());
-  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
-  TBOX_ASSERT(v->getDepth() == 1);
-
-  const hier::IntVector& directions(v->getDirectionVector());
-
-  TBOX_ASSERT(directions ==
-              hier::IntVector::min(directions, v_fine->getDirectionVector()));
-
-  const tbox::Pointer<CartesianPatchGeometry> cgeom =
-    coarse.getPatchGeometry();
-  const double *dx=cgeom->getDx();
-
-  /* Numbering of v nodes is
-
-     x--x--x--x--x  Fine
-     0  1  2  3  4
-
-     x-----x-----x Coarse
-     0     1     2
-
-     So the i'th coarse point is affected by the i*2-1,
-     i*2, and i*2+1 fine points.  So, for example, i_fine=3
-     affects both i_coarse=1 and i_coarse=2.
-
-     |---------------------------------------------------------------|
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     c               c               c               c               c
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     |---------------------------------------------------------------|
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     c               c               c               c               c
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     |---------------------------------------------------------------|
-
-     In 2D, a coarse point depends on six points.  In this
-     case, (i*2,j*2), (i*2,j*2+1), (i*2-1,j*2),
-     (i*2-1,j*2+1), (i*2+1,j*2), (i*2+1,j*2+1).
-
-     The coarse/fine boundaries get fixed up later in
-     V_Coarsen_Patch_Strategy::postprocessCoarsen.
-  */
-  hier::Index ip(1,0), jp(0,1);
-  for(int j=coarse_box.lower(1); j<=coarse_box.upper(1)+1; ++j)
-    for(int i=coarse_box.lower(0); i<=coarse_box.upper(0)+1; ++i)
-      {
-        if(directions(0) && j!=coarse_box.upper(1)+1)
-          {
-            pdat::SideIndex coarse(hier::Index(i,j),0,
-                                   pdat::SideIndex::Lower);
-            pdat::SideIndex fine(coarse*2);
-            if((i==coarse_box.lower(0)
-                && cgeom->getTouchesRegularBoundary(0,0))
-               || (i==coarse_box.upper(0)+1
-                   && cgeom->getTouchesRegularBoundary(0,1)))
-              {
-                (*v)(coarse)=((*v_fine)(fine) + (*v_fine)(fine+jp))/2;
-              }
-            else
-              {
-                const int axis=0;
-                FTensor::Tensor1<double,3> offset(0,0,0);
-                offset(axis)=dx[axis]/2;
-                FTensor::Tensor1<double,3> xyz(0,0,0);
-                for(int d=0;d<Dim.getValue();++d)
-                  xyz(d)=cgeom->getXLower()[d]
-                    + dx[d]*(coarse[d]-coarse_box.lower()[d] + 0.5) - offset(d);
-
-                coarsen_point_2D(coarse,ip,jp,v,v_fine);
-
-
-                // tbox::pout << "coarsen "
-                //            << coarse << " "
-                //            << xyz(0) << " "
-                //            << xyz(1) << " "
-                //            << dx[0] << " "
-                //            << fine << " "
-                //            << (*v)(coarse) << " "
-                //            << (*v_fine)(fine) << " "
-                //            << (*v_fine)(fine+ip) << " "
-                //            << (*v_fine)(fine-ip) << " "
-                //            << (*v_fine)(fine+jp) << " "
-                //            << (*v_fine)(fine+jp+ip) << " "
-                //            << (*v_fine)(fine+jp-ip) << " "
-                //            << "\n";
-              }
-          }
-        if(directions(1) && i!=coarse_box.upper(0)+1)
-          {
-            pdat::SideIndex coarse(hier::Index(i,j),1,
-                                   pdat::SideIndex::Lower);
-            pdat::SideIndex fine(coarse*2);
-            if((j==coarse_box.lower(1)
-                && cgeom->getTouchesRegularBoundary(1,0))
-               || (j==coarse_box.upper(1)+1
-                   && cgeom->getTouchesRegularBoundary(1,1)))
-              {
-                (*v)(coarse)=((*v_fine)(fine) + (*v_fine)(fine+ip))/2;
-              }
-            else
-              {
-                const int axis=1;
-                FTensor::Tensor1<double,3> offset(0,0,0);
-                offset(axis)=dx[axis]/2;
-                FTensor::Tensor1<double,3> xyz(0,0,0);
-                for(int d=0;d<Dim.getValue();++d)
-                  xyz(d)=cgeom->getXLower()[d]
-                    + dx[d]*(coarse[d]-coarse_box.lower()[d] + 0.5) - offset(d);
-
-                if(xyz(0)-dx[0]<0.5 && xyz(0)+dx[0]>0.5)
-                  {
-                    /* Interface between coarse and fine+1 */
-                    if((xyz(1)+dx[1]/2>0.6 && xyz(1)<0.6)
-                       || (xyz(1)+dx[1]/2>0.4 && xyz(1)<0.4))
-                      {
-                        // tbox::pout << "coarsen m ";
-                        (*v)(coarse)=(((*v_fine)(fine) + (*v_fine)(fine+ip))*2
-                                      + (*v_fine)(fine-jp) + (*v_fine)(fine+ip-jp))/3;
-                      }
-                    /* Interface between coarse and fine-1 */
-                    else if((xyz(1)-dx[1]/2<0.6 && xyz(1)>0.6)
-                            || (xyz(1)-dx[1]/2<0.4 && xyz(1)>0.4))
-                      {
-                        // tbox::pout << "coarsen p ";
-                        (*v)(coarse)=(((*v_fine)(fine) + (*v_fine)(fine+ip))*2
-                                      + (*v_fine)(fine+jp) + (*v_fine)(fine+ip+jp))/3;
-                      }
-                    else
-                      {
-                        // tbox::pout << "coarsen z ";
-                        coarsen_point_2D(coarse,jp,ip,v,v_fine);
-                      }
-                  }
-                else
-                  {
-                    // tbox::pout << "coarsen   ";
-                    coarsen_point_2D(coarse,jp,ip,v,v_fine);
-                  }
-
-                // /* Interface between coarse and fine-1 */
-                // if(xyz(0)+dx[0]/4>0.5 && xyz(0)<0.5)
-                //   {
-                //     tbox::pout << "coarsen m ";
-                //     (*v)(coarse)=(*v_fine)(fine)/2
-                //       + ((*v_fine)(fine-jp) + (*v_fine)(fine+jp))/4;
-                //   }
-                // /* Interface between coarse and fine+1 */
-                // else if(xyz(0)-dx[0]/4<0.5 && xyz(0)>0.5)
-                //   {
-                //     tbox::pout << "coarsen p ";
-                //     (*v)(coarse)=(*v_fine)(fine+ip)/2
-                //       + ((*v_fine)(fine-jp+ip) + (*v_fine)(fine+jp+ip))/4;
-                //   }
-                // else
-                //   {
-                //     tbox::pout << "coarsen   ";
-                //     coarsen_point_2D(coarse,jp,ip,v,v_fine);
-                //   }
-
-                // tbox::pout << coarse << " "
-                //            << xyz(0) << " "
-                //            << xyz(1) << " "
-                //            << dx[0] << " "
-                //            << fine << " "
-                //            << (*v)(coarse) << " "
-                //            << (*v_fine)(fine) << " "
-                //            << (*v_fine)(fine+jp) << " "
-                //            << (*v_fine)(fine-jp) << " "
-                //            << (*v_fine)(fine+ip) << " "
-                //            << (*v_fine)(fine+ip+jp) << " "
-                //            << (*v_fine)(fine+ip-jp) << " "
-                //            << "\n";
-              }
-          }
-      }
-}
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen/coarsen_3D.C
--- a/src/V_Coarsen/coarsen_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Weighted averaging operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_V_Coarsen_C
-#define included_geom_V_Coarsen_C
-
-#include "V_Coarsen.h"
-
-#include <float.h>
-#include <math.h>
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "Constants.h"
-
-using namespace SAMRAI;
-
-inline void coarsen_point_3D(const pdat::SideIndex &coarse,
-                             const hier::Index &ip, const hier::Index &jp,
-                             const hier::Index &kp,
-                             tbox::Pointer<pdat::SideData<double> > &v,
-                             tbox::Pointer<pdat::SideData<double> > &v_fine )
-{
-  pdat::SideIndex center(coarse*2);
-  (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp)
-                + (*v_fine)(center+kp) + (*v_fine)(center+jp+kp))/8
-    + ((*v_fine)(center-ip) + (*v_fine)(center-ip+jp)
-       + (*v_fine)(center-ip+kp) + (*v_fine)(center-ip+jp+kp)
-       + (*v_fine)(center+ip) + (*v_fine)(center+jp+ip)
-       + (*v_fine)(center+ip+kp) + (*v_fine)(center+jp+ip+kp))/16;
-}
-
-
-void SAMRAI::geom::V_Coarsen::coarsen_3D(hier::Patch& coarse,
-                                         const hier::Patch& fine,
-                                         const int dst_component,
-                                         const int src_component,
-                                         const hier::Box& coarse_box,
-                                         const hier::IntVector& ratio) const
-{
-  const tbox::Dimension& dim(getDim());
-
-  TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dim, coarse, fine, coarse_box, ratio);
-
-  tbox::Pointer<pdat::SideData<double> >
-    v_fine = fine.getPatchData(src_component);
-  tbox::Pointer<pdat::SideData<double> >
-    v = coarse.getPatchData(dst_component);
-
-  TBOX_ASSERT(!v.isNull());
-  TBOX_ASSERT(!v_fine.isNull());
-  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
-  TBOX_ASSERT(v->getDepth() == 1);
-
-  const hier::IntVector& directions(v->getDirectionVector());
-
-  TBOX_ASSERT(directions ==
-              hier::IntVector::min(directions, v_fine->getDirectionVector()));
-
-  const tbox::Pointer<CartesianPatchGeometry> cgeom =
-    coarse.getPatchGeometry();
-
-  /* Numbering of v nodes is
-
-     x--x--x--x--x  Fine
-     0  1  2  3  4
-
-     x-----x-----x Coarse
-     0     1     2
-
-     So the i'th coarse point is affected by the i*2-1,
-     i*2, and i*2+1 fine points.  So, for example, i_fine=3
-     affects both i_coarse=1 and i_coarse=2.
-
-     |---------------------------------------------------------------|
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     c               c               c               c               c
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     |---------------------------------------------------------------|
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     c               c               c               c               c
-     |               |               |               |               |
-     f       f       f       f       f       f       f       f       f
-     |               |               |               |               |
-     |---------------------------------------------------------------|
-
-     In 2D, a coarse point depends on six points.  In this
-     case, (i*2,j*2), (i*2,j*2+1), (i*2-1,j*2),
-     (i*2-1,j*2+1), (i*2+1,j*2), (i*2+1,j*2+1).
-
-
-          --------------------
-         /                   /|
-        /                   / |
-       /                   /  |
-      /                   /   |
-      -------------------     |
-     |                   |    |
-     |    f        f     |    |
-     |                   |    |
-     |        C          |   /
-     |                   |  /
-     |    f        f     | /
-     |                   |/
-      -------------------
-
-     In 3D, a coarse point depend on 12 points
-     (i*2,j*2,k*2), (i*2,j*2+1,k*2), (i*2,j*2,k*2+1), (i*2,j*2+1,k*2+1),
-     (i*2+1,j*2,k*2), (i*2+1,j*2+1,k*2), (i*2+1,j*2,k*2+1), (i*2+1,j*2+1,k*2+1),
-     (i*2-1,j*2,k*2), (i*2-1,j*2+1,k*2), (i*2-1,j*2,k*2+1), (i*2-1,j*2+1,k*2+1)
-
-     The coarse/fine boundaries get fixed up later in
-     V_Coarsen_Patch_Strategy::postprocessCoarsen.
-  */
-  hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
-  for(int k=coarse_box.lower(2); k<=coarse_box.upper(2)+1; ++k)
-    for(int j=coarse_box.lower(1); j<=coarse_box.upper(1)+1; ++j)
-      for(int i=coarse_box.lower(0); i<=coarse_box.upper(0)+1; ++i)
-        {
-          if(directions(0) && j!=coarse_box.upper(1)+1
-              && k!=coarse_box.upper(2)+1)
-            {
-              pdat::SideIndex coarse(hier::Index(i,j,k),0,
-                                     pdat::SideIndex::Lower);
-              pdat::SideIndex center(coarse*2);
-              if((i==coarse_box.lower(0)
-                  && cgeom->getTouchesRegularBoundary(0,0))
-                 || (i==coarse_box.upper(0)+1
-                     && cgeom->getTouchesRegularBoundary(0,1)))
-                {
-                  (*v)(coarse)=
-                    ((*v_fine)(center) + (*v_fine)(center+jp)
-                     + (*v_fine)(center+kp) + (*v_fine)(center+jp+kp))/4;
-                }
-              else
-                {
-                  coarsen_point_3D(coarse,ip,jp,kp,v,v_fine);
-                }
-            }
-          if(directions(1) && i!=coarse_box.upper(0)+1
-             && k!=coarse_box.upper(2)+1)
-            {
-              pdat::SideIndex coarse(hier::Index(i,j,k),1,
-                                     pdat::SideIndex::Lower);
-              pdat::SideIndex center(coarse*2);
-              if((j==coarse_box.lower(1)
-                  && cgeom->getTouchesRegularBoundary(1,0))
-                 || (j==coarse_box.upper(1)+1
-                     && cgeom->getTouchesRegularBoundary(1,1)))
-                {
-                  (*v)(coarse)=
-                    ((*v_fine)(center) + (*v_fine)(center+ip)
-                     + (*v_fine)(center+kp) + (*v_fine)(center+ip+kp))/4;
-                }
-              else
-                {
-                  coarsen_point_3D(coarse,jp,kp,ip,v,v_fine);
-                }
-            }
-          if(directions(2) && i!=coarse_box.upper(0)+1
-              && j!=coarse_box.upper(1)+1)
-            {
-              pdat::SideIndex coarse(hier::Index(i,j,k),2,
-                                     pdat::SideIndex::Lower);
-              pdat::SideIndex center(coarse*2);
-              if((k==coarse_box.lower(2)
-                  && cgeom->getTouchesRegularBoundary(2,0))
-                 || (k==coarse_box.upper(2)+1
-                     && cgeom->getTouchesRegularBoundary(2,1)))
-                {
-                  (*v)(coarse)=
-                    ((*v_fine)(center) + (*v_fine)(center+ip)
-                     + (*v_fine)(center+jp) + (*v_fine)(center+ip+jp))/4;
-                }
-              else
-                {
-                  coarsen_point_3D(coarse,kp,ip,jp,v,v_fine);
-                }
-            }
-        }
-}
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen_Patch_Strategy.h
--- a/src/V_Coarsen_Patch_Strategy.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Robin boundary condition support on cartesian grids. 
- *
- ************************************************************************/
-#ifndef included_solv_V_Coarsen_Patch_Strategy
-#define included_solv_V_Coarsen_Patch_Strategy
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/CoarsenPatchStrategy.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/CoarseFineBoundary.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/CellIndex.h"
-#include "Constants.h"
-#include "set_boundary.h"
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief Helper utility for setting boundary conditions on V.
- *
- * This class inherits and implements virtual functions from
- * xfer::CoarsenPatchStrategy so it may be used to help create
- * communication schedules if desired.
- */
-class V_Coarsen_Patch_Strategy:
-   public xfer::CoarsenPatchStrategy
-{
-
-public:
-   /*!
-    * @brief Constructor using.
-    *
-    * @param object_name Name of the object, for general referencing.
-    * @param coef_strategy Coefficients strategy being helped.
-    */
-   V_Coarsen_Patch_Strategy(
-      const tbox::Dimension& dim,
-      std::string object_name = std::string()):
-     xfer::CoarsenPatchStrategy(dim),
-     d_object_name(object_name) {}
-
-   /*!
-    * @brief Destructor.
-    */
-   virtual ~V_Coarsen_Patch_Strategy(void) {}
-
-   //@{ @name xfer::CoarsenPatchStrategy virtuals
-
-   virtual hier::IntVector
-   getCoarsenOpStencilWidth() const
-  { return hier::IntVector::getOne(getDim()); }
-
-   virtual void
-   preprocessCoarsen(hier::Patch& ,
-                    const hier::Patch& fine,
-                    const hier::Box& ,
-                    const hier::IntVector& )
-  {
-    set_boundary(fine,invalid_id,v_id,true);
-  }
-
-   virtual void
-   postprocessCoarsen(
-      hier::Patch& coarse,
-      const hier::Patch& fine,
-      const hier::Box& coarse_box,
-      const hier::IntVector& ratio)
-  {
-    if(getDim().getValue()==2)
-      postprocessCoarsen_2D(coarse,fine,coarse_box,ratio);
-    else
-      postprocessCoarsen_3D(coarse,fine,coarse_box,ratio);
-  }
-
-  void
-  postprocessCoarsen_2D(
-      hier::Patch& coarse,
-      const hier::Patch& fine,
-      const hier::Box& coarse_box,
-      const hier::IntVector& ratio);
-
-  void
-  postprocessCoarsen_3D(
-      hier::Patch& coarse,
-      const hier::Patch& fine,
-      const hier::Box& coarse_box,
-      const hier::IntVector& ratio);
-
-   //@}
-
-   //@{
-
-   /*!
-    * @name Functions to set boundary condition values
-    */
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the first ghost cells.
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::CoarsenPatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to cell-centered variables.
-    * -# Only one ghost cell width is filled.  Setting a Robin
-    *    boundary condition for cell-centered quantities requires
-    *    only one ghost cell to be set.
-    *    (More ghost cells can be filled by continuing the linear
-    *    distribution of data beyond the first cell, but that is
-    *    not implemented at this time.)
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to
-    * get the coefficients, then it sets the values in the first
-    * ghost cell on the boundary.
-    *
-    * To determine the value for the ghost cell,
-    * a @em linear approximation in the direction normal to the
-    * boundary is assumed.  We write the following discrete
-    * approximations:
-    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
-    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
-    * where the subscript b stands for the the boundary,
-    * i stands for the first cell inside the boundary and
-    * o stands for the first cell outside the boundary
-    * and h is the grid spacing normal to the boundary.
-    * Applying this to the Robin formula gives
-    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
-    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
-    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
-    *
-    * After setting the edge (face in 3D) boundary conditions,
-    * linear approximations are used to set the boundary conditions
-    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required in solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @internal To be more general to other data types,
-    * there could be versions for other data types also,
-    * such as ...InNodes, ...InFaces, etc.  However, I'm not
-    * sure exactly how to implement the Robin boundary condition
-    * on the faces and nodes when m != 1.  Should the boundary
-    * value be set or should the first ghost value be set?
-    *
-    * @internal I have not addressed possibility of differences
-    * in chosing the discrete formulation with which to compute
-    * the boundary value.  The above formulation is obviously
-    * one specific approximation, but there could be others.
-    * If anoter approximation is required, there should be
-    * another class like this or this class can offer a choice
-    * to be set by the user.  I favor another class.
-    *
-    * @internal Since the data alignment can be found through
-    * the target_data_id, these types of functions may be changed
-    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
-    * since it does assume boundary boxes.  This may have to be
-    * expanded to later include coarse-fine boundary boxes
-    * for more generality.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set ghost cells for an entire level.
-    *
-    * Loop through all patches on the given level and call
-    * setBoundaryValuesInCells(hier::Patch &patch,
-    *                          const double fill_time ,
-    *                          const hier::IntVector &ghost_width_to_fill ,
-    *                          int target_data_id ,
-    *                          bool homogeneous_bc=false )
-    * for each.
-    *
-    * @param level PatchLevel on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::PatchLevel& level,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the boundary nodes.
-    *
-    * This function is not yet implemented!
-    *
-    * There are some decisions that must be made before
-    * the implementation can be written.
-    * -# Do we set the values on the boundary or one cell
-    *    away from the boundary?
-    * -# What is the discrete formulation we should use
-    *    to compute the value to be set?
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::CoarsenPatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to node-centered variables.
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to get the
-    * coefficients, then it sets the values at the boundary nodes.
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required to solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param target_data_id hier::Patch data index of data to be set.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesAtNodes(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   //@}
-
-   //@{
-   /*!
-    * @name Ways to provide the Robin bc coefficients
-    */
-
-   /*!
-    * @brief Provide an implementation of the RobinBcCoefStrategy
-    * for determining the boundary coefficients.
-    *
-    * Provide the implementation that can be used to set the
-    * Robin bc coefficients.
-    *
-    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
-    *        the coefficient strategy.
-    */
-   // void
-   // setCoefImplementation(
-   //    const RobinBcCoefStrategy* coef_strategy);
-
-   /*!
-    * @brief Set the data id that should be filled when setting
-    * physical boundary conditions.
-    *
-    * When setPhysicalBoundaryConditions is called, the data
-    * specified will be set.  This information is required because
-    * the it is not passed in through the argument list of
-    * setPhysicalBounaryConditions.
-    */
-  void setSourceDataId(int id)
-  {
-    v_id=id;
-  }
-
-   /*!
-    * @brief Set whether boundary filling should assume homogeneous
-    * conditions.
-    *
-    * In certain circumstances, only the value of a is needed, while
-    * the value of g is temporarily not required and taken to be zero.
-    * (An example is in setting the boundary condition for error
-    * value in an iterative method.)  In such cases, use this function
-    * to set a flag that will cause a null pointer to be given to
-    * setBcCoefs() to indicate that fact.
-    */
-   // void
-   // setHomogeneousBc(
-   //    bool homogeneous_bc);
-
-   //@}
-
-  tbox::Array<tbox::Pointer<hier::CoarseFineBoundary> > coarse_fine;
-
-private:
-   /*!
-    * @brief Trim a boundary box so that it does not stick out
-    * past a given box.
-    *
-    * Certain boundary-related operations occur on patch data that
-    * do not or cannot extend past the edgr or corner of a patch.
-    * This function is used to trim down the parts of the boundary box
-    * that extend past those points so that a suitable index range
-    * is achieved.
-    *
-    * The boundary box trimmed must be of type 1 or 2.
-    *
-    * @param boundary_box Boundary box to be trimmed.
-    * @param limit_box hier::Box to not stick past
-    *
-    * @return New trimmed boundary box.
-    */
-   // hier::BoundaryBox
-   // trimBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box,
-   //    const hier::Box& limit_box) const;
-
-   /*!
-    * @brief Return box describing the index space of boundary nodes
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the nodes corresponding
-    * to the input boundary box.  These nodes lie on the boundary
-    * itself.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the node indices corresponding to
-    *   boundary_box
-    */
-   // hier::Box
-   // makeNodeBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   /*!
-    * @brief Return box describing the index space of faces
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the codimension 1
-    * surface corresponding to the input boundary box.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * This is a utility function for working with the
-    * indices coresponding to a boundary box but coincide
-    * with the patch boundary.
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the face indices corresponding to
-    *    boundary_box
-    */
-   // hier::Box
-   // makeFaceBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   std::string d_object_name;
-
-   /*!
-    * @brief Coefficient strategy giving a way to get to
-    * Robin bc coefficients.
-    */
-   // const RobinBcCoefStrategy* d_coef_strategy;
-
-   /*!
-    * @brief hier::Index of target patch data when filling ghosts.
-    */
-   int v_id;
-
-   /*!
-    * @brief Whether to assumg g=0 when filling ghosts.
-    */
-   // bool d_homogeneous_bc;
-
-   /*!
-    * @brief Timers for performance measurement.
-    */
-   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
-   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
-};
-
-}
-}
-
-#endif  // included_solv_V_Coarsen_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C
--- a/src/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-#include "V_Coarsen_Patch_Strategy.h"
-
-void
-SAMRAI::solv::V_Coarsen_Patch_Strategy::postprocessCoarsen_2D
-(hier::Patch& coarse,
- const hier::Patch& fine,
- const hier::Box& ,
- const hier::IntVector& )
-{
-  /* Fix up the boundary elements by iterating through the boundary
-     boxes */
-
-  /* We only care about edges, not corners, so we only iterate over
-     edge boundary boxes. */
-  const tbox::Array<hier::BoundaryBox>
-    &boundaries=coarse_fine[fine.getPatchLevelNumber()]->getEdgeBoundaries(coarse.getGlobalId());
-     
-  tbox::Pointer<pdat::SideData<double> >
-    v_fine = fine.getPatchData(v_id);
-  tbox::Pointer<pdat::SideData<double> >
-    v = coarse.getPatchData(v_id);
-
-  TBOX_ASSERT(!v.isNull());
-  TBOX_ASSERT(!v_fine.isNull());
-  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
-  TBOX_ASSERT(v->getDepth() == 1);
-
-  hier::Box gbox(v_fine->getGhostBox());
-  hier::Index ip(1,0), jp(0,1);
-  for(int mm=0; mm<boundaries.size(); ++mm)
-    {
-      hier::Box bbox=boundaries[mm].getBox();
-      int location_index=boundaries[mm].getLocationIndex();
-
-      hier::Index lower=hier::Index::coarsen(bbox.lower(),hier::Index(2,2)),
-        upper=hier::Index::coarsen(bbox.upper(),hier::Index(2,2));
-
-      for(int j=lower(1); j<=upper(1); ++j)
-        for(int i=lower(0); i<=upper(0); ++i)
-          {
-            /* Fix vx */
-            if(location_index==0)
-              {
-                pdat::SideIndex coarse(hier::Index(i,j),0,
-                                       pdat::SideIndex::Upper);
-                pdat::SideIndex center(coarse*2);
-                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
-                  {
-                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
-                  }
-              }
-            else if(location_index==1)
-              {
-                pdat::SideIndex coarse(hier::Index(i,j),0,
-                                       pdat::SideIndex::Lower);
-                pdat::SideIndex center(coarse*2);
-                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
-                  {
-                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
-                  }
-              }
-            /* Fix vy */
-            else if(location_index==2)
-              {
-                pdat::SideIndex coarse(hier::Index(i,j),1,
-                                       pdat::SideIndex::Upper);
-                pdat::SideIndex center(coarse*2);
-                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
-                  {
-                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
-                  }
-              }
-            else if(location_index==3)
-              {
-                pdat::SideIndex coarse(hier::Index(i,j),1,
-                                       pdat::SideIndex::Lower);
-                pdat::SideIndex center(coarse*2);
-                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
-                  {
-                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
-                  }
-              }
-            else
-              {
-                abort();
-              }
-          }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C
--- a/src/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-#include "V_Coarsen_Patch_Strategy.h"
-
-void
-SAMRAI::solv::V_Coarsen_Patch_Strategy::postprocessCoarsen_3D
-(hier::Patch& coarse,
- const hier::Patch& fine,
- const hier::Box& ,
- const hier::IntVector& )
-{
-  /* Fix up the boundary elements by iterating through the boundary
-     boxes */
-
-  /* We only care about faces, not edges or corners, so we only
-     iterate over face boundary boxes. */
-  const tbox::Array<hier::BoundaryBox> &boundaries
-    (coarse_fine[fine.getPatchLevelNumber()]
-     ->getFaceBoundaries(coarse.getGlobalId()));
-     
-  tbox::Pointer<pdat::SideData<double> >
-    v_fine = fine.getPatchData(v_id);
-  tbox::Pointer<pdat::SideData<double> >
-    v = coarse.getPatchData(v_id);
-
-  TBOX_ASSERT(!v.isNull());
-  TBOX_ASSERT(!v_fine.isNull());
-  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
-  TBOX_ASSERT(v->getDepth() == 1);
-
-  hier::Box gbox(v_fine->getGhostBox());
-  hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
-  for(int mm=0; mm<boundaries.size(); ++mm)
-    {
-      hier::Box bbox=boundaries[mm].getBox();
-      /* location_index tells where, in relation to the box, the boundary is.
-         0: x lower
-         1: x upper
-         2: y lower
-         3: y upper
-         4: z lower
-         5: z upper
-
-         Therefore, if location_index==3, then we need to set vy on
-         the __lower__ side of that boundary box. */
-         
-      int location_index=boundaries[mm].getLocationIndex();
-      int direction(location_index/2);
-      int side(location_index%2==0 ? pdat::SideIndex::Upper
-               : pdat::SideIndex::Lower);
-      int dir2((direction+1)%3), dir3((direction+2)%3);
-      hier::Index yp(ip), zp(ip);
-      switch(direction)
-        {
-        case 0:
-          yp=jp;
-          zp=kp;
-          break;
-        case 1:
-          yp=kp;
-          zp=ip;
-          break;
-        case 2:
-          yp=ip;
-          zp=jp;
-          break;
-        }      
-
-      hier::Index lower=hier::Index::coarsen(bbox.lower(),hier::Index(2,2,2)),
-        upper=hier::Index::coarsen(bbox.upper(),hier::Index(2,2,2));
-
-      for(int k=lower(2); k<=upper(2); ++k)
-        for(int j=lower(1); j<=upper(1); ++j)
-          for(int i=lower(0); i<=upper(0); ++i)
-            {
-              pdat::SideIndex coarse(hier::Index(i,j,k),direction,side);
-              pdat::SideIndex center(coarse*2);
-              if(center[dir2]>=gbox.lower(dir2)
-                 && center[dir2]<gbox.upper(dir2)
-                 && center[dir3]>=gbox.lower(dir3)
-                 && center[dir3]<gbox.upper(dir3))
-                {
-                  (*v)(coarse)=
-                    ((*v_fine)(center) + (*v_fine)(center+yp)
-                     + (*v_fine)(center+zp) + (*v_fine)(center+yp+zp))/4;
-                }
-            }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Refine.h
--- a/src/V_Refine.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#ifndef included_geom_V_Refine
-#define included_geom_V_Refine
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefineOperator.h"
-#include "SAMRAI/hier/Box.h"
-#include "SAMRAI/hier/IntVector.h"
-#include "SAMRAI/hier/Patch.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-
-#include "FTensor.hpp"
-#include <string>
-
-namespace SAMRAI {
-namespace geom {
-
-/**
- * Class V_Refine implements linear
- * interpolation for side-centered double patch data defined over a Cartesian
- * mesh.  It is derived from the xfer::RefineOperator base class.
- * CartesianSideDoubleConservativeLinearRefine does not handle the 
- * boundary for the velocity correctly, so use this instead for
- * velocity.
- *
- * The findRefineOperator() operator function returns true if the input
- * variable is side-centered double, and the std::string is "V_REFINE".
- *
- * @see xfer::RefineOperator
- */
-
-class V_Refine:
-  public xfer::RefineOperator
-{
-public:
-  /**
-   * Uninteresting default constructor.
-   */
-  explicit V_Refine(const tbox::Dimension& dim):
-    xfer::RefineOperator(dim, "V_REFINE")
-  {
-    d_name_id = "V_REFINE";
-  }
-
-
-  /**
-   * Uninteresting virtual destructor.
-   */
-  virtual ~V_Refine(){}
-
-  /**
-   * Return true if the variable and name std::string match side-centered
-   * double linear interpolation; otherwise, return false.
-   */
-  bool findRefineOperator(const tbox::Pointer<hier::Variable>& var,
-                          const std::string& op_name) const
-  {
-    TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
-
-    const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
-    if (!cast_var.isNull() && (op_name == d_name_id)) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-  /**
-   * Return name std::string identifier of this refinement operator.
-   */
-  const std::string& getOperatorName() const
-  {
-    return d_name_id;
-  }
-
-  /**
-   * The priority of side-centered double linear interpolation is 0.
-   * It will be performed before any user-defined interpolation operations.
-   */
-  int getOperatorPriority() const
-  {
-    return 0;
-  }
-
-  /**
-   * The stencil width of the linear interpolation operator is the vector
-   * of ones.  That is, its stencil extends one side outside the fine box.
-   */
-  hier::IntVector getStencilWidth() const
-  {
-    return hier::IntVector::getOne(getDim());
-  }
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the side-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the boxes contained in fine_overlap
-   * It is assumed that the coarse patch contains sufficient data for the
-   * stencil width of the refinement operator.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::BoxOverlap& fine_overlap,
-              const hier::IntVector& ratio) const;
-
-  /**
-   * Refine the source component on the coarse patch to the destination
-   * component on the fine patch using the side-centered double linear
-   * interpolation operator.  Interpolation is performed on the intersection
-   * of the destination patch and the fine box.   It is assumed that the
-   * coarse patch contains sufficient data for the stencil width of the
-   * refinement operator.  This differs from the above refine() method
-   * only in that it operates on a single fine box instead of a BoxOverlap.
-   */
-  void refine(hier::Patch& fine,
-              const hier::Patch& coarse,
-              const int dst_component,
-              const int src_component,
-              const hier::Box& fine_box,
-              const hier::IntVector& ratio,
-              const int &axis) const;
-
-  double refine_along_line(pdat::SideData<double> &v,
-                           const int &axis,
-                           const int &dim,
-                           const hier::Index pp[],
-                           const pdat::SideIndex &fine,
-                           const pdat::SideIndex &coarse,
-                           const hier::Box &coarse_box,
-                           const CartesianPatchGeometry &coarse_geom,
-                           const FTensor::Tensor1<double,3> &xyz,
-                           const double *dx) const;
-
-private:
-  std::string d_name_id;
-
-};
-
-}
-}
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Refine/refine.C
--- a/src/V_Refine/refine.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Linear refine operator for side-centered double data on
- *                a Cartesian mesh. 
- *
- ************************************************************************/
-
-#include "V_Refine.h"
-
-#include <float.h>
-#include <math.h>
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/hier/Index.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/SideVariable.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/pdat/CellData.h"
-
-#include "FTensor.hpp"
-
-void SAMRAI::geom::V_Refine::refine(
-   hier::Patch& fine,
-   const hier::Patch& coarse,
-   const int dst_component,
-   const int src_component,
-   const hier::BoxOverlap& fine_overlap,
-   const hier::IntVector& ratio) const
-{
-   const pdat::SideOverlap* t_overlap =
-      dynamic_cast<const pdat::SideOverlap *>(&fine_overlap);
-
-   TBOX_ASSERT(t_overlap != NULL);
-
-   for(int axis=0; axis<getDim().getValue(); ++axis)
-     {
-       const hier::BoxList& boxes = t_overlap->getDestinationBoxList(axis);
-       for (hier::BoxList::Iterator b(boxes); b; b++)
-         {
-           refine(fine,coarse,dst_component,src_component,b(),ratio,axis);
-         }
-     }
-}
-
-void SAMRAI::geom::V_Refine::refine(hier::Patch& fine_patch,
-                                    const hier::Patch& coarse_patch,
-                                    const int dst_component,
-                                    const int src_component,
-                                    const hier::Box& fine_box,
-                                    const hier::IntVector& ratio,
-                                    const int &axis) const
-{
-   const tbox::Dimension& dimension(getDim());
-   const int dim(dimension.getValue());
-   TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dimension, fine_patch, coarse_patch, fine_box, ratio);
-
-   tbox::Pointer<pdat::SideData<double> >
-   v_ptr = coarse_patch.getPatchData(src_component);
-   pdat::SideData<double> &v(*v_ptr);
-   tbox::Pointer<pdat::SideData<double> >
-   v_fine_ptr = fine_patch.getPatchData(dst_component);
-   pdat::SideData<double> &v_fine(*v_fine_ptr);
-
-#ifdef DEBUG_CHECK_ASSERTIONS
-   TBOX_ASSERT(!v_ptr.isNull());
-   TBOX_ASSERT(!v_fine_ptr.isNull());
-   TBOX_ASSERT(v.getDepth() == v_fine.getDepth());
-   TBOX_ASSERT(v.getDepth() == 1);
-#endif
-
-   hier::Box coarse_box=coarse_patch.getBox();
-   tbox::Pointer<geom::CartesianPatchGeometry>
-     coarse_geom = coarse_patch.getPatchGeometry();
-
-   tbox::Pointer<geom::CartesianPatchGeometry>
-     fine_geom = fine_patch.getPatchGeometry();
-   const double *dx=fine_geom->getDx();
-
-   const hier::Box &fine_patch_box(fine_patch.getBox());
-
-   hier::Index ip(hier::Index::getZeroIndex(dimension)), jp(ip), kp(ip);
-   ip[0]=1;
-   jp[1]=1;
-   if(dim>2)
-     kp[2]=1;
-   hier::Index pp[]={ip,jp,kp};
-
-   for(pdat::CellIterator ci(fine_box); ci; ci++)
-     {
-       pdat::SideIndex fine(*ci,axis,pdat::SideIndex::Lower);
-
-       pdat::SideIndex coarse(fine);
-       coarse.coarsen(hier::Index::getOneIndex(dimension)*2);
-
-       FTensor::Tensor1<double,3> offset(0,0,0);
-       offset(axis)=dx[axis]/2;
-       FTensor::Tensor1<double,3> xyz(0,0,0);
-       for(int d=0;d<dim;++d)
-         xyz(d)=fine_geom->getXLower()[d]
-           + dx[d]*(fine[d]-fine_patch_box.lower()[d] + 0.5) - offset(d);
-
-       if(fine[axis]%2==0)
-         {
-           v_fine(fine)=
-             refine_along_line(v,axis,dim,pp,fine,coarse,coarse_box,
-                               *coarse_geom,xyz,dx);
-         }
-       else
-         {
-           FTensor::Tensor1<double,3> xyz_low, xyz_high;
-           FTensor::Index<'a',3> a;
-
-           xyz_low(a)=xyz(a) - 2*offset(a);
-           xyz_high(a)=xyz(a) + 2*offset(a);
-
-           v_fine(fine)=
-             (refine_along_line(v,axis,dim,pp,fine,coarse,coarse_box,
-                                *coarse_geom,xyz_low,dx)
-              + refine_along_line(v,axis,dim,pp,fine,coarse+pp[axis],
-                                  coarse_box,*coarse_geom,xyz_high,dx))/2;
-         }
-     }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Refine/refine_along_line.C
--- a/src/V_Refine/refine_along_line.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-#include "V_Refine.h"
-
-/* This assumes that the levels are always properly nested, so that we
-   always have an extra grid space for interpolation.  So we only have
-   to have a special case for physical boundaries, where we do not
-   have an extra grid space. */
-
-/* Maybe this has to be fixed when dvx/dy != 0 on the outer boundary
-   because the approximation to the derivative is not accurate
-   enough? */
-
-/* Maybe in 3D we should include cross derivatives? */
-
-double SAMRAI::geom::V_Refine::refine_along_line
-(pdat::SideData<double> &v,
- const int &axis,
- const int &dim,
- const hier::Index pp[],
- const pdat::SideIndex &fine,
- const pdat::SideIndex &coarse,
- const hier::Box &coarse_box,
- const CartesianPatchGeometry &coarse_geom,
- const FTensor::Tensor1<double,3> &xyz,
- const double *dx) const
-{
-  double result=v(coarse);
-
-  for(int d=(axis+1)%dim;d!=axis;d=(d+1)%dim)
-    {
-      const int sgn(fine[d]%2==0 ? -1 : 1);
-
-      double dvx_dy;
-      if(coarse[d]==coarse_box.lower(d)
-         && coarse_geom.getTouchesRegularBoundary(d,0))
-        {
-          dvx_dy=sgn*(v(coarse+pp[d])-v(coarse))/4;
-        }
-      else if(coarse[d]==coarse_box.upper(d)
-              && coarse_geom.getTouchesRegularBoundary(d,1))
-        {
-          dvx_dy=sgn*(v(coarse)-v(coarse-pp[d]))/4;
-        }
-      else
-        {
-          dvx_dy=sgn*(v(coarse+pp[d])-v(coarse-pp[d]))/8;
-
-          if(axis==0 && xyz(0)-dx[0]<0.5+1e-6 && xyz(0)+dx[0]>0.5+1e-6)
-            {
-              const double y_min(0.5-sgn*0.1), y_max(0.5+sgn*0.1);
-              /* Top tip */
-              /* Singularity in coarse+1 */
-              if(sgn*(xyz(1)+sgn*dx[1]*0.5-y_max)<0 && sgn*(xyz(1)+sgn*dx[1]*2.5-y_max)>0)
-                {
-                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
-                  // tbox::pout << "refine p cp1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-
-                }
-              /* Singularity in coarse */
-              else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_max)<0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_max)>0)
-                {
-                  dvx_dy=0;
-                  // tbox::pout << "refine p c "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-                }
-              /* Singularity in coarse-1 */
-              else if(sgn*(xyz(1)-sgn*dx[1]*3.5-y_max)<0 && sgn*(xyz(1)-sgn*dx[1]*1.5-y_max)>0)
-                {
-                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
-                  // tbox::pout << "refine p cm1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-                }
-
-              /* Bottom tip */
-              /* Singularity in coarse+1 */
-              else if(sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)<0 && sgn*(xyz(1)+sgn*dx[1]*2.5-y_min)>0)
-                {
-                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
-                  // tbox::pout << "refine m cp1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-                }
-              /* Singularity in coarse */
-              else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)<0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)>0)
-                {
-                  dvx_dy=0;
-                  // tbox::pout << "refine m c "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-                }
-              /* Singularity in coarse-1 */
-              else if(sgn*(xyz(1)-sgn*dx[1]*3.5-y_min)<0 && sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)>0)
-                {
-                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
-                  // tbox::pout << "refine m cm1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + dvx_dy << " "
-                  //            << "\n";
-                }
-
-              // /* Bottom tip */
-              // /* Singularity in coarse+1 */
-              // else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)<0 && sgn*(xyz(1)-sgn*dx[1]*3.5-y_min)>0)
-              //   {
-              //     dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
-              //     tbox::pout << "refine m cp1 "
-              //                << 1/dx[0] << " "
-              //                << xyz(0) << " "
-              //                << xyz(1) << " "
-              //                << fine << " "
-              //                << coarse << " "
-              //                << sgn << " "
-              //                << v(coarse+pp[d]*sgn) << " "
-              //                << v(coarse) << " "
-              //                << v(coarse-pp[d]*sgn) << " "
-              //                << result + dvx_dy << " "
-              //                << "\n";
-              //   }
-              // /* Jump in coarse */
-              // else if(sgn*(xyz(1)-sgn*dx[1]*1.5-y_min)>0 && sgn*(xyz(1)+sgn*dx[1]*0.5-y_min)<0)
-              //   {
-              //     dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
-              //     tbox::pout << "refine m c "
-              //                << 1/dx[0] << " "
-              //                << xyz(0) << " "
-              //                << xyz(1) << " "
-              //                << fine << " "
-              //                << coarse << " "
-              //                << sgn << " "
-              //                << v(coarse+pp[d]*sgn) << " "
-              //                << v(coarse) << " "
-              //                << v(coarse-pp[d]*sgn) << " "
-              //                << result + dvx_dy << " "
-              //                << "\n";
-              //   }
-
-            }
-
-          // if(coarse[1]==6)
-          //       {
-          //         tbox::pout << "refine "
-          //                    << 1/dx[0] << " "
-          //                    << xyz(0) << " "
-          //                    << xyz(1) << " "
-          //                    << fine << " "
-          //                    << coarse << " "
-          //                    << sgn << " "
-          //                    << v(coarse+pp[d]*sgn) << " "
-          //                    << v(coarse) << " "
-          //                    << v(coarse-pp[d]*sgn) << " "
-          //                    << result + dvx_dy << " "
-          //                    << "\n";
-
-          //       }
-
-
-
-          if(axis==1 && xyz(1)>=0.4 && xyz(1)<=0.6)
-            {
-              /* Interface between fine and coarse+1, do a one-sided
-                 interpolation. */
-              if(sgn*(xyz(0)-0.5)<0 && sgn*(xyz(0)+sgn*1.5*dx[0]-0.5)>0)
-                {
-                  dvx_dy=(v(coarse)-v(coarse-pp[d]*sgn))/4;
-
-                  // tbox::pout << "refine fcp1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + sgn*dvx_dy << " "
-                  //            << "\n";
-                }
-              /* Interface between fine and coarse, use derivative
-                 from the other side. */
-              else if(sgn*(xyz(0)-0.5)>0 && sgn*(xyz(0)-sgn*dx[0]/2-0.5)<0)
-                {
-                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse)
-                          - (v(coarse)-v(coarse-pp[d]*sgn))*0.75);
-
-                  // tbox::pout << "refine fc "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + sgn*dvx_dy << " "
-                  //            << "\n";
-                }
-              /* Interface between coarse and coarse-1, do a one-sided
-                 interpolation. */
-              else if(sgn*(xyz(0)-0.5)>0 && sgn*(xyz(0)-sgn*2.5*dx[0]-0.5)<0)
-                {
-                  dvx_dy=(v(coarse+pp[d]*sgn)-v(coarse))/4;
-
-                  // tbox::pout << "refine ccm1 "
-                  //            << 1/dx[0] << " "
-                  //            << xyz(0) << " "
-                  //            << xyz(1) << " "
-                  //            << fine << " "
-                  //            << coarse << " "
-                  //            << sgn << " "
-                  //            << v(coarse+pp[d]*sgn) << " "
-                  //            << v(coarse) << " "
-                  //            << v(coarse-pp[d]*sgn) << " "
-                  //            << result + sgn*dvx_dy << " "
-                  //            << "\n";
-                }
-            }
-        }
-      result+=dvx_dy;
-    }
-  return result;
-}
-
diff -r daa8bb8aed75 -r dc04c13db402 src/V_Refine_Patch_Strategy.h
--- a/src/V_Refine_Patch_Strategy.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/*************************************************************************
- *
- * This file is part of the SAMRAI distribution.  For full copyright 
- * information, see COPYRIGHT and COPYING.LESSER. 
- *
- * Copyright:     (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description:   Robin boundary condition support on cartesian grids. 
- *
- ************************************************************************/
-#ifndef included_solv_V_Refine_Patch_Strategy
-#define included_solv_V_Refine_Patch_Strategy
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/xfer/RefinePatchStrategy.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/CellIndex.h"
-#include "Constants.h"
-#include "set_boundary.h"
-
-namespace SAMRAI {
-namespace solv {
-
-/*!
- * @brief Helper utility for setting boundary conditions on V.
- *
- * This class inherits and implements virtual functions from
- * xfer::RefinePatchStrategy so it may be used to help create
- * communication schedules if desired.
- */
-class V_Refine_Patch_Strategy:
-   public xfer::RefinePatchStrategy
-{
-
-public:
-   /*!
-    * @brief Constructor using.
-    *
-    * @param object_name Name of the object, for general referencing.
-    * @param coef_strategy Coefficients strategy being helped.
-    */
-   V_Refine_Patch_Strategy(
-      const tbox::Dimension& dim,
-      std::string object_name = std::string()):
-     xfer::RefinePatchStrategy(dim), d_dim(dim),d_object_name(object_name) {}
-
-   /*!
-    * @brief Destructor.
-    */
-   virtual ~V_Refine_Patch_Strategy(void) {}
-
-   //@{ @name xfer::RefinePatchStrategy virtuals
-
-   virtual void
-   setPhysicalBoundaryConditions(
-      hier::Patch& ,
-      const double ,
-      const hier::IntVector& ) {}
-   hier::IntVector
-   getRefineOpStencilWidth() const
-  { return hier::IntVector::getOne(d_dim); }
-   // virtual void
-   // preprocessRefineBoxes(
-   //    hier::Patch& fine,
-   //    const hier::Patch& coarse,
-   //    const hier::BoxList& fine_boxes,
-   //    const hier::IntVector& ratio) {}
-   virtual void
-   preprocessRefine(hier::Patch& ,
-                    const hier::Patch& coarse,
-                    const hier::Box& ,
-                    const hier::IntVector& )
-  {
-    set_boundary(coarse,invalid_id,v_id,true);
-  }
-
-   virtual void
-   postprocessRefineBoxes(
-      hier::Patch& ,
-      const hier::Patch& ,
-      const hier::BoxList& ,
-      const hier::IntVector& ) {}
-   virtual void
-   postprocessRefine(
-      hier::Patch& ,
-      const hier::Patch& ,
-      const hier::Box& ,
-      const hier::IntVector& ) {}
-
-   //@}
-
-   //@{
-
-   /*!
-    * @name Functions to set boundary condition values
-    */
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the first ghost cells.
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to cell-centered variables.
-    * -# Only one ghost cell width is filled.  Setting a Robin
-    *    boundary condition for cell-centered quantities requires
-    *    only one ghost cell to be set.
-    *    (More ghost cells can be filled by continuing the linear
-    *    distribution of data beyond the first cell, but that is
-    *    not implemented at this time.)
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to
-    * get the coefficients, then it sets the values in the first
-    * ghost cell on the boundary.
-    *
-    * To determine the value for the ghost cell,
-    * a @em linear approximation in the direction normal to the
-    * boundary is assumed.  We write the following discrete
-    * approximations:
-    * @f[ u_b = \frac{ u_i + u_o }{2} @f]
-    * @f[ [u_n]_b = \frac{ u_o - u_i }{h} @f]
-    * where the subscript b stands for the the boundary,
-    * i stands for the first cell inside the boundary and
-    * o stands for the first cell outside the boundary
-    * and h is the grid spacing normal to the boundary.
-    * Applying this to the Robin formula gives
-    * @f[ u_o = \frac{ h\gamma + u_i( \beta - \frac{h}{2} \alpha ) }
-    * { \beta + \frac{h}{2} \alpha } @f] or equivalently
-    * @f[ u_o = \frac{ hg + u_i (1-a(1+\frac{h}{2})) }{ 1-a(1-\frac{h}{2}) } @f]
-    *
-    * After setting the edge (face in 3D) boundary conditions,
-    * linear approximations are used to set the boundary conditions
-    * of higher boundary types (nodes in 2D, edges and nodes in 3D).
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required in solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @internal To be more general to other data types,
-    * there could be versions for other data types also,
-    * such as ...InNodes, ...InFaces, etc.  However, I'm not
-    * sure exactly how to implement the Robin boundary condition
-    * on the faces and nodes when m != 1.  Should the boundary
-    * value be set or should the first ghost value be set?
-    *
-    * @internal I have not addressed possibility of differences
-    * in chosing the discrete formulation with which to compute
-    * the boundary value.  The above formulation is obviously
-    * one specific approximation, but there could be others.
-    * If anoter approximation is required, there should be
-    * another class like this or this class can offer a choice
-    * to be set by the user.  I favor another class.
-    *
-    * @internal Since the data alignment can be found through
-    * the target_data_id, these types of functions may be changed
-    * to just plain setBoundaryValues or setBoundaryValuesInBoundaryBoxes
-    * since it does assume boundary boxes.  This may have to be
-    * expanded to later include coarse-fine boundary boxes
-    * for more generality.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set ghost cells for an entire level.
-    *
-    * Loop through all patches on the given level and call
-    * setBoundaryValuesInCells(hier::Patch &patch,
-    *                          const double fill_time ,
-    *                          const hier::IntVector &ghost_width_to_fill ,
-    *                          int target_data_id ,
-    *                          bool homogeneous_bc=false )
-    * for each.
-    *
-    * @param level PatchLevel on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param ghost_width_to_fill Max ghost width requiring fill
-    * @param target_data_id hier::Patch data index of data to be set.
-    *        This data must be a cell-centered double.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesInCells(
-   //    hier::PatchLevel& level,
-   //    const double fill_time,
-   //    const hier::IntVector& ghost_width_to_fill,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   /*!
-    * @brief Set the physical boundary condition by setting the
-    * value of the boundary nodes.
-    *
-    * This function is not yet implemented!
-    *
-    * There are some decisions that must be made before
-    * the implementation can be written.
-    * -# Do we set the values on the boundary or one cell
-    *    away from the boundary?
-    * -# What is the discrete formulation we should use
-    *    to compute the value to be set?
-    *
-    * This function has an interface similar to the virtual function
-    * xfer::RefinePatchStrategy::setPhysicalBoundaryConditions(),
-    * and it may be used to help implement that function,
-    * but it does not serve the same purpose.  The primary
-    * differences are:
-    * -# It specializes to node-centered variables.
-    * -# User must specify the index of the data whose ghost
-    *    cells need to be filled.  This index is used to determine
-    *    the variable for which to set the boundary coefficients
-    *    and to get the data to be set.
-    *
-    * This function calls RobinBcStrategy::setBcCoefs() to get the
-    * coefficients, then it sets the values at the boundary nodes.
-    *
-    * In some cases, the calling function wants to set the
-    * boundary condition homogeneously, with g=0.
-    * This is useful in problems where the the solution of the
-    * homogeneous problem is required to solving the inhomogeneous
-    * problem.  This function respects such requests specified
-    * through the argument @c homogeneous_bc.
-    *
-    * @param patch hier::Patch on which to set boundary condition
-    * @param fill_time Solution time corresponding to filling
-    * @param target_data_id hier::Patch data index of data to be set.
-    * @param homogeneous_bc Set a homogeneous boundary condition.
-    *    This means g=0 for the boundary.
-    */
-   // void
-   // setBoundaryValuesAtNodes(
-   //    hier::Patch& patch,
-   //    const double fill_time,
-   //    int target_data_id,
-   //    bool homogeneous_bc = false) const;
-
-   //@}
-
-   //@{
-   /*!
-    * @name Ways to provide the Robin bc coefficients
-    */
-
-   /*!
-    * @brief Provide an implementation of the RobinBcCoefStrategy
-    * for determining the boundary coefficients.
-    *
-    * Provide the implementation that can be used to set the
-    * Robin bc coefficients.
-    *
-    * @param coef_strategy tbox::Pointer to a concrete inmplementation of
-    *        the coefficient strategy.
-    */
-   // void
-   // setCoefImplementation(
-   //    const RobinBcCoefStrategy* coef_strategy);
-
-   /*!
-    * @brief Set the data id that should be filled when setting
-    * physical boundary conditions.
-    *
-    * When setPhysicalBoundaryConditions is called, the data
-    * specified will be set.  This information is required because
-    * the it is not passed in through the argument list of
-    * setPhysicalBounaryConditions.
-    */
-  void setTargetDataId(int id)
-  {
-    v_id=id;
-  }
-
-   /*!
-    * @brief Set whether boundary filling should assume homogeneous
-    * conditions.
-    *
-    * In certain circumstances, only the value of a is needed, while
-    * the value of g is temporarily not required and taken to be zero.
-    * (An example is in setting the boundary condition for error
-    * value in an iterative method.)  In such cases, use this function
-    * to set a flag that will cause a null pointer to be given to
-    * setBcCoefs() to indicate that fact.
-    */
-   // void
-   // setHomogeneousBc(
-   //    bool homogeneous_bc);
-
-   //@}
-
-private:
-   /*!
-    * @brief Trim a boundary box so that it does not stick out
-    * past a given box.
-    *
-    * Certain boundary-related operations occur on patch data that
-    * do not or cannot extend past the edgr or corner of a patch.
-    * This function is used to trim down the parts of the boundary box
-    * that extend past those points so that a suitable index range
-    * is achieved.
-    *
-    * The boundary box trimmed must be of type 1 or 2.
-    *
-    * @param boundary_box Boundary box to be trimmed.
-    * @param limit_box hier::Box to not stick past
-    *
-    * @return New trimmed boundary box.
-    */
-   // hier::BoundaryBox
-   // trimBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box,
-   //    const hier::Box& limit_box) const;
-
-   /*!
-    * @brief Return box describing the index space of boundary nodes
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the nodes corresponding
-    * to the input boundary box.  These nodes lie on the boundary
-    * itself.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the node indices corresponding to
-    *   boundary_box
-    */
-   // hier::Box
-   // makeNodeBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   /*!
-    * @brief Return box describing the index space of faces
-    * defined by a boundary box.
-    *
-    * Define a box describing the indices of the codimension 1
-    * surface corresponding to the input boundary box.
-    *
-    * The input boundary_box must be of type 1
-    * (see hier::BoundaryBox::getBoundaryType()).
-    *
-    * This is a utility function for working with the
-    * indices coresponding to a boundary box but coincide
-    * with the patch boundary.
-    *
-    * @param boundary_box input boundary box
-    * @return a box to define the face indices corresponding to
-    *    boundary_box
-    */
-   // hier::Box
-   // makeFaceBoundaryBox(
-   //    const hier::BoundaryBox& boundary_box) const;
-
-   const tbox::Dimension d_dim;
-
-   std::string d_object_name;
-
-   /*!
-    * @brief Coefficient strategy giving a way to get to
-    * Robin bc coefficients.
-    */
-   // const RobinBcCoefStrategy* d_coef_strategy;
-
-   /*!
-    * @brief hier::Index of target patch data when filling ghosts.
-    */
-   int v_id;
-
-   /*!
-    * @brief Whether to assumg g=0 when filling ghosts.
-    */
-   // bool d_homogeneous_bc;
-
-   /*!
-    * @brief Timers for performance measurement.
-    */
-   // tbox::Pointer<tbox::Timer> t_set_boundary_values_in_cells;
-   // tbox::Pointer<tbox::Timer> t_use_set_bc_coefs;
-};
-
-}
-}
-
-#endif  // included_solv_V_Refine_Patch_Strategy
diff -r daa8bb8aed75 -r dc04c13db402 src/dRc_dp.h
--- a/src/dRc_dp.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#ifndef GAMR_DRC_DP
-#define GAMR_DRC_DP
-
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/NodeData.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "dRm_dv.h"
-#include "Constants.h"
-
-/* These two functions should really have a more similar API */
-
-/* The derivative of the continuity equation with respect to
-   pressure.  Note that pressure does not appear in the continuity
-   equation, so we use Tackley's method to chain together
-   derivatives */
-
-inline double dRc_dp_2D(const SAMRAI::hier::Box &pbox,
-                        const SAMRAI::pdat::CellIndex &center,
-                        const SAMRAI::pdat::SideIndex &x,
-                        const SAMRAI::pdat::SideIndex &y,
-                        SAMRAI::pdat::CellData<double> &cell_moduli,
-                        SAMRAI::pdat::NodeData<double> &edge_moduli,
-                        SAMRAI::pdat::SideData<double> &v,
-                        const double &dx,
-                        const double &dy)
-{
-  const SAMRAI::hier::Index ip(1,0), jp(0,1);
-  const SAMRAI::pdat::NodeIndex
-    center_e(center,SAMRAI::pdat::NodeIndex::LowerLeft),
-    up_e(center_e+jp),right_e(center_e+ip);
-    
-  const double dRm_dp_xp(1/dx), dRm_dp_xm(-1/dx),
-    dRm_dp_yp(1/dy), dRm_dp_ym(-1/dy),
-    dRc_dvx_p(-1/dx), dRc_dvx_m(1/dx),
-    dRc_dvy_p(-1/dy), dRc_dvy_m(1/dy);
-
-  double result(0);
-
-  if(!(center[0]==pbox.lower(0) && v(x-ip)==boundary_value))
-    result+=dRc_dvx_m * dRm_dp_xm/dRm_dv_2D(cell_moduli,edge_moduli,
-                                            center,center-ip,up_e,center_e,
-                                            dx,dy);
-
-  if(!(center[0]==pbox.upper(0) && v(x+ip*2)==boundary_value))
-    result+=dRc_dvx_p * dRm_dp_xp/dRm_dv_2D(cell_moduli,edge_moduli,
-                                            center+ip,center,up_e+ip,
-                                            center_e+ip,dx,dy);
-  if(!(center[1]==pbox.lower(1) && v(y-jp)==boundary_value))
-    result+=dRc_dvy_m * dRm_dp_ym/dRm_dv_2D(cell_moduli,edge_moduli,
-                                            center,center-jp,right_e,center_e,
-                                            dy,dx);
-
-  if(!(center[1]==pbox.upper(1) && v(y+jp*2)==boundary_value))
-    result+=dRc_dvy_p * dRm_dp_yp/dRm_dv_2D(cell_moduli,edge_moduli,
-                                            center+jp,center,right_e+jp,
-                                            center_e+jp,dy,dx);
-                                            
-  return result;
-}
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/dRm_dv.h
--- a/src/dRm_dv.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#ifndef GAMR_DRM_DV
-#define GAMR_DRM_DV
-
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/pdat/EdgeData.h"
-
-/* The derivative of the momentum equation w/respect to velocity. It
-   is written from the perspective of vx(center_x), but pass in
-   different values for center etc. to get vy or vx(!center_x). */
-
-template<class E_data, class E_index>
-double dRm_dv_2D(SAMRAI::pdat::CellData<double> &cell_moduli,
-                 E_data &edge_moduli,
-                 const SAMRAI::pdat::CellIndex &center,
-                 const SAMRAI::pdat::CellIndex &left,
-                 const E_index &up_e,
-                 const E_index &center_e,
-                 const double &dx,
-                 const double &dy)
-{
-  return -(   (cell_moduli(center,0) + cell_moduli(left,0))
-           +2*(cell_moduli(center,1) + cell_moduli(left,1)))/(dx*dx)
-         -(edge_moduli(up_e,1) + edge_moduli(center_e,1))/(dy*dy);
-}
-
-inline double dRm_dv_3D(SAMRAI::pdat::CellData<double> &cell_moduli,
-		        SAMRAI::pdat::EdgeData<double> &edge_moduli,
-			const SAMRAI::pdat::CellIndex &center,
-			const SAMRAI::pdat::CellIndex &left,
-			const SAMRAI::pdat::EdgeIndex &front_y,
-			const SAMRAI::pdat::EdgeIndex &center_y,
-			const SAMRAI::pdat::EdgeIndex &up_z,
-			const SAMRAI::pdat::EdgeIndex &center_z,
-			const double &dx,
-			const double &dy,
-			const double &dz)
-{
-	  return dRm_dv_2D(cell_moduli,edge_moduli,center,left,front_y,center_y,dx,dy)
-		      - (edge_moduli(up_z,1) + edge_moduli(center_z,1))/(dz*dz);
-}
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 src/main.C
--- a/src/main.C	Tue Jun 05 15:28:40 2012 -0700
+++ b/src/main.C	Wed Jun 06 15:05:55 2012 -0700
@@ -29,14 +29,14 @@ using namespace std;
 #include "SAMRAI/tbox/Utilities.h"
 #include "SAMRAI/appu/VisItDataWriter.h"
 #include "SAMRAI/xfer/RefineOperator.h"
-#include "P_Refine.h"
-#include "V_Refine.h"
-#include "P_Boundary_Refine.h"
-#include "V_Boundary_Refine.h"
-#include "V_Coarsen.h"
-#include "Resid_Coarsen.h"
+#include "Elastic/P_Refine.h"
+#include "Elastic/V_Refine.h"
+#include "Elastic/P_Boundary_Refine.h"
+#include "Elastic/V_Boundary_Refine.h"
+#include "Elastic/V_Coarsen.h"
+#include "Elastic/Resid_Coarsen.h"
 
-#include "FACElastic.h"
+#include "Elastic/FAC.h"
 
 using namespace SAMRAI;
 
@@ -51,7 +51,7 @@ using namespace SAMRAI;
 * in the domain [0:1]x[0:1], with u=0 on the                           *
 * boundary.                                                            *
 *                                                                      *
-* FACElastic is the primary object used to                             *
+* Elastic::FAC is the primary object used to                             *
 * set up and solve the system.  It maintains                           *
 * the data for the computed solution u, the                            *
 * exact solution, and the right hand side.                             *
@@ -177,18 +177,18 @@ int main(
                        input_db->getDatabase("PatchHierarchy")));
 
     /*
-     * The FACElastic object is the main user object specific to the
+     * The Elastic::FAC object is the main user object specific to the
      * problem being solved.  It provides the implementations for setting
      * up the grid and plotting data.  It also wraps up the solve
      * process that includes making the initial guess, specifying the
      * boundary conditions and call the solver.
      */
 
-    FACElastic fac_elastic(base_name + "::FACElastic",
-                           dim,
-                           input_db->isDatabase("FACElastic") ?
-                           input_db->getDatabase("FACElastic") :
-                           tbox::Pointer<tbox::Database>(NULL));
+    Elastic::FAC fac_elastic(base_name + "::Elastic::FAC",
+                             dim,
+                             input_db->isDatabase("Elastic") ?
+                             input_db->getDatabase("Elastic") :
+                             tbox::Pointer<tbox::Database>(NULL));
 
     grid_geometry->addSpatialCoarsenOperator
       (tbox::Pointer<SAMRAI::xfer::CoarsenOperator>
@@ -245,7 +245,7 @@ int main(
 
     /*
      * Set up the plotter for the hierarchy just created.
-     * The FACElastic object handles the data and has the
+     * The Elastic::FAC object handles the data and has the
      * function setupExternalPlotter to register its data
      * with the plotter.
      */
@@ -283,7 +283,7 @@ int main(
     /*
      * Solve.
      */
-    fac_elastic.solveElastic();
+    fac_elastic.solve();
 
     bool done(false);
     for (int lnum = 0;
@@ -304,7 +304,7 @@ int main(
       // gridding_algorithm->makeFinerLevel(0.0,true,0);
       // tbox::plog << "Just added finer levels with lnum = " << lnum << endl;
       done = !(patch_hierarchy->finerLevelExists(lnum));
-      fac_elastic.solveElastic();
+      fac_elastic.solve();
     }
     // {
     //     tbox::Array<int> tag_buffer(patch_hierarchy->getMaxNumberOfLevels());
diff -r daa8bb8aed75 -r dc04c13db402 src/set_boundary.C
--- a/src/set_boundary.C	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-#include "set_boundary.h"
-#include "Constants.h"
-#include "SAMRAI/tbox/Pointer.h"
-#include "SAMRAI/pdat/SideData.h"
-#include "SAMRAI/pdat/CellData.h"
-#include "SAMRAI/geom/CartesianPatchGeometry.h"
-
-using namespace SAMRAI;
-
-void set_boundary(const SAMRAI::hier::Patch& patch, const int &p_id,
-                    const int &v_id, const bool &rhs)
-{
-  hier::Box pbox=patch.getBox();
-
-  tbox::Pointer<geom::CartesianPatchGeometry> geom = patch.getPatchGeometry();
-  const tbox::Dimension Dim(patch.getDim());
-  const int dim(patch.getDim().getValue());
-
-  const hier::Index zero(hier::Index::getZeroIndex(Dim));
-  hier::Index pp[]={zero,zero,zero};
-  for(int i=0;i<dim;++i)
-    pp[i][i]=1;
-  /* This should really get read from the input file. */
-  double lower_boundary[]={0,0,0};
-  bool lower_dirichlet[]={true,true,true};
-
-  // double upper_boundary[]={-6.94444444444e4,0,0};
-  // bool upper_dirichlet[]={true,false,true};
-
-  // bool upper_dirichlet[]={true,true,true};
-  // double upper_boundary[]={-1,1,0};
-
-  double p_lower[]={0,0,0};
-  double p_upper[]={0,0,0};
-
-  bool upper_dirichlet[]={true,true,true};
-  double upper_boundary[]={0,0,0};
-
-  if(v_id!=invalid_id)
-    {
-      tbox::Pointer<pdat::SideData<double> > v_ptr = patch.getPatchData(v_id);
-      pdat::SideData<double> &v(*v_ptr);
-
-      hier::Box gbox=v.getGhostBox();
-      for(int ix=0; ix<dim; ++ix)
-        {
-          for(pdat::SideIterator si(gbox,ix); si; si++)
-            {
-              pdat::SideIndex x(*si);
-
-              /* Set a sentinel value for normal components */
-              if(x[ix]<pbox.lower(ix) && geom->getTouchesRegularBoundary(ix,0))
-                {
-                  if(lower_dirichlet[ix])
-                    v(x)=boundary_value;
-                  else
-                    v(x)=v(x+pp[ix]*2);
-                }
-              else if(x[ix]>pbox.upper(ix)+1
-                      && geom->getTouchesRegularBoundary(ix,1))
-                {
-                  if(upper_dirichlet[ix])
-                    v(x)=boundary_value;
-                  else
-                    v(x)=v(x-pp[ix]*2);
-                }
-              /* Set values for normal components */
-              else if(x[ix]==pbox.lower(ix)
-                      && geom->getTouchesRegularBoundary(ix,0)
-                      && !rhs && lower_dirichlet[ix])
-                {
-                  v(x)=lower_boundary[ix];
-                }
-              else if(x[ix]==pbox.upper(ix)+1
-                      && geom->getTouchesRegularBoundary(ix,1)
-                      && !rhs && upper_dirichlet[ix])
-                {
-                  v(x)=upper_boundary[ix];
-                }
-              /* Set derivatives for tangential component.  The edges
-                 and corners are incorrect for now.  */
-              else
-                {
-                  for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
-                    {
-                      if(x[iy]<pbox.lower(iy)
-                         && geom->getTouchesRegularBoundary(iy,0))
-                        {
-                          v(x)=v(x+pp[iy]);
-                        }
-                      else if(x[iy]>pbox.upper(iy)
-                              && geom->getTouchesRegularBoundary(iy,1))
-                        {
-                          v(x)=v(x-pp[iy]);
-                        }
-                    }
-                }
-            }
-          /* Fix up the edges.  This has to be done in a different
-             loop, because the values on the faces will be used to
-             compute values in the edges and corners.  In 2D, I am not
-             sure that this is needed.  It is certainly not needed if
-             we have dirichlet conditions on the boundary.  It is
-             definitely needed in 3D.  We use the d/dx conditions
-             here, though we could use the d/dy conditions and get the
-             same number, as long as we have pure Neumann boundary
-             conditions, and not Robin. */
-
-          for(pdat::SideIterator si(gbox,ix); si; si++)
-            {
-              pdat::SideIndex x(*si);
-              if((x[ix]<pbox.lower(ix)
-                  && geom->getTouchesRegularBoundary(ix,0)
-                  && !lower_dirichlet[ix])
-                 || (x[ix]>pbox.upper(ix)+1
-                     && geom->getTouchesRegularBoundary(ix,1)
-                     && !upper_dirichlet[ix]))
-                {
-                  for(int iy=(ix+1)%dim; iy!=ix; iy=(iy+1)%dim)
-                    {
-                      if(x[iy]<pbox.lower(iy) 
-                         && geom->getTouchesRegularBoundary(iy,0))
-                        {
-                          v(x)=v(x+pp[iy]);
-                        }
-                      else if(x[iy]>pbox.upper(iy) 
-                              && geom->getTouchesRegularBoundary(iy,1))
-                        {
-                          v(x)=v(x-pp[iy]);
-                        }
-                    }
-                }
-            }
-          /* In 3D, fix the corners.  I am not sure that this is
-             needed. */
-          if(dim==3)
-            {
-              const int iy((ix+1)%dim), iz((iy+1)%dim);
-              for(pdat::SideIterator si(gbox,ix); si; si++)
-                {
-                  pdat::SideIndex x(*si);
-                  if(((x[ix]<pbox.lower(ix)
-                       && geom->getTouchesRegularBoundary(ix,0)
-                       && !lower_dirichlet[ix])
-                      || (x[ix]>pbox.upper(ix)+1
-                          && geom->getTouchesRegularBoundary(ix,1)
-                          && !upper_dirichlet[ix]))
-                     && ((x[iy]<pbox.lower(iy)
-                          && geom->getTouchesRegularBoundary(iy,0))
-                         || (x[iy]>pbox.upper(iy) 
-                             && geom->getTouchesRegularBoundary(iy,1))))
-                    {
-                      if(x[iz]<pbox.lower(iz) 
-                         && geom->getTouchesRegularBoundary(iz,0))
-                        {
-                          v(x)=v(x+pp[iz]);
-                        }
-                      else if(x[iz]>pbox.upper(iz) 
-                              && geom->getTouchesRegularBoundary(iz,1))
-                        {
-                          v(x)=v(x-pp[iz]);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff -r daa8bb8aed75 -r dc04c13db402 src/set_boundary.h
--- a/src/set_boundary.h	Tue Jun 05 15:28:40 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef SET_V_BOUNDARY_H
-#define SET_V_BOUNDARY_H
-
-#include "SAMRAI/hier/Patch.h"
-
-void set_boundary(const SAMRAI::hier::Patch& patch,
-                  const int &p_id, const int &v_id, const bool &rhs);
-
-#endif
diff -r daa8bb8aed75 -r dc04c13db402 wscript
--- a/wscript	Tue Jun 05 15:28:40 2012 -0700
+++ b/wscript	Wed Jun 06 15:05:55 2012 -0700
@@ -10,68 +10,68 @@ def build(bld):
     bld.program(
         features     = ['cxx','cprogram'],
         source       = ['src/main.C',
-                        'src/FACElastic/FACElastic.C',
-                        'src/FACElastic/fix_moduli.C',
-                        'src/FACElastic/applyGradientDetector.C',
-                        'src/FACElastic/initializeLevelData.C',
-                        'src/FACElastic/packDerivedDataIntoDoubleBuffer.C',
-                        'src/FACElastic/resetHierarchyConfiguration.C',
-                        'src/FACElastic/setupPlotter.C',
-                        'src/FACElastic/solveElastic.C',
-                        'src/P_Refine.C',
-                        'src/V_Refine/refine.C',
-                        'src/V_Refine/refine_along_line.C',
-                        'src/Resid_Coarsen.C',
-                        'src/V_Coarsen/coarsen_2D.C',
-                        'src/V_Coarsen/coarsen_3D.C',
-                        'src/P_Boundary_Refine/refine.C',
-                        'src/P_Boundary_Refine/Update_P_2D.C',
-                        'src/P_Boundary_Refine/Update_P_3D.C',
-                        'src/V_Boundary_Refine/refine.C',
-                        'src/V_Boundary_Refine/Update_V_2D.C',
-                        'src/V_Boundary_Refine/Update_V_3D.C',
-                        'src/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C',
-                        'src/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C',
-                        'src/set_boundary.C',
-                        'src/ElasticFACOps/ElasticFACOps.C',
-                        'src/ElasticFACOps/computeCompositeResidualOnLevel.C',
-                        'src/ElasticFACOps/residual_2D.C',
-                        'src/ElasticFACOps/residual_3D.C',
-                        'src/ElasticFACOps/computeResidualNorm.C',
-                        'src/ElasticFACOps/computeVectorWeights.C',
-                        'src/ElasticFACOps/deallocateOperatorState.C',
-                        'src/ElasticFACOps/finalizeCallback.C',
-                        'src/ElasticFACOps/initializeOperatorState.C',
-                        'src/ElasticFACOps/postprocessOneCycle.C',
-                        'src/ElasticFACOps/prolongErrorAndCorrect.C',
-                        'src/ElasticFACOps/restrictResidual.C',
-                        'src/ElasticFACOps/restrictSolution.C',
-                        'src/ElasticFACOps/smoothError.C',
-                        'src/ElasticFACOps/smooth_Tackley_2D.C',
-                        'src/ElasticFACOps/smooth_Tackley_3D.C',
-                        'src/ElasticFACOps/set_boundaries.C',
-                        'src/ElasticFACOps/solveCoarsestLevel.C',
-                        'src/ElasticFACOps/solveCoarsestLevel_HYPRE.C',
-                        'src/ElasticFACOps/smooth_V_2D.C',
-                        'src/ElasticFACOps/smooth_V_3D.C',
-                        'src/ElasticFACOps/xeqScheduleGhostFill.C',
-                        'src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C',
-                        'src/ElasticFACOps/xeqScheduleProlongation.C',
-                        'src/ElasticFACOps/xeqScheduleRRestriction.C',
-                        'src/ElasticFACOps/xeqScheduleURestriction.C',
-                        'src/ElasticFACSolver/ElasticFACSolver.C',
-                        'src/ElasticFACSolver/ElasticFACSolver_Destructor.C',
-                        'src/ElasticFACSolver/createVectorWrappers.C',
-                        'src/ElasticFACSolver/deallocateSolverState.C',
-                        'src/ElasticFACSolver/destroyVectorWrappers.C',
-                        'src/ElasticFACSolver/enableLogging.C',
-                        'src/ElasticFACSolver/getFromInput.C',
-                        'src/ElasticFACSolver/initializeSolverState.C',
-                        'src/ElasticFACSolver/initializeStatics.C',
-                        'src/ElasticFACSolver/setBcObject.C',
-                        'src/ElasticFACSolver/setBoundaries.C',
-                        'src/ElasticFACSolver/solveSystem.C',
-                        'src/ElasticHypreSolver.C'],
+                        'src/Elastic/FAC/FAC.C',
+                        'src/Elastic/FAC/fix_moduli.C',
+                        'src/Elastic/FAC/applyGradientDetector.C',
+                        'src/Elastic/FAC/initializeLevelData.C',
+                        'src/Elastic/FAC/packDerivedDataIntoDoubleBuffer.C',
+                        'src/Elastic/FAC/resetHierarchyConfiguration.C',
+                        'src/Elastic/FAC/setupPlotter.C',
+                        'src/Elastic/FAC/solve.C',
+                        'src/Elastic/P_Refine.C',
+                        'src/Elastic/V_Refine/refine.C',
+                        'src/Elastic/V_Refine/refine_along_line.C',
+                        'src/Elastic/Resid_Coarsen.C',
+                        'src/Elastic/V_Coarsen/coarsen_2D.C',
+                        'src/Elastic/V_Coarsen/coarsen_3D.C',
+                        'src/Elastic/P_Boundary_Refine/refine.C',
+                        'src/Elastic/P_Boundary_Refine/Update_P_2D.C',
+                        'src/Elastic/P_Boundary_Refine/Update_P_3D.C',
+                        'src/Elastic/V_Boundary_Refine/refine.C',
+                        'src/Elastic/V_Boundary_Refine/Update_V_2D.C',
+                        'src/Elastic/V_Boundary_Refine/Update_V_3D.C',
+                        'src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C',
+                        'src/Elastic/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C',
+                        'src/Elastic/set_boundary.C',
+                        'src/Elastic/FACOps/FACOps.C',
+                        'src/Elastic/FACOps/computeCompositeResidualOnLevel.C',
+                        'src/Elastic/FACOps/residual_2D.C',
+                        'src/Elastic/FACOps/residual_3D.C',
+                        'src/Elastic/FACOps/computeResidualNorm.C',
+                        'src/Elastic/FACOps/computeVectorWeights.C',
+                        'src/Elastic/FACOps/deallocateOperatorState.C',
+                        'src/Elastic/FACOps/finalizeCallback.C',
+                        'src/Elastic/FACOps/initializeOperatorState.C',
+                        'src/Elastic/FACOps/postprocessOneCycle.C',
+                        'src/Elastic/FACOps/prolongErrorAndCorrect.C',
+                        'src/Elastic/FACOps/restrictResidual.C',
+                        'src/Elastic/FACOps/restrictSolution.C',
+                        'src/Elastic/FACOps/smoothError.C',
+                        'src/Elastic/FACOps/smooth_Tackley_2D.C',
+                        'src/Elastic/FACOps/smooth_Tackley_3D.C',
+                        'src/Elastic/FACOps/set_boundaries.C',
+                        'src/Elastic/FACOps/solveCoarsestLevel.C',
+                        'src/Elastic/FACOps/solveCoarsestLevel_HYPRE.C',
+                        'src/Elastic/FACOps/smooth_V_2D.C',
+                        'src/Elastic/FACOps/smooth_V_3D.C',
+                        'src/Elastic/FACOps/xeqScheduleGhostFill.C',
+                        'src/Elastic/FACOps/xeqScheduleGhostFillNoCoarse.C',
+                        'src/Elastic/FACOps/xeqScheduleProlongation.C',
+                        'src/Elastic/FACOps/xeqScheduleRRestriction.C',
+                        'src/Elastic/FACOps/xeqScheduleURestriction.C',
+                        'src/Elastic/FACSolver/FACSolver.C',
+                        'src/Elastic/FACSolver/FACSolver_Destructor.C',
+                        'src/Elastic/FACSolver/createVectorWrappers.C',
+                        'src/Elastic/FACSolver/deallocateSolverState.C',
+                        'src/Elastic/FACSolver/destroyVectorWrappers.C',
+                        'src/Elastic/FACSolver/enableLogging.C',
+                        'src/Elastic/FACSolver/getFromInput.C',
+                        'src/Elastic/FACSolver/initializeSolverState.C',
+                        'src/Elastic/FACSolver/initializeStatics.C',
+                        'src/Elastic/FACSolver/setBcObject.C',
+                        'src/Elastic/FACSolver/setBoundaries.C',
+                        'src/Elastic/FACSolver/solveSystem.C',
+                        'src/Elastic/HypreSolver.C'],
 
         target       = 'gamra',
         cxxflags      = ['-O3', '-Wall', '-Wextra', '-Wconversion',



More information about the CIG-COMMITS mailing list