[PATCH] Fix ExpressionTest
Richard Guenther
rguenth at tat.physik.uni-tuebingen.de
Tue Aug 24 12:50:55 UTC 2004
This fixes ExpressionTest by deleting all the strange stuff
from FieldStencilSimple and replacing it with something that
resembles Engine/Stencil.h View1/View2. In turn we use the
FieldStencilSimple make() that takes a domain and was modeled
after View2 in twoPt() in the test.
Tested with the two FieldStencil tests that are available (though that is
not much...), ExpressionTest (the twoPt stuff) and StencilTests (tests
divVertToCell).
More testcases which show what is expected to work appreciated, because
I don't really know the desired semantics of FieldStencilSimple (and
Stencil) wrt views and domains.
Obviously I don't use Stencils myself.
Ok?
Richard.
2004Aug24 Richard Guenther <richard.guenther at uni-tuebingen.de>
* src/Engine/Stencil.h: do bounds check only with
POOMA_BOUNDS_CHECK.
src/Field/DiffOps/FieldStencil.h: rewrite make(stencil,
expr), add make(stencil, expr, domain), kill similar
broken Accumulate stuff, update documentation.
src/Field/tests/ExpressionTest.cpp: use FieldStencilSimple::make
with domain argument, don't take view ourselves.
-------------- next part --------------
Index: Engine/Stencil.h
===================================================================
RCS file: /home/pooma/Repository/r2/src/Engine/Stencil.h,v
retrieving revision 1.53
diff -u -c -r1.53 Stencil.h
*** Engine/Stencil.h 23 Aug 2004 18:44:17 -0000 1.53
--- Engine/Stencil.h 24 Aug 2004 12:42:03 -0000
***************
*** 432,438 ****
--- 432,440 ----
inline int first(int i) const
{
+ #if POOMA_BOUNDS_CHECK
PAssert(i >= 0 && i < D);
+ #endif
return 0;
}
Index: Field/DiffOps/FieldStencil.h
===================================================================
RCS file: /home/pooma/Repository/r2/src/Field/DiffOps/FieldStencil.h,v
retrieving revision 1.6
diff -u -c -r1.6 FieldStencil.h
*** Field/DiffOps/FieldStencil.h 22 Jul 2004 17:29:58 -0000 1.6
--- Field/DiffOps/FieldStencil.h 24 Aug 2004 12:42:03 -0000
***************
*** 60,126 ****
* and stick ONE stencil engine into it. Maybe this class can be generalized
* for fields that contain multiple stencil engines.
*
- * From the old r1 documentation:
- *
* FieldStencil is used to wrap a user-defined field-based stencil class.
* The idea is to encapsulate the majority of the crazy type manipulations
! * required to generate the output ConstField and the calculation of the
! * new number of guard layers.
*
* To create a stencil, users must create a class similar to the one below,
* which computes a central difference divergence of a vertex-centered Field
* and maps it to a cell-centered Field:
*
* <PRE>
! * template<class OutputCentering, class Mesh, class T>
! * class Div { };
! *
! * template<class T2, int Dim, class TM, class CS>
! * class DivVertToCell<Vector<Dim, T2>, UniformRectilinear<Dim, TM, CS> >
* {
* public:
! *
! * typedef T2 OutputElement_t;
! *
! * Centering<Dim> outputCentering() const
* {
! * return canonicalCentering<Dim>(CellType, Continuous);
* }
*
! * int lowerExtent(int) const
! * {
! * return 1;
! * }
! *
! * int upperExtent(int) const
! * {
! * return 1;
! * }
! *
! * template<class F>
! * inline OutputElement_t
! * operator()(const F &f, int i1) const
! * {
! * return (f(i1 + 1)(0) - f(i1 - 1)(0)) /
! * f.geometry().mesh().meshSpacing(0);
! * }
*
! * template<class F>
! * inline OutputElement_t
! * operator()(const F &f, int i1, int i2) const
! * {
! * return (f(i1 + 1, i2)(0) - f(i1 - 1, i2)(0)) /
! * f.geometry().mesh().meshSpacing()(0) +
! * (f(i1, i2 + 1)(1) - f(i1, i2 - 1)(1)) /
! * f.geometry().mesh().meshSpacing()(1);
! * }
* };
* </PRE>
*
! * There are 2 required typedefs: OutputCentering_t and OutputElement_t.
! * These export the type of the output centering and the type resulting
* from applying the stencil at a point.
*
* Then, there are two accessors: lowerExtent(int dir) and
* upperExtent(int dir). These return the extent of the stencil as a function
* of direction. As another example, a forward difference would have a lower
--- 60,139 ----
* and stick ONE stencil engine into it. Maybe this class can be generalized
* for fields that contain multiple stencil engines.
*
* FieldStencil is used to wrap a user-defined field-based stencil class.
* The idea is to encapsulate the majority of the crazy type manipulations
! * required to generate the output Field.
*
* To create a stencil, users must create a class similar to the one below,
* which computes a central difference divergence of a vertex-centered Field
* and maps it to a cell-centered Field:
*
* <PRE>
! * template<class T2, int Dim, class TM>
! * class DivVertToCell<Vector<Dim, T2>, UniformRectilinearMesh<Dim, TM> >
* {
* public:
! *
! * typedef T2 OutputElement_t;
! *
! * Centering<Dim> outputCentering() const
! * {
! * return canonicalCentering<Dim>(CellType, Continuous, AllDim);
! * }
! *
! * Centering<Dim> inputCentering() const
! * {
! * return canonicalCentering<Dim>(VertexType, Continuous, AllDim);
! * }
! *
! * // Constructors.
! *
! * // default version is required by default stencil engine constructor.
! *
! * DivVertToCell()
! * {
! * for (int d = 0; d < Dim; ++d)
* {
! * fact_m(d) = 1.0;
* }
+ * }
*
! * template<class FE>
! * DivVertToCell(const FE &fieldEngine)
! * {
! * for (int d = 0; d < Dim; ++d)
! * {
! * fact_m(d) = 1 / fieldEngine.mesh().spacings()(d);
! * }
! * }
! *
! * // Methods.
! *
! * int lowerExtent(int d) const { return 0; }
! * int upperExtent(int d) const { return 1; }
! *
! * template<class F>
! * inline OutputElement_t
! * operator()(const F &f, int i1) const
! * {
! * return OutputElement_t
! * (fact_m(0)*(f.read(i1+1)(0) - f.read(i1)(0)));
! * }
! *
! * // and versions for 2d and 3d
*
! * private:
! * Vector<Dim, TM> fact_m;
* };
* </PRE>
*
! * There is one required typedefs: OutputElement_t.
! * These export the type of the type resulting
* from applying the stencil at a point.
*
+ * There are two required methods returning the input and
+ * output centering.
+ *
* Then, there are two accessors: lowerExtent(int dir) and
* upperExtent(int dir). These return the extent of the stencil as a function
* of direction. As another example, a forward difference would have a lower
***************
*** 128,139 ****
* functions, which take a Field of some sort and a set indices, must be
* supplied. This is what actually computes the stencil.
*
! * A ConstField that contains an ApplyFieldStencil-engine that operates on
! * a Field f, is constructed by using operator()() for FieldStencil:
*
! * View1<FieldStencil<Div<OutputCentering, Mesh, T> >,
! * ConstField<Mesh, T, EngineTag> >::make(
! * Div<OutputCentering, Mesh, T>(), f);
*/
template<class Functor, class Expression>
--- 141,151 ----
* functions, which take a Field of some sort and a set indices, must be
* supplied. This is what actually computes the stencil.
*
! * A Field that contains a StencilEngine that operates on
! * a Field f, is constructed by using make() from FieldStencilSimple:
*
! * FieldStencilSimple<DivVertToCell<T, Mesh>, Field<Mesh, T, EngineTag> >
! * ::make(DivVertToCell<T, Mesh>(f.fieldEngine()), f);
*/
template<class Functor, class Expression>
***************
*** 152,226 ****
static inline
Type_t make(const Functor &stencil, const Expression &f)
{
! Type_t h(stencil.outputCentering(), f.layout(), f.mesh());
! h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
! // FIXME: need to add comparison for centerings.
! // PAssert(f.centering() == stencil.inputCentering());
! GuardLayers<outputDim> og(f.fieldEngine().guardLayers());
! for (int d = 0; d < outputDim; d++)
! {
! og.lower(d) -= stencil.lowerExtent(d);
! og.upper(d) -= stencil.upperExtent(d);
!
! // FIXME: Need to think about adjusting the guards. I don't
! // believe the old version:
! // if (inputCentering[d].first() == 0 &&
! // outputCentering[d].first() == 1)
! // og.upper(d)++;
! // if (inputCentering[d].first() == 1 &&
! // outputCentering[d].first() == 0)
! // og.upper(d)--;
! }
! h.fieldEngine().guardLayers() = og;
! h.fieldEngine().engine() = SEngine_t(stencil, f, h.physicalDomain());
! return h;
}
- template<class Accumulate>
static inline
! Type_t make(const Expression &f,
! const std::vector<FieldOffsetList<outputDim> > &nn,
! const Centering<outputDim> &outputCentering,
! Accumulate accumulate = Accumulate())
{
! PAssert(nn.size() == outputCentering.size());
! Type_t h(outputCentering, f.layout(), f.mesh());
! h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
! // FIXME: The guard layers are wrong; we need to find the maximum
! // offsets from all the functors below. (Should the individual
! // sub-fields have their own guard layers???)
!
! h.fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
!
! if (outputCentering.size() == 1)
! {
! h.fieldEngine().engine()
! = SEngine_t(Functor(nn[0], outputCentering, f.centering(),
! accumulate),
! f, h.physicalDomain());
! }
! else
! {
! int oc;
!
! for (oc = 0; oc < nn.size(); ++oc)
! {
! h[oc].fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
! h[oc].fieldEngine().engine()
! = SEngine_t(Functor(nn[oc], outputCentering[oc], f.centering(),
! accumulate),
! f, h[oc].physicalDomain());
! }
! }
! return h;
}
};
--- 164,203 ----
static inline
Type_t make(const Functor &stencil, const Expression &f)
{
! // FIXME: need to add comparison for centerings.
! // PAssert(f.centering() == stencil.inputCentering());
! // We need to use the centering, layout, mesh constructor.
! // The FieldEngine part initializes physicalCellDomain
! // and guards from the layout.
! Type_t h(stencil.outputCentering(), f.layout(), f.mesh());
+ // Initialize engine with appropriate StencilEngine
! Interval<outputDim> domain = insetDomain(stencil, f.physicalDomain());
! h.fieldEngine().engine() = SEngine_t(stencil, f, domain);
! return h;
}
static inline
! Type_t make(const Functor &stencil, const Expression &f, const Interval<outputDim> &domain)
{
! // FIXME: need to add comparison for centerings.
! // PAssert(f.centering() == stencil.inputCentering());
!
! // We need to use the centering, layout, mesh constructor.
! // The FieldEngine part initializes physicalCellDomain
! // and guards from the layout.
!
! Type_t h(stencil.outputCentering(), f.layout(), f.mesh());
! // Initialize engine with appropriate StencilEngine
! h.fieldEngine().engine() = SEngine_t(stencil, f, domain);
! return h;
}
};
Index: Field/tests/ExpressionTest.cpp
===================================================================
RCS file: /home/pooma/Repository/r2/src/Field/tests/ExpressionTest.cpp,v
retrieving revision 1.3
diff -u -c -r1.3 ExpressionTest.cpp
*** Field/tests/ExpressionTest.cpp 19 Jul 2004 18:20:41 -0000 1.3
--- Field/tests/ExpressionTest.cpp 24 Aug 2004 12:42:04 -0000
***************
*** 257,268 ****
Centering<Dim> inputCentering_m;
};
! template <class M, class T, class E, class Dom>
! typename FieldStencilSimple<TwoPt<M::dimensions>, typename View1<Field<M,T,E>, Dom>::Type_t >::Type_t
! twoPt(const Field<M,T,E>& expr, const Dom &domain)
{
! typedef FieldStencilSimple<TwoPt<M::dimensions>, typename View1<Field<M,T,E>, Dom>::Type_t > Ret_t;
! return Ret_t::make(TwoPt<M::dimensions>(expr), expr(domain));
}
template<class A1,class A2,class A3,class A4, class AInit>
--- 257,268 ----
Centering<Dim> inputCentering_m;
};
! template <class F, class Dom>
! typename FieldStencilSimple<TwoPt<F::dimensions>, F>::Type_t
! twoPt(const F& expr, const Dom &domain)
{
! typedef FieldStencilSimple<TwoPt<F::dimensions>, F> Ret_t;
! return Ret_t::make(TwoPt<F::dimensions>(expr), expr, domain);
}
template<class A1,class A2,class A3,class A4, class AInit>
More information about the pooma-dev
mailing list