Skip to content
Snippets Groups Projects
Commit 12689d09 authored by Gauthier Becker's avatar Gauthier Becker
Browse files

NonLinearSolver --> projects. Update All CMakeLists

remove main_dgshell.cpp which is now obsolete
parent e9e4398f
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1011 deletions
......@@ -54,7 +54,6 @@ option(ENABLE_SWIG "Enable swig" ON)
option(ENABLE_TAUCS "Enable Taucs linear algebra solver" ON)
option(ENABLE_TETGEN "Enable Tetgen mesh generator" ON)
option(ENABLE_TETGEN_NEW "Enable experimental version of Tetgen" OFF)
option(ENABLE_NON_LINEAR_SOLVER "Enable use of non linear solver" OFF)
set(GMSH_MAJOR_VERSION 2)
set(GMSH_MINOR_VERSION 5)
......@@ -278,21 +277,6 @@ add_subdirectory(Common)
add_subdirectory(Numeric)
add_subdirectory(Geo)
if(ENABLE_NON_LINEAR_SOLVER)
add_subdirectory(NonLinearSolver)
include_directories(NonLinearSolver/nlsolver)
include_directories(NonLinearSolver/BoundaryConditions)
include_directories(NonLinearSolver/contact)
include_directories(NonLinearSolver/Domain)
include_directories(NonLinearSolver/field)
include_directories(NonLinearSolver/Interface)
include_directories(NonLinearSolver/internalPoints)
include_directories(NonLinearSolver/materialLaw)
include_directories(NonLinearSolver/nlTerms)
include_directories(NonLinearSolver/space)
set_config_option(HAVE_NLMECHSOL "NlMechSol")
endif(ENABLE_NON_LINEAR_SOLVER)
if(ENABLE_MESH)
add_subdirectory(Mesh)
set_config_option(HAVE_MESH "Mesh")
......
# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
#
# See the LICENSE.txt file for license information. Please report all
# bugs and problems to <gmsh@geuz.org>.
set(SRC
nonLinearBC.cpp
)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
append_gmsh_src(NonLinearSolver/BoundaryConditions "${SRC};${HDR}")
//
//
// Description: Class to set Boundary Conditions
//
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "nonLinearBC.h"
//
//
// Description: Class to set Boundary Conditions
//
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
// Has to be regroup with BoundaryCondition defined in elasticitySolver.h These BC have to be defined in a separated file
// I add nonLinear above to avoid ambiguities
#ifndef NONLINEARBC_H_
#define NONLINEARBC_H_
#ifndef SWIG
#include "groupOfElements.h"
#include "simpleFunction.h"
#include "SVector3.h"
#include "quadratureRules.h"
#include "timeFunction.h"
#include "contactFunctionSpace.h"
#include "solverAlgorithms.h" // change this
class nonLinearBoundaryCondition
{
public:
enum location{UNDEF,ON_VERTEX,ON_EDGE,ON_FACE,ON_VOLUME,PRESSURE,RIGIDCONTACT};
location onWhat; // on vertices or elements
int _tag; // tag for the dofManager
groupOfElements *g; // support for this BC
nonLinearBoundaryCondition() : g(0),_tag(0),onWhat(UNDEF) {};
nonLinearBoundaryCondition(const nonLinearBoundaryCondition &source){
this->onWhat = source.onWhat;
this->_tag = source._tag;
this->g = source.g;
}
};
class nonLinearDirichletBC : public nonLinearBoundaryCondition
{
public:
int _comp; // component
simpleFunctionTime<double> _f;
FilterDof *_filter;
FunctionSpaceBase *_space;
nonLinearDirichletBC() : nonLinearBoundaryCondition(),_comp(0),_f(0), _space(NULL), _filter(NULL){}
nonLinearDirichletBC(const nonLinearDirichletBC &source) : nonLinearBoundaryCondition(source){
this->_comp = source._comp;
this->_f = source._f;
this->_space = source._space;
this->_filter = source._filter;
}
};
// group will be not used but allow to store in same vector
// tag == Master physical number
class rigidContactBC : public nonLinearBoundaryCondition
{
public:
rigidContactSpaceBase *space;
int _comp; // component
simpleFunctionTime<double> _f;
rigidContactBC(const int physMaster) : nonLinearBoundaryCondition(){
_tag = physMaster;
onWhat = RIGIDCONTACT;
}
rigidContactBC(const rigidContactBC &source) : nonLinearBoundaryCondition(source)
{
_comp = source._comp;
space = source.space;
_f = source._f;
}
~rigidContactBC(){}
void setSpace(rigidContactSpaceBase *sp){space = sp;}
};
#endif
class nonLinearNeumannBC : public nonLinearBoundaryCondition
{
public:
simpleFunction<double> *_f;
QuadratureBase* integ; // given by partDomain
FunctionSpaceBase *_space; // given by partDomain
LinearTermBase<double> *_term; // given by partDomain
int _comp; // component x, y or z to create function space
nonLinearNeumannBC () : nonLinearBoundaryCondition(),_f(NULL), integ(NULL), _space(NULL), _term(NULL) {}
nonLinearNeumannBC (const int tag, const int ow, simpleFunction<double>* f): nonLinearBoundaryCondition(), _f(f),
integ(NULL), _space(NULL), _term(NULL),
_comp(0)
{
_tag = tag;
switch(ow){
case 0:
this->onWhat = nonLinearBoundaryCondition::UNDEF;
break;
case 1:
this->onWhat = nonLinearBoundaryCondition::ON_VERTEX;
g = new groupOfElements(0,tag);
break;
case 2:
onWhat = nonLinearBoundaryCondition::ON_EDGE;
g = new groupOfElements(1,tag);
break;
case 3:
onWhat = nonLinearBoundaryCondition::ON_FACE;
g = new groupOfElements(2,tag);
break;
case 4:
onWhat = nonLinearBoundaryCondition::ON_VOLUME;
g = new groupOfElements(3,tag);
break;
case 5:
onWhat = nonLinearBoundaryCondition::PRESSURE;
g = new groupOfElements(2,tag);
break;
}
}
nonLinearNeumannBC(const nonLinearNeumannBC &source) : _f(source._f), nonLinearBoundaryCondition(source),
integ(source.integ), _space(source._space), _term(source._term),
_comp(source._comp){}
};
#ifndef SWIG
class initialCondition : public nonLinearDirichletBC {
public:
enum whichCondition{position=0, velocity=1, acceleration=2};
double _value;
whichCondition _wc;
initialCondition(double val, int comp, whichCondition wc) : nonLinearDirichletBC(), _value(val), _wc(wc){_comp=comp;}
~initialCondition(){}
initialCondition(const initialCondition &source) : nonLinearDirichletBC(source){
_value = source._value;
_wc = source._wc;
}
};
#endif
#endif // non linear Boundary Conditions
# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
#
# See the LICENSE.txt file for license information. Please report all
# bugs and problems to <gmsh@geuz.org>.
add_subdirectory(BoundaryConditions)
add_subdirectory(contact)
add_subdirectory(Domain)
add_subdirectory(field)
add_subdirectory(Interface)
add_subdirectory(internalPoints)
add_subdirectory(materialLaw)
add_subdirectory(nlTerms)
add_subdirectory(nlsolver)
add_subdirectory(space)
append_gmsh_src(NonLinearSolver "${SRC};${HDR}")
set(GMSH_DIRS ${GMSH_DIRS};NonLinearSolver PARENT_SCOPE)
# add pragma to compile nlmechsolpy.i in gmshpy.i
# no if because here it is sure to used NonLinearSolver
set(MAKE_C_FLAGS " ${CMAKE_C_FLAGS} -D_HAVE_NLMECHSOL")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -D_HAVE_NLMECHSOL")
# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
#
# See the LICENSE.txt file for license information. Please report all
# bugs and problems to <gmsh@geuz.org>.
set(SRC
partDomain.cpp
)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
append_gmsh_src(NonLinearSolver/Domain "${SRC};${HDR}")
//
// C++ Interface: partDomain
//
// Description: Interface class to used solver. Your term ha to be store in a domain
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "partDomain.h"
partDomain::partDomain(const partDomain &source){
_tag = source._tag;
_phys = source._phys;
_fullDg = source._fullDg;
btermBulk = source.btermBulk;
massterm = source.massterm;
ltermBulk = source.ltermBulk;
integBulk = source.integBulk;
g = source.g;
allDirichlet = source.allDirichlet;
allNeumann = source.allNeumann;
allInitial = source.allInitial;
_bmbp = source._bmbp;
_eps= source._eps;
_wsp = source._wsp;
setmaterial = source.setmaterial;
}
partDomain& partDomain::operator=(const partDomain &source)
{
_tag = source._tag;
_phys = source._phys;
_fullDg = source._fullDg;
btermBulk = source.btermBulk;
massterm = source.massterm;
ltermBulk = source.ltermBulk;
integBulk = source.integBulk;
g = source.g;
allDirichlet = source.allDirichlet;
allNeumann = source.allNeumann;
allInitial = source.allInitial;
_wsp = source._wsp;
_bmbp = source._bmbp;
_eps = source._eps;
setmaterial = source.setmaterial;
return *this;
}
dgPartDomain::dgPartDomain(const dgPartDomain &source) : partDomain(source){
btermBound = source.btermBound;
ltermBound = source.ltermBound;
btermVirtBound = source.btermVirtBound;
ltermVirtBound = source.ltermVirtBound;
integBound = source.integBound;
gi = source.gi;
gib = source.gib;
giv = source.giv;
_interByPert = source._interByPert;
_virtByPert = source._virtByPert;
}
dgPartDomain& dgPartDomain::operator=(dgPartDomain &source)
{
this->partDomain::operator=(source);
btermBound = source.btermBound;
ltermBound = source.ltermBound;
btermVirtBound = source.btermVirtBound;
ltermVirtBound = source.ltermVirtBound;
integBound = source.integBound;
gi = source.gi;
gib = source.gib;
giv = source.giv;
_interByPert = source._interByPert;
_virtByPert = source._virtByPert;
return *this;
}
void partDomain::setBulkMatrixByPerturbation(const int i, const double eps)
{
i == 0 ? _bmbp = false : _bmbp = true;
_eps = eps;
}
//
// C++ Interface: partDomain
//
// Description: Interface class to used solver. Your term ha to be store in a domain
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef PARTDOMAIN_H_
#define PARTDOMAIN_H_
#ifndef SWIG
#include "mlaw.h"
#include "SVector3.h"
#include "MInterfaceElement.h"
#include "groupOfElements.h"
#include "timeFunction.h"
#include "functionSpaceType.h"
#include "nonLinearBC.h"
#include "nlTerms.h"
#include "unknownField.h"
#include "InterfaceBuilder.h"
// class for a domain (pure virtual class)
#endif
class partDomain{
public :
typedef std::set<nonLinearDirichletBC*> diriContainer;
typedef std::set<nonLinearNeumannBC*> neuContainer;
typedef std::set<initialCondition*> initContainer;
protected :
int _tag; // tag for the dofManager
int _phys; // physical of interface group I don't know how to retrieve it from *g
bool _fullDg; // To know which formulation Cg/Dg or FullDg is used for this part
functionSpaceType::whichSpace _wsp;
BilinearTermBase* btermBulk;
BilinearTermBase* massterm;
LinearTermBase<double>* ltermBulk;
QuadratureBase* integBulk;
// for matrix by perturbation
bool _bmbp;
double _eps;
virtual void setBulkMatrixByPerturbation(const int i, const double eps=1e-8);
// To know if law is already set
bool setmaterial;
// BC are put in domain to be sure to use the good function space
// neumann BC
neuContainer allNeumann;
// dirichlet BC
diriContainer allDirichlet;
// initial Condition
initContainer allInitial;
public :
// Todo protect this variable
groupOfElements *g; // support for this field
#ifndef SWIG
// Constructors
partDomain(const int tag, const int phys,
const int ws = 0,const bool fdg=false) : g(0), _tag(tag), _phys(phys),
_bmbp(false), _eps(1e-8), _fullDg(fdg), setmaterial(false)
{
switch(ws){
case 0:
_wsp = functionSpaceType::Lagrange;
break;
case 10000: // Allow to set space later (used for interface domain)
_wsp = functionSpaceType::Inter;
break;
default:
Msg::Error("Function space type is unknown for partDomain %d. So Lagrange by default");
_wsp = functionSpaceType::Lagrange;
}
}
partDomain(const partDomain &source);
partDomain& operator=(const partDomain &source);
// ~partDomain(){delete btermBulk; delete ltermBulk; delete integBulk;}
BilinearTermBase* getBilinearBulkTerm() const{return btermBulk;}
BilinearTermBase* getBilinearMassTerm() const{return massterm;}
LinearTermBase<double>* getLinearBulkTerm() const{return ltermBulk;}
QuadratureBase* getBulkGaussIntegrationRule() const{return integBulk;}
// Dimension of domain
virtual int getDim() const=0;
int getTag()const{return _tag;}
int getPhysical() const{return _phys;}
virtual void initializeTerms(unknownField *uf,IPField *ip)=0;
// true is domain has interface terms
virtual bool IsInterfaceTerms() const=0;
functionSpaceType::whichSpace getFunctionSpaceType() const{return _wsp;}
// can be return const FunctionSpaceBase if the function of this class are declarated const
virtual FunctionSpaceBase* getFunctionSpace() const=0;
// some data of BC have to be set by domain
virtual void addDirichletBC(nonLinearDirichletBC *diri)=0; // space and filterDof
virtual void addNeumannBC(nonLinearNeumannBC *neu)=0; // space, integration rule and term
virtual void addInitialCondition(initialCondition *initC)=0; // idem as dirichlet
void setTimeBC(const double curtime){
for(neuContainer::iterator it=neuBegin(); it!=neuEnd(); ++it){
nonLinearNeumannBC *neu = *it;
simpleFunctionTime<double> *ft = dynamic_cast<simpleFunctionTime<double>*>(neu->_f);
ft->setTime(curtime);
}
for(diriContainer::iterator it=diriBegin(); it!=diriEnd(); ++it){
nonLinearDirichletBC *diri = *it;
diri->_f.setTime(curtime);
}
}
diriContainer::iterator diriBegin(){return allDirichlet.begin();}
diriContainer::iterator diriEnd(){return allDirichlet.end();}
neuContainer::iterator neuBegin(){return allNeumann.begin();}
neuContainer::iterator neuEnd(){return allNeumann.end();}
initContainer::iterator initCBegin(){return allInitial.begin();}
initContainer::iterator initCEnd(){return allInitial.end();}
// static void registerBindings(binding *b);
virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws)=0;
virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
materialLaw *mlaw,fullVector<double> &disp)=0;
virtual void setGaussIntegrationRule()=0;
virtual void inverseLinearTermSign()=0;
virtual bool getFormulation() const{return _fullDg;}
virtual void setMaterialLaw(const std::map<int,materialLaw*> maplaw)=0;
// No materialLaw store here but the function to give the material law exist
// The law has to be store in the derivated class
virtual materialLaw* getMaterialLaw()=0;
virtual const materialLaw* getMaterialLaw() const=0;
virtual int getLawNum() const=0;
// For dg formulation the stability parameters decrease the critical time step size
// in explicit. So this function allows to scale the time step
virtual double scaleTimeStep() const {return 1.;}
// creation of interface. At least boundary to create interface domain
// can be empty be not interdomain creation in this case
virtual void createInterface(manageInterface &maninter)=0;
//Iedge has to be change in IElement
virtual MElement* createVirtualInterface(IElement *ie) const=0;
virtual MElement* createInterface(IElement* ie1,IElement* ie2) const=0;
// Add for BC
virtual FilterDof* createFilterDof(const int comp) const=0;
#endif
};
// class for Dg part domain (pure virtual)
class dgPartDomain : public partDomain{
protected :
BilinearTermBase* btermBound;
LinearTermBase<double>* ltermBound;
BilinearTermBase* btermVirtBound;
LinearTermBase<double>* ltermVirtBound;
QuadratureBase* integBound;
// For matrix by perturbation
bool _interByPert;
bool _virtByPert;
public :
// TODO protect these variables
groupOfElements *gi; // support for the interfaceElement TODO cast to a groupOfElements
groupOfElements *gib; // support for the interfaceElement TODO cast to a groupOfElements
groupOfElements *giv; // support for the virtual interface element (used to set Neumann and Dirichlet BC)
#ifndef SWIG
dgPartDomain(const int tag, const int phys, const int ws = 0,
const bool fdg=false) : partDomain(tag,phys,ws,fdg), _interByPert(false), _virtByPert(false)
{
gi = new groupOfElements();
gib = new groupOfElements();
giv = new groupOfElements();
}
dgPartDomain(const dgPartDomain &source);
dgPartDomain& operator=(dgPartDomain &source);
// ~dgPartDomain(){delete btermBound; delete ltermBound; delete btermVirtBound; delete ltermVirtBound;
// delete integBound; delete gib; delete giv}
BilinearTermBase* getBilinearInterfaceTerm(){return btermBound;}
LinearTermBase<double>* getLinearInterfaceTerm()const{return ltermBound;}
BilinearTermBase* getBilinearVirtualInterfaceTerm(){return btermVirtBound;}
LinearTermBase<double>* getLinearVirtualInterfaceTerm(){return ltermVirtBound;}
QuadratureBase* getInterfaceGaussIntegrationRule() const {return integBound;}
virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws)=0;
virtual void computeIpv(AllIPState *aips,MInterfaceElement *ie, IntPt *GP,const IPStateBase::whichState ws,
partDomain* efMinus, partDomain *efPlus,materialLaw *mlawminus,
materialLaw *mlawplus,fullVector<double> &dispm,
fullVector<double> &dispp,const bool virt,const bool checkfrac=true)=0;
virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
materialLaw *mlaw,fullVector<double> &disp)=0;
virtual void addDirichletBC(nonLinearDirichletBC *diri)=0;
virtual void addNeumannBC(nonLinearNeumannBC *neu)=0;
virtual void addInitialCondition(initialCondition *initC)=0;
virtual void setGaussIntegrationRule()=0;
virtual int getDim() const=0;
virtual bool IsInterfaceTerms() const{return true;}
virtual FunctionSpaceBase* getFunctionSpace() const=0;
virtual FunctionSpaceBase* getFunctionSpaceMinus() const=0;
virtual FunctionSpaceBase* getFunctionSpacePlus() const=0;
virtual void matrixByPerturbation(const int ibulk, const int iinter, const int ivirt,const double eps=1e-8)=0;
// static void registerBindings(binding *b);
virtual void setMaterialLaw(const std::map<int,materialLaw*> maplaw)=0;
virtual materialLaw* getMaterialLaw(){Msg::Error("The law to retrieve is not given on a dgdom"); return NULL;}
virtual const materialLaw* getMaterialLaw() const{Msg::Error("The law to retrieve is not given on a dgdom"); return NULL;}
virtual materialLaw* getMaterialLawMinus()=0;
virtual const materialLaw* getMaterialLawMinus() const=0;
virtual materialLaw* getMaterialLawPlus()=0;
virtual const materialLaw* getMaterialLawPlus() const=0;
virtual int getLawNum() const=0;
virtual int getMinusLawNum() const=0;
virtual int getPlusLawNum() const=0;
virtual const partDomain* getMinusDomain() const=0;
virtual const partDomain* getPlusDomain() const=0;
virtual partDomain* getMinusDomain()=0;
virtual partDomain* getPlusDomain()=0;
virtual void createInterface(manageInterface &maninter)=0;
virtual MElement* createVirtualInterface(IElement *ie) const=0;
virtual MElement* createInterface(IElement *ie1, IElement *ie2) const=0;
// Add for BC
virtual FilterDof* createFilterDof(const int comp) const=0;
#endif
};
#endif
# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
#
# See the LICENSE.txt file for license information. Please report all
# bugs and problems to <gmsh@geuz.org>.
set(SRC
IEdge.cpp
IElement.cpp
InterfaceBuilder.cpp
MInterfaceElement.cpp
MInterfaceLine.cpp
)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
append_gmsh_src(NonLinearSolver/Interface "${SRC};${HDR}")
//
// C++ Interface: terms
//
// Description: Class to bluid an interface line (used at initialization)
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "IEdge.h"
//
// C++ Interface: terms
//
// Description: Class to bluid an interface line (used at initialization)
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef _IEDEGE_H_
#define _IEDEGE_H_
#include "IElement.h"
#include "MVertex.h"
#include "MElement.h"
// Class used to build 2D interface element
class IEdge : public IElement{
public :
IEdge(std::vector<MVertex*> &v,MElement *e, int i) : IElement(v,e,i){};
~IEdge(){};
unsigned long int getkey() const{
int i1,i2,i3;
i1 = vertex[0]->getNum();
i2 = vertex[1]->getNum();
i1>i2 ? i3=i1*100000+i2 : i3=i2*100000+i1; // change this
return i3;
}
virtual IElement::IEtype getType()const{return IElement::Edge;}
};
#endif // _IEDEGE_H_
//
// C++ Interface: terms
//
// Description: Class to bluid the interface element (used at initialization)
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "IElement.h"
//
// C++ Interface: terms
//
// Description: Class to bluid the interface element (used at initialization)
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef _IELEMENT_H_
#define _IELEMENT_H_
#include "MVertex.h"
#include "MElement.h"
class IElement{
public:
enum IEtype{Edge};
protected:
std::vector<MVertex*> vertex;
MElement *elem;
int phys;
public:
IElement(std::vector<MVertex*> &v,MElement *e, int i) : vertex(v), elem(e), phys(i){};
~IElement(){};
virtual unsigned long int getkey() const=0;
virtual IEtype getType() const=0;
// As for now only IEdge exists I don't know if these method are virtual pure
// virtual or are only for IEdge
virtual std::vector<MVertex*> getVertices() const{return vertex;}
virtual MElement* getElement() const{return elem;}
virtual MVertex* getFirstInteriorVertex() const {return vertex[2];}
virtual MVertex* getLastInteriorVertex() const {return *vertex.end();}
virtual int getPhys() const {return phys;}
};
#endif // _IELEMENT_H_
//
// C++ Interface: terms
//
// Description: Class to manage the creation of interface
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "InterfaceBuilder.h"
#include "partDomain.h"
unsigned long int manageInterface::getKey(partDomain* dom1, partDomain *dom2){
int i1 = dom1->getPhysical();
int i2 = dom2->getPhysical();
return manageInterface::getKey(i1,i2);
}
void manageInterface::insert(IElement *iele,partDomain *dom)
{
unsigned long int key = iele->getkey();
IelementContainer::iterator it_edge=mapinter.find(key);
if((it_edge == mapinter.end()) or (iele->getType() != it_edge->second->getType()))
mapinter.insert(IelementPart(key,iele));
else{ // create the interface
MElement *interel = dom->createInterface(iele,it_edge->second);
this->createinter(interel,iele,it_edge->second->getPhys());
}
}
void manageInterface::createinter(MElement *iele, IElement *ie, const int phys2)
{
unsigned int physkey = manageInterface::getKey(ie->getPhys(),phys2);
#ifdef _DEBUG
bool findi = false;
#endif
for(std::vector<partDomain*>::iterator it = _vdom->begin(); it!=_vdom->end(); ++it){
partDomain *dom = *it;
if(dom->getPhysical() == physkey){
dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
dgdom->gi->insert(iele);
#ifdef _DEBUG
findi=true;
#endif
}
}
#ifdef _DEBUG
if(!findi)
Msg::Error("Error with the creation of interfaceelement. It seems that an Interface element is not include in any domain");
#endif
if(physkey != phys2){
// search domain
for(std::vector<partDomain*>::iterator it = _vdom->begin(); it!=_vdom->end(); ++it){
partDomain *dom = *it;
if(dom->getPhysical() == ie->getPhys()){
dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
MElement* interel = dgdom->createVirtualInterface(ie);
dgdom->giv->insert(interel);
}
}
}
else{
this->erase(ie);
}
}
//
// C++ Interface: terms
//
// Description: Class to manage the creation of interface
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef _INTERFACEBUILDER_H_
#define _INTERFACEBUILDER_H_
#include "mlaw.h"
#include "IElement.h"
class partDomain;
class manageInterface{
public:
typedef std::map<unsigned long int,IElement*> IelementContainer; // create IElement type and Iede derive from Iedge
typedef std::pair<unsigned long int,IElement*> IelementPart;
protected:
IelementContainer mapinter;
std::vector<partDomain*> *_vdom;
public:
static unsigned long int getKey(const int npdom1, const int npdom2){
unsigned long int i;
if(npdom1 == npdom2){
return npdom1;
}
else{
npdom1<npdom2 ? i = npdom2*100000+npdom1 : i = npdom1*100000+npdom2;
return i;
}
}
unsigned long int getKey(partDomain* dom1, partDomain *dom2);
void insert(IElement *iele,partDomain *dom);
// not optimal for internal interface pass current dom for more efficiency ??
void createinter(MElement *ele, IElement *ie, const int phys2);
manageInterface(std::vector<partDomain*> *vdom) : _vdom(vdom){}
~manageInterface()
{
for(IelementContainer::iterator it = mapinter.begin(); it!=mapinter.end(); ++it){
delete it->second;
}
}
void erase(IElement *ie){
unsigned long int key = ie->getkey();
IelementContainer::iterator it = mapinter.find(key);
if(it != mapinter.end()){
delete it->second;
mapinter.erase(it);
}
}
void create(partDomain *dom1, partDomain *dom2, const std::map<int,materialLaw*> &maplaw,const int lawnum=0);
void createInterShell(partDomain *dom1, partDomain *dom2, const int lawnum,
const std::map<int,materialLaw*> &maplaw,const int ipert, const double eps=1e-8);
IelementContainer::iterator begin(){return mapinter.begin();}
IelementContainer::iterator end(){return mapinter.end();}
};
#endif //_INTERFACEBUILDER_H_
//
// C++ Interface: terms
//
// Description: Class of interface element used for DG
//
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
// Has to be merge with interface element defined in dg project HOW ??
#include "MInterfaceElement.h"
#include "quadratureRules.h"
#include "MLine.h"
double MInterfaceElement::characSize(MElement *e)
{
// Compute the area of the element
GaussQuadrature Integ_Bulk(GaussQuadrature::Grad); // which rule used for now not the same as the call function ??
IntPt *GP;
double perimeter = 0., Area = 0.;
double jac[3][3];
int npts=Integ_Bulk.getIntPoints(e,&GP);
// Area
for( int i = 0; i < npts; i++){
// Coordonate of Gauss' point i
const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2];
const double weight = GP[i].weight; const double detJ = e->getJacobian(u, v, w, jac); // Or compute jacobian with crossprod(phi0[0],phi0[1]) ??
Area += weight * detJ;
}
// perimeter
int nside = e->getNumEdges();
GaussQuadrature Integ_Bound(GaussQuadrature::ValVal);
std::vector<MVertex*> vver;
for(int i=0;i<nside;i++){
IntPt *GPb;
e->getEdgeVertices(i,vver);
MLineN mlin = MLineN(vver);
int npts = Integ_Bound.getIntPoints(&mlin,&GPb);
for(int j=0;j<npts; j++){
const double u = GPb[j].pt[0]; const double v = GPb[j].pt[1]; const double w = GPb[j].pt[2];
const double weight = GPb[j].weight; const double detJ = mlin.getJacobian(u, v, w, jac);
perimeter +=weight*detJ;
}
vver.clear();
}
return Area/perimeter;
}
//
// C++ Interface: terms
//
// Description: Class of interface element used for DG
//
//
// Author: <Gauthier BECKER>, (C) 2010
//
// Copyright: See COPYING file that comes with this distribution
//
//
// Has to be merge with interface element defined in dg project HOW ??
# ifndef _MINTERFACEELEMENT_H_
# define _MINTERFACEELEMENT_H_
#include "MElement.h"
// MinterfaceElement is a pure virtual class whose is interace has to be derived and derived from MElement too
// so MinterfaceElement can't not be derived from MElement
class MInterfaceElement{
public:
MInterfaceElement(){}
~MInterfaceElement(){}
virtual MElement* getElem(const int index) const=0;
virtual int getEdgeOrFaceNumber(const int index) const=0;
virtual bool isSameDirection(const int index) const=0;
// should return the element number !!
virtual int getNumber() const=0; // {return{this->getNum();} in your derived class it derived from an MElement* too !!
// compute the characteritic size of one element (This function can be defined as a method of MElement) ??
static double characSize(MElement *e); // Area/perimeter
};
#endif // _MINTERFACEELEMENT
//
// C++ Interface: terms
//
// Description: Class of interface element of line used for DG
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
// Has to be merge with interface element defined in dg project HOW ??
#include "MInterfaceLine.h"
MInterfaceLine::MInterfaceLine(std::vector<MVertex*> &v, int num, int part,
MElement *e_minus, MElement *e_plus) : MLineN(v, num, part), MInterfaceElement()
{
_numElem[0]=e_minus;
_numElem[1]=e_plus;
// Edge of element linked to interface element we identifie an interior point of the MLine (degree 2 min for shell) thus we used v[0]
for(int jj=0;jj<2;jj++){
int nopv = _numElem[jj]->getNumPrimaryVertices();
std::vector<MVertex*> vv;
for(int i = 0; i < nopv; i++){
_numElem[jj]->getEdgeVertices(i,vv);
for(int j = 2; j < vv.size(); j++){
if(vv[j] == v[2]){ // v[2] because it is the first interior node
_numEdge[jj] = i;
if(v[0] == vv[0]) _dir[jj] = true; // same orientation
else _dir[jj] = false;
}
}
}
}
}
void MInterfaceLine::getLocalVertexNum(const int i,std::vector<int> &vn)
{
switch(_numEdge[i]){
case 0 :
vn[0] = 0;
vn[1] = 1;
break;
case 1 :
vn[0] = 1;
vn[1] = 2;
break;
case 2 :
if(_numElem[i]->getType()==TYPE_TRI){vn[0]=2;vn[1]=0;}
else{vn[0]=2;vn[1]=3;}
break;
case 3 :
vn[0] = 3;
vn[1] = 0;
break;
default : Msg::Error("Impossible to get local vertex number in this case");
}
// interior edge node
for(int j=2;j<vn.size();j++)
vn[j]=_numElem[i]->getNumEdges()+_numEdge[i]*(_numElem[i]->getPolynomialOrder()-1)+(j-2);
}
// Get the u v value on element for a abscissa u on the interface element // TODO optmize by store in the class interface element the corresponding value (if many step must be compute once)??
void MInterfaceLine::getuvOnElem(const double u, double &uem, double &vem, double &uep, double &vep)
{ // w = 0 as no volume element are taken into account. The point is defined between u=-1 and u=1 on the interface element
double ue=0.,ve=0.;
for(int jj=0;jj<2;jj++){
switch(_numElem[jj]->getType()){
case TYPE_TRI :
switch(_numEdge[jj]){
case 0 :
if(_dir[jj]) {ue = 0.5 * ( 1 + u ); ve = 0.;}
else {ue = 0.5 * ( 1 - u ); ve = 0.;}
break;
case 1 :
if(_dir[jj]) {ue = 0.5 * (1 - u) ; ve = 0.5 * ( 1 + u );}
else {ue = 0.5 * (1 + u) ; ve = 0.5 * ( 1 - u );}
break;
case 2 :
if(_dir[jj]) { ue = 0; ve = 0.5 * (1 - u);}
else { ue = 0; ve = 0.5 * (1 + u);}
break;
}
break;
case TYPE_QUA :
switch(_numEdge[jj]){
case 0 :
if(_dir[jj]) {ue = u; ve = -1.;}
else {ue =-u; ve=-1;}
break;
case 1 :
if(_dir[jj]) {ue =1.; ve = u;}
else {ue = 1.; ve = -u;}
break;
case 2 :
if(_dir[jj]) {ue = -u; ve = 1;}
else {ue = u; ve = 1;}
break;
case 3 :
if(_dir[jj]) {ue = -1; ve = -u;}
else {ue = -1; ve = u;}
break;
}
break;
default : Msg::Error("The Method doesn't work for this type of element");
}
if(jj==0){uem=ue;vem=ve;}
else {uep=ue;vep=ve;}
}
}
//
// C++ Interface: terms
//
// Description: Class of interface element of line used for DG
//
//
// Author: <Gauthier BECKER>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
//
// Has to be merge with interface element defined in dg project HOW ??
#ifndef _MINTERFACELINE_H_
#define _MINTERFACELINE_H_
#include "MLine.h"
#include "MVertex.h"
#include "MInterfaceElement.h"
class MInterfaceLine : public MLineN, public MInterfaceElement{ // or don't derivate but in this case a vector with the vertices of interface element has to be save ??
protected :
// table of pointer on the two elements linked to the interface element
MElement *_numElem[2];
// edge's number linked to interface element of minus and plus element
int _numEdge[2];
// dir = true if the edge and the interface element are defined in the same sens and dir = false otherwise
bool _dir[2];
public :
MInterfaceLine(std::vector<MVertex*> &v, int num = 0, int part = 0, MElement *e_minus = 0, MElement *e_plus = 0);
// Destructor
~MInterfaceLine(){}
// Try to avoid this HOW
int getNumber() const{return this->getNum();}
// Give the number of minus 0 or plus 1 element
MElement* getElem(int index) const {return _numElem[index];}
void getuvOnElem(const double u, double &uem, double &vem, double &uep, double &vep);
// Return the edge number of element
int getEdgeOrFaceNumber(const int i) const {return _numEdge[i];}
// Return the local vertex number of interface
void getLocalVertexNum(const int i,std::vector<int> &vn);
// Compute the characteristic size of the side h_s = max_e (area_e/perimeter_e)
double getCharacteristicSize(){
double cm = this->characSize(_numElem[0]);
double cp = this->characSize(_numElem[1]);
return cm > cp ? cm : cp;
}
bool isSameDirection(const int i) const {return _dir[i];}
};
#endif // _MINTERFACELINE_H_
# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
#
# See the LICENSE.txt file for license information. Please report all
# bugs and problems to <gmsh@geuz.org>.
set(SRC
contactDomain.cpp
contactTerms.cpp
rigidCylinderContactTerms.cpp
# inline
contactFunctionSpace.h
nodeStiffnessContact.h
)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
append_gmsh_src(NonLinearSolver/contact "${SRC};${HDR}")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment