From e546b03d89b7ec06f28fd2dd28a700d8ff81290c Mon Sep 17 00:00:00 2001 From: Eric Bechet <eric.bechet@ulg.ac.be> Date: Sat, 12 Dec 2009 08:21:24 +0000 Subject: [PATCH] -added assembly for linear terms in dofmanager -done BC with linear terms in elasiticiy --- Solver/dofManager.h | 81 +++++++++++------- Solver/elasticitySolver.cpp | 160 ++++++++++++++++++++++++++---------- Solver/functionSpace.h | 2 +- Solver/terms.h | 38 ++++++++- 4 files changed, 209 insertions(+), 72 deletions(-) diff --git a/Solver/dofManager.h b/Solver/dofManager.h index 5ffcbf3b69..91bd3cf76b 100644 --- a/Solver/dofManager.h +++ b/Solver/dofManager.h @@ -179,48 +179,73 @@ class dofManager{ } for (unsigned int i = 0; i < R.size(); i++){ if (NR[i] != -1){ - for (unsigned int j = 0; j < C.size(); j++){ - if (NC[j] != -1){ - _current->addToMatrix(NR[i], NC[j], m(i, j)); - } - else{ - typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C[j]); - if (itFixed != fixed.end()){ - _current->addToRightHandSide(NR[i], -m(i,j) * itFixed->second); - } - } - } + for (unsigned int j = 0; j < C.size(); j++){ + if (NC[j] != -1){ + _current->addToMatrix(NR[i], NC[j], m(i, j)); + } + else{ + typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(C[j]); + if (itFixed != fixed.end()){ + _current->addToRightHandSide(NR[i], -m(i,j) * itFixed->second); + } + } + } } } } - inline void assemble(std::vector<Dof> &R, fullMatrix<dataMat> &m) + + inline void assemble(std::vector<Dof> &R, fullVector<dataMat> &m) // for linear forms { if (!_current->isAllocated()) _current->allocate(unknown.size()); - std::vector<int> NR(R.size()); - - for (unsigned int i = 0; i < R.size(); i++){ + for (unsigned int i = 0; i < R.size(); i++) + { std::map<Dof, int>::iterator itR = unknown.find(R[i]); if (itR != unknown.end()) NR[i] = itR->second; else NR[i] = -1; } + for (unsigned int i = 0; i < R.size(); i++) + { + if (NR[i] != -1) + { + _current->addToRightHandSide(NR[i], m(i)); + } + } + } - for (unsigned int i = 0; i < R.size(); i++){ - if (NR[i] != -1){ - for (unsigned int j = 0; j < R.size(); j++){ - if (NR[j] != -1){ - _current->addToMatrix(NR[i], NR[j], m(i, j)); - } - else{ - typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(R[j]); - if (itFixed != fixed.end()){ - _current->addToRightHandSide(NR[i], -m(i, j) * itFixed->second); - } - } - } + + inline void assemble(std::vector<Dof> &R, fullMatrix<dataMat> &m) + { + if (!_current->isAllocated()) _current->allocate(unknown.size()); + std::vector<int> NR(R.size()); + for (unsigned int i = 0; i < R.size(); i++) + { + std::map<Dof, int>::iterator itR = unknown.find(R[i]); + if (itR != unknown.end()) NR[i] = itR->second; + else NR[i] = -1; + } + for (unsigned int i = 0; i < R.size(); i++) + { + if (NR[i] != -1) + { + for (unsigned int j = 0; j < R.size(); j++) + { + if (NR[j] != -1) + { + _current->addToMatrix(NR[i], NR[j], m(i, j)); + } + else + { + typename std::map<Dof, dataVec>::iterator itFixed = fixed.find(R[j]); + if (itFixed != fixed.end()){ + _current->addToRightHandSide(NR[i], -m(i, j) * itFixed->second); + } + } + } } } } + inline void assemble(int entR, int typeR, int entC, int typeC, const dataMat &value) { assemble(Dof(entR, typeR), Dof(entC, typeC), value); diff --git a/Solver/elasticitySolver.cpp b/Solver/elasticitySolver.cpp index 35a5c62715..21b20c8590 100644 --- a/Solver/elasticitySolver.cpp +++ b/Solver/elasticitySolver.cpp @@ -313,13 +313,15 @@ void elasticitySolver::solve() El.addToMatrix(*pAssembler, *elasticFields[i].g, *elasticFields[j].g); } } - +/* printf("-- done assembling!\n"); - // for (int i=0;i<pAssembler->sizeOfR();i++){ - // printf("%g ",lsys->getFromRightHandSide(i)); - // } - // printf("\n"); - + for (int i=0;i<pAssembler->sizeOfR();i++) + { + if (fabs(lsys->getFromRightHandSide(i))>0.000001) + printf("%g ",lsys->getFromRightHandSide(i)); + } + printf("\n"); +*/ // solving lsys->systemSolve(); printf("-- done solving!\n"); @@ -404,60 +406,109 @@ void MyelasticitySolver::solve() } } - // line forces - for (std::map<int, SVector3 >::iterator it = lineForces.begin(); - it != lineForces.end(); ++it){ - DummyfemTerm El(pModel); + VectorLagrangeFunctionSpace P123(_tag);//,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y); + + //line forces + for (std::map<int, SVector3 >::iterator it =lineForces.begin(); + it != lineForces.end(); ++it) + { 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); + LoadTerm<VectorLagrangeFunctionSpace> Lterm(P123,f); printf("-- Force on edge %3d : %8.5f %8.5f %8.5f\n", iEdge, f.x(), f.y(), f.z()); + int dim=1; + std::map<int, std::vector<GEntity*> > groups[4]; + pModel->getPhysicalGroups(groups); + fullVector<double> localVector; + std::vector<Dof> R; + std::map<int, std::vector<GEntity*> >::iterator itg = groups[dim].find(iEdge); + if (itg == groups[dim].end()) {printf(" Nonexistent edge\n");break;} + for (unsigned int i = 0; i < itg->second.size(); ++i) + { + GEntity *ge = itg->second[i]; + for (unsigned int j = 0; j < ge->getNumMeshElements(); j++) + { + MElement *e = ge->getMeshElement(j); + int integrationOrder = 2 * e->getPolynomialOrder(); + int npts; + IntPt *GP; + e->getIntegrationPoints(integrationOrder, &npts, &GP); + R.clear(); + P123.getKeys(e,R); + Lterm.get(e,npts,GP,localVector); + pAssembler->assemble(R, localVector); + } + } } - // face forces + +//face forces for (std::map<int, SVector3 >::iterator it = faceForces.begin(); - it != faceForces.end(); ++it){ - DummyfemTerm El(pModel); + it != faceForces.end(); ++it) + { 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); + LoadTerm<VectorLagrangeFunctionSpace> Lterm(P123,f); printf("-- Force on face %3d : %8.5f %8.5f %8.5f\n", iFace, f.x(), f.y(), f.z()); + int dim=2; + std::map<int, std::vector<GEntity*> > groups[4]; + pModel->getPhysicalGroups(groups); + fullVector<double> localVector; + std::vector<Dof> R; + std::map<int, std::vector<GEntity*> >::iterator itg = groups[dim].find(iFace); + if (itg == groups[dim].end()) {printf(" Nonexistent face\n");break;} + for (unsigned int i = 0; i < itg->second.size(); ++i) + { + GEntity *ge = itg->second[i]; + for (unsigned int j = 0; j < ge->getNumMeshElements(); j++) + { + MElement *e = ge->getMeshElement(j); + int integrationOrder = 2 * e->getPolynomialOrder(); + int npts; + IntPt *GP; + e->getIntegrationPoints(integrationOrder, &npts, &GP); + R.clear(); + P123.getKeys(e,R); + Lterm.get(e,npts,GP,localVector); + pAssembler->assemble(R, localVector); + } + } } - // volume forces + +//volume forces for (std::map<int, SVector3 >::iterator it = volumeForces.begin(); - it != volumeForces.end(); ++it){ - DummyfemTerm El(pModel); + it != volumeForces.end(); ++it) + { int iVolume = it->first; SVector3 f = it->second; -// El.setVector(f); + LoadTerm<VectorLagrangeFunctionSpace> Lterm(P123,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); + int dim=3; + std::map<int, std::vector<GEntity*> > groups[4]; + pModel->getPhysicalGroups(groups); + fullVector<double> localVector; + std::vector<Dof> R; + std::map<int, std::vector<GEntity*> >::iterator itg = groups[dim].find(iVolume); + if (itg == groups[dim].end()) {printf(" Nonexistent volume\n");break;} + for (unsigned int i = 0; i < itg->second.size(); ++i) + { + GEntity *ge = itg->second[i]; + for (unsigned int j = 0; j < ge->getNumMeshElements(); j++) + { + MElement *e = ge->getMeshElement(j); + int integrationOrder = 2 * e->getPolynomialOrder(); + int npts; + IntPt *GP; + e->getIntegrationPoints(integrationOrder, &npts, &GP); + R.clear(); + P123.getKeys(e,R); + Lterm.get(e,npts,GP,localVector); + pAssembler->assemble(R, localVector); + } } } -*/ - VectorLagrangeFunctionSpace P123(_tag);//,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y); for (unsigned int i = 0; i < elasticFields.size(); i++) { @@ -477,6 +528,31 @@ void MyelasticitySolver::solve() pAssembler->assemble(R, localMatrix); } } + + +/* + + for (std::map<int, SVector3 >::iterator it = volumeForces.begin();it != volumeForces.end(); ++it) + { + int iVolume = it->first; + SVector3 f = it->second; + 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]); + } + } +*/ +/* + for (int i=0;i<pAssembler->sizeOfR();i++) + { + if (fabs(lsys->getFromRightHandSide(i))>0.000001) + printf("%g ",lsys->getFromRightHandSide(i)); + } + printf("\n"); +*/ printf("-- done assembling!\n"); lsys->systemSolve(); printf("-- done solving!\n"); diff --git a/Solver/functionSpace.h b/Solver/functionSpace.h index 9007b27ae1..ca26866c02 100644 --- a/Solver/functionSpace.h +++ b/Solver/functionSpace.h @@ -106,7 +106,7 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double> { int ndofs= ele->getNumVertices(); int curpos=vals.size(); - vals.reserve(curpos+ndofs); + 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) diff --git a/Solver/terms.h b/Solver/terms.h index df76f2987d..b229a2f555 100644 --- a/Solver/terms.h +++ b/Solver/terms.h @@ -82,8 +82,11 @@ class LinearTermBase template<class S1> class LinearTerm : public LinearTermBase { + protected : + S1& space1; public : - virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) =0; + LinearTerm(S1& space1_) : space1(space1_) {} + virtual void get(MElement *ele,int npts,IntPt *GP,fullVector<double> &m) =0; }; class ScalarTermBase @@ -168,6 +171,9 @@ template<class S1,class S2> class ElasticTerm : public BilinearTerm<S1,S2> // no + + + template<class S1> class ElasticTerm<S1,S1> : public BilinearTerm<S1,S1> // symmetric { protected : @@ -224,4 +230,34 @@ template<class S1> class ElasticTerm<S1,S1> : public BilinearTerm<S1,S1> // symm }; // class +inline double dot(const double &a, const double &b) +{ return a*b; } + +template<class S1> class LoadTerm : public LinearTerm<S1> +{ + typename S1::ValType Load; + public : + LoadTerm(S1& space1_,typename S1::ValType Load_) :LinearTerm<S1>(space1_),Load(Load_) {}; + virtual void get(MElement *ele,int npts,IntPt *GP,fullVector<double> &m) + { + double nbFF=LinearTerm<S1>::space1.getNumKeys(ele); + double jac[3][3]; + m.resize(nbFF); + m.scale(0.); + for (int i = 0; i < npts; 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 = ele->getJacobian(u, v, w, jac); + std::vector<typename S1::ValType> Vals; + LinearTerm<S1>::space1.f(ele,u, v, w, Vals); + for (int j = 0; j < nbFF ; ++j) + { + m(j)+=dot(Vals[j],Load)*weight*detJ; + } + } + } +}; + + + #endif// _TERMS_H_ -- GitLab