Patch to NewField/Field.h (1/3)
Dave Nystrom
wdn at lanl.gov
Tue Oct 16 22:26:40 UTC 2001
Below is a patched version of NewField/Field.h. One change eliminates the
use of "sv" which eliminates a ton of templates that could not be explicitly
instantiated. The fix was proposed by Jim Crotinger. The second change is
adding a const qualifier to allow compilation by KCC in strict mode. This
was a change by John Hall. Could someone make these changes to the Blanca
cvs branch of Pooma 2?
Thanks,
Dave Nystrom email: wdn at lanl.gov
LANL X-3 phone: 505-667-7913 fax: 505-665-3046
--------------------------NewField/Field.h-------------------------------
// -*- C++ -*-
// ACL:license
// ----------------------------------------------------------------------
// This software and ancillary information (herein called "SOFTWARE")
// called POOMA (Parallel Object-Oriented Methods and Applications) is
// made available under the terms described here. The SOFTWARE has been
// approved for release with associated LA-CC Number LA-CC-98-65.
//
// Unless otherwise indicated, this SOFTWARE has been authored by an
// employee or employees of the University of California, operator of the
// Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with
// the U.S. Department of Energy. The U.S. Government has rights to use,
// reproduce, and distribute this SOFTWARE. The public may copy, distribute,
// prepare derivative works and publicly display this SOFTWARE without
// charge, provided that this Notice and any statement of authorship are
// reproduced on all copies. Neither the Government nor the University
// makes any warranty, express or implied, or assumes any liability or
// responsibility for the use of this SOFTWARE.
//
// If SOFTWARE is modified to produce derivative works, such modified
// SOFTWARE should be clearly marked, so as not to confuse it with the
// version available from LANL.
//
// For more information about POOMA, send e-mail to pooma at acl.lanl.gov,
// or visit the POOMA web page at http://www.acl.lanl.gov/pooma/.
// ----------------------------------------------------------------------
// ACL:license
//-----------------------------------------------------------------------------
// Classes:
// Field
//-----------------------------------------------------------------------------
#ifndef POOMA_NEWFIELD_FIELD_H
#define POOMA_NEWFIELD_FIELD_H
//-----------------------------------------------------------------------------
// Overview:
//
// Field
// - ties together the notions of field-category and mesh.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes:
//-----------------------------------------------------------------------------
#include "Array/Array.h"
#include "Domain/CombineDomainOpt.h"
#include "Domain/NewDomain.h"
#include "Engine/ConstantFunctionEngine.h"
#include "Engine/Engine.h"
#include "Engine/EnginePatch.h"
#include "Engine/ExpressionEngine.h"
#include "Evaluator/Evaluator.h"
#include "PETE/PETE.h"
#include "Pooma/View.h"
#include "Utilities/PAssert.h"
#include "Utilities/RefCountedBlockPtr.h"
// NOTE: The current order of includes puts FieldCreateLeaf after the
// operators files to work around a bug with template instantiation in KCC.
#include "NewField/FieldMakeReturn.h"
#include "NewField/FieldOperators.h"
#include "NewField/PoomaFieldOperators.h"
#include "NewField/VectorFieldOperators.h"
#include "NewField/FieldCreateLeaf.h"
#include "NewField/PrintField.h"
#include "NewField/FieldEngine/FieldEnginePatch.h"
//-----------------------------------------------------------------------------
// Forward declarations:
//-----------------------------------------------------------------------------
struct CompressibleBrick;
template<class GeometryTag, class T, class EngineTag>
class Field;
template<class GeometryTag, class T, class EngineTag> class FieldEngine;
template<class LTag, class EngineTag>
struct MultiPatch;
template<int Dim> struct NoGeometry;
struct POOMA_DEFAULT_ENGINE_TYPE;
template<class Subject> class SubFieldView;
template<class Subject, class Domain, bool SV>
struct View1Implementation;
//-----------------------------------------------------------------------------
// Prototypes for the assign function used to assign an expression to a Field.
//
// Prototypes defined here:
// Field = Field
// Field = Array
// Field = scalar
///
// If you wish to have Field work with other types of objects on the right-
// hand side (for example, other classes that derive from Field), define
// extra assign() functions that take the following arguments:
//
// assign(Field<Mesh,T,EngineTag>, yourclass, Operator)
//
// where "yourclass" is the class that you would like to work on the
// right-hand side in an expression with a Field on the left-hand side.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag,
class GeometryTag2, class T2, class EngineTag2, class Op>
const Field<GeometryTag, T, EngineTag> &
assign(const Field<GeometryTag, T, EngineTag> &lhs,
const Field<GeometryTag2, T2, EngineTag2> &rhs,
const Op &op);
template<class GeometryTag, class T, class EngineTag,
int Dim2, class T2, class EngineTag2, class Op>
const Field<GeometryTag, T, EngineTag> &
assign(const Field<GeometryTag, T, EngineTag> &lhs,
const Array<Dim2, T2, EngineTag2> &rhs, const Op &op);
template<class GeometryTag, class T, class EngineTag, class T1, class Op>
const Field<GeometryTag, T, EngineTag> &
assign(const Field<GeometryTag, T, EngineTag> &lhs,
const T1 &rhs, const Op &op);
template<class GeometryTag, class T, class EngineTag,
int Dim2, class T2, class EngineTag2, class Op>
const Array<Dim2, T2, EngineTag2> &
assign(const Array<Dim2, T2, EngineTag2> &lhs,
const Field<GeometryTag, T, EngineTag> &rhs, const Op &op);
//-----------------------------------------------------------------------------
// SubFieldView is used to implement the syntax f[i], which selects the
// ith SubField for field f.
//-----------------------------------------------------------------------------
struct SubFieldViewFunctorTag;
template<class GeometryTag, class T, class EngineTag>
class SubFieldView<Field<GeometryTag, T, EngineTag> > {
public:
// Use it to construct the output field type.
typedef Field<GeometryTag, T, EngineTag> Type_t;
// The function that actually creates the view.
inline static Type_t make(const Type_t &s, int iSubField)
{
#if POOMA_BOUNDS_CHECK
PInsist(iSubField >= 0 && iSubField < s.numSubFields(),
"Field::operator[] indexing error.");
#endif
return Type_t(s, iSubField);
}
};
template<class GeometryTag, class T, class Expr>
class SubFieldView<Field<GeometryTag, T, ExpressionTag<Expr> > > {
public:
// Use it to construct the output field type.
typedef Field<GeometryTag, T, ExpressionTag<Expr> > Subject_t;
typedef
typename ForEach<Expr, SubFieldViewFunctorTag, TreeCombine>::Type_t
Expr_t;
typedef Field<GeometryTag, T, ExpressionTag<Expr_t> > Type_t;
// The function that actually creates the view.
inline static Type_t make(const Subject_t &s, int iSubField)
{
#if POOMA_BOUNDS_CHECK
PInsist(iSubField >= 0 && iSubField < s.numSubFields(),
"Field::operator[] indexing error.");
#endif
return Type_t(s, iSubField);
}
};
//-----------------------------------------------------------------------------
// View1Implementation<Field, D, SV> specialization for indexing a field
// with a single domain. There is a single-valued version (SV == true)
// and a multi-valued version (SV == false).
//-----------------------------------------------------------------------------
// Single-valued version. Handles scalars and Locs.
template<class GeometryTag, class T, class EngineTag, class Domain>
struct View1Implementation<Field<GeometryTag, T, EngineTag>, Domain, true>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t Engine_t;
// The return types are pretty simple here.
typedef typename Engine_t::Element_t ReadType_t;
typedef typename Engine_t::ElementRef_t Type_t;
template<class S1, class Combine>
inline static
Type_t make(const Subject_t &f, const S1 &s1,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine()(s);
}
template<class S1, class S2, class Combine>
inline static
Type_t make(const Subject_t &f,
const S1 &s1, const S2 &s2,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1, s2));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine()(s);
}
template<class S1, class S2, class S3,
class Combine>
inline static
Type_t make(const Subject_t &f,
const S1 &s1, const S2 &s2, const S3 &s3,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1, s2, s3));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine()(s);
}
template<class S1, class Combine>
inline static
ReadType_t makeRead(const Subject_t &f, const S1 &s1,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine().read(s);
}
template<class S1, class S2, class Combine>
inline static
ReadType_t makeRead(const Subject_t &f,
const S1 &s1, const S2 &s2,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1, s2));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine().read(s);
}
template<class S1, class S2, class S3,
class Combine>
inline static
ReadType_t makeRead(const Subject_t &f,
const S1 &s1, const S2 &s2, const S3 &s3,
const Combine &)
{
PAssert(f.numSubFields() == 0);
Domain s(Combine::make(f, s1, s2, s3));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return f.engine().read(s);
}
};
// Non-single-valued implementation. Works for general domains
// including Nodes and INodes.
// Use this little traits class to deduce the geometry tag for a view.
// It is always a NoGeometry unless the view is from an interval or
// an INode.
template<int Dim, class GeometryTag, class Domain>
struct NewGeometryTag
{
typedef NoGeometry<Dim> Type_t;
};
template<int Dim, class GeometryTag>
struct NewGeometryTag<Dim, GeometryTag, Interval<Dim> >
{
typedef GeometryTag Type_t;
};
template<int Dim, class GeometryTag>
struct NewGeometryTag<Dim, GeometryTag, INode<Dim> >
{
typedef GeometryTag Type_t;
};
template<class GeometryTag, class T, class EngineTag, class Domain>
struct View1Implementation<Field<GeometryTag, T, EngineTag>, Domain, false>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
// Deduce domains for the output type.
typedef typename FieldEngine_t::Engine_t Engine_t;
typedef typename NewEngine<Engine_t, Domain>::Type_t NewEngine_t;
typedef typename NewEngine_t::Element_t NewT_t;
typedef typename NewEngine_t::Tag_t NewEngineTag_t;
// Deduce the new GeometryTag.
typedef typename
NewGeometryTag<NewEngine_t::dimensions, GeometryTag, Domain>::Type_t
NewGeometryTag_t;
// The output types.
typedef Field<NewGeometryTag_t, NewT_t, NewEngineTag_t> ReadType_t;
typedef Field<NewGeometryTag_t, NewT_t, NewEngineTag_t> Type_t;
template<class S1, class Combine>
static
Type_t make(const Subject_t &f, const S1 &s1,
const Combine &)
{
Domain s(Combine::make(f, s1));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return Type_t(f, s);
}
template<class S1, class S2, class Combine>
static
Type_t make(const Subject_t &f, const S1 &s1,
const S2 &s2, const Combine &)
{
Domain s(Combine::make(f, s1, s2));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return Type_t(f, s);
}
template<class S1, class S2, class S3,
class Combine>
static
Type_t make(const Subject_t &f,
const S1 &s1, const S2 &s2, const S3 &s3,
const Combine &)
{
Domain s(Combine::make(f, s1, s2, s3));
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), s),
"Field view bounds error.");
#endif
return Type_t(f, s);
}
template<class S1, class Combine>
inline static
Type_t makeRead(const Subject_t &f, const S1 &s1,
const Combine &c)
{
return make(f, s1, c);
}
template<class S1, class S2, class Combine>
inline static
Type_t makeRead(const Subject_t &f, const S1 &s1,
const S2 &s2, const Combine &c)
{
return make(f, s1, s2, c);
}
template<class S1, class S2, class S3,
class Combine>
inline static
Type_t makeRead(const Subject_t &f,
const S1 &s1, const S2 &s2, const S3 &s3,
const Combine &c)
{
return make(f, s1, s2, s3, c);
}
};
//-----------------------------------------------------------------------------
// View1<Field, S1> specialization for indexing a field with a single domain.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag, class Sub1>
struct View1<Field<GeometryTag, T, EngineTag>, Sub1>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
// Deduce domains for the output type.
// At some point, we need to fix NewDomain1; until then, use
// the temporary version from NewDomain.h.
typedef typename FieldEngine_t::Domain_t Domain_t;
typedef TemporaryNewDomain1<Domain_t, Sub1> NewDomain_t;
typedef typename NewDomain_t::SliceType_t SDomain_t;
// Deduce appropriate version of implementation to dispatch to.
// static const bool sv = DomainTraits<SDomain_t>::singleValued;
typedef View1Implementation<Subject_t, SDomain_t, DomainTraits<SDomain_t>::singleValued> Dispatch_t;
// The optimized domain combiner.
typedef CombineDomainOpt<NewDomain_t, DomainTraits<SDomain_t>::singleValued> Combine_t;
// The return types.
typedef typename Dispatch_t::ReadType_t ReadType_t;
typedef typename Dispatch_t::Type_t Type_t;
// The functions that create the view.
inline static
Type_t make(const Subject_t &f, const Sub1 &s1)
{
return Dispatch_t::make(f, s1, Combine_t());
}
inline static
ReadType_t makeRead(const Subject_t &f, const Sub1 &s1)
{
return Dispatch_t::makeRead(f, s1, Combine_t());
}
};
//-----------------------------------------------------------------------------
// View1<Field, int> specialization for indexing a field with an int.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag>
struct View1<Field<GeometryTag, T, EngineTag>, int>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t Engine_t;
// The return types.
typedef typename Engine_t::Element_t ReadType_t;
typedef typename Engine_t::ElementRef_t Type_t;
// The functions that do the indexing.
inline static
Type_t make(const Subject_t &f, int s1)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<1>(s1)),
"Field view bounds error.");
#endif
return f.engine()(s1);
}
inline static
ReadType_t makeRead(const Subject_t &f, int s1)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<1>(s1)),
"Field view bounds error.");
#endif
return f.engine().read(s1);
}
};
//-----------------------------------------------------------------------------
// View2<Field, S1, S2> specialization for indexing a field with two
// domains.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag,
class Sub1, class Sub2>
struct View2<Field<GeometryTag, T, EngineTag>, Sub1, Sub2>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
// Deduce domains for the output type.
typedef typename FieldEngine_t::Domain_t Domain_t;
typedef NewDomain2<Sub1, Sub2> NewDomain_t;
typedef typename NewDomain_t::SliceType_t SDomain_t;
// Deduce appropriate version of implementation to dispatch to.
// static const bool sv = DomainTraits<SDomain_t>::singleValued;
typedef View1Implementation<Subject_t, SDomain_t, DomainTraits<SDomain_t>::singleValued> Dispatch_t;
// The optimized domain combiner.
typedef CombineDomainOpt<NewDomain_t, DomainTraits<SDomain_t>::singleValued> Combine_t;
// The return types.
typedef typename Dispatch_t::ReadType_t ReadType_t;
typedef typename Dispatch_t::Type_t Type_t;
// The functions that create the view.
inline static
Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
{
return Dispatch_t::make(f, s1, s2, Combine_t());
}
inline static
ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
{
return Dispatch_t::makeRead(f, s1, s2, Combine_t());
}
};
//-----------------------------------------------------------------------------
// View2<Field, int, int> specialization for indexing a field with two
// integers.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag>
struct View2<Field<GeometryTag, T, EngineTag>, int, int>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t Engine_t;
// The return types.
typedef typename Engine_t::Element_t ReadType_t;
typedef typename Engine_t::ElementRef_t Type_t;
// The functions that do the indexing.
inline static
Type_t make(const Subject_t &f, int s1, int s2)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<2>(s1, s2)),
"Field view bounds error.");
#endif
return f.engine()(s1, s2);
}
inline static
ReadType_t makeRead(const Subject_t &f, int s1, int s2)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<2>(s1, s2)),
"Field view bounds error.");
#endif
return f.engine().read(s1, s2);
}
};
//-----------------------------------------------------------------------------
// View3<Field, S1, S2, S3> specialization for indexing a field with three
// domains.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag,
class Sub1, class Sub2, class Sub3>
struct View3<Field<GeometryTag, T, EngineTag>, Sub1, Sub2, Sub3>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
// Deduce domains for the output type.
typedef typename FieldEngine_t::Domain_t Domain_t;
typedef NewDomain3<Sub1, Sub2, Sub3> NewDomain_t;
typedef typename NewDomain_t::SliceType_t SDomain_t;
// Deduce appropriate version of implementation to dispatch to.
// static const bool sv = DomainTraits<SDomain_t>::singleValued;
typedef View1Implementation<Subject_t, SDomain_t, DomainTraits<SDomain_t>::singleValued> Dispatch_t;
// The optimized domain combiner.
typedef CombineDomainOpt<NewDomain_t, DomainTraits<SDomain_t>::singleValued> Combine_t;
// The return types.
typedef typename Dispatch_t::ReadType_t ReadType_t;
typedef typename Dispatch_t::Type_t Type_t;
// The functions that create the view.
inline static
Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
const Sub3 &s3)
{
return Dispatch_t::make(f, s1, s2, s3, Combine_t());
}
inline static
ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
const Sub3 &s3)
{
return Dispatch_t::makeRead(f, s1, s2, s3, Combine_t());
}
};
//-----------------------------------------------------------------------------
// View3<Field, int, int, int> specialization for indexing a field with three
// integers.
//-----------------------------------------------------------------------------
template<class GeometryTag, class T, class EngineTag>
struct View3<Field<GeometryTag, T, EngineTag>, int, int, int>
{
// Convenience typedef for the thing we're taking a view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t Engine_t;
// The return types.
typedef typename Engine_t::Element_t ReadType_t;
typedef typename Engine_t::ElementRef_t Type_t;
// The functions that do the indexing.
inline static
Type_t make(const Subject_t &f, int s1, int s2, int s3)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<3>(s1, s2, s3)),
"Field view bounds error.");
#endif
return f.engine()(s1, s2, s3);
}
inline static
ReadType_t makeRead(const Subject_t &f, int s1, int s2, int s3)
{
PAssert(f.numSubFields() == 0);
#if POOMA_BOUNDS_CHECK
PInsist(contains(f.totalDomain(), Loc<3>(s1, s2, s3)),
"Field view bounds error.");
#endif
return f.engine().read(s1, s2, s3);
}
};
//-----------------------------------------------------------------------------
// Patch specialization for Field.
//-----------------------------------------------------------------------------
template<class Subject> struct Patch;
template<class GeometryTag, class T, class EngineTag>
struct Patch<Field<GeometryTag, T, EngineTag> >
{
typedef Field<GeometryTag, T, EngineTag> Subject_t;
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t OldEngine_t;
typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
// We've assumed that GeometryTag and T are the same for the patch engine.
typedef Field<GeometryTag, T, typename Engine_t::Tag_t> Type_t;
enum { dim = OldEngine_t::dimensions };
inline static
Type_t make(const Subject_t &f, int i)
{
PAssert(f.numSubFields() == 0);
return Type_t(f, FieldEnginePatch<dim>(i, f.physicalDomain()));
}
};
template<class GeometryTag, class T, class LTag, class EngineTag>
struct Patch<Field<GeometryTag, T, MultiPatch<LTag, EngineTag> > >
{
typedef Field<GeometryTag, T, MultiPatch<LTag, EngineTag> > Subject_t;
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t OldEngine_t;
typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
// We've assumed that GeometryTag and T are the same for the patch engine.
typedef Field<GeometryTag, T, typename Engine_t::Tag_t> Type_t;
enum { dim = OldEngine_t::dimensions };
typedef typename OldEngine_t::Layout_t Layout_t;
typedef typename Layout_t::Value_t Node_t;
inline static
Type_t make(const Subject_t &f, int i)
{
PAssert(f.numSubFields() == 0);
Node_t *node = f.engine().layout().nodeListLocal()[i];
return Type_t(f, FieldEnginePatch<dim>(i, intersect(f.physicalDomain(),
node->domain())));
}
};
//-----------------------------------------------------------------------------
// ComponentView specialization for Field. Implements views of the form
// f.comp(loc).
//-----------------------------------------------------------------------------
template<class Components, class Subject> struct ComponentView;
template<class Components>
class ComponentWrapper {
public:
explicit ComponentWrapper(const Components &c) : c_m(c) { }
const Components &components() const { return c_m; }
private:
const Components &c_m;
};
template<class Components, class GeometryTag, class T, class EngineTag>
struct ComponentView<Components, Field<GeometryTag, T, EngineTag> >
{
// Convenience typedef for the thing we're taking a component view of.
typedef Field<GeometryTag, T, EngineTag> Subject_t;
// All views need to get types from the FieldEngine class to avoid
// recursion.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
typedef typename FieldEngine_t::Engine_t Engine_t;
// Deduce the template parameters for the output type.
typedef typename Engine_t::Element_t Element_t;
typedef typename ComponentAccess<Element_t, Components>::Element_t NewT_t;
typedef CompFwd<Engine_t, Components> NewEngineTag_t;
// The output type.
typedef Field<GeometryTag, NewT_t, NewEngineTag_t> Type_t;
// A function that creates the view.
inline static
Type_t make(const Subject_t &f, const Components &c)
{
return Type_t(f, ComponentWrapper<Components>(c));
}
};
//-----------------------------------------------------------------------------
// Field.
//-----------------------------------------------------------------------------
template<class GeometryTag,
class T = POOMA_DEFAULT_ELEMENT_TYPE,
class EngineTag = POOMA_DEFAULT_ENGINE_TYPE>
class Field {
public:
//---------------------------------------------------------------------------
// Exported typedefs and enumerations.
// The specification type.
typedef GeometryTag GeometryTag_t;
// The type.
typedef T T_t;
// The engine tag.
typedef EngineTag EngineTag_t;
// This class.
typedef Field<GeometryTag, T, EngineTag> This_t;
// The field engine type.
typedef FieldEngine<GeometryTag, T, EngineTag> FieldEngine_t;
// The dimension (i.e., the number of indices required to select a point).
enum { dimensions = FieldEngine_t::dimensions };
// The engine type.
typedef Engine<dimensions, T, EngineTag> Engine_t;
// Element_t is the type of elements managed by this field's engine.
// ElementRef_t is the writable version.
typedef typename Engine_t::Element_t Element_t;
typedef typename Engine_t::ElementRef_t ElementRef_t;
// Layout_t is the Engine's layout.
typedef typename Engine_t::Layout_t Layout_t;
// The types of the our domains.
typedef typename Engine_t::Domain_t Domain_t;
//---------------------------------------------------------------------------
// User-callable constructors. These ctors are meant to be called by users.
// GeometryTag/centering/layout constructors. We use the specified mesh
// object to initialize our mesh and the layout to initialize
// the engines. Clearly, these must be synchronized. This is appropriate
// for multi-patch engines. We just store the centering.
Field()
: fieldEngine_m()
{ }
template<class I1>
explicit Field(const I1 &i1)
: fieldEngine_m(i1)
{ }
template<class I1, class I2>
Field(const I1 &i1, const I2 &i2)
: fieldEngine_m(i1, i2)
{ }
template<class I1, class I2, class I3>
Field(const I1 &i1, const I2 &i2, const I3 &i3)
: fieldEngine_m(i1, i2, i3)
{ }
template<class I1, class I2, class I3, class I4>
Field(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4)
: fieldEngine_m(i1, i2, i3, i4)
{ }
// Copy constructor.
Field(const This_t &model)
: fieldEngine_m(model.fieldEngine())
{ }
// Copy initializer.
void initialize(const This_t &model)
{ fieldEngine_m = model.fieldEngine(); }
//---------------------------------------------------------------------------
// Internal POOMA constructors. These ctors are used internally by POOMA.
More information about the pooma-dev
mailing list