[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