From e86a825bee472f48118667abb95057cacd951d2a Mon Sep 17 00:00:00 2001 From: Boris Sedji <sedji.boris@hotmail.com> Date: Wed, 3 Feb 2010 15:55:24 +0000 Subject: [PATCH] --- contrib/arc/Classes/FuncGradDisc.h | 192 +++++++++ contrib/arc/Classes/OctreeSolver.cpp | 488 ++++++++++++++++++++++ contrib/arc/Classes/OctreeSolver.h | 53 +++ contrib/arc/Classes/gLevelSetMesh.cpp | 21 + contrib/arc/Classes/gLevelSetMesh.h | 61 +++ contrib/arc/Classes/xFemFunctionSpace.cpp | 220 ++++++++++ contrib/arc/Classes/xFemFunctionSpace.h | 111 +++++ 7 files changed, 1146 insertions(+) create mode 100644 contrib/arc/Classes/FuncGradDisc.h create mode 100644 contrib/arc/Classes/OctreeSolver.cpp create mode 100644 contrib/arc/Classes/OctreeSolver.h create mode 100644 contrib/arc/Classes/gLevelSetMesh.cpp create mode 100644 contrib/arc/Classes/gLevelSetMesh.h create mode 100644 contrib/arc/Classes/xFemFunctionSpace.cpp create mode 100644 contrib/arc/Classes/xFemFunctionSpace.h diff --git a/contrib/arc/Classes/FuncGradDisc.h b/contrib/arc/Classes/FuncGradDisc.h new file mode 100644 index 0000000000..7bfcde4631 --- /dev/null +++ b/contrib/arc/Classes/FuncGradDisc.h @@ -0,0 +1,192 @@ +// +// Description : Heaviside function based on level set discontinuity description +// +// +// Author: <Boris Sedji>, 01/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef _FUNCGRADDISC_H_ +#define _FUNCGRADDISC_H_ + +#include "simpleFunction.h" +#include "DILevelset.h" +#include "MVertex.h" +#include "GModel.h" +//#include "gLevelSetMesh.cpp" + + +class FuncGradDisc : public simpleFunction<double> { + private : + + gLevelset *_ls; + GModel * _pModel; + + + public : + FuncGradDisc(gLevelset *ls,GModel *pModel){ + _ls = ls; + _pModel = pModel; + + } + virtual double operator () (double x,double y,double z) const + { + double test = (*_ls)(x,y,z); + SPoint3 p(x,y,z); + MElement *e = _pModel->getMeshElementByCoord(p); + if (e->getParent()) e = e->getParent(); + int numV = e->getNumVertices(); + double f = 0; + for (int i = 0;i<numV;i++) + { + f = f + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())); + } + f = f - abs((*_ls)(x,y,z)); + return f; + } + + double operator () (double x,double y,double z, MElement *e) const { + + SPoint3 p(x,y,z); + if (e->getParent()) e = e->getParent(); + int numV = e->getNumVertices(); + double xyz[3] = {x,y,z}; + double uvw[3]; + e->xyz2uvw(xyz,uvw); + double val[30]; + e->getShapeFunctions(uvw[0], uvw[1], uvw[2], val); + double f = 0; + for (int i = 0;i<numV;i++) + { + f = f + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*val[i]; + } + f = f - abs((*_ls)(x,y,z)); + return f; + + } + + virtual void gradient (double x, double y, double z, + double & dfdx, double & dfdy, double & dfdz) const + { + + SPoint3 p(x,y,z); + MElement *e = _pModel->getMeshElementByCoord(p); + if (e->getParent()) e = e->getParent(); + int numV = e->getNumVertices(); + double xyz[3] = {x,y,z}; + double uvw[3]; + e->xyz2uvw(xyz,uvw); + double gradsuvw[256][3]; + e->getGradShapeFunctions(uvw[0],uvw[1],uvw[2],gradsuvw); + + double jac[3][3]; + double invjac[3][3]; + double dNdx; + double dNdy; + double dNdz; + const double detJ = e->getJacobian(uvw[0], uvw[1], uvw[2], jac); + inv3x3(jac, invjac); + + dfdx = 0; + dfdy = 0; + dfdz = 0; + + if ((*_ls)(x,y,z)>0) + { + for (int i = 0;i<numV;i++) + { + dNdx = invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2]; + dNdy = invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2]; + dNdz = invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2]; + + dfdx = dfdx + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdx ; + dfdx = dfdx - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdx; + dfdy = dfdy + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdy ; + dfdy = dfdy - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdy; + dfdz = dfdz + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdz ; + dfdz = dfdz - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdz; + } + }else + { + for (int i = 0;i<numV;i++) + { + dNdx = invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2]; + dNdy = invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2]; + dNdz = invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2]; + + dfdx = dfdx + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdx ; + dfdx = dfdx + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdx; + dfdy = dfdy + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdy ; + dfdy = dfdy + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdy; + dfdz = dfdz + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdz ; + dfdz = dfdz + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdz; + } + } + + + + } + + + void gradient (double x, double y, double z, + double & dfdx, double & dfdy, double & dfdz,MElement *e) const + { + + SPoint3 p(x,y,z); + if (e->getParent()) e = e->getParent(); + int numV = e->getNumVertices(); + double xyz[3] = {x,y,z}; + double uvw[3]; + e->xyz2uvw(xyz,uvw); + double gradsuvw[256][3]; + e->getGradShapeFunctions(uvw[0],uvw[1],uvw[2],gradsuvw); + + double jac[3][3]; + double invjac[3][3]; + double dNdx; + double dNdy; + double dNdz; + const double detJ = e->getJacobian(uvw[0], uvw[1], uvw[2], jac); + inv3x3(jac, invjac); + + dfdx = 0; + dfdy = 0; + dfdz = 0; + + if ((*_ls)(x,y,z)<0) + { + for (int i = 0;i<numV;i++) + { + dNdx = invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2]; + dNdy = invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2]; + dNdz = invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2]; + + dfdx = dfdx + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdx ; + dfdx = dfdx - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdx; + dfdy = dfdy + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdy ; + dfdy = dfdy - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdy; + dfdz = dfdz + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdz ; + dfdz = dfdz - (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdz; + } + }else + { + for (int i = 0;i<numV;i++) + { + dNdx = invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2]; + dNdy = invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2]; + dNdz = invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2]; + + dfdx = dfdx + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdx ; + dfdx = dfdx + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdx; + dfdy = dfdy + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdy ; + dfdy = dfdy + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdy; + dfdz = dfdz + abs((*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z()))*dNdz ; + dfdz = dfdz + (*_ls)(e->getVertex(i)->x(),e->getVertex(i)->y(),e->getVertex(i)->z())*dNdz; + } + } + } +}; + +#endif diff --git a/contrib/arc/Classes/OctreeSolver.cpp b/contrib/arc/Classes/OctreeSolver.cpp new file mode 100644 index 0000000000..2401e6f013 --- /dev/null +++ b/contrib/arc/Classes/OctreeSolver.cpp @@ -0,0 +1,488 @@ +// +// Description : +// +// +// Author: <Boris Sedji>, 01/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + + + +#include <string.h> +#include "GmshConfig.h" +#include "elasticitySolver.h" +#include "linearSystemCSR.h" +#include "linearSystemPETSc.h" +#include "linearSystemGMM.h" +#include "Numeric.h" +#include "GModel.h" +#include "functionSpace.h" +#include "terms.h" +#include "solverAlgorithms.h" +#include "quadratureRules.h" +#include "solverField.h" +#if defined(HAVE_POST) +#include "PView.h" +#include "PViewData.h" +#include "MPoint.h" +#endif + +#include "OctreeSolver.h" +#include "DILevelset.h" +#include "NodeEnrichedFS.cpp" +#include "gLevelSetMesh.h" + +#include "groupOfElements.h" +#include "FuncGradDisc.h" + +#include "xFemFunctionSpace.cpp" + + +OctreeSolver::~OctreeSolver() +{ + //delete _funcEnrichment; +} + + +void OctreeSolver::setMesh(const std::string &meshFileName) +{ + std::cout<< "Mesh file : " << meshFileName.c_str() <<"\n"; + GModel *p = new GModel(); + p->readMSH(meshFileName.c_str()); + _dim = p->getNumRegions() ? 3 : 2; + int tag = 1; + //if (_ls) delete _ls; + gLevelSetMesh *ls = new gLevelSetMesh(&_LevelSetValue,p,tag); + GModel *pcut = p->buildCutGModel(ls); + pModel = pcut; + std::string ModelName = meshFileName.c_str() ; + ModelName.erase(ModelName.find(".",0),4); + ModelName.insert(ModelName.length(),"_cutLS.msh"); + pcut->writeMSH(ModelName,2.1,false,false); + GModel::setCurrent(pModel); + _ls = new gLevelSetMesh(&_LevelSetValue,p,tag); + //delete p; + delete ls; +} + +void OctreeSolver::setLevelSetValue(const std::string &fn) +{ + FILE *f = fopen(fn.c_str(), "r"); + char what[256]; + int num; + float val; + int numnodes; + fscanf(f, "%s", what); + std::cout<<" Fichier levelset :"<< fn << "\n"; + printf("%s",what); + fscanf(f, "%d", &numnodes); + std::cout<<" numnodes :"<< numnodes << "\n"; + while(!feof(f)){ + fscanf(f,"%d %f",&num,&val); + _LevelSetValue[num] = val ; + //std::cout<<"_LevelSetValue : "<< val << "\n"; + } + fclose(f); +} + + + + +void OctreeSolver::readInputFile(const std::string &fn) +{ + FILE *f = fopen(fn.c_str(), "r"); + char what[256]; + while(!feof(f)){ + if(fscanf(f, "%s", what) != 1) return; + if (!strcmp(what, "ElasticDomain")){ + GModel::setCurrent(pModel); + elasticField field; + int physical; + if(fscanf(f, "%d %lf %lf", &physical, &field._E, &field._nu) != 3) return; + field._tag = _tag; + field.g = new groupOfElements (_dim, physical); + elasticFields.push_back(field); + } + else if (!strcmp(what, "Void")){ + // elasticField field; + // create enrichment ... + // create the group ... + // assign a tag + // elasticFields.push_back(field); + } + else if (!strcmp(what, "NodeDisplacement")){ + double val; + int node, comp; + if(fscanf(f, "%d %d %lf", &node, &comp, &val) != 3) return; + dirichletBC diri; + diri.g = new groupOfElements (0, node); + diri._f= simpleFunction<double>(val); + diri._comp=comp; + diri._tag=node; + diri.onWhat=BoundaryCondition::ON_VERTEX; + allDirichlet.push_back(diri); + } + else if (!strcmp(what, "EdgeDisplacement")){ + GModel::setCurrent(pModel); + double val; + int edge, comp; + if(fscanf(f, "%d %d %lf", &edge, &comp, &val) != 3) return; + dirichletBC diri; + diri.g = new groupOfElements (1, edge); + diri._f= simpleFunction<double>(val); + diri._comp=comp; + diri._tag=edge; + diri.onWhat=BoundaryCondition::ON_EDGE; + allDirichlet.push_back(diri); + } + else if (!strcmp(what, "FaceDisplacement")){ + double val; + int face, comp; + if(fscanf(f, "%d %d %lf", &face, &comp, &val) != 3) return; + dirichletBC diri; + diri.g = new groupOfElements (2, face); + diri._f= simpleFunction<double>(val); + diri._comp=comp; + diri._tag=face; + diri.onWhat=BoundaryCondition::ON_FACE; + allDirichlet.push_back(diri); + } + else if (!strcmp(what, "NodeForce")){ + double val1, val2, val3; + int node; + if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4) return; + neumannBC neu; + neu.g = new groupOfElements (0, node); + neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3)); + neu._tag=node; + neu.onWhat=BoundaryCondition::ON_VERTEX; + allNeumann.push_back(neu); + } + else if (!strcmp(what, "EdgeForce")){ + GModel::setCurrent(pModel); + double val1, val2, val3; + int edge; + if(fscanf(f, "%d %lf %lf %lf", &edge, &val1, &val2, &val3) != 4) return; + neumannBC neu; + neu.g = new groupOfElements (1, edge); + neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3)); + neu._tag=edge; + neu.onWhat=BoundaryCondition::ON_EDGE; + allNeumann.push_back(neu); + } + else if (!strcmp(what, "FaceForce")){ + double val1, val2, val3; + int face; + if(fscanf(f, "%d %lf %lf %lf", &face, &val1, &val2, &val3) != 4) return; + neumannBC neu; + neu.g = new groupOfElements (2, face); + neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3)); + neu._tag=face; + neu.onWhat=BoundaryCondition::ON_FACE; + allNeumann.push_back(neu); + } + else if (!strcmp(what, "VolumeForce")){ + double val1, val2, val3; + int volume; + if(fscanf(f, "%d %lf %lf %lf", &volume, &val1, &val2, &val3) != 4) return; + neumannBC neu; + neu.g = new groupOfElements (3, volume); + neu._f= simpleFunction<SVector3>(SVector3(val1, val2, val3)); + neu._tag=volume; + neu.onWhat=BoundaryCondition::ON_VOLUME; + allNeumann.push_back(neu); + } + else if (!strcmp(what, "LevelSetFile")){ + char name[245]; + if(fscanf(f, "%s", name) != 1) return; + setLevelSetValue(name); + } + else if (!strcmp(what, "MeshFile")){ + char name[245]; + if(fscanf(f, "%s", name) != 1) return; + setMesh(name); + } + else { + Msg::Error("Invalid input : %s", what); +// return; + } + } + fclose(f); +} + + +void OctreeSolver::solve(){ + + //GModel::setCurrent(pModel); + +#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 + if (pAssembler) delete pAssembler; + pAssembler = new dofManager<double>(lsys); + + // determine all enriched nodes and save in map member _TagEnrichedVertex + + for (int i = 0; i < elasticFields.size(); ++i){ + std::set<MElement*>::const_iterator it = elasticFields[i].g->begin(); + for ( ; it != elasticFields[i].g->end(); ++it) + { + MElement *e = *it; + if (e->getParent()) // if element got parents + { + for (int k = 0; k < e->getParent()->getNumVertices(); ++k) + { // for all vertices in the element parent + _TagEnrichedVertex.insert(e->getParent()->getVertex(k)->getNum()); + } + } + } + } + + //_TagEnrichedVertex.clear(); + _EnrichComp.insert(0); + _EnrichComp.insert(1); + _EnrichComp.insert(2); + + _funcEnrichment = new FuncGradDisc(_ls,pModel); + + + // space function definition // + // Lagrange space with normal dofs + FunctionSpace<SVector3> *LagrangeSpace; + if (_dim==3) LagrangeSpace=new VectorLagrangeFunctionSpace(_tag); + if (_dim==2) LagrangeSpace=new VectorLagrangeFunctionSpace(_tag,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y); + + // Filtered space + FilterNodeEnriched *filter = new FilterNodeEnriched(&_TagEnrichedVertex , &_EnrichComp); + FilteredFS<SVector3> *LagrangeFiltered = new FilteredFS<SVector3>(LagrangeSpace,filter); + + // xfem filtered space + xFemFS<SVector3> *xFemLagrange = new xFemFS<SVector3>(LagrangeFiltered,_funcEnrichment); + + // Composite space : xfem + Lagrange + if (LagSpace) delete LagSpace; + + LagSpace = new CompositeFunctionSpace<SVector3>(*LagrangeSpace, *xFemLagrange); + + + std::cout << "Dirichlet BC"<< std::endl; + for (unsigned int i = 0; i < allDirichlet.size(); i++) + { + FilterDofComponent filter(allDirichlet[i]._comp); + FixNodalDofs(*LagSpace,allDirichlet[i].g->begin(),allDirichlet[i].g->end(),*pAssembler,allDirichlet[i]._f,filter); + } + + // we number the dofs : when a dof is numbered, it cannot be numbered + // again with another number. + for (unsigned int i = 0; i < elasticFields.size(); ++i) + { + NumberDofs(*LagSpace, elasticFields[i].g->begin(), elasticFields[i].g->end(),*pAssembler); + } + + // Now we start the assembly process + // First build the force vector + + GaussQuadrature Integ_Boundary(GaussQuadrature::Val); + std::cout << "Neumann BC"<< std::endl; + for (unsigned int i = 0; i < allNeumann.size(); i++) + { + LoadTerm<SVector3> Lterm(*LagSpace,allNeumann[i]._f); + Assemble(Lterm,*LagSpace,allNeumann[i].g->begin(),allNeumann[i].g->end(),Integ_Boundary,*pAssembler); + } + +// bulk material law + + GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad); + for (unsigned int i = 0; i < elasticFields.size(); i++) + { + IsotropicElasticTerm Eterm(*LagSpace,elasticFields[i]._E,elasticFields[i]._nu); +// LaplaceTerm<SVector3,SVector3> Eterm(*LagSpace); + Assemble(Eterm,*LagSpace,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,*pAssembler); + } + + printf("-- done assembling!\n"); + std::cout<<"Dof Number : " << pAssembler->sizeOfR() <<"\n"; + lsys->systemSolve(); + printf("-- done solving!\n"); + double energ=0; + for (unsigned int i = 0; i < elasticFields.size(); i++) + { + SolverField<SVector3> Field(pAssembler, LagSpace); + IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu); + BilinearTermToScalarTerm<SVector3,SVector3> Elastic_Energy_Term(Eterm); + Assemble(Elastic_Energy_Term,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,energ); + } + printf("elastic energy=%f\n",energ); + +// +// // determine all enriched nodes and save in map member _TagEnrichedVertex +// +//// for (int i = 0; i < elasticFields.size(); ++i){ +//// std::set<MElement*>::const_iterator it = elasticFields[i].g->begin(); +//// for ( ; it != elasticFields[i].g->end(); ++it) +//// { +//// MElement *e = *it; +//// if (e->getParent()) // if element got parents +//// { +//// for (int k = 0; k < e->getParent()->getNumVertices(); ++k) +//// { // for all vertices in the element parent +//// _TagEnrichedVertex.insert(e->getParent()->getVertex(k)->getNum()); +//// } +//// } +//// } +//// } +// +// _TagEnrichedVertex.clear(); +// +// // enriched composant +// _EnrichComp.push_back(0); +// _EnrichComp.push_back(1); +// _EnrichComp.push_back(2); +// +// // level set definition (in .dat ??) +// double a(0.), b(1.), c(0.), d(-4.7); +// int n(1); // pour level set +// gLevelset *ls = new gLevelsetPlane(a, b, c, d, n); +// _funcEnrichment = new FuncHeaviside(ls); +// +// +// // space function definition +// if (LagSpace) delete LagSpace; +// FunctionSpace<SVector3> *NLagSpace; +// if (LagSpace) delete LagSpace; +// if (_dim==3) NLagSpace=new VectorLagrangeFunctionSpace(_tag); +// if (_dim==2) NLagSpace=new VectorLagrangeFunctionSpace(_tag,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y); +// LagSpace = NLagSpace; +// //LagSpace = new NodeEnrichedFS<SVector3>(NLagSpace, &_TagEnrichedVertex ,&_EnrichComp, _funcEnrichment); +// //LagSpace = new ScalarXFEMToVectorFS(_tag,ScalarXFEMToVectorFS::VECTOR_X,ScalarXFEMToVectorFS::VECTOR_Y,_TagEnrichedVertex,_funcEnrichment); +// +// // 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 (int i = 0; i < elasticFields.size(); ++i){ +//// groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); +//// for ( ; it != elasticFields[i].g->end(); ++it) +//// { +//// MElement *e = *it; +//// std::cout<<"elasticfield e num : "<<e->getNum()<<"\n"; +//// if (e->getParent()) std::cout<<"e->getParent : "<<e->getParent()->getNum()<<"\n"; +//// std::cout<<"vertex num 1: "<<e->getVertex(0)->getNum()<<"\n"; +//// std::cout<<"vertex num 2: "<<e->getVertex(1)->getNum()<<"\n"; +//// std::cout<<"vertex num 3: "<<e->getVertex(2)->getNum()<<"\n"; +//// } +//// } +// +// +// +// +// std::cout << "Dirichlet BC"<< std::endl; +// for (unsigned int i = 0; i < allDirichlet.size(); i++) +// { +//// std::set<MElement*>::const_iterator it = allDirichlet[i].g->begin(); +//// for (;it!=allDirichlet[i].g->end();it++) +//// { +//// MElement *e = (*it); +////// std::cout<<"dirch tag: "<<allDirichlet[i]._tag<<"\n"; +////// +////// std::cout << "test" << std::endl; +//// +//// std::cout<<"dirich e num : "<<e->getNum()<<"\n"; +//// std::cout<<"y pos : "<< e->getVertex(0)->y() <<"\n"; +//// e->getVertex(0)->y(); +//// +//// //std::cout<<"y pos : "<< e->getNum() <<"\n"; +//// //printf("y pos : %d",e->getVertex(1)->y()); +//// } +// +// FilterDofComponent filter(allDirichlet[i]._comp); +// FixNodalDofs(*LagSpace,allDirichlet[i].g->begin(),allDirichlet[i].g->end(),*pAssembler,allDirichlet[i]._f,filter); +// } +// +// // we number the dofs : when a dof is numbered, it cannot be numbered +// // again with another number. +// for (unsigned int i = 0; i < elasticFields.size(); ++i) +// { +// NumberDofs(*LagSpace, elasticFields[i].g->begin(), elasticFields[i].g->end(),*pAssembler); +// } +// +// // Now we start the assembly process +// // First build the force vector +// +// GaussQuadrature Integ_Boundary(GaussQuadrature::Val); +// std::cout << "Neumann BC"<< std::endl; +// for (unsigned int i = 0; i < allNeumann.size(); i++) +// { +// LoadTerm<SVector3> Lterm(*LagSpace,allNeumann[i]._f); +// Assemble(Lterm,*LagSpace,allNeumann[i].g->begin(),allNeumann[i].g->end(),Integ_Boundary,*pAssembler); +// } +// +//// bulk material law +// +// GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad); +// for (unsigned int i = 0; i < elasticFields.size(); i++) +// { +// IsotropicElasticTerm Eterm(*LagSpace,elasticFields[i]._E,elasticFields[i]._nu); +//// LaplaceTerm<SVector3,SVector3> Eterm(*LagSpace); +// Assemble(Eterm,*LagSpace,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,*pAssembler); +// } +// +// printf("-- done assembling!\n"); +// std::cout<<"Dof Number : " << pAssembler->sizeOfR() <<"\n"; +// lsys->systemSolve(); +// printf("-- done solving!\n"); +// +// double energ=0; +// for (unsigned int i = 0; i < elasticFields.size(); i++) +// { +// SolverField<SVector3> Field(pAssembler, LagSpace); +// IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu); +// BilinearTermToScalarTerm<SVector3,SVector3> Elastic_Energy_Term(Eterm); +// Assemble(Elastic_Energy_Term,elasticFields[i].g->begin(),elasticFields[i].g->end(),Integ_Bulk,energ); +// } +// printf("elastic energy=%f\n",energ); +// for (int i=0;i<pAssembler->sizeOfR();i++) std::cout<< lsys->getFromSolution(i) << "\n"; + +} + + + +PView* OctreeSolver::buildDisplacementView (const std::string &postFileName) +{ + + std::set<MVertex*> v; + for (unsigned int i = 0; i < elasticFields.size(); ++i) + { + for (groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end(); ++it) + { + MElement *e=*it; + if (e->getParent()) e=e->getParent(); + for (int j = 0; j < e->getNumVertices(); ++j) v.insert(e->getVertex(j)); + } + } + std::map<int, std::vector<double> > data; + SolverField<SVector3> Field(pAssembler, LagSpace); + for ( std::set<MVertex*>::iterator it = v.begin(); it != v.end(); ++it) + { + SVector3 val; + MPoint p(*it); + Field.f(&p,0,0,0,val); + std::vector<double> vec(3);vec[0]=val(0);vec[1]=val(1);vec[2]=val(2); +// std::cout<<"ver num : " << (*it)->getNum() <<"\n" ; +// std::cout<<"( "<<vec[0]<<" "<<vec[1]<<" "<<vec[2]<<" )\n"; + data[(*it)->getNum()]=vec; + } + PView *pv = new PView (postFileName, "NodeData", pModel, data, 0.0); + return pv; + +} + diff --git a/contrib/arc/Classes/OctreeSolver.h b/contrib/arc/Classes/OctreeSolver.h new file mode 100644 index 0000000000..4298f1e7c9 --- /dev/null +++ b/contrib/arc/Classes/OctreeSolver.h @@ -0,0 +1,53 @@ +// +// Description : +// +// +// Author: <Boris Sedji>, 01/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + + +#ifndef _OCTREE_SOLVER_H_ +#define _OCTREE_SOLVER_H_ + +#include "elasticitySolver.h" +#include "simpleFunction.h" +//#include "QuadtreeLSImage.h" + +#include "gLevelSetMesh.cpp" +#include "FuncGradDisc.h" + +class OctreeSolver : public elasticitySolver +{ + protected : + + // map containing the tag of vertex and enriched status + std::set<int > _TagEnrichedVertex; + // enriched comp + std::set<int> _EnrichComp; + // simple multiplying function enrichment to enrich the space function + simpleFunction<double> *_funcEnrichment; + // level set value + std::map<int, double > _LevelSetValue; + // level set + gLevelSetMesh *_ls; + + public : + + OctreeSolver(int tag) : elasticitySolver(tag) {} + ~OctreeSolver(); + // + virtual void readInputFile(const std::string &fn); + // create a GModel and determine de dimension of mesh in meshFileName + virtual void setMesh(const std::string &meshFileName); + // set the map _LevelSetValue + void setLevelSetValue(const std::string &LevelSetValueFileName); + // system solve, read the .dat file, fill tagEnrichedVertex, fill funcEnrichment, solve + virtual void solve(); + virtual PView *buildDisplacementView(const std::string &postFileName); +}; + +#endif + diff --git a/contrib/arc/Classes/gLevelSetMesh.cpp b/contrib/arc/Classes/gLevelSetMesh.cpp new file mode 100644 index 0000000000..c831283971 --- /dev/null +++ b/contrib/arc/Classes/gLevelSetMesh.cpp @@ -0,0 +1,21 @@ +// +// Description : +// +// +// Author: <Boris Sedji>, 01/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "gLevelSetMesh.h" + +#include "SPoint3.h" +#include "MElement.h" +#include "MVertex.h" +#include "GModel.h" + +double gLevelSetMesh::getVertexValue(MVertex *v) const +{ + return (*_LevelSetValue)[v->getNum()]; +} diff --git a/contrib/arc/Classes/gLevelSetMesh.h b/contrib/arc/Classes/gLevelSetMesh.h new file mode 100644 index 0000000000..57ed49faf0 --- /dev/null +++ b/contrib/arc/Classes/gLevelSetMesh.h @@ -0,0 +1,61 @@ +// +// Description : +// +// +// Author: <Boris Sedji>, 01/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef _GLEVELSET_MESH_H_ +#define _GLEVELSET_MESH_H_ + +#include "DILevelset.h" +#include "MVertex.h" +#include "GModel.h" + +class gLevelSetMesh : public gLevelsetPrimitive +{ + protected : + + std::map<int, double > *_LevelSetValue; + GModel * _pModel; + + public : + gLevelSetMesh(std::map<int, double > * LevelSetValue, GModel *p, int &tag) : gLevelsetPrimitive(tag) + { + _LevelSetValue = LevelSetValue; + _pModel = p; + }; + // return negative value inward and positive value outward + virtual double operator() (const double &x, const double &y, const double &z) const + { + SPoint3 p(x,y,z); + MElement *e = _pModel->getMeshElementByCoord(p); + if (e->getParent()) e = e->getParent(); + int numV = e->getNumVertices(); + double xyz[3] = {x,y,z}; + double uvw[3]; + e->xyz2uvw(xyz,uvw); + double s[20]; + e->getShapeFunctions(uvw[0],uvw[1],uvw[2],s); + double ls = 0; + +// std::cout<<"xyz : "<< x << " "<<y <<" "<<z<<"\n"; + for (int i = 0;i<numV;i++) + { +// std::cout<<"Vertex xyz :"<< e->getVertex(i)->x() << " "<<e->getVertex(i)->y() <<" "<<e->getVertex(i)->z()<<"\n"; +// std::cout<<"Vertex LS : "<< getVertexValue(e->getVertex(i)) <<"\n"; + ls = ls + s[i]*getVertexValue(e->getVertex(i)); + } +// std::cout<<"=> LS : "<< ls <<"\n"; + return ls; + } + virtual double getVertexValue(MVertex *v) const; + int type() const {return LSMESH;} +}; + + + +#endif diff --git a/contrib/arc/Classes/xFemFunctionSpace.cpp b/contrib/arc/Classes/xFemFunctionSpace.cpp new file mode 100644 index 0000000000..06fc20fadc --- /dev/null +++ b/contrib/arc/Classes/xFemFunctionSpace.cpp @@ -0,0 +1,220 @@ +// +// Description : Filtered and xFem function space definition +// +// +// Author: <Eric Bechet>::<Boris Sedji>, 02/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "xFemFunctionSpace.h" + + +template <class T> void xFemFS<T>::f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals) +{ + // We need parent parameters + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + // Get the spacebase valsd + std::vector<ValType> valsd; + xFemFunctionSpace<T>::_spacebase->f(elep,u,v,w,valsd); + + int nbdofs=valsd.size(); + int curpos=vals.size(); // if in composite function space + vals.reserve(curpos+nbdofs); + + // then enriched dofs so the order is ex:(a2x,a2y,a3x,a3y) + if (nbdofs>0) // if enriched + { + // Enrichment function calcul + SPoint3 p; + elep->pnt(u, v, w, p); // parametric to cartesian coordinates + double func; + func = (*_funcEnrichment)(p.x(), p.y(), p.z(),elep); + for (int i=0 ;i<nbdofs;i++) + { + vals.push_back(valsd[i]*func); + } + } +} + +template <class T> void xFemFS<T>::gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) +{ + + // We need parent parameters + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + // Get the spacebase gradsd + std::vector<GradType> gradsd; + xFemFunctionSpace<T>::_spacebase->gradf(elep,u,v,w,gradsd); + + + int nbdofs=gradsd.size(); + + // We need spacebase valsd to compute total gradient + std::vector<ValType> valsd; + xFemFunctionSpace<T>::_spacebase->f(elep,u,v,w,valsd); + + int curpos=grads.size(); // if in composite function space + grads.reserve(curpos+nbdofs); + + // then enriched dofs so the order is ex:(a2x,a2y,a3x,a3y) + if (nbdofs>0) // if enriched + { + double df[3]; + SPoint3 p; + elep->pnt(u, v, w, p); + _funcEnrichment->gradient (p.x(), p.y(),p.z(),df[0],df[1],df[2],elep); + ValType gradfuncenrich(df[0],df[1],df[2]); + + // Enrichment function calcul + + double func; + func = (*_funcEnrichment)(p.x(), p.y(), p.z(),elep); + + for (int i=0 ;i<nbdofs;i++) + { + GradType GradFunc; + tensprod(valsd[i],gradfuncenrich,GradFunc); + grads.push_back(gradsd[i]*func + GradFunc); + } + } +} + +template <class T> int xFemFS<T>::getNumKeys(MElement *ele) +{ + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + int nbdofs = xFemFunctionSpace<T>::_spacebase->getNumKeys(ele); + return nbdofs; +} + +template <class T> void xFemFS<T>::getKeys(MElement *ele, std::vector<Dof> &keys) +{ + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + int normalk=xFemFunctionSpace<T>::_spacebase->getNumKeys(elep); + + std::vector<Dof> bufk; + bufk.reserve(normalk); + xFemFunctionSpace<T>::_spacebase->getKeys(elep,bufk); + int normaldofs=bufk.size(); + int nbdofs = normaldofs; + + int curpos=keys.size(); + keys.reserve(curpos+nbdofs); + + // get keys so the order is ex:(a2x,a2y,a3x,a3y) + // enriched dof tagged with ( i2 -> i2 + 1 ) + for (int i=0 ;i<nbdofs;i++) + { + int i1,i2; + Dof::getTwoIntsFromType(bufk[i].getType(), i1,i2); + keys.push_back(Dof(bufk[i].getEntity(),Dof::createTypeWithTwoInts(i1,i2+1))); + } +} + + +// Filtered function space +// + +template <class T> void FilteredFS<T>::f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals) +{ + // We need parent parameters + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + std::vector<ValType> valsd; + + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->f(elep,u,v,w,valsd); + + int normalk=FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getNumKeys(elep); + std::vector<Dof> bufk; + bufk.reserve(normalk); + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getKeys(elep,bufk); + + for (int i=0;i<bufk.size();i++) + { + if ((*FilteredFunctionSpace<T,FilterNodeEnriched>::_filter)(bufk[i])) + vals.push_back(valsd[i]); + } + +} + + +template <class T> void FilteredFS<T>::gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads) +{ + // We need parent parameters + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + // Get space base gradsd + std::vector<GradType> gradsd; + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->gradf(elep,u,v,w,gradsd); + + // Get numkeys + int normalk=FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getNumKeys(elep); + std::vector<Dof> bufk; + bufk.reserve(normalk); + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getKeys(elep,bufk); + + for (int i=0;i<bufk.size();i++) + { + if ( (*FilteredFunctionSpace<T,FilterNodeEnriched>::_filter)(bufk[i])) + grads.push_back(gradsd[i]); + } + +} + +template <class T> int FilteredFS<T>::getNumKeys(MElement *ele) +{ + MElement *elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + int nbdofs = 0; + + int normalk=FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getNumKeys(elep); + std::vector<Dof> bufk; + bufk.reserve(normalk); + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getKeys(elep,bufk); + + for (int i=0;i<bufk.size();i++) + { + if ( (*FilteredFunctionSpace<T,FilterNodeEnriched>::_filter)(bufk[i])) + nbdofs = nbdofs + 1; + } + return nbdofs; +} + +template <class T> void FilteredFS<T>::getKeys(MElement *ele, std::vector<Dof> &keys) +{ + MElement * elep; + if (ele->getParent()) elep = ele->getParent(); + else elep = ele; + + int normalk=FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getNumKeys(elep); + + std::vector<Dof> bufk; + bufk.reserve(normalk); + FilteredFunctionSpace<T,FilterNodeEnriched>::_spacebase->getKeys(elep,bufk); + int normaldofs=bufk.size(); + int nbdofs = 0; + + for (int i=0;i<bufk.size();i++) + { + if ( (*FilteredFunctionSpace<T,FilterNodeEnriched>::_filter)(bufk[i])) + keys.push_back(bufk[i]); + } +} + diff --git a/contrib/arc/Classes/xFemFunctionSpace.h b/contrib/arc/Classes/xFemFunctionSpace.h new file mode 100644 index 0000000000..b081870d5a --- /dev/null +++ b/contrib/arc/Classes/xFemFunctionSpace.h @@ -0,0 +1,111 @@ +// +// Description : Filtered and xFem function space definition +// +// +// Author: <Eric Bechet>::<Boris Sedji>, 02/2010 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef _XFEMFS_H_ +#define _XFEMFS_H_ + +#include "simpleFunction.h" + +class FilterNodeEnriched +{ + + private : + + std::set<int> *_TagEnrichedVertex; + std::set<int> * _EnrichComp; + + public : + + FilterNodeEnriched(std::set<int > * TagEnrichedVertex , std::set<int> * EnrichComp) + { + _TagEnrichedVertex = TagEnrichedVertex; + _EnrichComp = EnrichComp; + } + + virtual bool operator () (Dof & key) const + { + std::set<int>::iterator it1; + std::set<int>::iterator it2; + int i1,i2; + Dof::getTwoIntsFromType(key.getType(), i1,i2); + it2 = _EnrichComp->find(i1); + it1 = _TagEnrichedVertex->find(key.getEntity()); + if (it1!=_TagEnrichedVertex->end() & it2 != _EnrichComp->end()) + { + return true; + } + else return false; + } + + //std::vector<int> * getEnrichComp(){return _EnrichComp;} + +// void SetEnrichedVertex(MElement *elep, std::vector<int> & EnrichedVertex,int &nbdofs) +// { +// EnrichedVertex.clear(); +// nbdofs = 0; +// for (int i=0 ;i<elep->getNumVertices();i++) +// { +// std::set<int>::iterator it; +// it = _TagEnrichedVertex->find(elep->getVertex(i)->getNum()); +// if (it!=_TagEnrichedVertex->end()) +// { +// EnrichedVertex.push_back(i); +// nbdofs = nbdofs + 1*_EnrichComp->size(); // enriched dof +// } +// } +// } +}; + + +template<class T> +class xFemFS : public xFemFunctionSpace<T> +{ + + public : + + typedef typename TensorialTraits<T>::ValType ValType; + typedef typename TensorialTraits<T>::GradType GradType; + + protected: + + simpleFunction<double> *_funcEnrichment; + + public: + + xFemFS(FunctionSpace<T>* spacebase, simpleFunction<double> *funcEnrichment) : xFemFunctionSpace<T>(spacebase),_funcEnrichment(funcEnrichment) + {}; + + virtual void f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals); + virtual void gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads); + virtual int getNumKeys(MElement *ele); + virtual void getKeys(MElement *ele, std::vector<Dof> &keys); +}; + + + +template<class T> +class FilteredFS : public FilteredFunctionSpace<T,FilterNodeEnriched> +{ + + public : + + typedef typename TensorialTraits<T>::ValType ValType; + typedef typename TensorialTraits<T>::GradType GradType; + + public: + FilteredFS(FunctionSpace<T>* spacebase, FilterNodeEnriched *filter) : FilteredFunctionSpace<T,FilterNodeEnriched> (spacebase,filter) + {} + virtual void f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals); + virtual void gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads); + virtual int getNumKeys(MElement *ele); + virtual void getKeys(MElement *ele, std::vector<Dof> &keys); +}; + +#endif -- GitLab