From d651b7cd4d79c2ba98f59e1af611eee9800fc244 Mon Sep 17 00:00:00 2001 From: Eric Bechet <eric.bechet@ulg.ac.be> Date: Thu, 10 Dec 2009 10:38:33 +0000 Subject: [PATCH] Messed up with function spaces / working example in linear elasiticity --- Solver/CMakeLists.txt | 1 + Solver/SElement.cpp | 4 +- Solver/dofManager.h | 14 +-- Solver/elasticitySolver.cpp | 170 +++++++++++++++++++++++++++++ Solver/elasticitySolver.h | 14 ++- Solver/femTerm.h | 38 +++++++ Solver/functionSpace.cpp | 14 +++ Solver/functionSpace.h | 206 +++++++++++++++++++++++++++++++----- 8 files changed, 427 insertions(+), 34 deletions(-) create mode 100644 Solver/functionSpace.cpp diff --git a/Solver/CMakeLists.txt b/Solver/CMakeLists.txt index b230ce4275..add58f8e9a 100644 --- a/Solver/CMakeLists.txt +++ b/Solver/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC function.cpp functionDerivator.cpp luaFunction.cpp + functionSpace.cpp ) file(GLOB HDR RELATIVE ${CMAKE_SOURCE_DIR}/Solver *.h) diff --git a/Solver/SElement.cpp b/Solver/SElement.cpp index 8c9edcfd34..1c7a02354f 100644 --- a/Solver/SElement.cpp +++ b/Solver/SElement.cpp @@ -42,7 +42,7 @@ void SElement::gradNodalFunctions (double u, double v, double w, double invjac[3 _e->getShapeFunctions(u, v, w, sf); // FIXME : re-use sf for computing coordinates _e->pnt(u, v, w, p); - double E = (*_enrichement_s)(p.x(), p.y(), p.z()); + double E = (*_enrichement)(p.x(), p.y(), p.z()); double dEdx, dEdy, dEdz; _enrichement_s->gradient(p.x(), p.y(), p.z(), dEdx, dEdy, dEdz); for (int i = 0; i < N; i++){ @@ -62,7 +62,7 @@ void SElement::nodalFunctions (double u, double v, double w, double s[], SPoint3 p; // FIXME : re-use s for computing coordinates _e->pnt(u, v, w, p); - double E = (*_enrichement_s)(p.x(), p.y(), p.z()); + double E = (*_enrichement)(p.x(), p.y(), p.z()); for (int i = 0; i < N; i++){ s[i] *= E; } diff --git a/Solver/dofManager.h b/Solver/dofManager.h index 45802227b5..5ffcbf3b69 100644 --- a/Solver/dofManager.h +++ b/Solver/dofManager.h @@ -23,11 +23,11 @@ class Dof{ Dof(long int entity, int type) : _entity(entity), _type(type) {} inline long int getEntity() const { return _entity; } inline int getType() const { return _type; } - static int createTypeWithTwoInts(int i1, int i2) + inline static int createTypeWithTwoInts(int i1, int i2) { return i1 + 10000 * i2; } - static void getTwoIntsFromType(int t, int &i1, int &i2) + inline static void getTwoIntsFromType(int t, int &i1, int &i2) { i1 = t % 10000; i2 = t / 10000; @@ -50,18 +50,18 @@ template<class T> struct dofTraits typedef T MatType; }; -template<> struct dofTraits<fullVector<double> > +template<class T> struct dofTraits<fullVector<T> > { - typedef fullVector<double> VecType; - typedef fullMatrix<double> MatType; + typedef fullVector<T> VecType; + typedef fullMatrix<T> MatType; }; - +/* template<> struct dofTraits<fullVector<std::complex<double> > > { typedef fullVector<std::complex<double> > VecType; typedef fullMatrix<std::complex<double> > MatType; }; - +*/ template<class T> class DofAffineConstraint{ public: diff --git a/Solver/elasticitySolver.cpp b/Solver/elasticitySolver.cpp index 4358067e65..b2f6a33203 100644 --- a/Solver/elasticitySolver.cpp +++ b/Solver/elasticitySolver.cpp @@ -13,6 +13,8 @@ #include "linearSystemPETSc.h" #include "linearSystemGMM.h" #include "Numeric.h" +#include "functionSpace.h" +#include "terms.h" #if defined(HAVE_POST) #include "PView.h" @@ -321,3 +323,171 @@ void elasticitySolver::solve() // solving lsys->systemSolve(); } + + + + +void MyelasticitySolver::solve() +{ +#if defined(HAVE_TAUCS) + linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; +#elif defined(HAVE_PETSC) + linearSystemPETSc<double> *lsys = new linearSystemPETSc<double>; +#else + linearSystemGmm<double> *lsys = new linearSystemGmm<double>; + lsys->setNoisy(2); +#endif + pAssembler = new dofManager<double>(lsys); + + std::map<int, std::vector<GEntity*> > groups[4]; + pModel->getPhysicalGroups(groups); + + // we first do all fixations. the behavior of the dofManager is to + // give priority to fixations : when a dof is fixed, it cannot be + // numbered afterwards + + for (std::map<std::pair<int, int>, double>::iterator it = nodalDisplacements.begin(); + it != nodalDisplacements.end(); ++it){ + MVertex *v = pModel->getMeshVertexByTag(it->first.first); + pAssembler->fixVertex(v, it->first.second, _tag, it->second); + printf("-- Fixing node %3d comp %1d to %8.5f\n", + it->first.first, it->first.second, it->second); + } + + for (std::map<std::pair<int, int>, double>::iterator it = edgeDisplacements.begin(); + it != edgeDisplacements.end(); ++it){ + DummyfemTerm El(pModel); + El.dirichletNodalBC(it->first.first, 1, it->first.second, _tag, + simpleFunction<double>(it->second), *pAssembler); + printf("-- Fixing edge %3d comp %1d to %8.5f\n", + it->first.first, it->first.second, it->second); + } + + for (std::map<std::pair<int, int>, double>::iterator it = faceDisplacements.begin(); + it != faceDisplacements.end(); ++it){ + DummyfemTerm El(pModel); + El.dirichletNodalBC(it->first.first, 2, it->first.second, _tag, + simpleFunction<double>(it->second), *pAssembler); + printf("-- Fixing face %3d comp %1d to %8.5f\n", + it->first.first, it->first.second, it->second); + } + + // we number the nodes : when a node is numbered, it cannot be numbered + // again with another number. so we loop over elements + for (unsigned int i = 0; i < elasticFields.size(); ++i){ + groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); + for ( ; it != elasticFields[i].g->end(); ++it){ + SElement se(*it); + for (int j = 0; j < se.getNumNodalShapeFunctions(); ++j){ + pAssembler->numberVertex(se.getVertex(j), 0, elasticFields[i]._tag); + pAssembler->numberVertex(se.getVertex(j), 1, elasticFields[i]._tag); + pAssembler->numberVertex(se.getVertex(j), 2, elasticFields[i]._tag); + } + } + } + + // Now we start the assembly process + // First build the force vector + // Nodes at geometrical vertices + for (std::map<int, SVector3 >::iterator it = nodalForces.begin(); + it != nodalForces.end(); ++it){ + int iVertex = it->first; + SVector3 f = it->second; + std::vector<GEntity*> ent = groups[0][iVertex]; + for (unsigned int i = 0; i < ent.size(); i++){ + pAssembler->assemble(ent[i]->mesh_vertices[0], 0, _tag, f.x()); + pAssembler->assemble(ent[i]->mesh_vertices[0], 1, _tag, f.y()); + pAssembler->assemble(ent[i]->mesh_vertices[0], 2, _tag, f.z()); + printf("-- Force on node %3d(%3d) : %8.5f %8.5f %8.5f\n", + ent[i]->mesh_vertices[0]->getNum(), iVertex, f.x(), f.y(), f.z()); + } + } + + // line forces + for (std::map<int, SVector3 >::iterator it = lineForces.begin(); + it != lineForces.end(); ++it){ + DummyfemTerm El(pModel); + int iEdge = it->first; + SVector3 f = it->second; + El.neumannNodalBC(iEdge, 1, 0, _tag, simpleFunction<double>(f.x()), *pAssembler); + El.neumannNodalBC(iEdge, 1, 1, _tag, simpleFunction<double>(f.y()), *pAssembler); + El.neumannNodalBC(iEdge, 1, 2, _tag, simpleFunction<double>(f.z()), *pAssembler); + printf("-- Force on edge %3d : %8.5f %8.5f %8.5f\n", iEdge, f.x(), f.y(), f.z()); + } + + // face forces + for (std::map<int, SVector3 >::iterator it = faceForces.begin(); + it != faceForces.end(); ++it){ + DummyfemTerm El(pModel); + int iFace = it->first; + SVector3 f = it->second; + El.neumannNodalBC(iFace, 2, 0, _tag, simpleFunction<double>(f.x()), *pAssembler); + El.neumannNodalBC(iFace, 2, 1, _tag, simpleFunction<double>(f.y()), *pAssembler); + El.neumannNodalBC(iFace, 2, 2, _tag, simpleFunction<double>(f.z()), *pAssembler); + printf("-- Force on face %3d : %8.5f %8.5f %8.5f\n", iFace, f.x(), f.y(), f.z()); + } + + // volume forces + for (std::map<int, SVector3 >::iterator it = volumeForces.begin(); + it != volumeForces.end(); ++it){ + DummyfemTerm El(pModel); + int iVolume = it->first; + SVector3 f = it->second; +// El.setVector(f); + printf("-- Force on volume %3d : %8.5f %8.5f %8.5f\n", iVolume, f.x(), f.y(), f.z()); + std::vector<GEntity*> ent = groups[_dim][iVolume]; + for (unsigned int i = 0; i < ent.size(); i++){ + // to do + // El.addToRightHandSide(*pAssembler, ent[i]); + } + } + + // assembling the stifness matrix + for (unsigned int i = 0; i < elasticFields.size(); i++){ + SElement::setShapeEnrichement(elasticFields[i]._enrichment); + for (unsigned int j = 0; j < elasticFields.size(); j++){ + elasticityTerm El(0, elasticFields[i]._E, elasticFields[i]._nu, + elasticFields[i]._tag, elasticFields[j]._tag); + SElement::setTestEnrichement(elasticFields[j]._enrichment); + // printf("%d %d\n",elasticFields[i]._tag,elasticFields[j]._tag); + El.addToMatrix(*pAssembler, *elasticFields[i].g, *elasticFields[j].g); + } + } + +/* VectorLagrangeFunctionSpace L1(Dof::createTypeWithTwoInts(0,_tag),VectorLagrangeFunctionSpace::VECTOR_X); + VectorLagrangeFunctionSpace L2(Dof::createTypeWithTwoInts(1,_tag),VectorLagrangeFunctionSpace::VECTOR_Y); + VectorLagrangeFunctionSpace L3(Dof::createTypeWithTwoInts(2,_tag),VectorLagrangeFunctionSpace::VECTOR_Z); + CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType> P123(L1,L2,L3);*/ + VectorLagrangeFunctionSpace P123(_tag,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y); + + for (unsigned int i = 0; i < elasticFields.size(); i++) + { + DummyfemTerm El(pModel); +// ElasticTerm<CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType>,CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType> > Eterm(P123,elasticFields[i]._E,elasticFields[i]._nu); + ElasticTerm<VectorLagrangeFunctionSpace,VectorLagrangeFunctionSpace> Eterm(P123,elasticFields[i]._E,elasticFields[i]._nu); + fullMatrix<double> localMatrix(12,12); + std::vector<Dof> R;R.reserve(100); + for ( groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end() ; ++it) + { + MElement *e = *it; + R.clear(); + int integrationOrder = 3 * (e->getPolynomialOrder() - 1) ; + int npts=0; + IntPt *GP; + e->getIntegrationPoints(integrationOrder, &npts, &GP); + Eterm.get(e,npts,GP,localMatrix); + El.addToMatrix(*pAssembler,localMatrix,R); + } + } + + printf("-- done assembling!\n"); + // for (int i=0;i<pAssembler->sizeOfR();i++){ + // printf("%g ",lsys->getFromRightHandSide(i)); + // } + // printf("\n"); + + // solving + lsys->systemSolve(); +} + + diff --git a/Solver/elasticitySolver.h b/Solver/elasticitySolver.h index c0fedc0bb2..c3bb8026d5 100644 --- a/Solver/elasticitySolver.h +++ b/Solver/elasticitySolver.h @@ -63,7 +63,7 @@ class elasticitySolver{ void setMesh(const std::string &meshFileName); virtual void solve(); void readInputFile(const std::string &meshFileName); - PView *buildDisplacementView(const std::string &postFileName); + virtual PView *buildDisplacementView(const std::string &postFileName); // PView *buildVonMisesView(const std::string &postFileName); // std::pair<PView *, PView*> buildErrorEstimateView // (const std::string &errorFileName, double, int); @@ -71,4 +71,16 @@ class elasticitySolver{ // (const std::string &errorFileName, const elasticityData &ref, double, int); }; + + +// another elastic solver ... +class MyelasticitySolver : public elasticitySolver +{ + public: + MyelasticitySolver(int tag) : elasticitySolver(tag) {} + virtual void solve(); +}; + + + #endif diff --git a/Solver/femTerm.h b/Solver/femTerm.h index 3536058089..ee759aa75c 100644 --- a/Solver/femTerm.h +++ b/Solver/femTerm.h @@ -179,4 +179,42 @@ class femTerm { } }; + + +class DummyfemTerm : public femTerm<double> +{ + public: + typedef dofTraits<double>::VecType dataVec; + typedef dofTraits<double>::MatType dataMat; + DummyfemTerm(GModel *gm) : femTerm<double>(gm) {} + virtual ~DummyfemTerm() {} + private : // i dont want to mess with this anymore + virtual int sizeOfC(SElement *se) const {return 0;} + virtual int sizeOfR(SElement *se) const {return 0;} + virtual Dof getLocalDofR(SElement *se, int iRow) const {return Dof(0,0);} + virtual Dof getLocalDofC(SElement *se, int iCol) const {return Dof(0,0);} + virtual void elementMatrix(SElement *se, fullMatrix<dataMat> &m) const {m.scale(0.);} + virtual void elementVector(SElement *se, fullVector<dataVec> &m) const {m.scale(0.);} + public: + void addToMatrix(dofManager<dataVec> &dm, + fullMatrix<dataMat> &localMatrix, + std::vector<Dof> R,std::vector<Dof> C) const + { + dm.assemble(R, C, localMatrix); + } + + + void addToMatrix(dofManager<dataVec> &dm, + fullMatrix<dataMat> &localMatrix, + std::vector<Dof> R) const // symmetric version. + { + dm.assemble(R, localMatrix); + } + +}; + + + + + #endif diff --git a/Solver/functionSpace.cpp b/Solver/functionSpace.cpp new file mode 100644 index 0000000000..853c23188f --- /dev/null +++ b/Solver/functionSpace.cpp @@ -0,0 +1,14 @@ +// +// C++ Implementation: functionSpace +// +// Description: +// +// +// Author: <Eric Bechet>, (C) 2009 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "functionSpace.h" + +const SVector3 VectorLagrangeFunctionSpace::BasisVectors[3]={SVector3(1,0,0),SVector3(0,1,0),SVector3(0,0,1)}; diff --git a/Solver/functionSpace.h b/Solver/functionSpace.h index cc7ea643c9..3a540f69ec 100644 --- a/Solver/functionSpace.h +++ b/Solver/functionSpace.h @@ -2,12 +2,14 @@ #define _FUNCTION_SPACE_H_ #include "SVector3.h" +#include "STensor3.h" #include <vector> #include <iterator> #include "Numeric.h" +#include "MElement.h" +#include "dofManager.h" - -class STensor3{}; +//class STensor3{}; class SVoid{}; class basisFunction{ @@ -71,6 +73,7 @@ class FunctionSpace { public: virtual int f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals)=0; virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads)=0; +// virtual groupOfElements* getSupport()=0;// probablement inutile // virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads, STensor3 &invjac)=0;// on passe le jacobien que l'on veut ... /* virtual int hessf(MElement *ele, double u, double v, double w,std::vector<HessType> &hesss); virtual int divf(MElement *ele, double u, double v, double w,std::vector<DivType> &divs); @@ -112,7 +115,7 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double> virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) { int ndofs= ele->getNumVertices(); - grads.reserve(grads.size()+ndofs); +// grads.reserve(grads.size()+ndofs); double gradsuvw[256][3]; ele->getGradShapeFunctions(u, v, w, gradsuvw); double jac[3][3]; @@ -136,12 +139,13 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double> virtual int getKeys(MElement *ele, std::vector<Dof> &keys) // appends ... { int ndofs= ele->getNumVertices(); - keys.reserve(keys.size()+ndofs); +// keys.reserve(keys.size()+ndofs); for (int i=0;i<ndofs;++i) keys.push_back(getLocalDof(ele,i)); } }; +/* template <class T> class ScalarToAnyFunctionSpace : public FunctionSpace<T> // scalarFS * const vector (avec vecteur non const, peut etre utilise pour xfem directement { public : @@ -163,41 +167,160 @@ public : int nbdofs=valsd.size(); for (int i=0;i<nbdofs;++i) vals.push_back(multiplier*valsd[i]); } - virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads){}; + + virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) + { + std::vector<SVector3> gradsd; + ScalarFS->gradf(ele,u,v,w,gradsd); + int nbdofs=gradsd.size(); + GradType val; + for (int i=0;i<nbdofs;++i) + { + tensprod(multiplier,gradsd[i],val); + grads.push_back(val); + } + }; virtual int getNumKeys(MElement *ele) {return ScalarFS->getNumKeys(ele);} virtual int getKeys(MElement *ele, Dof *keys){ ScalarFS->getKeys(ele,keys);} virtual int getKeys(MElement *ele, std::vector<Dof> &keys) {ScalarFS->getKeys(ele,keys);} }; +*/ +template <class T> class ScalarToAnyFunctionSpace : public FunctionSpace<T> +{ +public : + typedef typename TensorialTraits<T>::ValType ValType; + typedef typename TensorialTraits<T>::GradType GradType; + typedef typename TensorialTraits<T>::HessType HessType; + typedef typename TensorialTraits<T>::DivType DivType; + typedef typename TensorialTraits<T>::CurlType CurlType; +protected : + std::vector<T> multipliers; + std::vector<int> comp; + FunctionSpace<double> *ScalarFS; +public : + template <class T2> ScalarToAnyFunctionSpace(const T2 &SFS, const T& mult, int comp_): ScalarFS(new T2(SFS)) + { + multipliers.push_back(mult);comp.push_back(comp_); + } + + template <class T2> ScalarToAnyFunctionSpace(const T2 &SFS, const T& mult1, int comp1_, + const T& mult2, int comp2_): ScalarFS(new T2(SFS)) + { + multipliers.push_back(mult1);multipliers.push_back(mult2);comp.push_back(comp1_);comp.push_back(comp2_); + } + + template <class T2> ScalarToAnyFunctionSpace(const T2 &SFS, const T& mult1, int comp1_, + const T& mult2, int comp2_,const T& mult3, int comp3_): ScalarFS(new T2(SFS)) + { + multipliers.push_back(mult1);multipliers.push_back(mult2);multipliers.push_back(mult3); + comp.push_back(comp1_);comp.push_back(comp2_);comp.push_back(comp3_); + } -class VectorLagrangeFunctionSpace : public ScalarToAnyFunctionSpace<SVector3> // it is a scalar lagrange times a constant vector. + virtual ~ScalarToAnyFunctionSpace() {delete ScalarFS;} + virtual int f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals) + { + std::vector<double> valsd; + ScalarFS->f(ele,u,v,w,valsd); + int nbdofs=valsd.size(); + int nbcomp=comp.size(); + for (int j=0;j<nbcomp;++j) + { + for (int i=0;i<nbdofs;++i) vals.push_back(multipliers[j]*valsd[i]); + } + } + + virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) + { + std::vector<SVector3> gradsd; + ScalarFS->gradf(ele,u,v,w,gradsd); + int nbdofs=gradsd.size(); + int nbcomp=comp.size(); + GradType val; + for (int j=0;j<nbcomp;++j) + { + for (int i=0;i<nbdofs;++i) + { + tensprod(multipliers[j],gradsd[i],val); + grads.push_back(val); + } + } + }; + virtual int getNumKeys(MElement *ele) {return ScalarFS->getNumKeys(ele)*comp.size();} + virtual int getKeys(MElement *ele, Dof *keys) + { + int nbcomp=comp.size(); + int nk=ScalarFS->getNumKeys(ele); + Dof *kptr=keys; + ScalarFS->getKeys(ele,kptr); + kptr+=nk; + for (int j=1;j<nbcomp;++j) + { + for (int i=0;i<nk;++i) + kptr[i]=kptr[i-nk]; + kptr+=nk; + } + kptr=keys; + for (int j=0;j<nbcomp;++j) + { + for (int i=0;i<nk;++i) + { + int i1,i2; + Dof::getTwoIntsFromType(kptr[i].getType(), i1,i2); + kptr[i]=Dof(kptr[i].getEntity(),Dof::createTypeWithTwoInts(comp[j],i2)); + } + kptr+=nk; + } + } + virtual int getKeys(MElement *ele, std::vector<Dof> &keys) + { + int nk=ScalarFS->getNumKeys(ele); + std::vector<Dof> bufk; + bufk.reserve(nk); + ScalarFS->getKeys(ele,bufk); + int nbcomp=comp.size(); + for (int j=0;j<nbcomp;++j) + { + for (int i=0;i<nk;++i) + { + int i1,i2; + Dof::getTwoIntsFromType(bufk[i].getType(), i1,i2); + keys.push_back(Dof(bufk[i].getEntity(),Dof::createTypeWithTwoInts(comp[j],i2))); + } + } + } +}; + +class VectorLagrangeFunctionSpace : public ScalarToAnyFunctionSpace<SVector3> { public: enum Along { VECTOR_X=0, VECTOR_Y=1, VECTOR_Z=2 }; + static const SVector3 BasisVectors[3]; + typedef TensorialTraits<SVector3>::ValType ValType; typedef TensorialTraits<SVector3>::GradType GradType; typedef TensorialTraits<SVector3>::HessType HessType; typedef TensorialTraits<SVector3>::DivType DivType; typedef TensorialTraits<SVector3>::CurlType CurlType; - protected: -// Along direction; - public: - VectorLagrangeFunctionSpace(int id,Along t) : ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id),SVector3(0.,0.,0.) )//,direction(t) - { - multiplier[t]=1.; - } -// virtual int f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals); -// virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads); -// virtual int getNumKeys(MElement *ele); -// virtual int getKeys(MElement *ele, Dof *keys); -// virtual int getKeys(MElement *ele, std::vector<Dof> &keys); + VectorLagrangeFunctionSpace(int id) : + ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id), + SVector3(1.,0.,0.),VECTOR_X, SVector3(0.,1.,0.),VECTOR_Y,SVector3(0.,0.,1.),VECTOR_Z) + {} + VectorLagrangeFunctionSpace(int id,Along comp1) : + ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id), + BasisVectors[comp1],comp1) + {} + VectorLagrangeFunctionSpace(int id,Along comp1,Along comp2) : + ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id), + BasisVectors[comp1],comp1, BasisVectors[comp2],comp2) + {} + VectorLagrangeFunctionSpace(int id,Along comp1,Along comp2, Along comp3) : + ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id), + BasisVectors[comp1],comp3, BasisVectors[comp2],comp2, BasisVectors[comp3],comp3) + {} }; - - - - template<class T> class CompositeFunctionSpace : public FunctionSpace<T> { @@ -235,8 +358,18 @@ class CompositeFunctionSpace : public FunctionSpace<T> delete (*it); } - virtual int f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals) {} - virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) {} + virtual int f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals) + { + for (iterFS it=_spaces.begin(); it!=_spaces.end();++it) + (*it)->f(ele,u,v,w,vals); + } + + virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) + { + for (iterFS it=_spaces.begin(); it!=_spaces.end();++it) + (*it)->gradf(ele,u,v,w,grads); + } + virtual int getNumKeys(MElement *ele) { int ndofs=0; @@ -244,6 +377,7 @@ class CompositeFunctionSpace : public FunctionSpace<T> ndofs+=(*it)->getNumKeys(ele); return ndofs; } + virtual int getKeys(MElement *ele, Dof *keys) { Dof *kptr=keys; @@ -280,4 +414,28 @@ class xFemFunctionSpace : public FunctionSpace<T> }; +template<class T,class F> +class FilteredFunctionSpace : public FunctionSpace<T> +{ + typedef typename TensorialTraits<T>::ValType ValType; + typedef typename TensorialTraits<T>::GradType GradType; + typedef typename TensorialTraits<T>::HessType HessType; + typedef typename TensorialTraits<T>::DivType DivType; + typedef typename TensorialTraits<T>::CurlType CurlType; + private: + FunctionSpace<T>* _spacebase; + F &_filter; + + public: + ValType f(MElement *ele, double u, double v, double w); + GradType gradf(MElement *ele, double u, double v, double w); + int getNumKeys(MElement *ele); + void getKeys(MElement *ele, Dof *keys); + void getKeys(MElement *ele, std::vector<Dof> &keys); +}; + + + + + #endif -- GitLab