Forked from
gmsh / gmsh
14964 commits behind the upstream repository.
-
Éric Béchet authored
No commit message
Éric Béchet authoredNo commit message
functionSpace.h 10.07 KiB
#ifndef _FUNCTION_SPACE_H_
#define _FUNCTION_SPACE_H_
#include "SVector3.h"
#include <vector>
#include <iterator>
#include "Numeric.h"
class STensor3{};
class SVoid{};
class basisFunction{
public:
virtual void f(MElement *ele, double u, double v, double w, double *s) = 0;
virtual void df(MElement *ele, double u, double v, double w, double *s) = 0;
};
class scalarPolynomialBasisFunction : public basisFunction{
private:
polynomialBasis *_basis;
public:
virtual void f(MElement *ele, double u, double v, double w, double *s);
virtual void df(MElement *ele, double u, double v, double w, double *s);
};
class vectorPolynomialBasisFunction : public basisFunction{
private:
polynomialBasis *_basis[3];
public:
virtual void f(MElement *ele, double u, double v, double w, double *s);
virtual void df(MElement *ele, double u, double v, double w, double *s);
};
template<class T> struct TensorialTraits
{
typedef T ValType;
typedef T GradType[3];
typedef T HessType[3][3];
typedef SVoid DivType;
typedef SVoid CurlType;
};
template<> struct TensorialTraits<double>
{
typedef double ValType;
typedef SVector3 GradType;
typedef STensor3 HessType;
typedef SVoid DivType;
typedef SVoid CurlType;
};
template<> struct TensorialTraits<SVector3>
{
typedef SVector3 ValType;
typedef STensor3 GradType;
typedef SVoid HessType;
typedef double DivType;
typedef SVector3 CurlType;
};
template<class T>
class FunctionSpace {
protected:
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;*/
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 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);
virtual int curlf(MElement *ele, double u, double v, double w,std::vector<CurlType> &curls);*/
virtual int getNumKeys(MElement *ele)=0; // if one needs the number of dofs
virtual int getKeys(MElement *ele, Dof *keys)=0; // may be faster once the number of dofs is known
virtual int getKeys(MElement *ele, std::vector<Dof> &keys)=0;
};
class ScalarLagrangeFunctionSpace : public FunctionSpace<double>
{
protected:
typedef TensorialTraits<double>::ValType ValType;
typedef TensorialTraits<double>::GradType GradType;
typedef TensorialTraits<double>::HessType HessType;
typedef TensorialTraits<double>::DivType DivType;
typedef TensorialTraits<double>::CurlType CurlType;
std::vector<basisFunction*> basisFunctions;
int _iField; // field number (used to build dof keys)
Dof getLocalDof(MElement *ele, int i) const
{
// int iComp = i / ele->getNumVertices();
// int ithLocalVertex = i % ele->getNumVertices();
return Dof(ele->getVertex(i)->getNum(),_iField);
}
public:
ScalarLagrangeFunctionSpace(int i=0):_iField(i) {}
virtual int getId(void) const {return _iField;};
virtual int f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals)
{
int ndofs= ele->getNumVertices();
int curpos=vals.size();
vals.resize(curpos+ndofs);
ele->getShapeFunctions(u, v, w, &(vals[curpos]));
};
virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads)
{
int ndofs= ele->getNumVertices();
grads.reserve(grads.size()+ndofs);
double gradsuvw[256][3];
ele->getGradShapeFunctions(u, v, w, gradsuvw);
double jac[3][3];
double invjac[3][3];
const double detJ = ele->getJacobian(u, v, w, jac); // a faire une fois pour toute ??
inv3x3(jac, invjac);
for (int i=0;i<ndofs;++i)
grads.push_back(GradType(
invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2],
invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2],
invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2]
));
};
virtual int getNumKeys(MElement *ele) {return ele->getNumVertices();}
virtual int getKeys(MElement *ele, Dof *keys)
{
int ndofs= ele->getNumVertices();
for (int i=0;i<ndofs;++i)
keys[i]=getLocalDof(ele,i);
}
virtual int getKeys(MElement *ele, std::vector<Dof> &keys) // appends ...
{
int ndofs= ele->getNumVertices();
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 :
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 :
T multiplier;
FunctionSpace<double> *ScalarFS;
public :
template <class T2> ScalarToAnyFunctionSpace(const T2 &SFS, const T& mult): multiplier(mult),ScalarFS(new T2(SFS)) {}
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();
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 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);}
};
class VectorLagrangeFunctionSpace : public ScalarToAnyFunctionSpace<SVector3> // it is a scalar lagrange times a constant vector.
{
public:
enum Along { VECTOR_X=0, VECTOR_Y=1, VECTOR_Z=2 };
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);
};
template<class T>
class CompositeFunctionSpace : 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;
typedef typename std::vector<FunctionSpace<T>* >::iterator iterFS;
protected:
std::vector<FunctionSpace<T>* > _spaces;
public:
template <class T1> CompositeFunctionSpace(const T1& t) { _spaces.push_back(new T1(t));}
template <class T1, class T2> CompositeFunctionSpace(const T1& t1, const T2& t2)
{ _spaces.push_back(new T1(t1));
_spaces.push_back(new T2(t2)); }
template <class T1, class T2, class T3> CompositeFunctionSpace(const T1& t1, const T2& t2, const T3& t3)
{ _spaces.push_back(new T1(t1));
_spaces.push_back(new T2(t2));
_spaces.push_back(new T3(t3)); }
template <class T1, class T2, class T3, class T4> CompositeFunctionSpace(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
{ _spaces.push_back(new T1(t1));
_spaces.push_back(new T2(t2));
_spaces.push_back(new T3(t3));
_spaces.push_back(new T4(t4)); }
template <class T1> void insert(const T1& t)
{
_spaces.push_back(new T(t));
}
~CompositeFunctionSpace(void)
{
for (iterFS it=_spaces.begin(); it!=_spaces.end();++it)
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 getNumKeys(MElement *ele)
{
int ndofs=0;
for (iterFS it=_spaces.begin(); it!=_spaces.end();++it)
ndofs+=(*it)->getNumKeys(ele);
return ndofs;
}
virtual int getKeys(MElement *ele, Dof *keys)
{
Dof *kptr=keys;
for (iterFS it=_spaces.begin(); it!=_spaces.end();++it)
{
(*it)->getKeys(ele,kptr);
kptr+=(*it)->getNumKeys(ele);
}
}
virtual int getKeys(MElement *ele, std::vector<Dof> &keys)
{
for (iterFS it=_spaces.begin(); it!=_spaces.end();++it)
(*it)->getKeys(ele,keys);
}
};
template<class T>
class xFemFunctionSpace : 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;
// Function<double>* enrichment;
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