src/Field/BCond.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef BCOND_H
00012 #define BCOND_H
00013 
00014 // include files
00015 #include "AppTypes/dcomplex.h"
00016 #include "Utility/RefCounted.h"
00017 #include "Utility/vmap.h"
00018 
00019 #ifdef IPPL_USE_STANDARD_HEADERS
00020 #include <iostream>
00021 using namespace std;
00022 #else
00023 #include <iostream.h>
00024 #endif
00025 
00026 // forward declarations
00027 template <unsigned D> class NDIndex;
00028 template <class T, unsigned D> class Vektor;
00029 template <class T, unsigned D> class Tenzor;
00030 template <class T, unsigned D> class SymTenzor;
00031 template <class T, unsigned D> class AntiSymTenzor;
00032 template<unsigned D, class T> class UniformCartesian;
00033 template<class T, unsigned D> class LField;
00034 template<class T, unsigned D> class BareField;
00035 template<class T, unsigned D, class M, class C> class Field;
00036 template <class T, unsigned D, class M, class C> class BCondBase;
00037 template <class T, unsigned D, class M, class C>
00038 ostream& operator<<(ostream&, const BCondBase<T,D,M,C>&);
00039 template <class T, unsigned D, class M, class C> class BConds;
00040 template <class T, unsigned D, class M, class C>
00041 ostream& operator<<(ostream&, const BConds<T,D,M,C>&);
00042 
00044 
00045 //
00046 // Traits used by the single-component version of the applicative templates.
00047 // General case: this covers intrinsic types like double, bool automatically:
00048 //
00049 
00050 template<class T>
00051 struct ApplyToComponentType 
00052 {
00053   typedef T type;
00054 };
00055 
00056 //
00057 // Specializations for multicomponent IPPL types;
00058 //
00059 template<class T,unsigned D>
00060 struct ApplyToComponentType< Vektor<T,D> > 
00061 {
00062   typedef T type;
00063 };
00064 
00065 template<class T,unsigned D>
00066 struct ApplyToComponentType< Tenzor<T,D> > 
00067 {
00068   typedef T type;
00069 };
00070 
00071 template<class T,unsigned D>
00072 struct ApplyToComponentType< SymTenzor<T,D> > 
00073 {
00074   typedef T type;
00075 };
00076 
00077 template<class T,unsigned D>
00078 struct ApplyToComponentType< AntiSymTenzor<T,D> > 
00079 {
00080   typedef T type;
00081 };
00082 
00083 // Helper classes for getting info about number of indices into 
00084 // BCond-class ctor functions.
00085 // Define tag types (like iterator tags in stl):
00086 
00087 class scalar_tag
00088 {
00089 #ifdef IPPL_PURIFY
00090 public:
00091   scalar_tag() {}
00092   scalar_tag(const scalar_tag &) {}
00093   scalar_tag& operator=(const scalar_tag &) { return *this; }
00094 #endif
00095 };
00096 
00097 class vektor_tag
00098 {
00099 #ifdef IPPL_PURIFY
00100 public:
00101   vektor_tag() {}
00102   vektor_tag(const vektor_tag &) {}
00103   vektor_tag& operator=(const vektor_tag &) { return *this; }
00104 #endif
00105 };
00106 
00107 class tenzor_tag
00108 {
00109 #ifdef IPPL_PURIFY
00110 public:
00111   tenzor_tag() {}
00112   tenzor_tag(const tenzor_tag &) {}
00113   tenzor_tag& operator=(const tenzor_tag &) { return *this; }
00114 #endif
00115 };
00116 
00117 class symtenzor_tag
00118 {
00119 #ifdef IPPL_PURIFY
00120 public:
00121   symtenzor_tag() {}
00122   symtenzor_tag(const symtenzor_tag &) {}
00123   symtenzor_tag& operator=(const symtenzor_tag &) { return *this; }
00124 #endif
00125 };
00126 
00127 class antisymtenzor_tag
00128 {
00129 #ifdef IPPL_PURIFY
00130 public:
00131   antisymtenzor_tag() {}
00132   antisymtenzor_tag(const antisymtenzor_tag &) {}
00133   antisymtenzor_tag& operator=(const antisymtenzor_tag &) { return *this; }
00134 #endif
00135 };
00136 
00137 // Implement tag types for intrinsic types:
00138 inline scalar_tag get_tag(dcomplex) { return scalar_tag(); }
00139 inline scalar_tag get_tag(double)   { return scalar_tag(); }
00140 inline scalar_tag get_tag(float)    { return scalar_tag(); }
00141 inline scalar_tag get_tag(int)      { return scalar_tag(); }
00142 inline scalar_tag get_tag(bool)     { return scalar_tag(); }
00143 inline scalar_tag get_tag(short)    { return scalar_tag(); }
00144 
00145 // Tag for Vektor types:
00146 template<class T, unsigned D>
00147 vektor_tag get_tag(Vektor<T,D>) { return vektor_tag(); }
00148 
00149 // Tag for Tenzor types:
00150 template<class T, unsigned D>
00151 tenzor_tag get_tag(Tenzor<T,D>) { return tenzor_tag(); }
00152 
00153 // Tag for AntiSymTenzor types
00154 template<class T, unsigned D>
00155 antisymtenzor_tag get_tag(AntiSymTenzor<T,D>) { return antisymtenzor_tag(); }
00156 
00157 // Tag for SymTenzor types
00158 template<class T, unsigned D>
00159 symtenzor_tag get_tag(SymTenzor<T,D>) { return symtenzor_tag(); }
00160 
00161 // Functions which return an enum value indicating scalar, vector, tensor,
00162 // or anti/symtensor type; used in constructors for PeriodicFace, etc., to
00163 // determine how to turn two 1D component indices into a single index value
00164 // for pointer offsetting into the Tenzor/Anti/SymTenzor object:
00165 enum TensorOrder_e { IPPL_SCALAR=0, IPPL_VECTOR=1, IPPL_TENSOR=2, 
00166                      IPPL_SYMTENSOR=3, IPPL_ANTISYMTENSOR=4 } ;
00167 inline TensorOrder_e getTensorOrder(const scalar_tag& ttag)
00168 {return IPPL_SCALAR;}
00169 inline TensorOrder_e getTensorOrder(const vektor_tag& ttag)
00170 {return IPPL_VECTOR;}
00171 inline TensorOrder_e getTensorOrder(const tenzor_tag& ttag)
00172 {return IPPL_TENSOR;}
00173 inline TensorOrder_e getTensorOrder(const antisymtenzor_tag& sttag)
00174 {return IPPL_ANTISYMTENSOR;}
00175 inline TensorOrder_e getTensorOrder(const symtenzor_tag& sttag)
00176 {return IPPL_SYMTENSOR;}
00177 
00179 
00180 template<class T, unsigned D, class M, class C>
00181 class BCondBase : public RefCounted
00182 {
00183 public:
00184 
00185   // Special value designating application to all components of elements:
00186   static int allComponents;
00187 
00188   // Constructor takes:
00189   // face: the face to apply the boundary condition on.
00190   // i,j : what component of T to apply the boundary condition to.
00191   // The components default to setting all components.
00192   BCondBase(unsigned int face,
00193             int i = allComponents,
00194             int j = allComponents);
00195 
00196   virtual void apply( Field<T,D,M,C>& ) = 0;
00197   virtual BCondBase<T,D,M,C>* clone() const = 0;
00198 
00199   // The convert_type() implementation is commented out, since it doesn't
00200   // work in general. If nobody really needs it, it will eventually be
00201   // eliminated; if somebody needs it, somebody needs to do a new 
00202   // implementation. --TJW
00203   //  virtual BCondBase<int,D,M,C>* convert_type(int) const = 0;
00204   virtual void write(ostream&) const;
00205 
00206   // Return component of Field element on which BC applies
00207   int getComponent() const { return m_component; }
00208 
00209   // Return face on which BC applies
00210   unsigned int getFace() const { return m_face; }
00211 
00212   // Returns whether or not this BC changes physical cells.
00213   bool changesPhysicalCells() const { return m_changePhysical; }
00214 
00215 protected:
00216 
00217   // Following are hooks for BC-by-Field-element-component support:
00218   // Component of Field elements (Vektor, e.g.) on which the BC applies:
00219   int m_component;
00220   
00221   // What face to apply the boundary condition to.
00222   unsigned int m_face;
00223 
00224   // True if this boundary condition changes physical cells.
00225   bool m_changePhysical;
00226 };
00227 
00229 
00230 template<
00231   class T,
00232   unsigned D,
00233   class M=UniformCartesian<D,double>,
00234   class C=typename M::DefaultCentering>
00235 class BConds
00236   : public vmap<int, RefCountedP< BCondBase<T,D,M,C> > >
00237 {
00238 public: 
00239   typedef typename vmap<int, RefCountedP <BCondBase<T,D,M,C> > >::iterator 
00240     iterator; 
00241   typedef typename vmap<int, RefCountedP <BCondBase<T,D,M,C> > >::const_iterator 
00242     const_iterator; 
00243   // See comments in BCondBase class definition regarding convert_type() --TJW
00244   //  BConds<int,D,M,C>* convert_type(int) const ;
00245   void apply( Field<T,D,M,C>& a );
00246   bool changesPhysicalCells() const;
00247   virtual void write(ostream&) const;
00248 };
00249 
00251 
00252 // TJW: so far, componentwise specification of BCondNoAction not possible
00253 
00254 template<class T,
00255          unsigned D, 
00256          class M=UniformCartesian<D,double>, 
00257          class C=typename M::DefaultCentering>
00258 class BCondNoAction : public BCondBase<T,D,M,C>
00259 {
00260 public:
00261   BCondNoAction(int face) : BCondBase<T,D,M,C>(face) {}
00262 
00263   virtual void apply( Field<T,D,M,C>& ) {}
00264   BCondBase<T,D,M,C>* clone() const
00265   {
00266     return new BCondNoAction<T,D,M,C>( *this );
00267   }
00268 
00269   // Print out information about the BC to a stream.
00270   virtual void write(ostream& out) const;
00271 };
00272 
00274 
00275 template<class T,
00276          unsigned D, 
00277          class M=UniformCartesian<D,double>, 
00278          class C=typename M::DefaultCentering>
00279 class PeriodicFace : public BCondBase<T,D,M,C>
00280 {
00281 public:
00282   // Constructor takes zero, one, or two int's specifying components of 
00283   // multicomponent types like Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00284   // Zero int's specified means apply to all components; one means apply to
00285   // component (i), and two means apply to component (i,j),
00286   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00287 
00288   PeriodicFace(unsigned f, 
00289                int i = BCondBaseTDMC::allComponents,
00290                int j = BCondBaseTDMC::allComponents);
00291 
00292   // Apply the boundary condition to a particular Field.
00293   virtual void apply( Field<T,D,M,C>& );
00294 
00295   // Make a copy of the concrete type.
00296   virtual BCondBase<T,D,M,C>* clone() const
00297   {
00298     return new PeriodicFace<T,D,M,C>( *this );
00299   }
00300 
00301   // Print out information about the BC to a stream.
00302   virtual void write(ostream& out) const;
00303 };
00304 
00306 
00307 template<class T, unsigned D, 
00308          class M=UniformCartesian<D,double>, 
00309          class C=typename M::DefaultCentering>
00310 class ParallelPeriodicFace : public PeriodicFace<T,D,M,C>
00311 {
00312 public:
00313 
00314   // Constructor takes zero, one, or two int's specifying components
00315   // of multicomponent types like Vektor/Tenzor/AntiTenzor/SymTenzor
00316   // this BC applies to.  Zero int's means apply to all components;
00317   // one means apply to component (i), and two means apply to
00318   // component (i,j),
00319 
00320   typedef BCondBase<T,D,M,C> Base_t;
00321 
00322   ParallelPeriodicFace(unsigned f, 
00323                        int i = Base_t::allComponents,
00324                        int j = Base_t::allComponents)
00325     : PeriodicFace<T,D,M,C>(f,i,j) 
00326   { }
00327 
00328   // Apply the boundary condition to a particular Field.
00329 
00330   virtual void apply( Field<T,D,M,C>& );
00331 
00332   // Make a copy of the concrete type.
00333 
00334   virtual Base_t * clone() const
00335   {
00336     return new ParallelPeriodicFace<T,D,M,C>( *this );
00337   }
00338 
00339   // Print out information about the BC to a stream.
00340 
00341   virtual void write(ostream& out) const;
00342 };
00343 
00345 
00346 template<class T,
00347          unsigned D, 
00348          class M=UniformCartesian<D,double>, 
00349          class C=typename M::DefaultCentering>
00350 class ExtrapolateFace : public BCondBase<T,D,M,C>
00351 {
00352 public:
00353   // Constructor takes zero, one, or two int's specifying components of 
00354   // multicomponent types like Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00355   // Zero int's specified means apply to all components; one means apply to
00356   // component (i), and two means apply to component (i,j),
00357   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00358   ExtrapolateFace(unsigned f, T o, T s, 
00359                   int i = BCondBaseTDMC::allComponents,
00360                   int j = BCondBaseTDMC::allComponents);
00361 
00362   // Apply the boundary condition to a given Field.
00363   virtual void apply( Field<T,D,M,C>& );
00364 
00365   // Make a copy of the concrete type.
00366   virtual BCondBase<T,D,M,C>* clone() const
00367   {
00368     return new ExtrapolateFace<T,D,M,C>( *this );
00369   }
00370 
00371   // Print out some information about the BC to a given stream.
00372   virtual void write(ostream&) const;
00373 
00374   const T& getOffset() const { return Offset; }
00375   const T& getSlope() const { return Slope; }
00376 
00377 protected:
00378   T Offset, Slope;
00379 };
00380 
00381 
00383 
00384 // TJW added 12/16/1997 as per Tecolote team's request: this one sets last
00385 // physical element layer to zero for vert-centered elements/components. For
00386 // cell-centered, doesn't need to do this because the zero point of an odd
00387 // function is halfway between the last physical element and the first guard
00388 // element.
00389 
00390 template<class T,
00391          unsigned D, 
00392          class M=UniformCartesian<D,double>, 
00393          class C=typename M::DefaultCentering>
00394 class ExtrapolateAndZeroFace : public BCondBase<T,D,M,C>
00395 {
00396 public:
00397   // Constructor takes zero, one, or two int's specifying components of 
00398   // multicomponent types like Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00399   // Zero int's specified means apply to all components; one means apply to
00400   // component (i), and two means apply to component (i,j),
00401   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00402   ExtrapolateAndZeroFace(unsigned f, T o, T s, 
00403                   int i = BCondBaseTDMC::allComponents,
00404                   int j = BCondBaseTDMC::allComponents);
00405 
00406   // Apply the boundary condition to a given Field.
00407   virtual void apply( Field<T,D,M,C>& );
00408 
00409   // Make a copy of the concrete type.
00410   virtual BCondBase<T,D,M,C>* clone() const
00411   {
00412     return new ExtrapolateAndZeroFace<T,D,M,C>( *this );
00413   }
00414 
00415   // Print out some information about the BC to a given stream.
00416   virtual void write(ostream&) const;
00417 
00418   const T& getOffset() const { return Offset; }
00419   const T& getSlope() const { return Slope; }
00420 
00421 protected:
00422   T Offset, Slope;
00423 };
00424 
00425 
00427 
00428 template<class T,
00429          unsigned D, 
00430          class M=UniformCartesian<D,double>, 
00431          class C=typename M::DefaultCentering>
00432 class PosReflectFace : public ExtrapolateFace<T,D,M,C>
00433 {
00434 public: 
00435   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00436   PosReflectFace(unsigned f,
00437                  int i = BCondBaseTDMC::allComponents,
00438                  int j = BCondBaseTDMC::allComponents)
00439     : ExtrapolateFace<T,D,M,C>(f,0,1,i,j) {}
00440 
00441   // Print out information about the BC to a stream.
00442   virtual void write(ostream& out) const;
00443 };
00444 
00446 
00447 template<class T,
00448          unsigned D, 
00449          class M=UniformCartesian<D,double>, 
00450          class C=typename M::DefaultCentering>
00451 class NegReflectFace : public ExtrapolateFace<T,D,M,C>
00452 {
00453 public: 
00454   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00455   NegReflectFace(unsigned f,
00456                  int i = BCondBaseTDMC::allComponents,
00457                  int j = BCondBaseTDMC::allComponents)
00458     : ExtrapolateFace<T,D,M,C>(f,0,-1,i,j) {}
00459 
00460   // Print out information about the BC to a stream.
00461   virtual void write(ostream& out) const;
00462 };
00463 
00465 
00466 // TJW added 12/16/1997 as per Tecolote team's request: this one sets last
00467 // physical element layer to zero for vert-centered elements/components. For
00468 // cell-centered, doesn't need to do this because the zero point of an odd
00469 // function is halfway between the last physical element and the first guard
00470 // element.
00471 
00472 template<class T,
00473          unsigned D, 
00474          class M=UniformCartesian<D,double>, 
00475          class C=typename M::DefaultCentering>
00476 class NegReflectAndZeroFace : public ExtrapolateAndZeroFace<T,D,M,C>
00477 {
00478 public: 
00479   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00480   NegReflectAndZeroFace(unsigned f,
00481                         int i = BCondBaseTDMC::allComponents,
00482                         int j = BCondBaseTDMC::allComponents)
00483     : ExtrapolateAndZeroFace<T,D,M,C>(f,0,-1,i,j) {}
00484 
00485   // Print out information about the BC to a stream.
00486   virtual void write(ostream& out) const;
00487 };
00488 
00490 
00491 template<class T,
00492          unsigned D, 
00493          class M=UniformCartesian<D,double>, 
00494          class C=typename M::DefaultCentering>
00495 class ConstantFace : public ExtrapolateFace<T,D,M,C>
00496 {
00497 public: 
00498   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00499   ConstantFace(unsigned f, T c,
00500                int i = BCondBaseTDMC::allComponents,
00501                int j = BCondBaseTDMC::allComponents)
00502     : ExtrapolateFace<T,D,M,C>(f,c,0,i,j) {}
00503 
00504   // Print out information about the BC to a stream.
00505   virtual void write(ostream& out) const;
00506 };
00507 
00509 
00510 template<class T,
00511          unsigned D, 
00512          class M=UniformCartesian<D,double>, 
00513          class C=typename M::DefaultCentering>
00514 class ZeroFace : public ExtrapolateFace<T,D,M,C>
00515 {
00516 public: 
00517   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00518   ZeroFace(unsigned f,
00519            int i = BCondBaseTDMC::allComponents,
00520            int j = BCondBaseTDMC::allComponents)
00521     : ExtrapolateFace<T,D,M,C>(f,0,0,i,j) {}
00522 
00523   // Print out information about the BC to a stream.
00524   virtual void write(ostream& out) const;
00525 };
00526 
00528 
00529 // TJW added 1/25/1998 as per Blanca's (Don Marshal's, for the Lagrangian
00530 // code) request: this one sets last physical element layer to zero for
00531 // vert-centered elements/components. For cell-centered, doesn't need to do
00532 // this because the zero point of an odd function is halfway between the last
00533 // physical element and the first guard element.
00534 
00535 template<class T,
00536          unsigned D, 
00537          class M=UniformCartesian<D,double>, 
00538          class C=typename M::DefaultCentering>
00539 class ZeroGuardsAndZeroFace : public ExtrapolateAndZeroFace<T,D,M,C>
00540 {
00541 public: 
00542   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00543   ZeroGuardsAndZeroFace(unsigned f,
00544                         int i = BCondBaseTDMC::allComponents,
00545                         int j = BCondBaseTDMC::allComponents)
00546     : ExtrapolateAndZeroFace<T,D,M,C>(f,0,0,i,j) {}
00547 
00548   // Print out information about the BC to a stream.
00549   virtual void write(ostream& out) const;
00550 };
00551 
00553 
00554 //-----------------------------------------------------------------------------
00555 // Had to depart from the paradigm of the other boundary condition types to
00556 // implement FunctionFace. Couldn't use the same single FunctionFace class for
00557 // both whole-Field-element and componentwise functions, because the return 
00558 // of the user-provided function has to be different for the two cases. 
00559 // Instead, left FunctionFace as whole-element-only (no component specification
00560 // allowed) and introduced new ComponentFunctionFace for componentwise, 
00561 // disallowing via runtime error the allComponents specification allowed in all
00562 // the other BC types. --Tim Williams 3/31/1997
00563 //-----------------------------------------------------------------------------
00564 
00565 template<class T,
00566          unsigned D, 
00567          class M=UniformCartesian<D,double>, 
00568          class C=typename M::DefaultCentering>
00569 class FunctionFace : public BCondBase<T,D,M,C>
00570 {
00571 public: 
00572   // Constructor does *not* allow extra one or two arguments specifying
00573   // components of multicomponent types, as PeriodicFace and all other BC types
00574   // here do; user must use ComponentFunctionFace for these cases. This
00575   // constructor only takes the takes arguments for the user-supplied function
00576   // and for the active face on the mesh to which this BC applies. The function
00577   // must have return type T (can't return single components; must use the
00578   // other class ComponentFunctionFace to do this):
00579   FunctionFace(T (*func)(const T&), unsigned face);
00580 
00581   void apply( Field<T,D,M,C>& );
00582 
00583   BCondBase<T,D,M,C>* clone() const
00584   {
00585     return new FunctionFace<T,D,M,C>( *this );
00586   }
00587   // See comments in BCondBase class definition regarding convert_type() --TJW
00588   //  BCondBase<int,D,M,C>* convert_type(int) const
00589   //  {
00590   //    assert(false);
00591   //    return 0;
00592   //  }
00593 
00594   // Print out information about the BC to a stream.
00595   virtual void write(ostream& out) const;
00596 
00597   // tjw 3/12/1999: see below
00598   T (*Func)(const T&);
00599 
00600 private:
00601   // tjw 3/12/1999; had to make this public for test/simple/bc2.cpp to work:
00602   //  T (*Func)(T&);
00603 };
00604 
00606 
00607 template<class T,
00608          unsigned D, 
00609          class M=UniformCartesian<D,double>, 
00610          class C=typename M::DefaultCentering>
00611 class ComponentFunctionFace : public BCondBase<T,D,M,C>
00612 {
00613 public: 
00614   // In addition to arguments for FunctionFace, this constructor takes
00615   // one, or two unsigned's specifying components of multicomponent types like 
00616   // Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00617   // One unsigned means apply to component (i), and two means apply to 
00618   // component (i,j). Note: unlike all other non-FunctionFace BC types here,
00619   // you *can't* specify nothing or BCondBase<T,D,M,C>::allComponents to 
00620   // indicate all components; you *must* use FunctionFace class for doing
00621   // all components. 
00622   // ComponentFunctionFace() will give a runtime error if you try to construct
00623   // it for all components (which it defaults to, meaning the default is a
00624   // runtime error, which should probably be changed some time if somebody can
00625   // figure out how). This is not as bad as you might think, though; most 
00626   // likely the user would be specifying T as the return type of his supplied
00627   // function when he is trying to do the all-component case, in which he'd
00628   // get a compile error on the type of the constructor argument Func.
00629   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00630   ComponentFunctionFace(typename ApplyToComponentType<T>::type 
00631                         (*func)( typename ApplyToComponentType<T>::type), 
00632                         unsigned face,
00633                         int i = BCondBaseTDMC::allComponents,
00634                         int j = BCondBaseTDMC::allComponents);
00635 
00636   void apply( Field<T,D,M,C>& );
00637 
00638   BCondBase<T,D,M,C>* clone() const
00639   {
00640     return new ComponentFunctionFace<T,D,M,C>( *this );
00641   }
00642   // See comments in BCondBase class definition regarding convert_type() --TJW
00643   //  BCondBase<int,D,M,C>* convert_type(int) const
00644   //  {
00645   //    assert(false);
00646   //    return 0;
00647   //  }
00648 
00649   // Print out information about the BC to a stream.
00650   virtual void write(ostream& out) const;
00651 
00652   // tjw 3/12/1999: see below
00653   typename ApplyToComponentType<T>::type 
00654     (*Func)( typename ApplyToComponentType<T>::type );
00655 
00656 private:
00657   // tjw 3/12/1999; had to make this public for test/simple/bc2.cpp to work:
00658   //  typename ApplyToComponentType<T>::type 
00659   //  (*Func)( typename ApplyToComponentType<T>::type );
00660 };
00661 
00663 
00664 /*
00665   Special for Conejo: The Eureka boundary condition.
00666   
00667   This is an augmented zero boundary condition which sets
00668   more locations to zero for some cases.
00669   
00670   Instead of setting just the guard layers to zero, it sets the guard 
00671   layers plus one to zero in all cases except one:
00672   Face centered data (which as all but one dimension cell centered), 
00673   on the directions in which it is cell centered.  
00674   
00675 */
00676 
00677 template<class T,
00678          unsigned D, 
00679          class M=UniformCartesian<D,double>, 
00680          class C=typename M::DefaultCentering>
00681 class EurekaFace : public BCondBase<T,D,M,C>
00682 {
00683 public:
00684   // Constructor takes:
00685   // face: the face to apply the boundary condition on.
00686   // i,j : what component of T to apply the boundary condition to.
00687   // The components default to setting all components.
00688   // All it has to do is tell the base class to set itself up.
00689   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00690   EurekaFace(unsigned int face,
00691              int i = BCondBaseTDMC::allComponents,
00692              int j = BCondBaseTDMC::allComponents)
00693     : BCondBase<T,D,M,C>(face,i,j) { BCondBase<T,D,M,C>::m_changePhysical = true; }
00694 
00695   // Apply the boundary condition to a given Field.
00696   virtual void apply( Field<T,D,M,C>& ) ;
00697 
00698   // Make a copy of one of these.
00699   BCondBase<T,D,M,C>* clone() const
00700   {
00701     return new EurekaFace<T,D,M,C>(*this);
00702   }
00703 
00704   // Print out information about the BC to a stream.
00705   virtual void write(ostream& out) const;
00706 
00707 };         
00708 
00710 
00711 // ----------------------------------------------------------------------------
00712 // TJW added 1/26/1998 as per Blanca's (Jerry Brock's, for the tracer particle
00713 // code) request: this one takes the values of the last two physical elements,
00714 // and linearly extrapolates from the line through them out to all the guard
00715 // elements. This is independent of centering. The intended use is for filling
00716 // global guard layers of a Field of Vektors holding the mesh node position
00717 // values, for which this does the right thing at hi and lo faces (exactly
00718 // right for uniform cartesian meshes, and a reasonable thing to do for
00719 // nonuniform cartesian meshes).
00720 // 
00721 // Had to depart from the paradigm of the other boundary condition types to
00722 // implement LinearExtrapolateFace. Couldn't use the same single
00723 // LinearExtrapolateFace class for both whole-Field-element and componentwise
00724 // functions, because I couldn't figure out how to implement it using PETE and
00725 // applicative templates.  Instead, created LinearExtrapolateFace as
00726 // whole-element-only (no component specification allowed) and separate
00727 // ComponentLinearExtrapolateFace for componentwise, disallowing via runtime
00728 // error the allComponents specification allowed in all the other BC
00729 // types. --Tim Williams 1/26/1999
00730 // ----------------------------------------------------------------------------
00731 
00732 template<class T,
00733          unsigned D, 
00734          class M=UniformCartesian<D,double>, 
00735          class C=typename M::DefaultCentering>
00736 class LinearExtrapolateFace : public BCondBase<T,D,M,C>
00737 {
00738 public:
00739   // Constructor takes zero, one, or two int's specifying components of 
00740   // multicomponent types like Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00741   // Zero int's specified means apply to all components; one means apply to
00742   // component (i), and two means apply to component (i,j),
00743   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00744   LinearExtrapolateFace(unsigned f) :
00745     BCondBase<T,D,M,C>(f) {}
00746 
00747   // Apply the boundary condition to a given Field.
00748   virtual void apply( Field<T,D,M,C> &A);
00749 
00750   // Make a copy of the concrete type.
00751   virtual BCondBase<T,D,M,C>* clone() const
00752   {
00753     return new LinearExtrapolateFace<T,D,M,C>( *this );
00754   }
00755 
00756   // Print out some information about the BC to a given stream.
00757   virtual void write(ostream&) const;
00758 
00759 };
00760 
00761 
00762 template<class T,
00763          unsigned D, 
00764          class M=UniformCartesian<D,double>, 
00765          class C=typename M::DefaultCentering>
00766 class ComponentLinearExtrapolateFace : public BCondBase<T,D,M,C>
00767 {
00768 public:
00769   // Constructor takes zero, one, or two int's specifying components of 
00770   // multicomponent types like Vektor/Tenzor/Anti/SymTenzor this BC applies to.
00771   // Zero int's specified means apply to all components; one means apply to
00772   // component (i), and two means apply to component (i,j),
00773   typedef BCondBase<T,D,M,C> BCondBaseTDMC;
00774   ComponentLinearExtrapolateFace(unsigned f,
00775                         int i = BCondBaseTDMC::allComponents,
00776                         int j = BCondBaseTDMC::allComponents) :
00777     BCondBase<T,D,M,C>(f,i,j) {
00778       // Disallow specification of all components (default, unfortunately):
00779       if ( (j == BCondBase<T,D,M,C>::allComponents) &&
00780            (i == BCondBase<T,D,M,C>::allComponents) )
00781         ERRORMSG("ComponentLinearExtrapolateFace(): allComponents specified; "
00782                  << "not allowed; use LinearExtrapolateFace "
00783                  << "class instead." << endl);
00784   }
00785 
00786   // Apply the boundary condition to a given Field.
00787   virtual void apply( Field<T,D,M,C> &A);
00788 
00789   // Make a copy of the concrete type.
00790   virtual BCondBase<T,D,M,C>* clone() const
00791   {
00792     return new ComponentLinearExtrapolateFace<T,D,M,C>( *this );
00793   }
00794 
00795   // Print out some information about the BC to a given stream.
00796   virtual void write(ostream&) const;
00797 
00798 };
00799 
00800 
00802 
00803 template<class T,
00804          unsigned D, 
00805          class M=UniformCartesian<D,double>, 
00806          class C=typename M::DefaultCentering>
00807 class PatchBC : public BCondBase<T,D,M,C>
00808 {
00809 public: 
00810 
00811   //
00812   // Initialize with a functor and the face to apply that functor to.
00813   //
00814   PatchBC(unsigned face);
00815 
00816   //
00817   // Virtual function to apply this BC to a Field.
00818   //
00819   void apply( Field<T,D,M,C>& );
00820 
00821   //
00822   // Virtual function for the user to supply to apply this BC to
00823   // a given vnode.
00824   //
00825   virtual void applyPatch(typename Field<T,D,M,C>::iterator,
00826                           const NDIndex<D>&) = 0;
00827 
00828   //
00829   // Print out information about the BC to a stream.
00830   //
00831   virtual void write(ostream& out) const
00832     {
00833         out << "PatchBC(" << this->getFace() << ")";
00834     }
00835 
00836 private:
00837 
00838 };
00839 
00841 
00842 //
00843 // Define global streaming functions that just call the
00844 // write function for each of the above base classes.
00845 //
00846 
00847 template<class T, unsigned D, class M, class C >
00848 inline ostream&
00849 operator<<(ostream& o, const BCondBase<T,D,M,C>& bc)
00850 {
00851   bc.write(o);
00852   return o;
00853 }
00854 
00855 
00856 template<class T, unsigned D, class M, class C >
00857 inline ostream&
00858 operator<<(ostream& o, const BConds<T,D,M,C>& bc)
00859 {
00860   bc.write(o);
00861   return o;
00862 }
00863 
00865 
00866 #include "Field/BCond.cpp"
00867 
00868 #endif // BCOND_H
00869 
00870 /***************************************************************************
00871  * $RCSfile: BCond.h,v $   $Author: adelmann $
00872  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:26 $
00873  * IPPL_VERSION_ID: $Id: BCond.h,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $ 
00874  ***************************************************************************/

Generated on Mon Jan 16 13:23:44 2006 for IPPL by  doxygen 1.4.6