[cig-commits] commit: Properly coarsen the velocity.
Mercurial
hg at geodynamics.org
Fri Feb 25 14:14:59 PST 2011
changeset: 51:3e6b26e0406f
user: Walter Landry <wlandry at caltech.edu>
date: Thu Jan 13 06:48:18 2011 -0800
files: Makefile StokesFACOps/initializeOperatorState.C V_Coarsen.C V_Coarsen.h main.C
description:
Properly coarsen the velocity.
diff -r 7c50513735ca -r 3e6b26e0406f Makefile
--- a/Makefile Thu Jan 13 06:46:28 2011 -0800
+++ b/Makefile Thu Jan 13 06:48:18 2011 -0800
@@ -30,7 +30,7 @@ CXX_OBJS = main.o FACStokes/FACStok
FACStokes/resetHierarchyConfiguration.o \
FACStokes/setupPlotter.o \
FACStokes/solveStokes.o \
- P_Refine.o V_Refine.o \
+ P_Refine.o V_Refine.o V_Coarsen.o \
StokesFACOps/StokesFACOps.o \
StokesFACOps/checkInputPatchDataIndices.o \
StokesFACOps/computeCompositeResidualOnLevel.o \
diff -r 7c50513735ca -r 3e6b26e0406f StokesFACOps/initializeOperatorState.C
--- a/StokesFACOps/initializeOperatorState.C Thu Jan 13 06:46:28 2011 -0800
+++ b/StokesFACOps/initializeOperatorState.C Thu Jan 13 06:48:18 2011 -0800
@@ -248,7 +248,7 @@ void SAMRAI::solv::StokesFACOps::initial
v_urestriction_coarsen_operator =
v_rrestriction_coarsen_operator =
geometry->lookupCoarsenOperator(variable,
- "CONSERVATIVE_COARSEN");
+ "V_COARSEN");
vdb->mapIndexToVariable(d_oflux_scratch_id, variable);
d_flux_coarsen_operator =
diff -r 7c50513735ca -r 3e6b26e0406f V_Coarsen.C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/V_Coarsen.C Thu Jan 13 06:48:18 2011 -0800
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution. For full copyright
+ * information, see COPYRIGHT and COPYING.LESSER.
+ *
+ * Copyright: (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description: Weighted averaging operator for side-centered double data on
+ * a Cartesian mesh.
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Coarsen_C
+#define included_geom_V_Coarsen_C
+
+#include "V_Coarsen.h"
+
+#include <float.h>
+#include <math.h>
+#include "SAMRAI/geom/CartesianPatchGeometry.h"
+#include "SAMRAI/hier/Index.h"
+#include "SAMRAI/pdat/SideData.h"
+#include "SAMRAI/pdat/SideVariable.h"
+#include "SAMRAI/tbox/Utilities.h"
+
+
+void SAMRAI::geom::V_Coarsen::coarsen(hier::Patch& coarse,
+ const hier::Patch& fine,
+ const int dst_component,
+ const int src_component,
+ const hier::Box& coarse_box,
+ const hier::IntVector& ratio) const
+{
+ const tbox::Dimension& dim(getDim());
+
+ TBOX_DIM_ASSERT_CHECK_DIM_ARGS4(dim, coarse, fine, coarse_box, ratio);
+
+ tbox::Pointer<pdat::SideData<double> >
+ v_fine = fine.getPatchData(src_component);
+ tbox::Pointer<pdat::SideData<double> >
+ v = coarse.getPatchData(dst_component);
+
+ TBOX_ASSERT(!v.isNull());
+ TBOX_ASSERT(!v_fine.isNull());
+ TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
+ TBOX_ASSERT(v->getDepth() == 1);
+
+ const hier::IntVector& directions(v->getDirectionVector());
+
+ TBOX_ASSERT(directions ==
+ hier::IntVector::min(directions, v_fine->getDirectionVector()));
+
+ const tbox::Pointer<CartesianPatchGeometry> fgeom =
+ fine.getPatchGeometry();
+ const tbox::Pointer<CartesianPatchGeometry> cgeom =
+ coarse.getPatchGeometry();
+
+ const hier::Index ifirstc = coarse_box.lower();
+ const hier::Index ilastc = coarse_box.upper();
+
+ /* Numbering of v nodes is
+
+ x--x--x--x--x Fine
+ 0 1 2 3 4
+
+ x-----x-----x Coarse
+ 0 1 2
+
+ So the i'th coarse point is affected by the i*2-1,
+ i*2, and i*2+1 fine points. So, for example, i_fine=3
+ affects both i_coarse=1 and i_coarse=2.
+
+
+ |---------------------------------------|
+ | | | | |
+ f f f f f f f f f
+ | | | | |
+ c---------c---------c---------c---------c
+ | | | | |
+ f f f f f f f f f
+ | | | | |
+ |---------------------------------------|
+ | | | | |
+ f f f f f f f f f
+ | | | | |
+ c---------c---------c---------c---------c
+ | | | | |
+ f f f f f f f f f
+ | | | | |
+ |---------------------------------------|
+
+ In 2D, a coarse point depends on six points. In this
+ case, (i*2,j*2), (i*2,j*2+1), (i*2-1,j*2),
+ (i*2-1,j*2+1), (i*2+1,j*2), (i*2+1,j*2+1).
+
+ */
+ for(int j=coarse_box.lower(1); j<=coarse_box.upper(1)+1; ++j)
+ for(int i=coarse_box.lower(0); i<=coarse_box.upper(0)+1; ++i)
+ {
+ hier::Index ip(1,0), jp(0,1);
+ if(directions(0) && j!=coarse_box.upper(1)+1)
+ {
+ pdat::SideIndex coarse(hier::Index(i,j),0,
+ pdat::SideIndex::Lower);
+ pdat::SideIndex center(coarse*2);
+ if(i==coarse_box.lower(0)
+ && cgeom->getTouchesRegularBoundary(0,0))
+ {
+ (*v)(coarse)=0;
+ }
+ else if(i==coarse_box.upper(0)+1
+ && cgeom->getTouchesRegularBoundary(0,1))
+ {
+ (*v)(coarse)=0;
+ }
+ else
+ {
+ (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/4
+ + ((*v_fine)(center-ip) + (*v_fine)(center-ip+jp)
+ + (*v_fine)(center+ip) + (*v_fine)(center+ip+jp))/8;
+ }
+ }
+ if(directions(1) && i!=coarse_box.upper(0)+1)
+ {
+ pdat::SideIndex coarse(hier::Index(i,j),1,
+ pdat::SideIndex::Lower);
+ pdat::SideIndex center(coarse*2);
+ if(j==coarse_box.lower(1)
+ && cgeom->getTouchesRegularBoundary(1,0))
+ {
+ (*v)(coarse)=0;
+ }
+ else if(j==coarse_box.upper(1)+1
+ && cgeom->getTouchesRegularBoundary(1,1))
+ {
+ (*v)(coarse)=0;
+ }
+ else
+ {
+ (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/4
+ + ((*v_fine)(center-jp) + (*v_fine)(center-jp+ip)
+ + (*v_fine)(center+jp) + (*v_fine)(center+ip+jp))/8;
+ }
+ }
+ }
+}
+
+#endif
diff -r 7c50513735ca -r 3e6b26e0406f V_Coarsen.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/V_Coarsen.h Thu Jan 13 06:48:18 2011 -0800
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * This file is part of the SAMRAI distribution. For full copyright
+ * information, see COPYRIGHT and COPYING.LESSER.
+ *
+ * Copyright: (c) 1997-2010 Lawrence Livermore National Security, LLC
+ * Description: Weighted averaging operator for side-centered double data on
+ * a Cartesian mesh.
+ *
+ ************************************************************************/
+
+#ifndef included_geom_V_Coarsen
+#define included_geom_V_Coarsen
+
+#include "SAMRAI/SAMRAI_config.h"
+
+#include "SAMRAI/xfer/CoarsenOperator.h"
+#include "SAMRAI/hier/Box.h"
+#include "SAMRAI/hier/IntVector.h"
+#include "SAMRAI/hier/Patch.h"
+#include "SAMRAI/tbox/Pointer.h"
+#include "SAMRAI/pdat/SideVariable.h"
+
+#include <string>
+
+namespace SAMRAI {
+namespace geom {
+
+/**
+ * Class V_Coarsen implements averaging
+ * for side-centered double patch data defined over
+ * a Cartesian mesh. It is derived from the xfer::CoarsenOperator base class.
+ * The numerical operations for theaveraging use FORTRAN numerical routines.
+ *
+ * CartesianSideDoubleWeightedAverage averages over the nearest two
+ * cells, which is not what we want for multigrid. This averages over
+ * the nearest six points (in 2D). The findCoarsenOperator() operator
+ * function returns true if the input variable is side-centered
+ * double, and the std::string is "V_COARSEN".
+ *
+ * @see xfer::CoarsenOperator
+ */
+
+class V_Coarsen:
+ public xfer::CoarsenOperator
+{
+public:
+ /**
+ * Uninteresting default constructor.
+ */
+ explicit V_Coarsen(const tbox::Dimension& dim):
+ xfer::CoarsenOperator(dim, "V_COARSEN")
+ {
+ d_name_id = "V_COARSEN";
+ }
+
+ /**
+ * Uninteresting virtual destructor.
+ */
+ virtual ~V_Coarsen(){}
+
+ /**
+ * Return true if the variable and name std::string match the side-centered
+ * double weighted averaging; otherwise, return false.
+ */
+
+ bool findCoarsenOperator(const tbox::Pointer<hier::Variable>& var,
+ const std::string& op_name) const
+ {
+ TBOX_DIM_ASSERT_CHECK_ARGS2(*this, *var);
+
+ const tbox::Pointer<pdat::SideVariable<double> > cast_var(var);
+ if (!cast_var.isNull() && (op_name == d_name_id)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return name std::string identifier of this coarsening operator.
+ */
+ const std::string& getOperatorName() const
+ {
+ return d_name_id;
+ }
+
+ /**
+ * The priority of side-centered double weighted averaging is 0.
+ * It will be performed before any user-defined coarsen operations.
+ */
+ int getOperatorPriority() const
+ {
+ return 0;
+ }
+
+ /**
+ * The stencil width of the weighted averaging operator is the vector of
+ * zeros. That is, its stencil does not extend outside the fine box.
+ */
+ hier::IntVector getStencilWidth() const
+ {
+ return hier::IntVector::getZero(getDim());
+ }
+
+ /**
+ * Coarsen the source component on the fine patch to the destination
+ * component on the coarse patch using the side-centered double weighted
+ * averaging operator. Coarsening is performed on the intersection of
+ * the destination patch and the coarse box. It is assumed that the
+ * fine patch contains sufficient data for the stencil width of the
+ * coarsening operator.
+ */
+ void
+ coarsen(
+ hier::Patch& coarse,
+ const hier::Patch& fine,
+ const int dst_component,
+ const int src_component,
+ const hier::Box& coarse_box,
+ const hier::IntVector& ratio) const;
+
+private:
+ std::string d_name_id;
+
+};
+
+}
+}
+#endif
diff -r 7c50513735ca -r 3e6b26e0406f main.C
--- a/main.C Thu Jan 13 06:46:28 2011 -0800
+++ b/main.C Thu Jan 13 06:48:18 2011 -0800
@@ -31,6 +31,7 @@ using namespace std;
#include "SAMRAI/xfer/RefineOperator.h"
#include "P_Refine.h"
#include "V_Refine.h"
+#include "V_Coarsen.h"
#include "FACStokes.h"
@@ -153,6 +154,7 @@ int main(
grid_geometry->printClassData(tbox::plog);
grid_geometry->addSpatialRefineOperator(tbox::Pointer<SAMRAI::xfer::RefineOperator>(new SAMRAI::geom::P_Refine(dim)));
grid_geometry->addSpatialRefineOperator(tbox::Pointer<SAMRAI::xfer::RefineOperator>(new SAMRAI::geom::V_Refine(dim)));
+ grid_geometry->addSpatialCoarsenOperator(tbox::Pointer<SAMRAI::xfer::CoarsenOperator>(new SAMRAI::geom::V_Coarsen(dim)));
More information about the CIG-COMMITS
mailing list