SundanceBasisFamily.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef SUNDANCE_BASISFAMILY_H
00043 #define SUNDANCE_BASISFAMILY_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "SundanceBasisFamilyBase.hpp"
00047 #include "SundanceOrderedHandle.hpp"
00048 #include "Teuchos_Array.hpp"
00049 
00050 namespace Sundance
00051 {
00052 using Teuchos::XMLObject;
00053 using Teuchos::tuple;
00054 using Teuchos::Array;
00055 
00056 class CommonFuncDataStub;
00057 
00058 /** 
00059  * BasisFamily is the user-level handle class for specifying the basis with
00060  * which a test, unknown, or discrete function is represented.  Basis
00061  * functions can be vector-valued, as is the case with, for example, the
00062  * Nedelec basis in electromagnetics; the dim() method returns the spatial
00063  * dimension of the basis functions. Scalar-valued bases naturally have
00064  * dim()=1.
00065 
00066 */
00067 class BasisFamily : public OrderedHandle<BasisFamilyBase>
00068 {
00069 public:
00070   /* handle ctor boilerplate */
00071   ORDERED_HANDLE_CTORS(BasisFamily, BasisFamilyBase);
00072 
00073   /** write to XML */
00074   XMLObject toXML() const ;
00075 
00076   /** 
00077    * \brief Return the polynomial order of the basis functions, for use in
00078    * determining the quadrature rule required to integrate a product of
00079    * basis functions exactly. The polynomial order will be the smallest
00080    * integer for which all mixed partial derivatives vanish exactly.
00081    *  
00082    * Note: in H(div) and H(curl) spaces the order of accuracy is not
00083    * always an integer, and the relationship between the order of accuracy
00084    * and the return value of the order() method is not necessarily simple
00085    * (for instance, it can depend on things such as the convexity of the
00086    * boundary). Thus it is better to think of this method as specifying
00087    * the required order of quadrature, and not the order of accuracy of
00088    * approximation nor the order to which the space is complete.
00089    */
00090   int order() const ;
00091 
00092   /** \brief
00093    * Return the number of DOFs for this basis on the given 
00094    * reference cell type, including its facets.
00095    */
00096   int nReferenceDOFsWithFacets(const CellType& maximalCellType,
00097     const CellType& cellType) const ;
00098 
00099   /** \brief
00100    * Return the number of DOFs for this basis on the given 
00101    * reference cell type, not including those on facets.
00102    */
00103   int nReferenceDOFsWithoutFacets(const CellType& maximalCellType,
00104     const CellType& cellType) const ;
00105 
00106   /** 
00107    * \brief Return the dimension of the members of 
00108    * a vector-valued basis. Return 1 if the basis
00109    * is scalar-valued. Otherwise, return the spatial dimension.
00110    */
00111   int dim() const ;
00112 
00113   /** 
00114    * \brief Return the tensor order of the members of 
00115    * a basis.
00116    */
00117   int tensorOrder() const {return ptr()->tensorOrder();}
00118 
00119   /** */
00120   bool operator==(const BasisFamily& other) const ;
00121 
00122   
00123 
00124   /** \brief Inform caller as to whether I am a scalar basis. */
00125   bool isScalarBasis() const {return ptr()->isScalarBasis();}
00126 
00127   /** \brief Inform caller as to whether I am an H(div) basis. */
00128   bool isHDivBasis() const {return ptr()->isHDivBasis();}
00129 
00130   /** \brief Inform caller as to whether I am an H(curl) basis. */
00131   bool isHCurlBasis() const {return ptr()->isHCurlBasis();}
00132 
00133   /** Sum up the dim() values for array of bases. */
00134   static int size(const Array<BasisFamily>& b) ;
00135 
00136   /** Extract the basis from an expression */
00137   static BasisFamily getBasis(const RCP<const CommonFuncDataStub>& funcData);
00138 
00139   /** Extract the basis from an expression */
00140   static RCP<BasisDOFTopologyBase> getBasisTopology(const RCP<const CommonFuncDataStub>& funcData);
00141 
00142   /** */
00143   void refEval(
00144     const CellType& cellType,
00145     const Array<Point>& pts,
00146     const SpatialDerivSpecifier& deriv,
00147     Array<Array<Array<double> > >& result,
00148     int verbosity) const ;
00149 
00150   /**  */
00151   void getConstrainsForHNDoF( const int indexInParent,
00152             const int maxCellDim,
00153             const int maxNrChild,
00154             const int facetDim,
00155             const int facetIndex,
00156             const int nodeIndex,
00157             Array<int>& localDoFs,
00158             Array<int>& parentFacetDim,
00159             Array<int>& parentFacetIndex,
00160             Array<int>& parentFacetNode,
00161             Array<double>& coefs
00162             ) const;
00163 
00164 
00165 
00166   /** \brief Inform caller whether basis requires an element transformation */
00167   bool requiresBasisTransformation() const { return ptr()->requiresBasisTransformation(); }
00168 
00169 
00170   /** */
00171   virtual void preApplyTransformation( const CellType &maxCellType ,
00172                const Mesh &mesh,
00173                const Array<int> &cellLIDs,
00174                const CellJacobianBatch& JVol,
00175                RCP<Array<double> >& A
00176                ) const 
00177   { 
00178     ptr()->preApplyTransformation( maxCellType ,
00179            mesh,
00180            cellLIDs,
00181            JVol,
00182            A);
00183   }
00184   /**  */
00185   virtual void postApplyTransformation( const CellType &maxCellType ,
00186           const Mesh &mesh,
00187           const Array<int> &cellLIDs,
00188           const CellJacobianBatch& JVol,
00189           RCP<Array<double> >& A ) const
00190   {
00191     ptr()->postApplyTransformation( maxCellType ,
00192             mesh ,
00193             cellLIDs ,
00194             JVol,
00195             A);
00196   }
00197   
00198   virtual void preApplyTransformationTranspose( const CellType &maxCellType ,
00199             const Mesh &mesh,
00200             const Array<int> &cellLIDs,
00201             const CellJacobianBatch& JVol,
00202             Array<double>& A ) const
00203   {
00204     ptr()->preApplyTransformationTranspose( maxCellType ,
00205               mesh ,
00206               cellLIDs ,
00207               JVol ,
00208               A );
00209   }
00210 
00211 };
00212 
00213 /** \relates BasisFamily */
00214 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b)
00215 {
00216   return Array<BasisFamily>(tuple(a,b));
00217 }
00218 
00219 /** \relates BasisFamily */
00220 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00221   const BasisFamily& c)
00222 {
00223   return tuple(a,b,c);
00224 }
00225 
00226 /** \relates BasisFamily */
00227 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00228   const BasisFamily& c, const BasisFamily& d)
00229 {
00230   return tuple(a,b,c,d);
00231 }
00232 
00233 /** \relates BasisFamily */
00234 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00235   const BasisFamily& c, const BasisFamily& d, 
00236   const BasisFamily& e)
00237 {
00238   return tuple(a,b,c,d,e);
00239 }
00240 
00241 
00242 /** \relates BasisFamily */
00243 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00244   const BasisFamily& c, const BasisFamily& d, 
00245   const BasisFamily& e, const BasisFamily& f)
00246 {
00247   return tuple(a,b,c,d,e,f);
00248 }
00249 
00250 /** \relates BasisFamily */
00251 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00252   const BasisFamily& c, const BasisFamily& d, 
00253   const BasisFamily& e, const BasisFamily& f, 
00254   const BasisFamily& g)
00255 {
00256   return tuple(a,b,c,d,e,f,g);
00257 }
00258 
00259 /** \relates BasisFamily */
00260 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00261   const BasisFamily& c, const BasisFamily& d, 
00262   const BasisFamily& e, const BasisFamily& f, 
00263   const BasisFamily& g, const BasisFamily& h)
00264 {
00265   return tuple(a,b,c,d,e,f,g,h);
00266 }
00267 
00268 /** \relates BasisFamily */
00269 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00270   const BasisFamily& c, const BasisFamily& d, 
00271   const BasisFamily& e, const BasisFamily& f, 
00272   const BasisFamily& g, const BasisFamily& h, 
00273   const BasisFamily& i)
00274 {
00275   return tuple(a,b,c,d,e,f,g,h,i);
00276 }
00277 
00278 /** \relates BasisFamily */
00279 inline Array<BasisFamily> List(const BasisFamily& a, const BasisFamily& b,
00280   const BasisFamily& c, const BasisFamily& d, 
00281   const BasisFamily& e, const BasisFamily& f, 
00282   const BasisFamily& g, const BasisFamily& h, 
00283   const BasisFamily& i, const BasisFamily& j)
00284 {
00285   return tuple(a,b,c,d,e,f,g,h,i,j);
00286 }
00287 
00288 /** */
00289 inline Array<BasisFamily> replicate(const BasisFamily& b, int n)
00290 {
00291   Array<BasisFamily> rtn(n);
00292   for (int i=0; i<n; i++) rtn[i] = b;
00293   return rtn;
00294 }
00295 
00296 
00297 /** */
00298 inline Array<BasisFamily> replicate(const Array<BasisFamily>& b, int n)
00299 {
00300   Array<BasisFamily> rtn(n*b.size());
00301   for (int i=0; i<n*b.size(); i++) rtn[i] = b[0];
00302   return rtn;
00303 }
00304 
00305 class BasisArray : public Array<BasisFamily>
00306 {
00307 public:
00308   BasisArray() : Array<BasisFamily>() {;}
00309 
00310   BasisArray(int n) : Array<BasisFamily>(n) {;}
00311 
00312   BasisArray(const Array<BasisFamily>& a) 
00313     : Array<BasisFamily>(a) 
00314     {;}
00315 
00316 };
00317 
00318 
00319 /** \relates BasisFamily */
00320 Array<std::pair<int, int> > vectorDimStructure(const Array<BasisFamily>& basis);
00321 
00322 
00323 /** \relates BasisFamily */
00324 Array<std::pair<int, int> > vectorDimStructure(const BasisFamily& basis);
00325 
00326 
00327 /** \relates BasisFamily 
00328  * Indicate whether members of a basis have support on a boundary only
00329  * if their associated dofs live on the boundary. This will return true
00330  * for Lagrange, false for P1NC, RT, Nedelec, and most other bases. 
00331  *
00332  * This is used to simplify boundary integrals.
00333  */
00334 bool basisRestrictableToBoundary(const BasisFamily& b);
00335 
00336 
00337 }
00338 
00339 #endif

Site Contact