[cig-commits] commit: Rename Stokes -> Elastic
Mercurial
hg at geodynamics.org
Thu Jun 7 13:36:07 PDT 2012
changeset: 280:daa8bb8aed75
user: Walter Landry <wlandry at caltech.edu>
date: Tue Jun 05 15:28:40 2012 -0700
files: input/fault.input 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/FACStokes.h src/FACStokes/FACStokes.C src/FACStokes/applyGradientDetector.C src/FACStokes/fix_moduli.C src/FACStokes/initializeLevelData.C src/FACStokes/packDerivedDataIntoDoubleBuffer.C src/FACStokes/resetHierarchyConfiguration.C src/FACStokes/setupPlotter.C src/FACStokes/solveStokes.C src/StokesFACOps.I src/StokesFACOps.h src/StokesFACOps/StokesFACOps.C src/StokesFACOps/computeCompositeResidualOnLevel.C src/StokesFACOps/computeResidualNorm.C src/StokesFACOps/computeVectorWeights.C src/StokesFACOps/deallocateOperatorState.C src/StokesFACOps/finalizeCallback.C src/StokesFACOps/initializeOperatorState.C src/StokesFACOps/postprocessOneCycle.C src/StokesFACOps/prolongErrorAndCorrect.C src/StokesFACOps/residual_2D.C src/StokesFACOps/residual_3D.C src/StokesFACOps/restrictResidual.C src/StokesFACOps/restrictSolution.C src/StokesFACOps/set_boundaries.C src/StokesFACOps/smoothError.C src/StokesFACOps/smooth_Tackley_2D.C src/StokesFACOps/smooth_Tackley_3D.C src/StokesFACOps/smooth_V_2D.C src/StokesFACOps/smooth_V_3D.C src/StokesFACOps/solveCoarsestLevel.C src/StokesFACOps/solveCoarsestLevel_HYPRE.C src/StokesFACOps/xeqScheduleGhostFill.C src/StokesFACOps/xeqScheduleGhostFillNoCoarse.C src/StokesFACOps/xeqScheduleProlongation.C src/StokesFACOps/xeqScheduleRRestriction.C src/StokesFACOps/xeqScheduleURestriction.C src/StokesFACSolver.I src/StokesFACSolver.h src/StokesFACSolver/StokesFACSolver.C src/StokesFACSolver/StokesFACSolver_Destructor.C src/StokesFACSolver/createVectorWrappers.C src/StokesFACSolver/deallocateSolverState.C src/StokesFACSolver/destroyVectorWrappers.C src/StokesFACSolver/enableLogging.C src/StokesFACSolver/getFromInput.C src/StokesFACSolver/initializeSolverState.C src/StokesFACSolver/initializeStatics.C src/StokesFACSolver/setBcObject.C src/StokesFACSolver/setBoundaries.C src/StokesFACSolver/solveSystem.C src/StokesHypreSolver.C src/StokesHypreSolver.I src/StokesHypreSolver.h src/main.C wscript
description:
Rename Stokes -> Elastic
diff -r 56c59b83f606 -r daa8bb8aed75 input/fault.input
--- a/input/fault.input Tue Jun 05 14:36:48 2012 -0700
+++ b/input/fault.input Tue Jun 05 15:28:40 2012 -0700
@@ -23,7 +23,7 @@ Main {
vis_writer = "Vizamrai", "VisIt"
}
-FACStokes {
+FACElastic {
// 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps.I
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps.I Tue Jun 05 15:28:40 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 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps.h Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,1077 @@
+/*************************************************************************
+ *
+ * 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 ¢er,
+ 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 ¢er,
+ 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 ¢er,
+ 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 ¢er,
+ 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 ¢er,
+ 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 ¢er,
+ 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/ElasticFACOps.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/ElasticFACOps.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/computeCompositeResidualOnLevel.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/computeCompositeResidualOnLevel.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,107 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/computeResidualNorm.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/computeResidualNorm.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,33 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/computeVectorWeights.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/computeVectorWeights.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/deallocateOperatorState.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/deallocateOperatorState.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/finalizeCallback.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/finalizeCallback.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/initializeOperatorState.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/initializeOperatorState.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/postprocessOneCycle.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/postprocessOneCycle.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/prolongErrorAndCorrect.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/prolongErrorAndCorrect.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/residual_2D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/residual_2D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,83 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/residual_3D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/residual_3D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,73 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/restrictResidual.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/restrictResidual.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/restrictSolution.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/restrictSolution.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/set_boundaries.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/set_boundaries.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/smoothError.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/smoothError.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/smooth_Tackley_2D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/smooth_Tackley_2D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,200 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/smooth_Tackley_3D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/smooth_Tackley_3D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,148 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/smooth_V_2D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/smooth_V_2D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,79 @@
+#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 ¢er,
+ 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/smooth_V_3D.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/smooth_V_3D.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,78 @@
+#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 ¢er,
+ 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/solveCoarsestLevel.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/solveCoarsestLevel.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/solveCoarsestLevel_HYPRE.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/solveCoarsestLevel_HYPRE.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/xeqScheduleGhostFill.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/xeqScheduleGhostFill.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/xeqScheduleGhostFillNoCoarse.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/xeqScheduleProlongation.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/xeqScheduleProlongation.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/xeqScheduleRRestriction.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/xeqScheduleRRestriction.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACOps/xeqScheduleURestriction.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACOps/xeqScheduleURestriction.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver.I
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver.I Tue Jun 05 15:28:40 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 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver.h Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,673 @@
+/*************************************************************************
+ *
+ * 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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/ElasticFACSolver.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/ElasticFACSolver.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/ElasticFACSolver_Destructor.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/ElasticFACSolver_Destructor.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/createVectorWrappers.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/createVectorWrappers.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/deallocateSolverState.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/deallocateSolverState.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/destroyVectorWrappers.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/destroyVectorWrappers.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/enableLogging.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/enableLogging.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/getFromInput.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/getFromInput.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/initializeSolverState.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/initializeSolverState.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/initializeStatics.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/initializeStatics.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/setBcObject.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/setBcObject.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/setBoundaries.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/setBoundaries.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticFACSolver/solveSystem.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticFACSolver/solveSystem.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticHypreSolver.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticHypreSolver.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/ElasticHypreSolver.I
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticHypreSolver.I Tue Jun 05 15:28:40 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 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 56c59b83f606 -r daa8bb8aed75 src/ElasticHypreSolver.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ElasticHypreSolver.h Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,615 @@
+/*************************************************************************
+ *
+ * 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 56c59b83f606 -r daa8bb8aed75 src/FACElastic.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic.h Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * 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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/FACElastic.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/FACElastic.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/applyGradientDetector.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/applyGradientDetector.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,113 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/fix_moduli.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/fix_moduli.C Tue Jun 05 15:28:40 2012 -0700
@@ -0,0 +1,141 @@
+#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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/initializeLevelData.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/initializeLevelData.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/packDerivedDataIntoDoubleBuffer.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/packDerivedDataIntoDoubleBuffer.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/resetHierarchyConfiguration.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/resetHierarchyConfiguration.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/setupPlotter.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/setupPlotter.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACElastic/solveElastic.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/FACElastic/solveElastic.C Tue Jun 05 15:28:40 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 "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 56c59b83f606 -r daa8bb8aed75 src/FACStokes.h
--- a/src/FACStokes.h Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#ifndef included_FACStokes
-#define included_FACStokes
-
-#include "StokesFACSolver.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 Stokes equation on a SAMR grid.
- */
- class FACStokes:
- 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)
- */
- FACStokes(const std::string& object_name,
- const tbox::Dimension& dim,
- tbox::Pointer<tbox::Database> database =
- tbox::Pointer<tbox::Database>(NULL));
-
- virtual ~FACStokes() {}
-
- //@{ @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 Stokes solver
- *
- * Set up the linear algebra problem and use a
- * solv::StokesFACSolver object to solve it.
- * -# Set initial guess
- * -# Set boundary conditions
- * -# Specify Stokes equation parameters
- * -# Call solver
- */
- int
- solveStokes();
-
-#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 stokes solver.
- */
- solv::StokesFACSolver d_stokes_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_FACStokes
diff -r 56c59b83f606 -r daa8bb8aed75 src/FACStokes/FACStokes.C
--- a/src/FACStokes/FACStokes.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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. *
-*************************************************************************
-*/
- FACStokes::FACStokes(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_stokes_fac_solver((d_dim),
- object_name + "::stokes_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_stokes_fac_solver.setBcObject(&d_bc_coefs);
- }
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/FACStokes/applyGradientDetector.C
--- a/src/FACStokes/applyGradientDetector.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#include "FACStokes.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-#include "SAMRAI/pdat/MDA_Access.h"
-#include "SAMRAI/pdat/ArrayDataAccess.h"
-
-void SAMRAI::FACStokes::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 56c59b83f606 -r daa8bb8aed75 src/FACStokes/fix_moduli.C
--- a/src/FACStokes/fix_moduli.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-#include "FACStokes.h"
-#include "SAMRAI/geom/CartesianGridGeometry.h"
-
-/* Fix the moduli on the coarse grids by coarsening from the finer
- grids. */
-
-void SAMRAI::FACStokes::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 56c59b83f606 -r daa8bb8aed75 src/FACStokes/initializeLevelData.C
--- a/src/FACStokes/initializeLevelData.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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::FACStokes::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 56c59b83f606 -r daa8bb8aed75 src/FACStokes/packDerivedDataIntoDoubleBuffer.C
--- a/src/FACStokes/packDerivedDataIntoDoubleBuffer.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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 FACStokes::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"
- <<
- "FACStokesX::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 56c59b83f606 -r daa8bb8aed75 src/FACStokes/resetHierarchyConfiguration.C
--- a/src/FACStokes/resetHierarchyConfiguration.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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 FACStokes::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 56c59b83f606 -r daa8bb8aed75 src/FACStokes/setupPlotter.C
--- a/src/FACStokes/setupPlotter.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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 FACStokes::setupPlotter(appu::VisItDataWriter& plotter) const {
- if (d_hierarchy.isNull()) {
- TBOX_ERROR(d_object_name << ": No hierarchy in\n"
- << " FACStokes::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("Stokes source",
- "SCALAR",
- p_rhs_id);
-
- return 0;
- }
-#endif
-
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/FACStokes/solveStokes.C
--- a/src/FACStokes/solveStokes.C Tue Jun 05 14:36:48 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 Stokes solver
- *
- ************************************************************************/
-#include "FACStokes.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 Stokes problem. We explicitly initialize and *
-* deallocate the solver state in this example. *
-*************************************************************************
-*/
-int SAMRAI::FACStokes::solveStokes()
-{
-
- 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_stokes_fac_solver.set_boundaries(p_id,v_id,level,false);
- }
-
- fix_moduli();
-
- d_stokes_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_stokes_fac_solver.solveSystem(p_id,p_rhs_id,v_id,v_rhs_id);
- /*
- * Present data on the solve.
- */
- // double avg_factor, final_factor;
- // d_stokes_fac_solver.getConvergenceFactors(avg_factor, final_factor);
- // tbox::plog << "\t" << (solver_ret ? "" : "NOT ") << "converged " << "\n"
- // << " iterations: "
- // << d_stokes_fac_solver.getNumberOfIterations() << "\n"
- // << " residual: "<< d_stokes_fac_solver.getResidualNorm()
- // << "\n"
- // << " average convergence: "<< avg_factor << "\n"
- // << " final convergence: "<< final_factor << "\n"
- // << std::flush;
-
- d_stokes_fac_solver.deallocateSolverState();
-
- return 0;
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps.I
--- a/src/StokesFACOps.I Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-namespace SAMRAI {
-namespace solv {
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::setPreconditioner(
- const FACPreconditioner* preconditioner) {
- d_preconditioner = preconditioner;
-}
-
-#ifdef HAVE_HYPRE
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::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 StokesFACOps::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 StokesFACOps::enableLogging(
- bool enable_logging)
-{
- d_enable_logging = enable_logging;
-}
-
-/*
- ********************************************************************
- * Set the choice for smoothing algorithm. *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::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 StokesFACOps::setSmoothingChoice.");
- }
-#endif
- d_smoothing_choice = smoothing_choice;
-}
-
-/*
- ********************************************************************
- * Set the choice for the coarse level solver. *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::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 scapStokesOpsX::setCoarseLevelSolver.");
- }
-}
-
-/*
- ********************************************************************
- * Set the tolerance for the coarse level solver. *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::setCoarsestLevelSolverTolerance(
- double tol) {
- d_coarse_solver_tolerance = tol;
-}
-
-/*
- ********************************************************************
- * Set the tolerance for the coarse level solver. *
- ********************************************************************
- */
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACOps::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 StokesFACOps::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 StokesFACOps::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 StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps.h
--- a/src/StokesFACOps.h Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#ifndef included_solv_StokesFACOps
-#define included_solv_StokesFACOps
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "SAMRAI/solv/FACOperatorStrategy.h"
-#include "StokesHypreSolver.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 Stokes'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 Stokes's equation using a cell-centered
- * second-order finite-volume discretization.
- * It is designed to provide all operations specific to
- * the scalar Stokes's equation,
- * @f[ \nabla \cdot D \nabla u + C u = f @f]
- * (see StokesSpecifications) 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 Stokes-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 StokesSpecifications 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 StokesFACOps:
- 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
- */
- StokesFACOps(
- 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.
- */
- ~StokesFACOps(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 ¢er,
- 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 ¢er,
- 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 ¢er,
- 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 ¢er,
- 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 ¢er,
- 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 ¢er,
- 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.
- */
- StokesHypreSolver 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 "StokesFACOps.I"
-#endif
-
-#endif // included_solv_StokesFACOps
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/StokesFACOps.C
--- a/src/StokesFACOps/StokesFACOps.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-#ifndef SAMRAI_INLINE
-#include "StokesFACOps.I"
-#endif
-
-namespace SAMRAI {
- namespace solv {
-
- tbox::Pointer<pdat::CellVariable<double> >
- StokesFACOps::s_cell_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
- tbox::Pointer<pdat::SideVariable<double> >
- StokesFACOps::s_side_scratch_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
- tbox::StartupShutdownManager::Handler
- StokesFACOps::s_finalize_handler(
- 0,
- 0,
- 0,
- StokesFACOps::finalizeCallback,
- tbox::StartupShutdownManager::priorityVariables);
-
- /*
-********************************************************************
-* Constructor. *
-********************************************************************
-*/
- StokesFACOps::StokesFACOps(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::StokesFACOps::restrictSolution()");
- t_restrict_residual = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::restrictResidual()");
- t_prolong = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::prolongErrorAndCorrect()");
- t_smooth_error = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::smoothError()");
- t_solve_coarsest = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::solveCoarsestLevel()");
- t_compute_composite_residual = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::computeCompositeResidualOnLevel()");
- t_compute_residual_norm = tbox::TimerManager::getManager()->
- getTimer("solv::StokesFACOps::computeResidualNorm()");
-
- if (d_dim == tbox::Dimension(1) || d_dim > tbox::Dimension(3)) {
- TBOX_ERROR("StokesFACOps : 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 << "StokesFACOps::private_cell_scratch" << dim.getValue();
- s_cell_scratch_var[dim.getValue() - 1] = new pdat::CellVariable<double>
- (dim, ss.str());
- ss.str("");
- ss << "StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/computeCompositeResidualOnLevel.C
--- a/src/StokesFACOps/computeCompositeResidualOnLevel.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/computeResidualNorm.C
--- a/src/StokesFACOps/computeResidualNorm.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#include "StokesFACOps.h"
-
-double SAMRAI::solv::StokesFACOps::computeResidualNorm
-(const SAMRAIVectorReal<double>& residual,
- int fine_ln,
- int coarse_ln)
-{
- if (coarse_ln != residual.getCoarsestLevelNumber() ||
- fine_ln != residual.getFinestLevelNumber()) {
- TBOX_ERROR("StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/computeVectorWeights.C
--- a/src/StokesFACOps/computeVectorWeights.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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 StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/deallocateOperatorState.C
--- a/src/StokesFACOps/deallocateOperatorState.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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 StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/finalizeCallback.C
--- a/src/StokesFACOps/finalizeCallback.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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
- StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/initializeOperatorState.C
--- a/src/StokesFACOps/initializeOperatorState.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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::StokesFACOps::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"
- // <<
- // "StokesFACOps::initializeOperatorState\n"
- // << "You must use "
- // <<
- // "StokesFACOps::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_stokes_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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/postprocessOneCycle.C
--- a/src/StokesFACOps/postprocessOneCycle.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/prolongErrorAndCorrect.C
--- a/src/StokesFACOps/prolongErrorAndCorrect.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/residual_2D.C
--- a/src/StokesFACOps/residual_2D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/residual_3D.C
--- a/src/StokesFACOps/residual_3D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/restrictResidual.C
--- a/src/StokesFACOps/restrictResidual.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/restrictSolution.C
--- a/src/StokesFACOps/restrictSolution.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/set_boundaries.C
--- a/src/StokesFACOps/set_boundaries.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/smoothError.C
--- a/src/StokesFACOps/smoothError.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 StokesFACOps.");
- } else {
- TBOX_ERROR(d_object_name << ": Bad smoothing choice '"
- << d_smoothing_choice
- << "' in StokesFACOps.");
- }
-
- t_smooth_error->stop();
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/smooth_Tackley_2D.C
--- a/src/StokesFACOps/smooth_Tackley_2D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Workhorse function to smooth error using red-black *
-* Gauss-Seidel iterations. *
-********************************************************************
-*/
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/smooth_Tackley_3D.C
--- a/src/StokesFACOps/smooth_Tackley_3D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Workhorse function to smooth error using red-black *
-* Gauss-Seidel iterations. *
-********************************************************************
-*/
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/smooth_V_2D.C
--- a/src/StokesFACOps/smooth_V_2D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-#include "dRm_dv.h"
-/*
-********************************************************************
-* Updates one component of the velocity during a red-black *
-* Gauss-Seidel iteration. *
-********************************************************************
-*/
-void SAMRAI::solv::StokesFACOps::smooth_V_2D
-(const int &axis,
- const hier::Box &pbox,
- tbox::Pointer<geom::CartesianPatchGeometry> &geom,
- const pdat::CellIndex ¢er,
- 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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/smooth_V_3D.C
--- a/src/StokesFACOps/smooth_V_3D.C Tue Jun 05 14:36:48 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#include "StokesFACOps.h"
-#include "Constants.h"
-#include "dRc_dp.h"
-/*
-********************************************************************
-* Updates one component of the velocity during a red-black *
-* Gauss-Seidel iteration. *
-********************************************************************
-*/
-void SAMRAI::solv::StokesFACOps::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 ¢er,
- 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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/solveCoarsestLevel.C
--- a/src/StokesFACOps/solveCoarsestLevel.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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::StokesFACOps::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 "
- << "scapStokesOps::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 scapStokesOps::solveCoarsestLevel.");
- }
-
- xeqScheduleGhostFillNoCoarse(data.getComponentDescriptorIndex(0),
- data.getComponentDescriptorIndex(1),
- coarsest_ln);
- t_solve_coarsest->stop();
-
- return return_value;
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/solveCoarsestLevel_HYPRE.C
--- a/src/StokesFACOps/solveCoarsestLevel_HYPRE.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.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 "StokesHypreSolver.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 StokesFACOps::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 "
- << "StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/xeqScheduleGhostFill.C
--- a/src/StokesFACOps/xeqScheduleGhostFill.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/xeqScheduleGhostFillNoCoarse.C
--- a/src/StokesFACOps/xeqScheduleGhostFillNoCoarse.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/xeqScheduleProlongation.C
--- a/src/StokesFACOps/xeqScheduleProlongation.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/xeqScheduleRRestriction.C
--- a/src/StokesFACOps/xeqScheduleRRestriction.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACOps/xeqScheduleURestriction.C
--- a/src/StokesFACOps/xeqScheduleURestriction.C Tue Jun 05 14:36:48 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 Stokes using FAC
- *
- ************************************************************************/
-#include "StokesFACOps.h"
-
-void SAMRAI::solv::StokesFACOps::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver.I
--- a/src/StokesFACSolver.I Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-namespace SAMRAI {
-namespace solv {
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::set_P_ProlongationMethod(
- const std::string& p_prolongation_method)
-{
- d_fac_ops.set_P_ProlongationMethod(p_prolongation_method);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::set_V_ProlongationMethod(
- const std::string& v_prolongation_method)
-{
- d_fac_ops.set_V_ProlongationMethod(v_prolongation_method);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setCoarsestLevelSolverChoice(
- const std::string& choice)
-{
- d_fac_ops.setCoarsestLevelSolverChoice(choice);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setCoarsestLevelSolverTolerance(
- double tol)
-{
- d_fac_ops.setCoarsestLevelSolverTolerance(tol);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setCoarsestLevelSolverMaxIterations(
- int max_iterations)
-{
- d_fac_ops.setCoarsestLevelSolverMaxIterations(max_iterations);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setCoarseFineDiscretization(
- const std::string& coarsefine_method)
-{
- d_fac_ops.setCoarseFineDiscretization(coarsefine_method);
-}
-
-#ifdef HAVE_HYPRE
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::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 StokesFACSolver::setPresmoothingSweeps(
- int num_pre_sweeps) {
- d_fac_precond.setPresmoothingSweeps(num_pre_sweeps);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setPostsmoothingSweeps(
- int num_post_sweeps) {
- d_fac_precond.setPostsmoothingSweeps(num_post_sweeps);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setMaxCycles(
- int max_cycles) {
- d_fac_precond.setMaxCycles(max_cycles);
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::setResidualTolerance(
- double residual_tol) {
- d_fac_precond.setResidualTolerance(residual_tol);
-}
-
-SAMRAI_INLINE_KEYWORD
-int StokesFACSolver::getNumberOfIterations() const
-{
- return d_fac_precond.getNumberOfIterations();
-}
-
-SAMRAI_INLINE_KEYWORD
-double StokesFACSolver::getResidualNorm() const
-{
- return d_fac_precond.getResidualNorm();
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesFACSolver::getConvergenceFactors(
- double& avg_factor,
- double& final_factor)
-const
-{
- d_fac_precond.getConvergenceFactors(avg_factor, final_factor);
-}
-
-}
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver.h
--- a/src/StokesFACSolver.h Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#ifndef included_solv_StokesFACSolver
-#define included_solv_StokesFACSolver
-
-#include "SAMRAI/SAMRAI_config.h"
-
-#include "SAMRAI/solv/FACPreconditioner.h"
-#include "StokesFACOps.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 Stokes's equation on SAMR grid,
- * wrapping up lower-level components (FAC cycling, Stokes 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 StokesHierarchySolver<DIM> class.
- * Although this class hides the lower-level components (FAC cycling,
- * Stokes 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 Stokes
- * 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 StokesFACSolver 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 StokesFACSolver
-{
-
-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)
- */
- StokesFACSolver(
- const tbox::Dimension& dim,
- const std::string& object_name,
- tbox::Pointer<tbox::Database> database =
- tbox::Pointer<tbox::Database>());
-
- /*!
- * @brief Destructor.
- */
- ~StokesFACSolver(
- void);
-
- /*!
- * @brief Enable logging.
- *
- * To disable, pass in @c false.
- */
- void
- enableLogging(
- bool logging);
-
- /*!
- * @brief Solve Stokes'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 Stokes'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 StokesHYPRESolver 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
- * Stokes discretization.
- */
- StokesFACOps 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 "StokesFACSolver.I"
-#endif
-
-#endif // included_solv_StokesFACSolver
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/StokesFACSolver.C
--- a/src/StokesFACSolver/StokesFACSolver.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#ifndef included_solv_StokesFACSolver_C
-#define included_solv_StokesFACSolver_C
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-#ifndef SAMRAI_INLINE
-#include "StokesFACSolver.I"
-#endif
-
-namespace SAMRAI {
- namespace solv {
-
- /*
-*************************************************************************
-* *
-* Initialize the static data members. *
-* *
-*************************************************************************
-*/
-
- bool StokesFACSolver::s_initialized = 0;
- int StokesFACSolver::s_weight_id[SAMRAI::tbox::Dimension::
- MAXIMUM_DIMENSION_VALUE];
- int StokesFACSolver::s_instance_counter[SAMRAI::tbox::Dimension::
- MAXIMUM_DIMENSION_VALUE];
-
- /*
-*************************************************************************
-* *
-* Constructor sets uninitialized solver state. *
-* Set default iteration and convergence parameters. *
-* *
-* By default settings: *
-* - Stokes equation specified has D=1, C=0. *
-* - State is uninitialized *
-* - Logging is disabled *
-* - Context for internal data is set based on object name. *
-* *
-*************************************************************************
-*/
-
- StokesFACSolver::StokesFACSolver(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("StokesFACSolver_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("StokesFACSolver_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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/StokesFACSolver_Destructor.C
--- a/src/StokesFACSolver/StokesFACSolver_Destructor.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver. *
-* Deallocate internal data. *
-* *
-*************************************************************************
-*/
- StokesFACSolver::~StokesFACSolver()
- {
- 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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/createVectorWrappers.C
--- a/src/StokesFACSolver/createVectorWrappers.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.h"
-#include "SAMRAI/tbox/PIO.h"
-#include "SAMRAI/tbox/Utilities.h"
-#include "SAMRAI/tbox/StartupShutdownManager.h"
-
-#include IOMANIP_HEADER_FILE
-
-void SAMRAI::solv::StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/deallocateSolverState.C
--- a/src/StokesFACSolver/deallocateSolverState.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/destroyVectorWrappers.C
--- a/src/StokesFACSolver/destroyVectorWrappers.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::destroyVectorWrappers() {
- d_uv.setNull();
- d_fv.setNull();
- }
-
- }
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/enableLogging.C
--- a/src/StokesFACSolver/enableLogging.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::enableLogging(
- bool logging)
- {
- d_enable_logging = logging;
- d_fac_precond.enableLogging(d_enable_logging);
- d_fac_ops.enableLogging(d_enable_logging);
- }
-
- }
-}
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/getFromInput.C
--- a/src/StokesFACSolver/getFromInput.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 Stokes 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 StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/initializeSolverState.C
--- a/src/StokesFACSolver/initializeSolverState.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 *
-* Stokes FAC operator. *
-* *
-*************************************************************************
-*/
-
-void SAMRAI::solv::StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/initializeStatics.C
--- a/src/StokesFACSolver/initializeStatics.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/setBcObject.C
--- a/src/StokesFACSolver/setBcObject.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/setBoundaries.C
--- a/src/StokesFACSolver/setBoundaries.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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 StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesFACSolver/solveSystem.C
--- a/src/StokesFACSolver/solveSystem.C Tue Jun 05 14:36:48 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 stokes equation.
- *
- ************************************************************************/
-#include "SAMRAI/pdat/CellVariable.h"
-#include "StokesFACSolver.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::StokesFACSolver::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::StokesFACSolver::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 << "StokesFACSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesHypreSolver.C
--- a/src/StokesHypreSolver.C Tue Jun 05 14:36:48 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_StokesHypreSolver_C
-#define included_solv_StokesHypreSolver_C
-
-#include "StokesHypreSolver.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 "StokesHypreSolver.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> >
-StokesHypreSolver::s_Ak0_var[tbox::Dimension::MAXIMUM_DIMENSION_VALUE];
-
-tbox::StartupShutdownManager::Handler StokesHypreSolver::s_finalize_handler(
- 0,
- 0,
- 0,
- StokesHypreSolver::finalizeCallback,
- tbox::StartupShutdownManager::priorityVariables);
-
-/*
- *************************************************************************
- * Constructor *
- *************************************************************************
- */
-
-StokesHypreSolver::StokesHypreSolver(
- 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(" StokesHypreSolver : DIM == 1 or > 3 not implemented");
- }
-
- t_solve_system = tbox::TimerManager::getManager()->
- getTimer("solv::StokesHypreSolver::solveSystem()");
- t_set_matrix_coefficients = tbox::TimerManager::getManager()->
- getTimer("solv::StokesHypreSolver::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 StokesHypreSolver::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("StokesHypreSolver 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 StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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(
- "StokesHypreSolver 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. *
- * *
- *************************************************************************
- */
-
-StokesHypreSolver::~StokesHypreSolver()
-{
- 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 StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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 StokesSpecificiations *
- * object and by the boundary condition. *
- * *
- *************************************************************************
- */
-
-void StokesHypreSolver::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 "
- <<
- "StokesHypreSolver::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 "
- <<
- "StokesHypreSolver::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 StokesHypreSolver::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 "
- << "StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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("StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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("StokesHypreSolver error...\n"
- << "DIM > 3 not supported." << std::endl);
- }
-}
-
-void StokesHypreSolver::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("StokesHypreSolver error...\n"
- << "DIM > 3 not supported." << std::endl);
- }
-}
-
-void StokesHypreSolver::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("StokesHypreSolver error...\n"
- << "DIM > 3 not supported." << std::endl);
- }
-}
-
-void
-StokesHypreSolver::finalizeCallback()
-{
- for (int d = 0; d < tbox::Dimension::MAXIMUM_DIMENSION_VALUE; ++d) {
- s_Ak0_var[d].setNull();
- }
-}
-
-}
-}
-
-#endif
-#endif
diff -r 56c59b83f606 -r daa8bb8aed75 src/StokesHypreSolver.I
--- a/src/StokesHypreSolver.I Tue Jun 05 14:36:48 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 StokesHypreSolver::setSolnIdDepth(
- const int depth) {
- d_soln_depth = depth;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::setRhsIdDepth(
- const int depth) {
- d_rhs_depth = depth;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::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 StokesHypreSolver::getNumberOfIterations() const
-{
- return d_number_iterations;
-}
-
-SAMRAI_INLINE_KEYWORD
-double StokesHypreSolver::getRelativeResidualNorm() const
-{
- return d_relative_residual_norm;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::setNumPreRelaxSteps(
- const int steps)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
- TBOX_ASSERT(!d_hierarchy.isNull());
-#endif
- d_num_pre_relax_steps = steps;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::setNumPostRelaxSteps(
- const int steps)
-{
-#ifdef DEBUG_CHECK_ASSERTIONS
- TBOX_ASSERT(!d_hierarchy.isNull());
-#endif
- d_num_post_relax_steps = steps;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::setPrintSolverInfo(
- const bool print)
-{
- d_print_solver_info = print;
-}
-
-SAMRAI_INLINE_KEYWORD
-void StokesHypreSolver::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 56c59b83f606 -r daa8bb8aed75 src/StokesHypreSolver.h
--- a/src/StokesHypreSolver.h Tue Jun 05 14:36:48 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_StokesHypreSolver
-#define included_solv_StokesHypreSolver
-
-#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)
- * Stokes's equation on a single level in a hierarchy.
- *
- * Class StokesHypreSolver 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 StokesSpecifications).
- * 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
- * StokesHypreSolver:
- * - Create a StokesHypreSolver object.
- * - Initialize StokesHypreSolver 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 StokesHypreSolver
-{
-public:
- /*!
- * @brief Constructor.
- *
- * @param object_name Name of object.
- * @param database tbox::Database for input.
- */
- StokesHypreSolver(
- const tbox::Dimension& dim,
- const std::string& object_name,
- tbox::Pointer<tbox::Database> database =
- tbox::Pointer<tbox::Database>(NULL));
-
- /*!
- * The Stokes destructor releases all internally managed data.
- */
- ~StokesHypreSolver();
-
- /*!
- * @brief Initialize to a given hierarchy.
- *
- * Initializer Stokes 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 Stokes equation parameters,
- * see the light-weight StokesSpecifications 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 "StokesHypreSolver.I"
-#endif
-
-#endif
-
-#endif
diff -r 56c59b83f606 -r daa8bb8aed75 src/main.C
--- a/src/main.C Tue Jun 05 14:36:48 2012 -0700
+++ b/src/main.C Tue Jun 05 15:28:40 2012 -0700
@@ -4,7 +4,7 @@
* information, see COPYRIGHT and COPYING.LESSER.
*
* Copyright: (c) 1997-2010 Lawrence Livermore National Security, LLC
- * Description: Main program for FAC Stokes example
+ * Description: Main program for FAC Elastic example
*
************************************************************************/
#include "SAMRAI/SAMRAI_config.h"
@@ -36,7 +36,7 @@ using namespace std;
#include "V_Coarsen.h"
#include "Resid_Coarsen.h"
-#include "FACStokes.h"
+#include "FACElastic.h"
using namespace SAMRAI;
@@ -44,20 +44,20 @@ using namespace SAMRAI;
************************************************************************
* *
* This is the driver program to demonstrate *
-* how to use the FAC Stokes solver. *
+* how to use the FAC Elastic solver. *
* *
* We set up the simple problem *
* u + div(grad(u)) = sin(x)*sin(y) *
* in the domain [0:1]x[0:1], with u=0 on the *
* boundary. *
* *
-* FACStokes is the primary object used to *
+* FACElastic 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. *
* *
* The hierarchy created to solve this problem *
-* has only one level. (The FAC Stokes solver *
+* has only one level. (The FAC Elastic solver *
* is a single-level solver.) *
* *
*************************************************************************
@@ -177,21 +177,22 @@ int main(
input_db->getDatabase("PatchHierarchy")));
/*
- * The FACStokes object is the main user object specific to the
+ * The FACElastic 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.
*/
- FACStokes fac_stokes(base_name + "::FACStokes",
- dim,
- input_db->isDatabase("FACStokes") ?
- input_db->getDatabase("FACStokes") :
- tbox::Pointer<tbox::Database>(NULL));
+
+ FACElastic fac_elastic(base_name + "::FACElastic",
+ dim,
+ input_db->isDatabase("FACElastic") ?
+ input_db->getDatabase("FACElastic") :
+ tbox::Pointer<tbox::Database>(NULL));
grid_geometry->addSpatialCoarsenOperator
(tbox::Pointer<SAMRAI::xfer::CoarsenOperator>
- (new SAMRAI::geom::Resid_Coarsen(dim,fac_stokes.cell_moduli_id)));
+ (new SAMRAI::geom::Resid_Coarsen(dim,fac_elastic.cell_moduli_id)));
/*
* Create the tag-and-initializer, box-generator and load-balancer
@@ -202,7 +203,7 @@ int main(
(dim,
"CellTaggingMethod",
tbox::Pointer<mesh::StandardTagAndInitStrategy>
- (&fac_stokes, false),
+ (&fac_elastic, false),
input_db->getDatabase("StandardTagAndInitialize")
));
tbox::Pointer<mesh::BergerRigoutsos>
@@ -244,7 +245,7 @@ int main(
/*
* Set up the plotter for the hierarchy just created.
- * The FACStokes object handles the data and has the
+ * The FACElastic object handles the data and has the
* function setupExternalPlotter to register its data
* with the plotter.
*/
@@ -265,7 +266,7 @@ int main(
visit_writer = new appu::VisItDataWriter(dim,
"Visit Writer",
vis_filename + ".visit");
- fac_stokes.setupPlotter(*visit_writer);
+ fac_elastic.setupPlotter(*visit_writer);
}
#endif
@@ -282,7 +283,7 @@ int main(
/*
* Solve.
*/
- fac_stokes.solveStokes();
+ fac_elastic.solveElastic();
bool done(false);
for (int lnum = 0;
@@ -303,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_stokes.solveStokes();
+ fac_elastic.solveElastic();
}
// {
// tbox::Array<int> tag_buffer(patch_hierarchy->getMaxNumberOfLevels());
diff -r 56c59b83f606 -r daa8bb8aed75 wscript
--- a/wscript Tue Jun 05 14:36:48 2012 -0700
+++ b/wscript Tue Jun 05 15:28:40 2012 -0700
@@ -10,14 +10,14 @@ def build(bld):
bld.program(
features = ['cxx','cprogram'],
source = ['src/main.C',
- 'src/FACStokes/FACStokes.C',
- 'src/FACStokes/fix_moduli.C',
- 'src/FACStokes/applyGradientDetector.C',
- 'src/FACStokes/initializeLevelData.C',
- 'src/FACStokes/packDerivedDataIntoDoubleBuffer.C',
- 'src/FACStokes/resetHierarchyConfiguration.C',
- 'src/FACStokes/setupPlotter.C',
- 'src/FACStokes/solveStokes.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',
@@ -33,51 +33,51 @@ def build(bld):
'src/V_Coarsen_Patch_Strategy/postprocessCoarsen_2D.C',
'src/V_Coarsen_Patch_Strategy/postprocessCoarsen_3D.C',
'src/set_boundary.C',
- 'src/StokesFACOps/StokesFACOps.C',
- 'src/StokesFACOps/computeCompositeResidualOnLevel.C',
- 'src/StokesFACOps/residual_2D.C',
- 'src/StokesFACOps/residual_3D.C',
- 'src/StokesFACOps/computeResidualNorm.C',
- 'src/StokesFACOps/computeVectorWeights.C',
- 'src/StokesFACOps/deallocateOperatorState.C',
- 'src/StokesFACOps/finalizeCallback.C',
- 'src/StokesFACOps/initializeOperatorState.C',
- 'src/StokesFACOps/postprocessOneCycle.C',
- 'src/StokesFACOps/prolongErrorAndCorrect.C',
- 'src/StokesFACOps/restrictResidual.C',
- 'src/StokesFACOps/restrictSolution.C',
- 'src/StokesFACOps/smoothError.C',
- 'src/StokesFACOps/smooth_Tackley_2D.C',
- 'src/StokesFACOps/smooth_Tackley_3D.C',
- 'src/StokesFACOps/set_boundaries.C',
- 'src/StokesFACOps/solveCoarsestLevel.C',
- 'src/StokesFACOps/solveCoarsestLevel_HYPRE.C',
- 'src/StokesFACOps/smooth_V_2D.C',
- 'src/StokesFACOps/smooth_V_3D.C',
- 'src/StokesFACOps/xeqScheduleGhostFill.C',
- 'src/StokesFACOps/xeqScheduleGhostFillNoCoarse.C',
- 'src/StokesFACOps/xeqScheduleProlongation.C',
- 'src/StokesFACOps/xeqScheduleRRestriction.C',
- 'src/StokesFACOps/xeqScheduleURestriction.C',
- 'src/StokesFACSolver/StokesFACSolver.C',
- 'src/StokesFACSolver/StokesFACSolver_Destructor.C',
- 'src/StokesFACSolver/createVectorWrappers.C',
- 'src/StokesFACSolver/deallocateSolverState.C',
- 'src/StokesFACSolver/destroyVectorWrappers.C',
- 'src/StokesFACSolver/enableLogging.C',
- 'src/StokesFACSolver/getFromInput.C',
- 'src/StokesFACSolver/initializeSolverState.C',
- 'src/StokesFACSolver/initializeStatics.C',
- 'src/StokesFACSolver/setBcObject.C',
- 'src/StokesFACSolver/setBoundaries.C',
- 'src/StokesFACSolver/solveSystem.C',
- 'src/StokesHypreSolver.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'],
target = 'gamra',
- # cxxflags = ['-O3', '-Wall', '-Wextra', '-Wconversion',
- # '-DTESTING=0', '-Drestrict='],
- cxxflags = ['-g', '-Wall', '-Wextra', '-Wconversion',
- '-Drestrict='],
+ cxxflags = ['-O3', '-Wall', '-Wextra', '-Wconversion',
+ '-DTESTING=0', '-Drestrict='],
+ # cxxflags = ['-g', '-Wall', '-Wextra', '-Wconversion',
+ # '-Drestrict='],
lib = ['SAMRAI_appu', 'SAMRAI_algs', 'SAMRAI_solv',
'SAMRAI_geom', 'SAMRAI_mesh', 'SAMRAI_math',
'SAMRAI_pdat', 'SAMRAI_xfer', 'SAMRAI_hier',
More information about the CIG-COMMITS
mailing list