Field.h 6.83 KB
Newer Older
gsell's avatar
gsell committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/***************************************************************************
 *
 * The IPPL Framework
 *
 ***************************************************************************/

#ifndef FIELD_H
#define FIELD_H

// include files
#include "Field/BareField.h"
#include "Field/FieldSpec.h"
#include "Field/LField.h"
#include "Field/BCond.h"
#include "Field/ReductionLoc.h"
#include "SubField/SubField.h"
#include "DataSource/DataSource.h"
#include "Meshes/UniformCartesian.h"

// forward declarations
template <class T, unsigned D, unsigned B, class M, class C> 
class IndexedField;

/***********************************************************************
      This is the user visible Field of type T.
      It doesn't even really do expression evaluation; that is
      handled with the templates in PETE.h
***********************************************************************/

template<class T, unsigned Dim,
         class M=UniformCartesian<Dim,double>,
         class C=typename M::DefaultCentering >
class Field : public BareField<T,Dim>, public DataSource {

  friend class BareFieldIterator<T,Dim>;

public: 
  //# public typedefs
  typedef M Mesh_t;
  typedef C Centering_t;
  typedef BareField<T,Dim>                   Base_t;
  typedef FieldLayout<Dim>                   Layout_t;
  typedef BConds<T,Dim,M,C>                  bcond_container;
  typedef BCondBase<T,Dim,M,C>               bcond_value;
  typedef typename bcond_container::iterator bcond_iterator;

  // A default constructor, which should be used only if the user calls the
  // 'initialize' function before doing anything else.  There are no special
  // checks in the rest of the Field methods to check that the Field has
  // been properly initialized.
  Field();

  // Destroy the Field.
  virtual ~Field();

  // Create a new Field with a given layout and optional guard cells.
  // The default type of BCond lets you add new ones dynamically.
  // The makeMesh() global function is a way to allow for different types of
  // constructor arguments for different mesh types.
  Field(Layout_t &);
  Field(Layout_t &,const GuardCellSizes<Dim>&);
  Field(Layout_t &,const BConds<T,Dim,M,C>&);
  Field(Layout_t &,const GuardCellSizes<Dim>&,const BConds<T,Dim,M,C>&);
  Field(Layout_t &,const BConds<T,Dim,M,C>&,const GuardCellSizes<Dim>&);
  Field(FieldSpec<T,Dim,M,C>&);
66
  constexpr Field(Field<T,Dim,M,C>&) = default;
gsell's avatar
gsell committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

  // Constructors including a Mesh object as argument:
  Field(Mesh_t&, Layout_t &);
  Field(Mesh_t&, Layout_t &, const GuardCellSizes<Dim>&);
  Field(Mesh_t&, Layout_t &, const BConds<T,Dim,M,C>&);
  Field(Mesh_t&, Layout_t &, const GuardCellSizes<Dim>&,
	const BConds<T,Dim,M,C>&);
  Field(Mesh_t&, Layout_t &, const BConds<T,Dim,M,C>&,
	const GuardCellSizes<Dim>&);
  Field(Mesh_t&, FieldSpec<T,Dim,M,C>&);

  // Initialize the Field, if it was constructed from the default constructor.
  // This should NOT be called if the Field was constructed by providing
  // a FieldLayout or FieldSpec
  void initialize(Layout_t &);
  void initialize(Layout_t &, const GuardCellSizes<Dim>&);
  void initialize(Layout_t &, const BConds<T,Dim,M,C>&);
  void initialize(Layout_t &, const GuardCellSizes<Dim>&,
		  const BConds<T,Dim,M,C>&);
  void initialize(Layout_t &, const BConds<T,Dim,M,C>&,
		  const GuardCellSizes<Dim>&);
  void initialize(FieldSpec<T,Dim,M,C>&);

  // Initialize the Field, also specifying a mesh
  void initialize(Mesh_t&, Layout_t &);
uldis_l's avatar
uldis_l committed
92
  void initialize(Mesh_t&, Layout_t &, const bool); //UL: for pinned memory allocation
gsell's avatar
gsell committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
  void initialize(Mesh_t&, Layout_t &, const GuardCellSizes<Dim>&);
  void initialize(Mesh_t&, Layout_t &, const BConds<T,Dim,M,C>&);
  void initialize(Mesh_t&, Layout_t &, const GuardCellSizes<Dim>&,
		  const BConds<T,Dim,M,C>&);
  void initialize(Mesh_t&, Layout_t &, const BConds<T,Dim,M,C>&,
		  const GuardCellSizes<Dim>&);
  void initialize(Mesh_t&, FieldSpec<T,Dim,M,C>&);

  // Definitions for accessing boundary conditions.
  const bcond_value&     getBCond(int bc) const { return *(Bc[bc]); }
  bcond_value&           getBCond(int bc)       { return *(Bc[bc]); }
  const bcond_container& getBConds()      const { return Bc; }
  bcond_container&       getBConds()            { return Bc; }
  bcond_iterator         begin_BConds()         { return Bc.begin(); }
  bcond_iterator         end_BConds()           { return Bc.end(); }

  // Access to the mesh
  Mesh_t& get_mesh() const { return *mesh; }

  // When we apply a bracket it converts the type to IndexedField so
  // that we can check at compile time that we have the right number
  // of indexes and brackets.  There are a number of different types
  // which we can use to index a Field in order to get a reference to
  // a subset of that Field.
  IndexedField<T,Dim,1,M,C>   operator[](const Index&);
  IndexedField<T,Dim,1,M,C>   operator[](int);
  IndexedField<T,Dim,Dim,M,C> operator[](const NDIndex<Dim>&);
  SubField<T,Dim,M,C,SIndex<Dim> >  operator[](const SIndex<Dim>&);

  // Assignment from constants and other arrays.
  const Field<T,Dim,M,C>& operator=(T x) {
    assign(*this,x);
    return *this;
  }

  const Field<T,Dim,M,C>& operator=(const Field<T,Dim,M,C>& x) {
    assign(*this,x);
    return *this;
  }

  template<class X>
  const Field<T,Dim,M,C>& operator=(const BareField<X,Dim>& x) {
    assign(*this,x);
    return *this;
  }

  template<class B>
  const Field<T,Dim,M,C>& operator=(const PETE_Expr<B>& x) {
    assign(*this,x);
    return *this;
  }

  // If you make any modifications using an iterator, you must call this.
  void fillGuardCells(bool reallyFill = true) const;

  // I/O (special stuff not inherited from BareField):
  // Print out contents of Centering class
  void print_Centerings(std::ostream&);

  //
  // virtual functions for FieldLayoutUser's (and other UserList users)
  //

  // Repartition onto a new layout, or when the mesh changes
  virtual void Repartition(UserList *);

  // Tell this object that an object is being deleted
  virtual void notifyUserOfDelete(UserList *);

protected:
  // a virtual function which is called by this base class to get a
  // specific instance of DataSourceObject based on the type of data
  // and the connection method (the argument to the call).
  virtual DataSourceObject *createDataSourceObject(const char *, DataConnect *,
						   int);

private:
  // The boundary conditions.
  bcond_container Bc;

  // The Mesh object, and a flag indicating if we constructed it
  Mesh_t* mesh;
  bool WeOwnMesh;

  // store the given mesh object pointer, and the flag whether we own it or not.
  // if we own it, we must make sure to delete it when this Field is deleted.
  void store_mesh(Mesh_t*, bool);

  // delete the mesh object, if necessary; otherwise, just zero the pointer
  void delete_mesh();
};

185
#include "Field/Field.hpp"
gsell's avatar
gsell committed
186

187
#endif
gsell's avatar
gsell committed
188

189 190 191 192 193 194 195
// vi: set et ts=4 sw=4 sts=4:
// Local Variables:
// mode:c
// c-basic-offset: 4
// indent-tabs-mode: nil
// require-final-newline: nil
// End: