aboutsummaryrefslogtreecommitdiff
path: root/src/patch/patch_interp.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/patch/patch_interp.hh')
-rw-r--r--src/patch/patch_interp.hh146
1 files changed, 87 insertions, 59 deletions
diff --git a/src/patch/patch_interp.hh b/src/patch/patch_interp.hh
index b1aea5f..19d6f54 100644
--- a/src/patch/patch_interp.hh
+++ b/src/patch/patch_interp.hh
@@ -34,15 +34,20 @@
// The way our coordinates are constructed, any two adjacent patches
// share a common (perpendicular) coordinate. Thus we only have to do
// 1-dimensional interpolation here (in the parallel direction).
-//
// In other words, for each iperp we do interpolation in par.
-// We implement this in the obvious way, keeping (a pointer to) a
-// separate interpolation object for each (gridfn,iperp).
//
-// FIXME:
-// Right now the choice of interpolator is hard-wired, and the set of
-// parameters it takes (the order) is hard-wired into our interface
-// and thus propagates up to our caller's code.
+// In general we interpolate each gridfn at a number of distinct par
+// for each iperp; the integer "parindex" indexes these points. We
+// attach no particular semantics to parindex, and it need not be 0-origin.
+// However, we do assume that its range is roughly comparable at all
+// values of iperp, so there's no major waste in treating (iperp,parindex)
+// as a 2-D index space for the interpolation points.
+//
+// We use the Cactus local interpolator CCTK_InterpLocalUniform()
+// to do the interpolation. To minimize interpolator overheads, we
+// interpolate all the gridfns at each iperp in a single interpolator
+// call. [Different iperp values involve different sets of (1-D)
+// gridfn data, and so inherently require distinct interpolator calls.]
//
class patch_frontier
@@ -52,46 +57,70 @@ public:
const patch& my_patch() const { return my_patch_; }
const patch_edge& my_edge() const { return my_edge_; }
- // set up a specified gridfn's interpolation state
- // ... this copies gridfn data if needed,
- // and sets up any interpolator state
- // ... it looks at what type of ghost zones are on the
- // adjacent edges to decide how to handle the corners:
- // * if an adjacent ghost zone is a symmetry ghost zone
- // we assume it's already been mirrored by the time
- // we get set up ==> we can (and do) use the data from it
- // * if an adjacent ghost zone is an interpatch ghost zone,
- // we can't assume it's already been interpatch-interpolated
- // by the time we're called ==> we don't use data from it
- void setup_interpolation_for_gridfn(int gfn);
-
- // interpolate a specified gridfn
- // ... setup_interpolation_for_gridfn(gfn) must have already been called
- fp interpolate(int gfn, int iperp, fp par) const;
-
-private:
// min/max (iperp,ipar) of the frontier
int min_iperp() const { return min_iperp_; }
int max_iperp() const { return max_iperp_; }
int min_ipar() const { return min_ipar_; }
int max_ipar() const { return max_ipar_; }
- // for reasons described in setup_interpolation_for_gridfn(),
- // we use 0-origin "relative ipar" coordinates
- int ripar_of_ipar(int ipar) const { return ipar - min_ipar(); }
- int ipar_of_ripar(int ripar) const { return ripar + min_ipar(); }
- int min_ripar() const { return 0; }
- int max_ripar() const { return ripar_of_ipar(max_ipar()); }
-
+ //
+ // ***** main client interface *****
+ //
+public:
+ // interpolate specified range of ghosted gridfns
+ // at all the coordinates specified when we were constructed,
+ // store interpolated data in result_buffer(gfn, iperp,parindex)
+ void interpolate(int ghosted_min_gfn, ghosted_max_gfn,
+ jtutil::array3d<fp>& result_buffer);
+
+private:
+ //
+ // ***** constructor, destructor *****
+ //
public:
- // constructor, destructor
- // ... constructor requires that the adjacent-side ghost_zone
- // objects already exist, since they're used in determining
- // the ipar range over which the interpolation will be done
+ //
+ // Constructor arguments:
+ // my_edge_in = identifies the patch/edge to which this frontier
+ // is to belong
+ // [min,max]_iperp_in = the range of iperp for this frontier
+ // [min,max]_parindex_in = extreme [min,max] range of parindex
+ // (for sizing (iperp,parindex) arrays etc)
+ // [min,max]_parindex_used_in(iperp)
+ // = [min,max] range of parindex actually used at each iperp
+ // interp_par(iperp,parindex)
+ // = gives the par coordinates at which we will interpolate;
+ // array entries outside the range [min,max]_parindex_in
+ // are unused (n.b. this interface implicitly takes the
+ // par coordinates to be independent of ghosted_gfn)
+ // ghosted_[min,max]_gfn = the largest ghosted_gfn range for this
+ // frontier; any given interpolate() call
+ // may specify a subrange
+ // interp_handle_in = Cactus handle to the interpolation operator
+ // interp_par_table_handle_in
+ // = Cactus handle to a Cactus key/value table giving
+ // parameters (eg order) for the interpolation operator
+ //
+ // ... constructor looks at what type of ghost zones are on the
+ // adjacent edges to decide how to handle the corners:
+ // * if an adjacent ghost zone is a symmetry ghost zone
+ // we assume it's already been mirrored by the time
+ // we get set up ==> we can (and do) use the data from it
+ // * if an adjacent ghost zone is an interpatch ghost zone,
+ // we can't assume it's already been interpatch-interpolated
+ // by the time we're called ==> we don't use data from it
+ // ==> constructor requires that the adjacent-side ghost_zone
+ // objects already exist!
+ //
patch_frontier(const patch_edge& my_edge_in,
int min_iperp_in, int max_iperp_in,
- int interpolator_order);
+ int min_parindex_in, int max_parindex_in,
+ const jtutil::array1d<fp>& min_parindex_used_in,
+ const jtutil::array1d<fp>& max_parindex_used_in,
+ const jtutil::array2d<fp>& interp_par_in,
+ int ghosted_min_gfn_in, int ghosted_max_gfn_in,
+ int interp_handle_in,
+ int interp_par_table_handle_in);
~patch_frontier();
private:
@@ -102,29 +131,28 @@ private:
patch_frontier& operator=(const patch_frontier& rhs);
private:
- const patch& my_patch_;
const patch_edge& my_edge_;
+ const patch& my_patch_;
- // range of iperp,ipar from which we can use data
int min_iperp_, max_iperp_;
- int min_ipar_, max_ipar_;
-
- // maps ripar <--> par
- linear_map<fp>* ripar_map_;
-
- // the interpolator interface we're using requires that
- // the gridfn data to be interpolated (i.e. for any given
- // gridfn and iperp) must be in a contiguous 1-D data array,
- // so we have to copy from the patch data into this buffer
- // ... subscripts are (gfn,iperp,ipar)
- // (this is contiguous in ipar as required)
- array3d<fp>* gridfn_buffer_;
-
- // --> array of --> to interpolator objects
- // ... subscripts are (gfn,iperp)
- // ... we own the pointed-to objects
- // ... interpolator objects use ripar as integer coordinate;
- // see setup_interpolation_for_gridfn() for discussion of this
- typedef interpolation::Lagrange_uniform_1d<fp> interpolator_t_;
- array2d<interpolator_t_*>* interpolator_;
+
+ // range of ghosted gfns for which we may interpolate
+ // (an actual interpolation may cover a subrange of this)
+ int ghosted_min_gfn_, ghosted_max_gfn_;
+
+ // Cactus handle to the interpolation operator
+ int interp_handle_;
+
+ // Cactus handle to a Cactus key/value table
+ // giving parameters (eg order) for the interpolation operator
+ int interp_par_table_handle_;
+
+ // (par) coordinate origin and delta values for the interpolator
+ fp interp_coord_origin_, interp_coord_delta_;
+
+ // par coordinates at which we are to interpolate
+ // ... interpolation treats this as a 1-D array;
+ // we set up values in 3-D
+ // ... subscripts are (gfn, iperp,parindex)
+ jtutil::array3d<fp> interp_par_coords_;
};