// patch_frontier.hh -- interpolate data for another patch's ghost zone // $Id$ // // prerequisites: // // // // "jt/util.hh" // "jt/array.hh" // "jt/linear_map.hh" // "jt/interpolate.hh" // fp.hh // coords.hh // grid.hh // fd_grid.hh // patch.hh // patch_edge.hh // //***************************************************************************** // // patch_frontier - interpolation from just inside patch edge // // // A patch_frontier object is responsible for interpolating gridfn data // from its owning patch for use by another patch's ghost_zone object // (in setting up the gridfn in the other ghost zone). // // // 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. // // 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 { public: // to which patch/edge do we belong? const patch& my_patch() const { return my_patch_; } const patch_edge& my_edge() const { return my_edge_; } // 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_; } // // ***** 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& result_buffer); private: // // ***** constructor, destructor ***** // public: // // 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 min_parindex_in, int max_parindex_in, const jtutil::array1d& min_parindex_used_in, const jtutil::array1d& max_parindex_used_in, const jtutil::array2d& 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: // we forbid copying and passing by value // by declaring the copy constructor and assignment operator // private, but never defining them patch_frontier(const patch_frontier& rhs); patch_frontier& operator=(const patch_frontier& rhs); private: const patch_edge& my_edge_; const patch& my_patch_; int min_iperp_, max_iperp_; // 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 interp_par_coords_; };