freepooma-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch to NewField/Field.h (1/3)


From: Dave Nystrom
Subject: Patch to NewField/Field.h (1/3)
Date: Tue, 16 Oct 2001 16:26:40 -0600
User-agent: SEMI/1.13.7 (Awazu) CLIME/1.13.6 (中 ノ庄) MULE XEmacs/21.1 (patch 14) (Cuyahoga Valley) (i386-redhat-linux)

Message-ID: <15308.46112.115873.241342@saltydog.lanl.gov>
Date: Tue, 16 Oct 2001 16:26:40 -0600
From: Dave Nystrom <wdn@lanl.gov>
To: pooma-dev <pooma-dev@pooma.codesourcery.com>
Subject: Patch to NewField/Field.h
X-Mailer: VM 6.89 under 21.1 (patch 14) "Cuyahoga Valley" XEmacs Lucid
User-Agent: SEMI/1.13.7 (Awazu) CLIME/1.13.6 (=?ISO-2022-JP?B?GyRCQ2YbKEI=?=
 =?ISO-2022-JP?B?GyRCJU4+MRsoQg==?=) MULE XEmacs/21.1 (patch 14) (Cuyahoga
 Valley) (i386-redhat-linux)
MIME-Version: 1.0 (generated by SEMI 1.13.7 - "Awazu")
Content-Type: text/plain; charset=US-ASCII

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@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@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.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]