// ********** DO NOT REMOVE THIS BANNER ********** // ORIG-DATE: Jan 2008 // -*- Mode : c++ -*- // // SUMMARY : Generic Fiinite Element header 1d, 2d, 3d // USAGE : LGPL // ORG : LJLL Universite Pierre et Marie Curi, Paris, FRANCE // AUTHOR : Frederic Hecht // E-MAIL : frederic.hecht@ann.jussieu.fr // /* This file is part of Freefem++ Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Freefem++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Thank to the ARN () FF2A3 grant ref:ANR-07-CIS7-002-01 */ #ifndef FESpacen_HPP_ #define FESpacen_HPP_ /* * FEspacen.hpp * EF23n * * Created by Frédéric Hecht on 04/12/07. * Copyright 2007 Universite Pierre et marie Curie All rights reserved. * */ #include #include #include #include #include #include #include using namespace std; #include "error.hpp" #include "ufunction.hpp" #include "MeshLn.hpp" #include "MeshSn.hpp" #include "Mesh3dn.hpp" #include "Mesh2dn.hpp" #include "Mesh1dn.hpp" #include "RNM.hpp" #include "QuadratureFormular.hpp" namespace Fem2D { template class GFESpace; template class GFElement; template class GbaseFElement; template class GTypeOfFE; // numbering of derivative enum operatortype { op_id=0, op_dx=1,op_dy=2, op_dxx=3,op_dyy=4, op_dyx=5,op_dxy=5, op_dz=6, op_dzz=7, op_dzx=8,op_dxz=8, op_dzy=9,op_dyz=9 }; typedef unsigned int What_d; const unsigned int Fop_id= 1<< op_id; const unsigned int Fop_dx= 1<< op_dx; const unsigned int Fop_dy= 1<< op_dy; const unsigned int Fop_dz= 1<< op_dz; const unsigned int Fop_dxx= 1<< op_dxx; const unsigned int Fop_dxy= 1<< op_dxy; const unsigned int Fop_dxz= 1<< op_dxz; const unsigned int Fop_dyx= 1<< op_dyx; const unsigned int Fop_dyy= 1<< op_dyy; const unsigned int Fop_dyz= 1<< op_dyz; const unsigned int Fop_dzx= 1<< op_dzx; const unsigned int Fop_dzy= 1<< op_dzy; const unsigned int Fop_dzz= 1<< op_dzz; const unsigned int Fop_D0 = Fop_id; const unsigned int Fop_D1 = Fop_dx | Fop_dy | Fop_dz; const unsigned int Fop_D2 = Fop_dxx | Fop_dyy | Fop_dzz | Fop_dxy | Fop_dxz | Fop_dyz; const unsigned int Fop_Dall = Fop_D0| Fop_D1| Fop_D2; inline What_d Fwhatd(const operatortype op) { return 1<< op;} const int last_operatortype=10; const bool operatortypeValue[last_operatortype]= {true,false,false,false,false,false,false,false,false,false} ; inline void initwhatd(bool *whatd,int k) { for (int i=0;i RN_; typedef KN RN; typedef KNM_ RNM_; typedef KNMK_ RNMK_; typedef KNMK RNMK; template class GFElement; template class GFESpace; templateclass GTypeOfFE ; class dataTypeOfFE { private: const int * data; const int * dataalloc; public: const int ndfonVertex; const int ndfonEdge; const int ndfonFace; const int ndfonVolume; const int NbDoF; const int NbNode; int N,nb_sub_fem; const int nbsubdivision; // nb of subdivision for plot const bool discontinue; int const * const DFOnWhat; int const * const DFOfNode; // nu du df on Node int const * const NodeOfDF; // nu du node du df int const * const fromFE; // the df come from df of FE int const * const fromDF; // the df come from with FE int const * const fromASubFE; // avril 2006 for CL int const * const fromASubDF; // avril 2006 for CL int const * const dim_which_sub_fem; // from atomic sub FE for CL const int * ndfOn() const { return & ndfonVertex;} dataTypeOfFE(const int *nnitemdim,const int dfon[4],int NN,int nbsubdivisionn,int nb_sub_femm=1,bool discon=true); // pour evite un template // nitemdim : nbitem : si d==2 3,3,1,0 , si d=3: 4,6,4,1 , si d==1 = 2,1,0,0 // dfon : nombre de df par item // NN dataTypeOfFE(const int nitemdim[4],const KN< dataTypeOfFE const *> & tef); virtual ~dataTypeOfFE(){ if(dataalloc) delete [] dataalloc;} }; template class InterpolationMatrix { public: const int N,np,ncoef; bool invariant; int k; KN P; KN coef; KN comp; KN p; KN dofe; template InterpolationMatrix(const GFESpace &Vh); template InterpolationMatrix(const GTypeOfFE & tef); template void set(const GFElement & FK); private: // copie interdit ... InterpolationMatrix(const InterpolationMatrix &); void operator=(const InterpolationMatrix &); }; template ostream & operator<<(ostream& f,const InterpolationMatrix &M) { f<< M.N << " "<< M.k << " "<< M.np << " "<< M.ncoef << endl; f<< " = " << M.P ; f << "coef=" <& U,const KN_& Viso,int j=0,float *colors=0,int nbcolors=0,bool hsv=true,bool drawborder=true) const ; // Draw iso line void Drawfill(const KN_& U,const KN_& Viso,int j=0,double rapz=1,float *colors=0,int nbcolors=0,bool hsv=true,bool drawborder=true) const ; // Draw iso line void Draw(const KN_& U,const KN_ & Viso, R coef,int j0=0,int j1=1,float *colors=0,int nbcolors=0,bool hsv=true,bool drawborder=true) const ; // Arrow void Draw(const KN_& U,const KN_& V,const KN_ & Viso, R coef,int iu=0,int iv=0,float *colors=0,int nbcolors=0,bool hsv=true,bool drawborder=true) const ; // Arrow Rd MinMax(const KN_& U,const KN_& V,int j0,int j1,bool bb=true) const ; Rd MinMax(const KN_& U,int j0, bool bb=true) const ; // void destroy() {RefCounter::destroy();} */ bool isFEMesh() const { return ! NodesOfElement && ( N==1) ;} // to make optim template KN newSaveDraw(const KN_ & U,int composante,int & lg,KN &Psub,KN &Ksub,int op_U=0) const ; private: // for gibbs int gibbsv (long* ptvoi,long* vois,long* lvois,long* w,long* v); }; template inline GbaseFElement::GbaseFElement( const GFESpace &aVh, int k) : Vh(aVh),T(Vh.Th[k]),tfe(aVh.TFE[k]),N(aVh.N),number(k){} template inline GbaseFElement::GbaseFElement(const GbaseFElement & K, const GTypeOfFE & atfe) : Vh(K.Vh),T(K.T),tfe(&atfe),N(Vh.N),number(K.number){} template GFElement::GFElement(const GFESpace * VVh,int k) : GbaseFElement(*VVh,k) , p(this->Vh.PtrFirstNodeOfElement(k)), nb(this->Vh.NbOfNodesInElement(k)) {} template inline int GFElement::operator[](int i) const { return p ? p[i] : ((&this->T[i])-this->Vh.Th.vertices);} template inline int GFElement::operator()(int i,int df) const { return this->Vh.FirstDFOfNode(p ? p[i] : ((&this->T[i])-this->Vh.Th.vertices)) + df;} template inline int GFElement::NbDoF(int i) const { int node =p ? p[i] : ((&this->T[i])-this->Vh.Th.vertices); return this->Vh.LastDFOfNode(node)-this->Vh.FirstDFOfNode(node);} template inline void GFElement::BF(const RdHat & PHat,RNMK_ & val) const { this->tfe->FB(Fop_D0|Fop_D1,this->Vh.Th,this->T,PHat,val);} template inline void GFElement::BF(const What_d whatd,const RdHat & PHat,RNMK_ & val) const { this->tfe->FB(whatd,this->Vh.Th,this->T,PHat,val);} //template // inline void GFElement::set(InterpolationMatrix &M) const { this->tfe->set(this->Vh.Th,this->T,&M);} template inline R GFElement::operator()(const RdHat & PHat, const KN_ & u,int i,int op) const { return (*this->tfe)(*this,PHat,u,i,op); } template inline complex GFElement::operator()(const RdHat & PHat,const KN_ > & u,int i,int op) const { complex * pu=u; // pointeur du tableau double *pr = static_cast(static_cast(pu)); const KN_ ur(pr,u.n,u.step*2); const KN_ ui(pr+1,u.n,u.step*2); return complex((*this->tfe)(*this,PHat,ur,i,op),(*this->tfe)(*this,PHat,ui,i,op)); } template R GTypeOfFE::operator()(const GFElement & K,const RdHat & PHat,const KN_ & u,int componante,int op) const { KNMK fb(NbDoF,N,last_operatortype); // the value for basic fonction KN fk(NbDoF); for (int i=0;i class GTypeOfFESum: public GTypeOfFE { public: typedef GFElement FElement; typedef typename Mesh::Element Element; typedef typename Element::RdHat RdHat; typedef typename Mesh::Rd Rd; const int k; KN *> teb; KN NN,DF,comp,numPtInterpolation; GTypeOfFESum(const KN< GTypeOfFE const *> & t); GTypeOfFESum(const GFESpace **,int kk); GTypeOfFESum(const GFESpace &,int kk); void Build(); // the true constructor void init(InterpolationMatrix & M,FElement * pK=0,int odf=0,int ocomp=0,int *pp=0) const; void set(const Mesh & Th,const Element & K,InterpolationMatrix & M,int ocoef,int odf,int *nump ) const; // no change by deflaut void FB(const What_d whatd,const Mesh & Th,const Element & K,const RdHat &PHat, KNMK_ & val) const ; ~GTypeOfFESum(){} } ; template void GTypeOfFESum::FB(const What_d whatd,const Mesh & Th,const Element & K,const RdHat &PHat, KNMK_ & val) const { val=0.0; SubArray t(val.K()); for (int i=0;iFB(whatd,Th,K,PHat,v); else v=val(SubArray(DF[j+1]-DF[j],DF[j]),SubArray(NN[j+1]-NN[j],NN[j]),t); } } template template InterpolationMatrix::InterpolationMatrix(const GFESpace &Vh) : N(Vh.N),np(Vh.maxNbPtforInterpolation),ncoef(Vh.maxNbcoefforInterpolation), invariant(Vh.TFE.constant() ? Vh.TFE[0]->invariantinterpolationMatrix: false), k(-1), P(np), comp(ncoef), p(ncoef), dofe(ncoef) { Vh.TFE[0]->GTypeOfFE::init(*this,0,0,0,0); } template template InterpolationMatrix::InterpolationMatrix(const GTypeOfFE & tef) : N(tef.N),np(tef.NbPtforInterpolation),ncoef(tef.NbcoefforInterpolation), invariant(tef.invariantinterpolationMatrix), k(-1), P(np), comp(ncoef), p(ncoef), dofe(ncoef) { // virtual void init(InterpolationMatrix & M,FElement * pK=0,int odf=0,int ocomp=0,int *pp=0) const tef.GTypeOfFE::init(*this,0,0,0,0); } template template void InterpolationMatrix::set(const GFElement & FK) { if(k==FK.number) return; k=FK.number; if(invariant) return; FK.set(*this); //assert(invariant); // a faire ... } typedef GTypeOfFE TypeOfFE3; typedef GTypeOfFE TypeOfFES; typedef GTypeOfFE TypeOfFEL; typedef GFESpace FESpace3; typedef GFESpace FESpaceS; typedef GFESpace FESpaceL; typedef GFESpace FESpace2; typedef GFElement FElementL; typedef GFElement FElement3; typedef GFElement FElementS; typedef GFElement FElement2; typedef GbaseFElement baseFElement2; typedef GbaseFElement baseFElement3; typedef GbaseFElement baseFElementS; typedef GbaseFElement baseFElementL; } #endif