/*************************************************************** * UserPatchX.h * * An expanded version of PatchX.h This one illustrates a number of useful * helper functions beyond the minimum given in PatchX.h, along with sketches of * possible implementations. * * Daniel Shalit 01/12/01 ****************************************************************/ #ifndef _included_PatchX_h #define _included_PatchX_h typedef int SIZE_T; class PatchX { private: dTYPE* _data //dTYPE may be intrinsic or user defined. RegionX _region; // The region Region1 _fields; // The range of the fields. // Note the internal use of the // Region1 specifier for fields. public: // // Constructors // PatchX( ) {} PatchX(const RegionX& region, Region1 fields ) : _region(region), _fields(fields){ _data.resize(region, fields); } // Just for convenience if you don't feel like declaring a Region1 for the // solution fields in your application code. PatchX(const RegionX& region, const int cs, const int ce ) : {PatchX ( region, Region1(cs, ce) )} PatchX(const RegionX& region, const int Nfields) : {PatchX( region, Region1(1, Nfields) )} // Copy constructor PatchX(const PatchX& patch, const RegionX& Rs, Region1 fields) : _region(patch.region()*Rs), _fields(patch.fields()*fields){PatchX( _region, _fields} // // Destructors // virtual ~PatchX(){} /**************************************************************** virtual void instantiate (const RegionX& R, const Region1& fields): Set the attributes of a Patch. This function allows us to resize the Patch, changing the Region and the number of fields. If the Patch already contains storage we recycle the space. A concrete implementation is responsible for filling in the storage in an appropriate way, probably using the Copy() function ************************************************************/ virtual void instantiate (const RegionX& R, const Region1& fields): _region(R), _fields(fields) = 0; // // Functions for querying various patch attributes. These must be // implemented as shown since KeLP class methods depend them. // const Region1& fields() const { return _fields; } const int cs() const { return _fields.lower(0) ; } const int ce() const { return _fields.upper(0) ; } const int nFields() const { return fields().size(); } // // Bounds // const RegionX& region() const { return _region; } const PointX& lower() const { return _region.lower(); } const PointX& upper() const { return _region.upper(); } PointX extents() const { return _region.extents(); } const int lower(const int k) const { return _region.lower(k); } const int upper(const int k) const { return _region.upper(k); } const int extents(const int k) const { return _region.extents(k); } // This tells the user if the size of a serialized region of data // can be computed with local information only virtual const int isPreallocatable() const = 0; // // Functions to move data from/to PatchX /**************************************************************** virtual void Copy(const RegionX& Rd, const PatchX& Ps, const RegionX& Rs, const int csd=1, const int ced=1, const int css=1, const int ces = 1 ) Copy from (Ps on Rs over fields css through ces) into (*this on Rd over fields csd through ced) Various quantities in the source and destination must conform: Rs must lie wholly within Ps's Region Rd must lie wholly within *this's Region (css:ces) must be valid field indices for Ps (csd:ced) must be valid field indices for Pd Cs and Cd must have same length, but can be displaced i. e. ced - csd == ces - css Note that Rs and Rd need not necessarily have the same number of points Such a constraint might be required of an ordinary array class, and properly belongs in a concrete class definition rather than in Patch ***************************************************************/ virtual void Copy(const RegionX& Rd, const PatchX& Ps, const RegionX& Rs, const int csd=1, const int ced=1, const int css=1, const int ces = 1 ) = 0; // // Some handy special case versions // virtual void Copy(const PatchX& Ps, const RegionX& Rs, const int cs, const int ce ) { assert(Rs*Ps.region() == Rs*region()); Copy(Rs, Ps, Rs, cs, ce, cs, ce); } virtual void Copy(const PatchX& Ps, const RegionX& Rs) { Copy(Rs,Ps,Ps.region(), cs(),ce(), Ps.cs(),Ps.ce()); } virtual void Copy(const PatchX& Ps) {RegionX Rs = Ps.region(); Copy(Rs,Ps,Ps.region(), cs(),ce(), Ps.cs(),Ps.ce()); } virtual void Copy(const RegionX& Rd, const PatchX& Ps, const RegionX& Rs) { Copy(Rs,Ps,Ps.region(),Ps.cs(), cs(),ce(), Ps.ce()); } // Returns the number of bytes required to store this Patch restricted // to the Region Rs over fields Rc.lower(0) through Rc.upper(0) virtual const SIZE_T LinearSize(const RegionX& Rs, const Region1& myFields) const; // Pack the subset of Patch restricted to Region Rd and fields (cs:ce) // into previously allocated contiguous storage virtual void SerializeIn(void *Lptr, const RegionX& Rd, const int cs, const int ce) const; // Unpack data previously Serialized in contiguous storage into an // existing patch virtual void SerializeOut(void *Lptr, const RegionX& Rs, const int cs, const int ce); }; #endif