diff --git a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.cpp b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.cpp index 3dfe11b0f7f45be084c5a0ac3c7322b4296b8d7c..4e1e963974ff1024cc565000a31b80b7c90b075d 100644 --- a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.cpp +++ b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.cpp @@ -278,18 +278,9 @@ void nonLinearPeriodicBC::setPeriodicBCOptions(const int method, const int seg, this->setPBCPolynomialDegree(1,seg); this->setPBCPolynomialDegree(2,seg); - if (method == 3 or method == 4){ - printf("Using FE segment method, add new vertex flag is always actived \n"); - this->setAddNewVertices(0,true); - this->setAddNewVertices(1,true); - this->setAddNewVertices(2,true); - } - else{ - this->setAddNewVertices(0,add); - this->setAddNewVertices(1,add); - this->setAddNewVertices(2,add); - } - + this->setAddNewVertices(0,add); + this->setAddNewVertices(1,add); + this->setAddNewVertices(2,add); if (this->getPBCMethod() == nonLinearPeriodicBC::CEM){ printf("Periodic mesh formulation is used for building the PBC constraint \n"); diff --git a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h index 52dab7f328d3a408a98469c1265c2a4d06d26358..c7cfcc42481405439862b5191eabdf548b669d84 100644 --- a/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h +++ b/NonLinearSolver/BoundaryConditions/nonLinearMicroBC.h @@ -442,18 +442,11 @@ class nonLinearPeriodicBC: public nonLinearMicroBC{ return _forceInterp; } - bool isNewVertices() const{ - return (_XaddNewVertices&& _YaddNewVertices)&&_ZaddNewVertices; - } - bool addNewVertices(const int i) const { // add new Dof flag - if (_wM == CSIM) return true; - else { - if (i ==0) return _XaddNewVertices; - else if (i==1) return _YaddNewVertices; - else if (i==2) return _ZaddNewVertices; - else Msg::Fatal("direction must be correctly defined addNewVertices(i)"); - }; + if (i ==0) return _XaddNewVertices; + else if (i==1) return _YaddNewVertices; + else if (i==2) return _ZaddNewVertices; + else Msg::Fatal("direction must be correctly defined addNewVertices(i)"); }; whichMethod getPBCMethod() const{ diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp index dc33c05dac037bc13832510b3cd0ae6b7c52693c..7a3cc2d27db5e7179a4e9611e5455a67b2dde87e 100644 --- a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp +++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp @@ -9051,8 +9051,7 @@ stiffnessCondensation* nonLinearMechSolver::createStiffnessCondensation(const bo } else if (dynamic_cast<nonLinearPeriodicBC*>(_microBC)){ nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_microBC); - bool addnewvertexflag = pbc->isNewVertices(); - if (addnewvertexflag and pbc->getOrder()==1){ + if (_pAl->getSplittedDof()->sizeOfVirtualDof() >0 and pbc->getOrder()==1){ #if defined(HAVE_PETSC) Msg::Info("interpolationStiffnessCondensationPETSC is used for nonLinearPeriodicBC"); stiffCon = new interpolationStiffnessCondensationPETSC(pAssembler,_pAl,sflag,tflag); diff --git a/NonLinearSolver/periodicBC/numericalFunctions.h b/NonLinearSolver/periodicBC/numericalFunctions.h index 8908cbf961e6cd65cfd1482a80acd033eb82224a..559a2eaf4c299823baf39ca6d281542d7d6f5cb5 100644 --- a/NonLinearSolver/periodicBC/numericalFunctions.h +++ b/NonLinearSolver/periodicBC/numericalFunctions.h @@ -19,6 +19,22 @@ #include "STensor53.h" #include "STensor63.h" +inline SPoint3 computeTwoLineIntersectionOnSurface(const SPoint3& A, const SPoint3& B, const SPoint3& C, const SPoint3& D){ + // Line AB and CD cut at I + // ABCD on a same plane + SVector3 AB(A,B); + SVector3 CD(C,D); + SVector3 facN = crossprod(AB,CD); + SVector3 n = crossprod(CD,facN); + SVector3 AD(A,D); + double t = dot(AD,n)/dot(AB,n); + + double x = A.x() + t*AB.x(); + double y = A.y() + t*AB.y(); + double z = A.z() + t*AB.z(); + return SPoint3(x,y,z); +}; + inline void computeSurface(const SPoint3& A, const SPoint3& B, const SPoint3& C,double &a, double& b, double &c, double &d){ SVector3 AB(A,B); SVector3 AC(A,C); diff --git a/NonLinearSolver/periodicBC/pbcAlgorithm.cpp b/NonLinearSolver/periodicBC/pbcAlgorithm.cpp index c8e943641e10154aec7fd39aa3dbef1d7b02fbf6..2fb6e3b6d853eafbe4df44e6c36ffe9883761d56 100644 --- a/NonLinearSolver/periodicBC/pbcAlgorithm.cpp +++ b/NonLinearSolver/periodicBC/pbcAlgorithm.cpp @@ -120,13 +120,6 @@ int pbcAlgorithm::getNumberMicroToMacroHomogenizedVariables() const{ return dimStress; } -void pbcAlgorithm::switchMicroBC(){ - _pbcConstraint->switchMicroBC(); - // split dofs - this->splitDofs(); -}; - - void pbcAlgorithm::updateConstraint(const IPField* ipfield){ for (std::set<constraintElement*>::iterator it= _pbcConstraint->constraintGroupBegin(); it!= _pbcConstraint->constraintGroupEnd(); it++){ diff --git a/NonLinearSolver/periodicBC/pbcAlgorithm.h b/NonLinearSolver/periodicBC/pbcAlgorithm.h index 5e56af6eb1fe0110085854babdb5def04521ad0f..e9ed9519f781d82224e76db36c73b0dbd2d1dba6 100644 --- a/NonLinearSolver/periodicBC/pbcAlgorithm.h +++ b/NonLinearSolver/periodicBC/pbcAlgorithm.h @@ -36,8 +36,6 @@ class pbcAlgorithm{ pbcAlgorithm(nonLinearMechSolver* solver); virtual ~pbcAlgorithm(); - void switchMicroBC(); - pbcDofManager* getSplittedDof() {return _splittedDofs;}; splitStiffnessMatrix* getSplitStiffness() {return _splittedDofs->getSplitStiffnessMatrix();}; pbcConstraintElementGroup* getPBCConstraintGroup() {return _pbcConstraint;}; diff --git a/NonLinearSolver/periodicBC/pbcConstraintElement.cpp b/NonLinearSolver/periodicBC/pbcConstraintElement.cpp index 129a74395f77914abc4bf878161c98ef398b8ea8..f84b5cc020cd10fe983aad60245142654730f8ec 100644 --- a/NonLinearSolver/periodicBC/pbcConstraintElement.cpp +++ b/NonLinearSolver/periodicBC/pbcConstraintElement.cpp @@ -631,8 +631,9 @@ FEConstraintElement::FEConstraintElement(nonLinearMicroBC* mbc, FunctionSpaceBas }; _Cbc.resize(_ndofs,size*_ndofs); _Cbc.setAll(0.); - for (int j=0; j<_ndofs; j++){ - for (int i=0; i<size; i++){ + + for (int i=0; i<size; i++){ + for (int j=0; j<_ndofs; j++){ _C(j,col) = -1.*_fVal[i]; _Cbc(j,col-_ndofs) = _fVal[i]; col++; @@ -672,7 +673,9 @@ FEConstraintElement::~FEConstraintElement(){}; void FEConstraintElement::getConstraintKeys(std::vector<Dof>& keys) const{ getKeysFromVertex(_periodicSpace,_v, getComp(), keys); - _periodicSpace->getKeys(_e,keys); + for (int i=0; i< _e->getNumVertices(); i++){ + getKeysFromVertex(_periodicSpace,_e->getVertex(i),getComp(),keys); + } }; void FEConstraintElement::getMultiplierKeys(std::vector<Dof>& keys) const{ diff --git a/NonLinearSolver/periodicBC/pbcCreateConstraints.cpp b/NonLinearSolver/periodicBC/pbcCreateConstraints.cpp index 9b9bb338cb0f928de52000f35c7d39d596526ec2..816d95a90707485c8eeee8e00d3d6411f47b1bb1 100644 --- a/NonLinearSolver/periodicBC/pbcCreateConstraints.cpp +++ b/NonLinearSolver/periodicBC/pbcCreateConstraints.cpp @@ -19,6 +19,374 @@ #include "pbcSupplementConstraintExtraDofDiffusion.h" #include "directionalConstraintElement.h" +void InterpolationOperations::groupIntersection(groupOfElements* g1, groupOfElements* g2, std::set<MVertex*>& ver){ + for (groupOfElements::vertexContainer::iterator it1 = g1->vbegin(); it1!= g1->vend(); it1++){ + MVertex* v1 = *it1; + for (groupOfElements::vertexContainer::iterator it2 = g2->vbegin(); it2!= g2->vend(); it2++){ + MVertex* v2 = *it2; + if (v1->getNum() ==v2->getNum()){ + ver.insert(v1); + }; + }; + }; +}; + +void InterpolationOperations::groupIntersection(std::set<MVertex*>& g1, std::set<MVertex*>& g2, std::set<MVertex*>& ver){ + for (std::set<MVertex*>::iterator it1 = g1.begin(); it1!= g1.end(); it1++){ + MVertex* v1 = *it1; + for (std::set<MVertex*>::iterator it2 = g2.begin(); it2 != g2.end(); it2++){ + MVertex* v2 = *it2; + if (v1==v2){ + ver.insert(v1); + }; + }; + }; +}; + +void InterpolationOperations::intersectionBetweenTwoFaces(const groupOfElements* face1, const groupOfElements* face2, groupOfElements& line){ + + std::vector<std::vector<MVertex*> > allEdges; + for (groupOfElements::elementContainer::iterator itL = face1->begin(); itL!= face1->end(); itL++){ + MElement* eleL = *itL; + if (eleL->getDim() != 2){ + Msg::Fatal("This fuction is implemented from 2D elements only"); + } + bool found = false; + for (int i=0; i< eleL->getNumEdges(); i++){ + std::vector<MVertex*> vvL; + eleL->getEdgeVertices(i,vvL); + // found in face3 + for (groupOfElements::elementContainer::iterator itR = face2->begin(); itR!= face2->end(); itR++){ + MElement* eleR = *itR; + for (int j=0; j< eleR->getNumEdges(); j++){ + std::vector<MVertex*> vvR; + eleR->getEdgeVertices(j,vvR); + if (((vvL[0]->getNum() == vvR[0]->getNum()) and (vvL[1]->getNum() == vvR[1]->getNum())) or + ((vvL[0]->getNum() == vvR[1]->getNum()) and (vvL[1]->getNum() == vvR[0]->getNum()))){ + allEdges.push_back(vvL); + found = true; + break; + } + + } + if (found) break; + } + if (found) break; + + } + } + + // add to grEle + for (int i=0; i< allEdges.size(); i++){ + std::vector<MVertex*>& vv = allEdges[i]; + MElement* ele = new MLineN(vv); + line.insert(ele); + } +}; + +void InterpolationOperations::createLinePolynomialBase(const int degree, // degree + const bool createNewVer, // true if new vertices are created false if interpolation base is taken from existing vertices + MVertex* vstart, MVertex* vend, // vstart and vend + std::set<MVertex*>& line, // current line + std::vector<MVertex*>& base, // base obtained + std::set<MVertex*>& virtVer // virtualVertices to store all virtual virtices which has been created + ){ + base.resize(degree+1); + base[0] = vstart; + base[degree] = vend; + if (degree > 1){ + if (createNewVer){ + // create (degree-1) new vertices which are equally distributed + double x0 = vstart->x(); double x1 = vend->x(); + double y0 = vstart->y(); double y1 = vend->y(); + double z0 = vstart->z(); double z1 = vend->z(); + + double dx = (x1-x0)/degree; + double dy = (y1-y0)/degree; + double dz = (z1-z0)/degree; + for (int j=0; j<degree-1; j++){ + double xi = x0+ (j+1)*dx; + double yi = y0+ (j+1)*dy; + double zi = z0+ (j+1)*dz; + MVertex* v = new MVertex(xi,yi,zi); + base[j+1] = v; + virtVer.insert(v); // as new vertices + }; + } + else{ + // get (degree-1) vertices from existing vertices + std::vector<MVertex*> list; + std::vector<double> vals; + for (std::set<MVertex*>::iterator it=line.begin(); it!=line.end(); it++){ + MVertex* v=*it; + if ((v->getNum() != vstart->getNum()) and (v->getNum() != vend->getNum())){ + list.push_back(v); + vals.push_back(v->distance(vstart)); + } + }; + + // reorder based on distant to vstart + int size=list.size(); + for (int i=0; i<size; i++){ + for (int j=i; j<size; j++){ + if (vals[j]<vals[i]){ + double temp=vals[i]; vals[i]=vals[j]; vals[j]=temp; + MVertex* vtemp=list[i]; list[i]=list[j]; list[j]=vtemp; + }; + }; + }; + // at leat + if (degree-1>=size){ + Msg::Warning("all vertices on this linea are taken in interpolation basis"); + for (int i=0; i< size; i++){ + base[i+1] = list[i]; + } + } + else{ + int interval = (size)/(degree-1); + for (int j=0; j<degree-1; j++){ + base[j+1] = list[j*interval]; + }; + } + } + } +}; + + +template<class Iterator> +MVertex* InterpolationOperations::findNearestVertex(Iterator itbegin, Iterator itend, MVertex* vp){ + MVertex* vinit = *itbegin; + double dist=vinit->distance(vp); + for (Iterator it=itbegin; it!=itend; it++){ + MVertex* v=*it; + double tempDist=v->distance(vp); + if (tempDist<dist) { + dist=tempDist; + vinit=v; + }; + }; + return vinit; +}; + +MVertex* InterpolationOperations::findNearestVertex(groupOfElements* g, MVertex* vp){ + + return findNearestVertex(g->vbegin(), g->vend(),vp); +}; + +void InterpolationOperations::createGroupLinearLineElementFromVerticesVector(std::vector<MVertex*>& b, groupOfElements& gr){ + for (int i=0; i<b.size()-1; i++){ + MElement* line = new MLine(b[i],b[i+1]); + gr.insert(line); + } +}; + +void InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(std::vector<MVertex*>& b, groupOfElements& gr, std::set<MVertex*>& virVertices){ + // base will be modified due to create new vertices + std::vector<MVertex*> xtemp(b); + b.clear(); + for (int i=0; i<xtemp.size()-1; i++){ + b.push_back(xtemp[i]); + MVertex* v = new MVertex(0.5*(xtemp[i+1]->x()+xtemp[i]->x()), + 0.5*(xtemp[i+1]->y()+xtemp[i]->y()), + 0.5*(xtemp[i+1]->z()+xtemp[i]->z())); + + b.push_back(v); + virVertices.insert(v); + MElement* line = new MLine3(xtemp[i],xtemp[i+1],v); + gr.insert(line); + } + // add last vertex + b.push_back(xtemp[xtemp.size()-1]); +}; + +void InterpolationOperations::createLinearElementBCGroup3DFromTwoEdges( std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, + MVertex* vc, groupOfElements& g, std::set<MVertex*>& newVer){ + if (vlx[0] != vly[0]){ + Msg::Fatal("two BC group must be started by same vertex"); + return; + } + MVertex* vroot = vlx[0]; + + int NX = vlx.size(); + int NY = vly.size(); + + std::vector<std::vector<MVertex*> > vmat; + vmat.push_back(vlx); + + for (int j=1; j<NY; j++){ + std::vector<MVertex*> vv; + vv.push_back(vly[j]); + for (int i=1; i< NX; i++){ + MVertex* vertex = NULL; + if (j == NY-1 && i == NX-1){ + vertex = vc; + } + else{ + vertex = new MVertex(0,0,0); + vertex->x() = vlx[i]->x() - vroot->x()+ vly[j]->x(); + vertex->y() = vlx[i]->y() - vroot->y()+ vly[j]->y(); + vertex->z() = vlx[i]->z() - vroot->z()+ vly[j]->z(); + newVer.insert(vertex); + } + vv.push_back(vertex); + } + vmat.push_back(vv); + } + + + for (int i=0; i<NX-1; i++){ + for (int j=0; j<NY-1; j++){ + MElement* e = new MQuadrangle(vmat[j][i],vmat[j][i+1],vmat[j+1][i+1],vmat[j+1][i]); + g.insert(e); + } + } + +}; + +void InterpolationOperations::createQuadraticElementBCGroup3DFromTwoEdges( std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, + MVertex* vc, groupOfElements& g, std::set<MVertex*>& newVer){ + if (vlx[0] != vly[0]){ + Msg::Fatal("two BC group must be started by same vertex"); + return; + } + MVertex* vroot = vlx[0]; + + int NX = vlx.size(); + int NY = vly.size(); + + std::vector<std::vector<MVertex*> > vmat; + vmat.push_back(vlx); + + for (int j=1; j<NY; j++){ + std::vector<MVertex*> vv; + vv.push_back(vly[j]); + for (int i=1; i< NX; i++){ + MVertex* vertex = NULL; + if (j == NY-1 && i == NX-1){ + vertex = vc; + } + else{ + vertex = new MVertex(0,0,0); + vertex->x() = vlx[i]->x() - vroot->x()+ vly[j]->x(); + vertex->y() = vlx[i]->y() - vroot->y()+ vly[j]->y(); + vertex->z() = vlx[i]->z() - vroot->z()+ vly[j]->z(); + newVer.insert(vertex); + } + vv.push_back(vertex); + } + vmat.push_back(vv); + } + + + for (int i=0; i<NX-1; i+=2){ + for (int j=0; j<NY-1; j+=2){ + MElement* e = new MQuadrangle9(vmat[j][i],vmat[j][i+2],vmat[j+2][i+2],vmat[j+2][i], + vmat[j][i+1],vmat[j+1][i+2],vmat[j+2][i+1],vmat[j+1][i], + vmat[j+1][i+1]); + g.insert(e); + } + } + +}; + +void InterpolationOperations::createPolynomialBasePoints(nonLinearPeriodicBC* pbc, + MVertex* v1, MVertex* v2, MVertex* v4, MVertex* v5, + std::set<MVertex*>& l12, std::set<MVertex*>& l41,std::set<MVertex*>& l15, + std::vector<MVertex*>& xbase, std::vector<MVertex*>& ybase, std::vector<MVertex*>& zbase, + std::set<MVertex*>& newVertices){ + // direction x, y, z are defined as follows + // x - 12 + // y - 14 + // z - 15 + + int dim = pbc->getDim(); + + int degreeX = pbc->getPBCPolynomialDegree(0); + int degreeY = pbc->getPBCPolynomialDegree(1);; + int degreeZ = pbc->getPBCPolynomialDegree(2);; + + // modify degree following available vertices in l12, l14, l15 + if (!pbc->isForcedInterpolationDegree()){ + int sizeX = l12.size(); + int sizeY = l41.size(); + int sizeZ = l15.size(); + Msg::Info("Maximal number of Boundary Nodes in X direction %d, Y direction %d, Z direction %d",sizeX,sizeY,sizeZ); + + + if (pbc->getPBCMethod() == nonLinearPeriodicBC::LIM or + pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ + // first order + if (degreeX>sizeX-1) degreeX = sizeX-1; + if (degreeY>sizeY-1) degreeY = sizeY-1; + if (degreeZ>sizeZ-1 && dim == 3) degreeZ = sizeZ-1; + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM or + pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ + // second-order + if (degreeX>(sizeX-1)/2) degreeX = (sizeX-1)/2; + if (degreeY>(sizeY-1)/2) degreeY = (sizeY-1)/2; + if (degreeZ>(sizeZ-1)/2 && dim == 3) degreeZ = (sizeZ-1)/2; + } + else{ + Msg::Fatal("interpolation type must be defined"); + } + // at leat, interpolation must be linear + if (degreeX<1) degreeX = 1; + if (degreeY<1) degreeY = 1; + if (degreeZ<1) degreeZ = 1; + + // modify degree + pbc->setPBCPolynomialDegree(0,degreeX); + pbc->setPBCPolynomialDegree(1,degreeY); + pbc->setPBCPolynomialDegree(2,degreeZ); + + // force add new vertices + if (sizeX < 2) pbc->setAddNewVertices(0,true); + if (sizeY < 2) pbc->setAddNewVertices(1,true); + if (sizeZ < 2) pbc->setAddNewVertices(2,true); + + } + + Msg::Info("Interpolation degree used in X direction %d, Y direction %d, Z direction %d",degreeX,degreeY,degreeZ); + + + InterpolationOperations::createLinePolynomialBase(degreeX,pbc->addNewVertices(0),v1,v2,l12,xbase,newVertices); + InterpolationOperations::createLinePolynomialBase(degreeY,pbc->addNewVertices(1),v1,v4,l41,ybase,newVertices); + if (dim == 3){ + InterpolationOperations::createLinePolynomialBase(degreeZ,pbc->addNewVertices(2),v1,v5,l15,zbase,newVertices); + } + + +}; + +bool InterpolationOperations::isInside(MVertex* v, MElement* e){ + int dim = e->getDim(); + std::vector<MVertex*> vv; + e->getVertices(vv); + + SPoint3 pp; + if (dim == 1){ + pp = project(v->point(),vv[0]->point(), vv[1]->point()); + } + else if (dim ==2){ + pp = project(v->point(),vv[0]->point(), vv[1]->point(),vv[2]->point()); + } + + double xyz[3] = {pp[0],pp[1],pp[2]}; + double uvw[3]; + + e->xyz2uvw(xyz,uvw); + if (e->isInside(uvw[0],uvw[1],uvw[2])){ + return true; + } + else return false; + +}; + + + + + groupOfElementsDomainDecomposition::groupOfElementsDomainDecomposition(const int phys, groupOfElements* g_, std::vector<partDomain*>& allDomain): g(g_),physical(phys){ // init map @@ -77,12 +445,12 @@ groupOfElementsDomainDecomposition::~groupOfElementsDomainDecomposition(){ pbcConstraintElementGroup::pbcConstraintElementGroup(nonLinearMechSolver* sl, FunctionSpaceBase* lagspace, FunctionSpaceBase* multspace) :_solver(sl), _v1(NULL),_v2(NULL),_v4(NULL),_v5(NULL), - _v3(NULL),_v6(NULL),_v7(NULL),_v8(NULL), _gXY(NULL),_gYZ(NULL),_gZX(NULL), - _gX(NULL),_gY(NULL),_gZ(NULL), _g(NULL), + _v3(NULL),_v6(NULL),_v7(NULL),_v8(NULL), _g(NULL), _LagSpace(lagspace),_MultSpace(multspace), _periodic12(0.),_periodic14(0.),_periodic15(0.), - _e1(1.,0.,0.),_e2(0.,1.,0.),_e3(0.,0.,1.), - _e1Rotated(1.,0.,0.),_e2Rotated(0.,1.,0.),_e3Rotated(0.,0.,1.){ + f1234(NULL), f5678(NULL), f1562(NULL),f4873(NULL), f1584(NULL), f2673(NULL), + _gX(NULL),_gY(NULL),_gZ(NULL), + _gXY(NULL),_gYZ(NULL),_gZX(NULL){ this->__init__(); }; @@ -92,82 +460,29 @@ pbcConstraintElementGroup::~pbcConstraintElementGroup(){ if (cel) delete cel; cel = NULL; } - _allConstraint.clear(); - _cVertices.clear(); - _bVertices.clear(); for (std::set<MVertex*>::iterator it = _virtualVertices.begin(); it!= _virtualVertices.end(); it++){ MVertex* v = *it; if (v) delete v; v = NULL; } - _virtualVertices.clear(); - l12.clear(); - l23.clear(); - l34.clear(); - l41.clear(); - l56.clear(); - l67.clear(); - l78.clear(); - l85.clear(); - l15.clear(); - l26.clear(); - l37.clear(); - l48.clear(); if (_g) delete _g; _g = NULL; - if (_gX) delete _gX; _gX = NULL; - if (_gY) delete _gY; _gY = NULL; - if (_gZ) delete _gZ; _gZ = NULL; - - if (_gXY) delete _gXY; _gXY = NULL; - if (_gYZ) delete _gYZ; _gYZ = NULL; - if (_gZX) delete _gZX; _gZX = NULL; + + if (_gX) delete _gX; + if (_gY) delete _gY; + if (_gZ) delete _gZ; + if (_gXY) delete _gXY; + if (_gYZ) delete _gYZ; + if (_gZX) delete _gZX; for (int i=0; i< _boundaryDGMap.size(); i++){ delete _boundaryDGMap[i]; } - _boundaryDGMap.clear(); for (std::map<partDomain*,FunctionSpaceBase*>::iterator it = _allDGMultSpace.begin(); it!=_allDGMultSpace.end(); it++){ if (it->second!=NULL) delete it->second; } - _allDGMultSpace.clear(); }; -void pbcConstraintElementGroup::groupIntersection(groupOfElements* g1, groupOfElements* g2, std::set<MVertex*>& ver) const{ - for (groupOfElements::vertexContainer::iterator it1 = g1->vbegin(); it1!= g1->vend(); it1++){ - MVertex* v1 = *it1; - for (groupOfElements::vertexContainer::iterator it2 = g2->vbegin(); it2!= g2->vend(); it2++){ - MVertex* v2 = *it2; - if (v1->getNum() ==v2->getNum()){ - ver.insert(v1); - }; - }; - }; -}; -void pbcConstraintElementGroup::groupIntersection(groupOfElements* g1, groupOfElements* g2, groupOfElements* &g) const{ - std::vector<MElement*> egroup; - for (groupOfElements::elementContainer::iterator it1 = g1->begin(); it1!= g1->end(); it1++){ - MElement* e1 = *it1; - for (groupOfElements::elementContainer::iterator it2 = g2->begin(); it2!= g2->end(); it2++){ - MElement* e2 = *it2; - if (e1 == e2){ - egroup.push_back(e1); - }; - }; - }; - g = new groupOfElements(egroup); -}; -void pbcConstraintElementGroup::groupIntersection(std::set<MVertex*>& g1, std::set<MVertex*>& g2, std::set<MVertex*>& ver) const{ - for (std::set<MVertex*>::iterator it1 = g1.begin(); it1!= g1.end(); it1++){ - MVertex* v1 = *it1; - for (std::set<MVertex*>::iterator it2 = g2.begin(); it2 != g2.end(); it2++){ - MVertex* v2 = *it2; - if (v1==v2){ - ver.insert(v1); - }; - }; - }; -}; void pbcConstraintElementGroup::__init__(){ std::vector<partDomain*>& allDomain = *(_solver->getDomainVector()); @@ -193,12 +508,16 @@ void pbcConstraintElementGroup::__init__(){ if (_g->size()==0) Msg::Fatal("Error in setting domain"); + + const std::vector<int>& bphysical = _solver->getMicroBC()->getBoundaryPhysicals(); + const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); + if (bgroup.size() == 0) Msg::Fatal("microscopic boundary condition has not any support"); + int dim = _solver->getMicroBC()->getDim(); if (_fullDG){ Msg::Info("start decomsing boundary element to domains"); _boundaryDGMap.clear(); - const std::vector<int>& bphysical = _solver->getMicroBC()->getBoundaryPhysicals(); - const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); + for (int ig=0; ig< bgroup.size(); ig++){ groupOfElements* gr = bgroup[ig]; groupOfElementsDomainDecomposition* grDomPart = new groupOfElementsDomainDecomposition(bphysical[ig], gr,allDomain); @@ -227,361 +546,235 @@ void pbcConstraintElementGroup::__init__(){ } } } + + if (dim == 2){ + if (bgroup.size() != 4) Msg::Fatal("Boundary support must be 4 edges"); + l12.clear(); + l12.insert(bgroup[0]->vbegin(),bgroup[0]->vend()); + l41.clear(); + l41.insert(bgroup[1]->vbegin(),bgroup[1]->vend()); + l34.clear(); + l34.insert(bgroup[2]->vbegin(),bgroup[2]->vend()); + l23.clear(); + l23.insert(bgroup[3]->vbegin(),bgroup[3]->vend()); + + _bVertices.clear(); + InterpolationOperations::groupIntersection(bgroup[0],bgroup[1],_bVertices); + InterpolationOperations::groupIntersection(bgroup[1],bgroup[2],_bVertices); + InterpolationOperations::groupIntersection(bgroup[2],bgroup[3],_bVertices); + InterpolationOperations::groupIntersection(bgroup[3],bgroup[0],_bVertices); + + _cVertices.clear(); + _cVertices.insert(_bVertices.begin(),_bVertices.end()); + #ifdef _DEBUG + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + Msg::Info("corner vertex %d ",(*it)->getNum()); + }; + #endif //_DEBUG + } + else if (dim == 3){ + if (bgroup.size() != 6) Msg::Fatal("Boundary support must be 6 faces"); + // all faces + f1234 = bgroup[0]; + f5678 = bgroup[3]; + f1562 = bgroup[1]; + f4873 = bgroup[4]; + f1584 = bgroup[2]; + f2673 = bgroup[5]; + + // all edges + l12.clear(); InterpolationOperations::groupIntersection(f1234,f1562,l12); + l23.clear(); InterpolationOperations::groupIntersection(f1234,f2673,l23); + l34.clear(); InterpolationOperations::groupIntersection(f1234,f4873,l34); + l41.clear(); InterpolationOperations::groupIntersection(f1234,f1584,l41); + l56.clear(); InterpolationOperations::groupIntersection(f5678,f1562,l56); + l67.clear(); InterpolationOperations::groupIntersection(f5678,f2673,l67); + l78.clear(); InterpolationOperations::groupIntersection(f5678,f4873,l78); + l85.clear(); InterpolationOperations::groupIntersection(f5678,f1584,l85); + l15.clear(); InterpolationOperations::groupIntersection(f1562,f1584,l15); + l26.clear(); InterpolationOperations::groupIntersection(f1562,f2673,l26); + l37.clear(); InterpolationOperations::groupIntersection(f2673,f4873,l37); + l48.clear(); InterpolationOperations::groupIntersection(f4873,f1584,l48); + + + _bVertices.clear(); + _bVertices.insert(l12.begin(),l12.end()); + _bVertices.insert(l23.begin(),l23.end()); + _bVertices.insert(l34.begin(),l34.end()); + _bVertices.insert(l41.begin(),l41.end()); + _bVertices.insert(l56.begin(),l56.end()); + _bVertices.insert(l67.begin(),l67.end()); + _bVertices.insert(l78.begin(),l78.end()); + _bVertices.insert(l85.begin(),l85.end()); + _bVertices.insert(l15.begin(),l15.end()); + _bVertices.insert(l26.begin(),l26.end()); + _bVertices.insert(l37.begin(),l37.end()); + _bVertices.insert(l48.begin(),l48.end()); + + + #ifdef _DEBUG + for (std::set<MVertex*>::iterator it = l12.begin(); it!= l12.end(); it++){ + Msg::Info("vertex %d 12",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l23.begin(); it!= l23.end(); it++){ + Msg::Info("vertex %d 23",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l34.begin(); it!= l34.end(); it++){ + Msg::Info("vertex %d 34",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l41.begin(); it!= l41.end(); it++){ + Msg::Info("vertex %d 41",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l56.begin(); it!= l56.end(); it++){ + Msg::Info("vertex %d 56",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l67.begin(); it!= l67.end(); it++){ + Msg::Info("vertex %d 67",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l78.begin(); it!= l78.end(); it++){ + Msg::Info("vertex %d 78",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l85.begin(); it!= l85.end(); it++){ + Msg::Info("vertex %d 85",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l15.begin(); it!= l15.end(); it++){ + Msg::Info("vertex %d 15",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l26.begin(); it!= l26.end(); it++){ + Msg::Info("vertex %d 26",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l37.begin(); it!= l37.end(); it++){ + Msg::Info("vertex %d 37",(*it)->getNum()); + }; + for (std::set<MVertex*>::iterator it = l48.begin(); it!= l48.end(); it++){ + Msg::Info("vertex %d 48",(*it)->getNum()); + }; + #endif //_DEBUG + + // corner vertices + _cVertices.clear(); + InterpolationOperations::groupIntersection(l12,l23,_cVertices); + InterpolationOperations::groupIntersection(l23,l34,_cVertices); + InterpolationOperations::groupIntersection(l34,l41,_cVertices); + InterpolationOperations::groupIntersection(l41,l12,_cVertices); + InterpolationOperations::groupIntersection(l56,l67,_cVertices); + InterpolationOperations::groupIntersection(l67,l78,_cVertices); + InterpolationOperations::groupIntersection(l78,l85,_cVertices); + InterpolationOperations::groupIntersection(l85,l56,_cVertices); + + #ifdef _DEBUG + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + Msg::Info("corner vertex %d ",(*it)->getNum()); + }; + #endif //_DEBUG + } - nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); - int dim = _solver->getMicroBC()->getDim(); - if (pbc != NULL && bgroup.size()>0){ - if (dim ==2){ - if (bgroup.size() == 4){ - groupIntersection(bgroup[0],bgroup[1],_bVertices); - groupIntersection(bgroup[1],bgroup[2],_bVertices); - groupIntersection(bgroup[2],bgroup[3],_bVertices); - groupIntersection(bgroup[3],bgroup[0],_bVertices); - - l12.insert(bgroup[0]->vbegin(),bgroup[0]->vend()); - l41.insert(bgroup[1]->vbegin(),bgroup[1]->vend()); - l34.insert(bgroup[2]->vbegin(),bgroup[2]->vend()); - l23.insert(bgroup[3]->vbegin(),bgroup[3]->vend()); - - #ifdef _DEBUG - for (std::set<MVertex*>::iterator it = l12.begin(); it!= l12.end(); it++){ - Msg::Info("vertex %d 12",(*it)->getNum()); - }; - for (std::set<MVertex*>::iterator it = l23.begin(); it!= l23.end(); it++){ - Msg::Info("vertex %d 23",(*it)->getNum()); - }; - for (std::set<MVertex*>::iterator it = l34.begin(); it!= l34.end(); it++){ - Msg::Info("vertex %d 34",(*it)->getNum()); - }; - for (std::set<MVertex*>::iterator it = l41.begin(); it!= l41.end(); it++){ - Msg::Info("vertex %d 41",(*it)->getNum()); - }; - #endif //_DEBUG - - for (std::set<MVertex*>::iterator it = _bVertices.begin(); it!= _bVertices.end(); it++){ - _cVertices.insert(*it); - } - } - else if (bgroup.size() == 2){ - l12.insert(bgroup[0]->vbegin(),bgroup[0]->vend()); - l34.insert(bgroup[2]->vbegin(),bgroup[2]->vend()); - - #ifdef _DEBUG - for (std::set<MVertex*>::iterator it = l12.begin(); it!= l12.end(); it++){ - Msg::Info("vertex %d 12",(*it)->getNum()); - }; - for (std::set<MVertex*>::iterator it = l34.begin(); it!= l34.end(); it++){ - Msg::Info("vertex %d 34",(*it)->getNum()); - }; - #endif //_DEBUG - } - else{ - Msg::Fatal("Error in setting PBC, the number of physical for PBC must be equal to 2, 4. In this case: %d ",bgroup.size()); - } - } - else if (dim ==3){ - if (bgroup.size() == 6){ - f1234 = bgroup[0]; - f5678 = bgroup[3]; - f1562 = bgroup[1]; - f4873 = bgroup[4]; - f1584 = bgroup[2]; - f2673 = bgroup[5]; - - groupIntersection(f1234,f1562,l12); - for (std::set<MVertex*>::iterator it = l12.begin(); it!= l12.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 12",(*it)->getNum()); - #endif //_DEBUG - }; - groupIntersection(f1234,f2673,l23); - for (std::set<MVertex*>::iterator it = l23.begin(); it!= l23.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 23",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f1234,f4873,l34); - for (std::set<MVertex*>::iterator it = l34.begin(); it!= l34.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 34",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f1234,f1584,l41); - for (std::set<MVertex*>::iterator it = l41.begin(); it!= l41.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 41",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f1562,l56); - for (std::set<MVertex*>::iterator it = l56.begin(); it!= l56.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 56",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f2673,l67); - for (std::set<MVertex*>::iterator it = l67.begin(); it!= l67.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 67",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f4873,l78); - for (std::set<MVertex*>::iterator it = l78.begin(); it!= l78.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 78",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f1584,l85); - for (std::set<MVertex*>::iterator it = l85.begin(); it!= l85.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 85",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f1562,f1584,l15); - for (std::set<MVertex*>::iterator it = l15.begin(); it!= l15.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 15",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f1562,f2673,l26); - for (std::set<MVertex*>::iterator it = l26.begin(); it!= l26.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 26",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f2673,f4873,l37); - for (std::set<MVertex*>::iterator it = l37.begin(); it!= l37.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 37",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f4873,f1584,l48); - for (std::set<MVertex*>::iterator it = l48.begin(); it!= l48.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 48",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(l12,l23,_cVertices); - groupIntersection(l23,l34,_cVertices); - groupIntersection(l34,l41,_cVertices); - groupIntersection(l41,l12,_cVertices); - groupIntersection(l56,l67,_cVertices); - groupIntersection(l67,l78,_cVertices); - groupIntersection(l78,l85,_cVertices); - groupIntersection(l85,l56,_cVertices); - } - else if (bgroup.size() == 4){ - f1234 = bgroup[0]; - f5678 = bgroup[2]; - - f1584 = bgroup[1]; - f2673 = bgroup[3]; - - groupIntersection(f1234,f1584,l41); - for (std::set<MVertex*>::iterator it = l41.begin(); it!= l41.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 41",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f1234,f2673,l23); - for (std::set<MVertex*>::iterator it = l23.begin(); it!= l23.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 23",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f2673,l67); - for (std::set<MVertex*>::iterator it = l67.begin(); it!= l67.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 67",(*it)->getNum()); - #endif //_DEBUG - }; - - groupIntersection(f5678,f1584,l85); - for (std::set<MVertex*>::iterator it = l85.begin(); it!= l85.end(); it++){ - _bVertices.insert(*it); - #ifdef _DEBUG - Msg::Info("vertex %d 85",(*it)->getNum()); - #endif //_DEBUG - }; - - } - else if (bgroup.size() == 2){ - f1234 = bgroup[0]; - f5678 = bgroup[1]; - } - else{ - Msg::Fatal("Error in setting PBC, the number of physical for PBC must be equal to 2, 4, 6. In this case: %d ",bgroup.size()); - } - } - - #ifdef _DEBUG - for (std::set<MVertex*>::iterator it = _bVertices.begin(); it!= _bVertices.end(); it++){ - MVertex* v = *it; - Msg::Info("Boundary vertex = %d",v->getNum()); - } - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* v = *it; - Msg::Info("Corner vertex = %d",v->getNum()); - } - #endif //_DEBUG - - addControlPoints(); - addOtherCornerPoints(); - } -}; - - -void pbcConstraintElementGroup::addControlPoints(){ + // add control points, v1-v2-v4 in 2D, v1, v2, v4, v5 in 3D std::set<MVertex*> vv; - groupIntersection(l12,l41,vv); - if (_solver->getMicroBC()->getDim() == 3){ - groupIntersection(l12,l15,vv); - groupIntersection(l41,l15,vv); - } - if (vv.size()==0){ - MVertex* v1(NULL),*v2(NULL),*v3(NULL); - if (l12.size()>0 and l41.size()>2 ){ - v1 = *(l12.begin()); - std::set<MVertex*>::iterator it = l41.begin(); - v2 = *(it); - it++; - v3 = *(it); - } - if (v1!=NULL and v2!=NULL and v3!=NULL){ - SPoint3 pp= project(v1->point(),v2->point(),v3->point()); + if (dim ==2){ + vv.clear(); + InterpolationOperations::groupIntersection(l12,l41,vv); + if (vv.size() > 0){ + _v1 = *(vv.begin()); + } + else{ + MElement* ex = *(bgroup[0]->begin()); + MElement* ey = *(bgroup[1]->begin()); + std::vector<MVertex*> vx, vy; + ex->getVertices(vx); + ey->getVertices(vy); + SPoint3 pp = computeTwoLineIntersectionOnSurface(vx[0]->point(),vx[1]->point(),vy[0]->point(),vy[1]->point()); _v1 = new MVertex(pp.x(),pp.y(),pp.z()); Msg::Info("Create root vertex v1 %d: %e %e %e",_v1->getNum(),pp.x(),pp.y(),pp.z()); - l12.insert(_v1); - l41.insert(_v1); - if (_solver->getMicroBC()->getDim()==3){ - l15.insert(_v1); - } _virtualVertices.insert(_v1); _cVertices.insert(_v1); _bVertices.insert(_v1); } - } - else { - _v1 = *(vv.begin()); - } - - vv.clear(); - groupIntersection(l12,l23,vv); - if (_solver->getMicroBC()->getDim()==3){ - groupIntersection(l12,l26,vv); - groupIntersection(l23,l26,vv); - } - if (vv.size()==0){ - MVertex* v1(NULL),*v2(NULL),*v3(NULL); - if (l12.size()>0 and l23.size()>2){ - v1 = *(l12.begin()); - std::set<MVertex*>::iterator it = l23.begin(); - v2 = *(it); - it++; - v3 = *(it); - } - if (v1!=NULL and v2!=NULL and v3!=NULL){ - SPoint3 pp= project(v1->point(),v2->point(),v3->point()); + + // find v2 + vv.clear(); + InterpolationOperations::groupIntersection(l12,l23,vv); + if (vv.size() > 0){ + _v2 = *(vv.begin()); + } + else{ + MElement* ex = *(bgroup[0]->begin()); + MElement* ey = *(bgroup[3]->begin()); + std::vector<MVertex*> vx, vy; + ex->getVertices(vx); + ey->getVertices(vy); + SPoint3 pp = computeTwoLineIntersectionOnSurface(vx[0]->point(),vx[1]->point(),vy[0]->point(),vy[1]->point()); _v2 = new MVertex(pp.x(),pp.y(),pp.z()); Msg::Info("Create root vertex v2 %d: %e %e %e",_v2->getNum(),pp.x(),pp.y(),pp.z()); - l12.insert(_v2); _virtualVertices.insert(_v2); _cVertices.insert(_v2); _bVertices.insert(_v2); } - } - else { - _v2 = *(vv.begin()); - } - - vv.clear(); - groupIntersection(l34,l41,vv); - if (_solver->getMicroBC()->getDim()==3){ - groupIntersection(l34,l48,vv); - groupIntersection(l41,l48,vv); - } - if (vv.size()==0){ - MVertex* v1(NULL),*v2(NULL),*v3(NULL); - if (l41.size()>0 and l34.size()>2){ - v1 = *(l41.begin()); - std::set<MVertex*>::iterator it = l34.begin(); - v2 = *(it); - it++; - v3 = *(it); - } - if (v1!=NULL and v2!=NULL and v3!=NULL){ - SPoint3 pp= project(v1->point(),v2->point(),v3->point()); + + // find v3 + vv.clear(); + InterpolationOperations::groupIntersection(l23,l34,vv); + if (vv.size()>0){ + _v3 = *(vv.begin()); + } + else{ + MElement* ex = *(bgroup[3]->begin()); + MElement* ey = *(bgroup[2]->begin()); + std::vector<MVertex*> vx, vy; + ex->getVertices(vx); + ey->getVertices(vy); + SPoint3 pp = computeTwoLineIntersectionOnSurface(vx[0]->point(),vx[1]->point(),vy[0]->point(),vy[1]->point()); + _v3 = new MVertex(pp.x(),pp.y(),pp.z()); + Msg::Info("Create root vertex v3 %d: %e %e %e",_v3->getNum(),pp.x(),pp.y(),pp.z()); + _virtualVertices.insert(_v3); + _cVertices.insert(_v3); + _bVertices.insert(_v3); + } + + // find v4 + vv.clear(); + InterpolationOperations::groupIntersection(l34,l41,vv); + if (vv.size() > 0){ + _v4 = *(vv.begin()); + } + else{ + MElement* ex = *(bgroup[2]->begin()); + MElement* ey = *(bgroup[1]->begin()); + std::vector<MVertex*> vx, vy; + ex->getVertices(vx); + ey->getVertices(vy); + SPoint3 pp = computeTwoLineIntersectionOnSurface(vx[0]->point(),vx[1]->point(),vy[0]->point(),vy[1]->point()); _v4 = new MVertex(pp.x(),pp.y(),pp.z()); Msg::Info("Create root vertex v4 %d: %e %e %e",_v4->getNum(),pp.x(),pp.y(),pp.z()); - l41.insert(_v4); _virtualVertices.insert(_v4); _cVertices.insert(_v4); _bVertices.insert(_v4); } + + _periodic12[0] = _v2->x() - _v1->x(); + _periodic12[1] = _v2->y() - _v1->y(); + _periodic12[2] = _v2->z() - _v1->z(); + + _periodic14[0] = _v4->x() - _v1->x(); + _periodic14[1] = _v4->y() - _v1->y(); + _periodic14[2] = _v4->z() - _v1->z(); + + _periodic15 = crossprod(_periodic12,_periodic14); + _periodic15.normalize(); } - else { - _v4 = *(vv.begin()); - } - if (_solver->getMicroBC()->getDim()==3){ + else if (dim == 3){ vv.clear(); - groupIntersection(l85,l15,vv); - groupIntersection(l85,l56,vv); - groupIntersection(l56,l15,vv); - - if (vv.size()==0){ - MVertex* v1(NULL),*v2(NULL),*v3(NULL); - if (l15.size()>0 and l85.size()>2){ - v1 = *(l15.begin()); - std::set<MVertex*>::iterator it = l85.begin(); - v2 = *(it); - it++; - v3 = *(it); - } - - if (v1!=NULL and v2!=NULL and v3!=NULL){ - SPoint3 pp= project(v1->point(),v2->point(),v3->point()); - _v5 = new MVertex(pp.x(),pp.y(),pp.z()); - Msg::Info("Create root vertex v5 %d: %e %e %e",_v5->getNum(),pp.x(),pp.y(),pp.z()); - l15.insert(_v5); - _virtualVertices.insert(_v5); - _cVertices.insert(_v5); - _bVertices.insert(_v5); - } - + InterpolationOperations::groupIntersection(l12,l41,vv); + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l12,l15,vv); } - else { - _v5 = *(vv.begin()); + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l41,l15,vv); } - - if (_v1==NULL){ + if (vv.size() > 0){ + _v1 = *(vv.begin()); + } + else{ MElement* e1 = *(f1234->begin()); MElement* e2 = *(f1584->begin()); MElement* e3 = *(f1562->begin()); @@ -608,8 +801,20 @@ void pbcConstraintElementGroup::addControlPoints(){ _cVertices.insert(_v1); _bVertices.insert(_v1); } - - if (_v2==NULL){ + + // v2 + vv.clear(); + InterpolationOperations::groupIntersection(l12,l23,vv); + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l12,l26,vv); + } + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l23,l26,vv); + } + if (vv.size() > 0) { + _v2 = *(vv.begin()); + } + else{ MElement* e1 = *(f1234->begin()); MElement* e2 = *(f2673->begin()); MElement* e3 = *(f1562->begin()); @@ -636,8 +841,20 @@ void pbcConstraintElementGroup::addControlPoints(){ _cVertices.insert(_v2); _bVertices.insert(_v2); } - - if (_v4==NULL){ + + // find v4 + vv.clear(); + InterpolationOperations::groupIntersection(l34,l41,vv); + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l34,l48,vv); + } + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l41,l48,vv); + } + if (vv.size() > 0) { + _v4 = *(vv.begin()); + } + else{ MElement* e1 = *(f1234->begin()); MElement* e2 = *(f1584->begin()); MElement* e3 = *(f4873->begin()); @@ -664,8 +881,20 @@ void pbcConstraintElementGroup::addControlPoints(){ _cVertices.insert(_v4); _bVertices.insert(_v4); } - - if (_v5==NULL){ + + // find v5 + vv.clear(); + InterpolationOperations::groupIntersection(l85,l15,vv); + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l85,l56,vv); + } + if (vv.size() == 0){ + InterpolationOperations::groupIntersection(l56,l15,vv); + } + if (vv.size() >0) { + _v5 = *(vv.begin()); + } + else{ MElement* e1 = *(f1584->begin()); MElement* e2 = *(f5678->begin()); MElement* e3 = *(f1562->begin()); @@ -692,72 +921,39 @@ void pbcConstraintElementGroup::addControlPoints(){ _cVertices.insert(_v5); _bVertices.insert(_v5); } - - } - - _periodic12[0] = _v2->x() - _v1->x(); - _periodic12[1] = _v2->y() - _v1->y(); - _periodic12[2] = _v2->z() - _v1->z(); - - _periodic14[0] = _v4->x() - _v1->x(); - _periodic14[1] = _v4->y() - _v1->y(); - _periodic14[2] = _v4->z() - _v1->z(); - - if (_solver->getMicroBC()->getDim() == 3){ - _periodic15[0] = _v5->x() - _v1->x(); - _periodic15[1] = _v5->y() - _v1->y(); - _periodic15[2] = _v5->z() - _v1->z(); - } - - _periodic12.print("periodic 1 --> 2"); - _periodic14.print("periodic 1 --> 4"); - - - if (_solver->getMicroBC()->getDim() == 3){ - _periodic15.print("periodic 1 --> 5"); - } - -}; - -void pbcConstraintElementGroup::addOtherCornerPoints(){ - std::set<MVertex*> vv; - // find _v3 - vv.clear(); - groupIntersection(l23,l34,vv); - if (_solver->getMicroBC()->getDim() ==3){ - if (vv.size()==0) - groupIntersection(l34,l37,vv); - if (vv.size() ==0) - groupIntersection(l23,l37,vv); - } - - if (vv.size()==0){ - double x = _v4->x() + _v2->x() - _v1->x(); - double y = _v4->y() + _v2->y() - _v1->y(); - double z = _v4->z() + _v2->z() - _v1->z(); - _v3 = new MVertex(x,y,z); - Msg::Info("Create root vertex v3 %d: %e %e %e",_v3->getNum(),x,y,z); - l23.insert(_v3); - l34.insert(_v3); - if (_solver->getMicroBC()->getDim() ==3) - l37.insert(_v3); - _virtualVertices.insert(_v3); - _cVertices.insert(_v3); - _bVertices.insert(_v3); - } - else { - _v3 = *(vv.begin()); - } - - if (_solver->getMicroBC()->getDim() ==3){ + + + // find v3 + vv.clear(); + InterpolationOperations::groupIntersection(l23,l34,vv); + if (vv.size()==0){ + InterpolationOperations::groupIntersection(l34,l37,vv); + } + if (vv.size() ==0){ + InterpolationOperations::groupIntersection(l23,l37,vv); + } + if (vv.size() > 0){ + _v3 = *(vv.begin()); + } + else{ + double x = _v4->x() + _v2->x() - _v1->x(); + double y = _v4->y() + _v2->y() - _v1->y(); + double z = _v4->z() + _v2->z() - _v1->z(); + _v3 = new MVertex(x,y,z); + Msg::Info("Create root vertex v3 %d: %e %e %e",_v3->getNum(),x,y,z); + _virtualVertices.insert(_v3); + _cVertices.insert(_v3); + _bVertices.insert(_v3); + } + // find _v6 vv.clear(); - groupIntersection(l26,l56,vv); + InterpolationOperations::groupIntersection(l26,l56,vv); if (vv.size() == 0) - groupIntersection(l56,l67,vv); + InterpolationOperations::groupIntersection(l56,l67,vv); if (vv.size() == 0) - groupIntersection(l26,l67,vv); + InterpolationOperations::groupIntersection(l26,l67,vv); if (vv.size()==0){ double x = _v2->x() + _v5->x() - _v1->x(); @@ -765,9 +961,6 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ double z = _v2->z() + _v5->z() - _v1->z(); _v6 = new MVertex(x,y,z); Msg::Info("Create root vertex v6 %d: %e %e %e",_v6->getNum(),x,y,z); - l26.insert(_v6); - l56.insert(_v6); - l67.insert(_v6); _virtualVertices.insert(_v6); _cVertices.insert(_v6); _bVertices.insert(_v6); @@ -778,12 +971,12 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ // find _v8 vv.clear(); - groupIntersection(l85,l48,vv); + InterpolationOperations::groupIntersection(l85,l48,vv); if (vv.size() == 0) - groupIntersection(l48,l78,vv); + InterpolationOperations::groupIntersection(l48,l78,vv); if (vv.size() == 0) - groupIntersection(l85,l78,vv); + InterpolationOperations::groupIntersection(l85,l78,vv); if (vv.size()==0){ double x = _v4->x() + _v5->x() - _v1->x(); @@ -791,9 +984,6 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ double z = _v4->z() + _v5->z() - _v1->z(); _v8 = new MVertex(x,y,z); Msg::Info("Create root vertex v8 %d: %e %e %e",_v8->getNum(),x,y,z); - l48.insert(_v8); - l78.insert(_v8); - l85.insert(_v8); _virtualVertices.insert(_v8); _cVertices.insert(_v8); _bVertices.insert(_v8); @@ -804,12 +994,12 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ // find _v7 vv.clear(); - groupIntersection(l78,l37,vv); + InterpolationOperations::groupIntersection(l78,l37,vv); if (vv.size() == 0) - groupIntersection(l37,l67,vv); + InterpolationOperations::groupIntersection(l37,l67,vv); if (vv.size() == 0) - groupIntersection(l78,l67,vv); + InterpolationOperations::groupIntersection(l78,l67,vv); if (vv.size()==0){ double x = _v3->x() + _v5->x() - _v1->x(); @@ -817,9 +1007,6 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ double z = _v3->z() + _v5->z() - _v1->z(); _v7 = new MVertex(x,y,z); Msg::Info("Create root vertex v7 %d: %e %e %e",_v7->getNum(),x,y,z); - l78.insert(_v7); - l37.insert(_v7); - l67.insert(_v7); _virtualVertices.insert(_v7); _cVertices.insert(_v7); _bVertices.insert(_v7); @@ -827,333 +1014,26 @@ void pbcConstraintElementGroup::addOtherCornerPoints(){ else { _v7 = *(vv.begin()); } - } -}; - -void pbcConstraintElementGroup::createPolynomialBasePoints(){ - int dim = _solver->getMicroBC()->getDim(); - nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - int degreeX = pbc->getPBCPolynomialDegree(0); - int degreeY = pbc->getPBCPolynomialDegree(1);; - int degreeZ = pbc->getPBCPolynomialDegree(2);; - - if (!pbc->isForcedInterpolationDegree()){ - int sizeX = l12.size(); - int sizeY = l41.size(); - int sizeZ = l15.size(); - - Msg::Info("Maximal number of Boundary Nodes in X direction %d, Y direction %d, Z direction %d",sizeX,sizeY,sizeZ); - if (pbc->getPBCMethod() == nonLinearPeriodicBC::LIM or - pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ - // first order - if (degreeX>sizeX-1) degreeX = sizeX-1; - if (degreeY>sizeY-1) degreeY = sizeY-1; - if (degreeZ>sizeZ-1 && dim == 3) degreeZ = sizeZ-1; - } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM or - pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ - // second-order - if (degreeX>(sizeX-1)/2) degreeX = (sizeX-1)/2; - if (degreeY>(sizeY-1)/2) degreeY = (sizeY-1)/2; - if (degreeZ>(sizeZ-1)/2 && dim == 3) degreeZ = (sizeZ-1)/2; - } - else{ - Msg::Fatal("interpolation type must be defined"); - } - if (degreeX<1) degreeX = 1; - if (degreeY<1) degreeY = 1; - if (degreeZ<1) degreeZ = 1; - - // modify degree - pbc->setPBCPolynomialDegree(0,degreeX); - pbc->setPBCPolynomialDegree(1,degreeY); - pbc->setPBCPolynomialDegree(2,degreeZ); - } - - Msg::Info("Interpolation degree used in X direction %d, Y direction %d, Z direction %d",degreeX,degreeY,degreeZ); - - bool ok = false; - if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN or - pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ - ok = true; - } - if (pbc->addNewVertices(0) or l12.size()<=2 or ok){ - this->createNewVerticesForInterpolationPoints(degreeX,_v1,_v2,_xBase,_cVertices); - } - else - this->getInterpolatioPointsFromExistingVertices(degreeX,_v1,_v4,l12.begin(), l12.end(),_xBase); - - - if (pbc->addNewVertices(1) or l41.size()<=2 or ok){ - this->createNewVerticesForInterpolationPoints(degreeY,_v1,_v4,_yBase,_cVertices); - } - else - this->getInterpolatioPointsFromExistingVertices(degreeY,_v1,_v2,l41.begin(), l41.end(),_yBase); - - if (dim == 3){ - if (pbc->addNewVertices(2) or l15.size()<=2 or ok){ - this->createNewVerticesForInterpolationPoints(degreeZ,_v1,_v5,_zBase,_cVertices); - } - else - this->getInterpolatioPointsFromExistingVertices(degreeZ,_v1,_v4,l15.begin(), l15.end(),_zBase); - } -}; - -void pbcConstraintElementGroup::createBCGroup3D( std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, - MVertex* vc, groupOfElements* g){ - if (vlx[0] != vly[0]){ - Msg::Fatal("two BC group must be started by same vertex"); - return; - } - MVertex* vroot = vlx[0]; - nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - if (pbc == NULL) return; - int NX = vlx.size(); - int NY = vly.size(); - - std::vector<std::vector<MVertex*> > vmat; - vmat.push_back(vlx); - - for (int j=1; j<NY; j++){ - std::vector<MVertex*> vv; - vv.push_back(vly[j]); - for (int i=1; i< NX; i++){ - MVertex* vertex = NULL; - if (j == NY-1 && i == NX-1){ - vertex = vc; - } - else{ - vertex = new MVertex(0,0,0); - vertex->x() = vlx[i]->x() - vroot->x()+ vly[j]->x(); - vertex->y() = vlx[i]->y() - vroot->y()+ vly[j]->y(); - vertex->z() = vlx[i]->z() - vroot->z()+ vly[j]->z(); - _virtualVertices.insert(vertex); - } - vv.push_back(vertex); - } - vmat.push_back(vv); - } - - - if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ - for (int i=0; i<NX-1; i++){ - for (int j=0; j<NY-1; j++){ - MElement* e = new MQuadrangle(vmat[j][i],vmat[j][i+1],vmat[j+1][i+1],vmat[j+1][i]); - g->insert(e); - } - } - } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ - for (int i=0; i<NX-1; i+=2){ - for (int j=0; j<NY-1; j+=2){ - MElement* e = new MQuadrangle9(vmat[j][i],vmat[j][i+2],vmat[j+2][i+2],vmat[j+2][i], - vmat[j][i+1],vmat[j+1][i+2],vmat[j+2][i+1],vmat[j+1][i], - vmat[j+1][i+1]); - g->insert(e); - } - } - } -}; - -void pbcConstraintElementGroup::intersectionBetweenTwoFaces(const groupOfElements* face1, const groupOfElements* face2, groupOfElements* & line) const{ - - std::vector<std::vector<MVertex*> > allEdges; - for (groupOfElements::elementContainer::iterator itL = face1->begin(); itL!= face1->end(); itL++){ - MElement* eleL = *itL; - if (eleL->getDim() != 2){ - Msg::Fatal("This fuction is implemented from 2D elements only"); - } - bool found = false; - for (int i=0; i< eleL->getNumEdges(); i++){ - std::vector<MVertex*> vvL; - eleL->getEdgeVertices(i,vvL); - // found in face3 - for (groupOfElements::elementContainer::iterator itR = face2->begin(); itR!= face2->end(); itR++){ - MElement* eleR = *itR; - for (int j=0; j< eleR->getNumEdges(); j++){ - std::vector<MVertex*> vvR; - eleR->getEdgeVertices(j,vvR); - if (((vvL[0]->getNum() == vvR[0]->getNum()) and (vvL[1]->getNum() == vvR[1]->getNum())) or - ((vvL[0]->getNum() == vvR[1]->getNum()) and (vvL[1]->getNum() == vvR[0]->getNum()))){ - allEdges.push_back(vvL); - found = true; - break; - } - - } - if (found) break; - } - if (found) break; - - } - } - - // add to grEle - if (line == NULL) line = new groupOfElements(); - for (int i=0; i< allEdges.size(); i++){ - std::vector<MVertex*>& vv = allEdges[i]; - MElement* ele = new MLineN(vv); - line->insert(ele); - } -}; - -void pbcConstraintElementGroup::intersectionBetweenTwoLines(const groupOfElements* line1, const groupOfElements* line2, groupOfElements* & pt) const{ - std::vector<MVertex*> allVertex; - for (groupOfElements::vertexContainer::iterator itL = line1->vbegin(); itL!= line1->vend(); itL++){ - MVertex* v1 = *itL; - for (groupOfElements::vertexContainer::iterator itR = line2->vbegin(); itR!= line2->vend(); itR++){ - MVertex* v2 = *itR; - if (v1->getNum() == v2->getNum()){ - allVertex.push_back(v1); - break; - } - } - } - - if (pt == NULL) pt = new groupOfElements(); - for (int i=0; i< allVertex.size(); i++){ - MElement* ele = new MPoint(allVertex[i]); - pt->insert(ele); - } -}; - -void pbcConstraintElementGroup::createAllBCGroups(){ - int dim = _solver->getMicroBC()->getDim(); - if (_gX != NULL) delete _gX; - _gX = new groupOfElements(); - if (_gY != NULL) delete _gY; - _gY = new groupOfElements(); - - nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ - for (int i=0; i<_xBase.size()-1; i++){ - MElement* line = new MLine(_xBase[i],_xBase[i+1]); - _gX->insert(line); - } - - for (int i=0; i<_yBase.size()-1; i++){ - MElement* line = new MLine(_yBase[i],_yBase[i+1]); - _gY->insert(line); - } - - if (dim == 3){ - _gZ = new groupOfElements(); - for (int i=0; i<_zBase.size()-1; i++){ - MElement* line = new MLine(_zBase[i],_zBase[i+1]); - _gZ->insert(line); - } - } - } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ - std::vector<MVertex*> xtemp(_xBase); - _xBase.clear(); - for (int i=0; i<xtemp.size()-1; i++){ - _xBase.push_back(xtemp[i]); - MVertex* v = new MVertex(0.5*(xtemp[i+1]->x()+xtemp[i]->x()), - 0.5*(xtemp[i+1]->y()+xtemp[i]->y()), - 0.5*(xtemp[i+1]->z()+xtemp[i]->z())); - - _virtualVertices.insert(v); - _bVertices.insert(v); - _xBase.push_back(v); - - MElement* line = new MLine3(xtemp[i],xtemp[i+1],v); - _gX->insert(line); - if (i == xtemp.size()-2){ - _xBase.push_back(xtemp[i+1]); - } - } - - std::vector<MVertex*> ytemp(_yBase); - _yBase.clear(); - for (int i=0; i<ytemp.size()-1; i++){ - _yBase.push_back(ytemp[i]); - MVertex* v = new MVertex(0.5*(ytemp[i+1]->x()+ytemp[i]->x()), - 0.5*(ytemp[i+1]->y()+ytemp[i]->y()), - 0.5*(ytemp[i+1]->z()+ytemp[i]->z())); - - _virtualVertices.insert(v); - _bVertices.insert(v); - _yBase.push_back(v); - - MElement* line = new MLine3(ytemp[i],ytemp[i+1],v); - _gY->insert(line); - if (i == ytemp.size()-2){ - _yBase.push_back(ytemp[i+1]); - } - } - - if (dim== 3){ - std::vector<MVertex*> ztemp(_zBase); - _zBase.clear(); - if (_gZ != NULL) delete _gZ; - _gZ = new groupOfElements(); - for (int i=0; i<ztemp.size()-1; i++){ - _zBase.push_back(ztemp[i]); - MVertex* v = new MVertex(0.5*(ztemp[i+1]->x()+ztemp[i]->x()), - 0.5*(ztemp[i+1]->y()+ztemp[i]->y()), - 0.5*(ztemp[i+1]->z()+ztemp[i]->z())); - - _virtualVertices.insert(v); - _bVertices.insert(v); - _zBase.push_back(v); - - MElement* line = new MLine3(ztemp[i],ztemp[i+1],v); - _gZ->insert(line); - if (i == ztemp.size()-2){ - _zBase.push_back(ztemp[i+1]); - } - } + + + _periodic12[0] = _v2->x() - _v1->x(); + _periodic12[1] = _v2->y() - _v1->y(); + _periodic12[2] = _v2->z() - _v1->z(); - } - }; + _periodic14[0] = _v4->x() - _v1->x(); + _periodic14[1] = _v4->y() - _v1->y(); + _periodic14[2] = _v4->z() - _v1->z(); - if (dim == 3){ - if (_gXY != NULL) delete _gXY; - if (_gYZ != NULL) delete _gYZ; - if (_gZX != NULL) delete _gZX; - _gXY = new groupOfElements(); - _gZX = new groupOfElements(); - _gYZ = new groupOfElements(); - - this->createBCGroup3D(_xBase,_yBase,_v3,_gXY); - this->createBCGroup3D(_yBase,_zBase,_v8,_gYZ); - this->createBCGroup3D(_zBase,_xBase,_v6,_gZX); + _periodic15[0] = _v5->x() - _v1->x(); + _periodic15[1] = _v5->y() - _v1->y(); + _periodic15[2] = _v5->z() - _v1->z(); } + _periodic12.print("periodic 1 --> 2"); + _periodic14.print("periodic 1 --> 4"); + _periodic15.print("periodic 1 --> 5"); + }; -template<class Iterator> -MVertex* pbcConstraintElementGroup::findNearestVertex(Iterator itbegin, Iterator itend, MVertex* vp){ - MVertex* vinit = *itbegin; - double dist=vinit->distance(vp); - for (Iterator it=itbegin; it!=itend; it++){ - MVertex* v=*it; - double tempDist=v->distance(vp); - if (tempDist<dist) { - dist=tempDist; - vinit=v; - }; - }; - return vinit; -}; - -MVertex* pbcConstraintElementGroup::findNearestVertex(groupOfElements* g, MVertex* vp){ - /* - groupOfElements::vertexContainer::iterator it = g->vbegin(); - MVertex* vinit = *it; - double dist=vinit->distance(vp); - for (groupOfElements::vertexContainer::iterator it=g->vbegin(); it!=g->vend(); it++){ - MVertex* v=*it; - double tempDist=v->distance(vp); - if (tempDist<dist) { - dist=tempDist; - vinit=v; - }; - }; - return vinit; - */ - return findNearestVertex(g->vbegin(), g->vend(),vp); -}; template<class Iterator> void pbcConstraintElementGroup::periodicConditionForPeriodicMesh(Iterator posivtiveitbegin, Iterator positiveitend, @@ -1162,7 +1042,7 @@ void pbcConstraintElementGroup::periodicConditionForPeriodicMesh(Iterator posivt for (Iterator itp = posivtiveitbegin; itp!= positiveitend; itp++){ MVertex* v = *itp; if ( others.find(v) == others.end()){ - MVertex* vn = findNearestVertex(negativeitbegin,negativeitend,v); + MVertex* vn = InterpolationOperations::findNearestVertex(negativeitbegin,negativeitend,v); constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,-1,v,vn,vrootP,vrootN); _allConstraint.insert(cel); }; @@ -1177,7 +1057,7 @@ void pbcConstraintElementGroup::periodicConditionForPeriodicMesh(const int comp, for (Iterator itp = posivtiveitbegin; itp!= positiveitend; itp++){ MVertex* v = *itp; if ( others.find(v) == others.end()){ - MVertex* vn = findNearestVertex(negativeitbegin,negativeitend,v); + MVertex* vn = InterpolationOperations::findNearestVertex(negativeitbegin,negativeitend,v); constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,comp,v,vn,vrootP,vrootN,fact); _allConstraint.insert(cel); }; @@ -1185,77 +1065,6 @@ void pbcConstraintElementGroup::periodicConditionForPeriodicMesh(const int comp, }; - -void pbcConstraintElementGroup::createNewVerticesForInterpolationPoints(int degree, MVertex* vinit, MVertex* vend, - std::vector<MVertex*>& base, - std::set<MVertex*>& others){ - base.clear(); - double x0 = vinit->x(); double x1 = vend->x(); - double y0 = vinit->y(); double y1 = vend->y(); - double z0 = vinit->z(); double z1 = vend->z(); - if (others.find(vinit) == others.end()){ - MVertex* v = new MVertex(x0,y0,z0); - base.push_back(v); - _virtualVertices.insert(v); - } - else{ - base.push_back(vinit); - }; - double dx = (x1-x0)/degree; - double dy = (y1-y0)/degree; - double dz = (z1-z0)/degree; - for (int j=0; j<degree-1; j++){ - double xi = x0+ (j+1)*dx; - double yi = y0+ (j+1)*dy; - double zi = z0+ (j+1)*dz; - MVertex* v = new MVertex(xi,yi,zi); - base.push_back(v); - _virtualVertices.insert(v); - }; - - if (others.find(vend) == others.end()){ - MVertex* v = new MVertex(x1,y1,z1); - base.push_back(v); - _virtualVertices.insert(v); - } - else{ - base.push_back(vend); - }; -}; - -template<class Iterator> -void pbcConstraintElementGroup::getInterpolatioPointsFromExistingVertices(int degree, MVertex* v1, MVertex* v2, - Iterator itbegin, Iterator itend, - std::vector<MVertex*>& base){ - base.clear(); - std::vector<MVertex*> list; - std::vector<double> vals; - for (Iterator it=itbegin; it!=itend; it++){ - MVertex* v=*it; - list.push_back(v); - vals.push_back(distance(v->point(),v1->point(),v2->point())); - }; - - int size=list.size(); - for (int i=0; i<size; i++){ - for (int j=i; j<size; j++){ - if (vals[j]<vals[i]){ - double temp=vals[i]; vals[i]=vals[j]; vals[j]=temp; - MVertex* vtemp=list[i]; list[i]=list[j]; list[j]=vtemp; - }; - }; - }; - if (degree>size-1){ - degree=size-1; - std::cout<<"Modify the imposed degree: "<<degree<<std::endl; - }; - base.push_back(list[0]); - for (int j=0; j<degree-1; j++){ - base.push_back(list[(j+1)*(size-1)/degree]); - }; - base.push_back(list[size-1]); -}; - // for cubic spline template<class Iterator> void pbcConstraintElementGroup::cubicSplineFormCondition(Iterator itbegin, Iterator itend, @@ -1586,30 +1395,35 @@ void pbcConstraintElementGroup::lagrangePeriodicConditionCoonsPatch(Iterator itb }; }; -bool pbcConstraintElementGroup::isInside(MVertex* v, MElement* e) const{ - int dim = e->getDim(); - std::vector<MVertex*> vv; - e->getVertices(vv); - - SPoint3 pp; - if (dim == 1){ - pp = project(v->point(),vv[0]->point(), vv[1]->point()); - } - else if (dim ==2){ - pp = project(v->point(),vv[0]->point(), vv[1]->point(),vv[2]->point()); - } - - double xyz[3] = {pp[0],pp[1],pp[2]}; - double uvw[3]; - - e->xyz2uvw(xyz,uvw); - if (e->isInside(uvw[0],uvw[1],uvw[2])){ - return true; - } - else return false; - +template<class Iterator> +void pbcConstraintElementGroup::pbcFormFEConstraintElementGroup(Iterator itbegin, Iterator itend, + groupOfElements* g, std::set<MVertex*>& others, + MVertex* vrootP, MVertex* vrootN){ + std::set<MVertex*> allCheck(others); + allCheck.insert(g->vbegin(),g->vend()); + for (Iterator it = itbegin; it!= itend;it++){ + MVertex* v = *it; + if (allCheck.find(v)==allCheck.end()){ + MElement* e = NULL; + for (groupOfElements::elementContainer::iterator itg = g->begin(); itg!= g->end(); itg++){ + MElement* ele = *itg; + if (InterpolationOperations::isInside(v,ele)){ + e = ele; + break; + } + } + if (e == NULL){ + Msg::Error("receive element not found"); + } + else{ + constraintElement* cele = new FEConstraintElement(_solver->getMicroBC() ,_LagSpace,_MultSpace, -1,v,e,vrootP,vrootN); + _allConstraint.insert(cele); + } + }; + }; }; + template<class Iterator> void pbcConstraintElementGroup::pbcFEConstraintElementGroup(Iterator itbegin, Iterator itend, groupOfElements* g, std::set<MVertex*>& others, @@ -1620,7 +1434,7 @@ void pbcConstraintElementGroup::pbcFEConstraintElementGroup(Iterator itbegin, It MElement* e = NULL; for (groupOfElements::elementContainer::iterator itg = g->begin(); itg!= g->end(); itg++){ MElement* ele = *itg; - if (isInside(v,ele)){ + if (InterpolationOperations::isInside(v,ele)){ e = ele; break; } @@ -1640,41 +1454,92 @@ void pbcConstraintElementGroup::createFEConstraintElementGroup(){ int dim = _solver->getMicroBC()->getDim(); nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); - // create base - this->createPolynomialBasePoints(); - this->createAllBCGroups(); - + // create base + std::set<MVertex*> newVirVertices; + InterpolationOperations::createPolynomialBasePoints(pbc,_v1,_v2,_v4,_v5,l12,l41,l15,_xBase,_yBase,_zBase,newVirVertices); + if (dim ==2){ - this->pbcFEConstraintElementGroup(l12.begin(),l12.end(),_gX,_cVertices,_v1,_v1); + if (_gX == NULL) _gX = new groupOfElements(); + else _gX->clearAll(); + + if (_gY == NULL) _gY = new groupOfElements(); + else _gY->clearAll(); + + if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ + InterpolationOperations::createGroupLinearLineElementFromVerticesVector(_xBase,*_gX); + InterpolationOperations::createGroupLinearLineElementFromVerticesVector(_yBase,*_gY); + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ + InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(_xBase,*_gX,newVirVertices); + InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(_yBase,*_gY,newVirVertices); + } + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); + + this->pbcFormFEConstraintElementGroup(l12.begin(),l12.end(),_gX,_cVertices,_v1,_v1); this->pbcFEConstraintElementGroup(l34.begin(),l34.end(),_gX,_cVertices,_v4,_v1); - this->pbcFEConstraintElementGroup(l41.begin(),l41.end(),_gY,_cVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(l41.begin(),l41.end(),_gY,_cVertices,_v1,_v1); this->pbcFEConstraintElementGroup(l23.begin(),l23.end(),_gY,_cVertices,_v2,_v1); } else if (dim == 3){ - #ifdef _DEBUG - Msg::Error("ele num gxy =%d, gyz = %d, gzx = %d",_gXY->size(),_gYZ->size(), _gZX->size()); - #endif - + if (_gX == NULL) _gX = new groupOfElements(); + else _gX->clearAll(); + if (_gY == NULL) _gY = new groupOfElements(); + else _gY->clearAll(); + if (_gZ == NULL) _gZ = new groupOfElements(); + else _gZ->clearAll(); + if (_gXY == NULL) _gXY = new groupOfElements(); + else _gXY->clearAll(); + if (_gYZ == NULL) _gYZ = new groupOfElements(); + else _gYZ->clearAll(); + if (_gZX == NULL) _gZX = new groupOfElements(); + else _gZX->clearAll(); + + + if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN){ + InterpolationOperations::createGroupLinearLineElementFromVerticesVector(_xBase,*_gX); + InterpolationOperations::createGroupLinearLineElementFromVerticesVector(_yBase,*_gY); + InterpolationOperations::createGroupLinearLineElementFromVerticesVector(_zBase,*_gZ); + + _bVertices.insert(newVirVertices.begin(),newVirVertices.end()); + + InterpolationOperations::createLinearElementBCGroup3DFromTwoEdges(_xBase,_yBase,_v3,*_gXY,newVirVertices); + InterpolationOperations::createLinearElementBCGroup3DFromTwoEdges(_yBase,_zBase,_v8,*_gYZ,newVirVertices); + InterpolationOperations::createLinearElementBCGroup3DFromTwoEdges(_zBase,_xBase,_v6,*_gZX,newVirVertices); + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); + + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ + InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(_xBase,*_gX,newVirVertices); + InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(_yBase,*_gY,newVirVertices); + InterpolationOperations::createGroupQuadraticLineElementFromVerticesVector(_zBase,*_gZ,newVirVertices); + _bVertices.insert(newVirVertices.begin(),newVirVertices.end()); + + InterpolationOperations::createQuadraticElementBCGroup3DFromTwoEdges(_xBase,_yBase,_v3,*_gXY,newVirVertices); + InterpolationOperations::createQuadraticElementBCGroup3DFromTwoEdges(_yBase,_zBase,_v8,*_gYZ,newVirVertices); + InterpolationOperations::createQuadraticElementBCGroup3DFromTwoEdges(_zBase,_xBase,_v6,*_gZX,newVirVertices); + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); + } + - this->pbcFEConstraintElementGroup(l12.begin(),l12.end(),_gX,_cVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(l12.begin(),l12.end(),_gX,_cVertices,_v1,_v1); this->pbcFEConstraintElementGroup(l34.begin(),l34.end(),_gX,_cVertices,_v4,_v1); this->pbcFEConstraintElementGroup(l78.begin(),l78.end(),_gX,_cVertices,_v8,_v1); this->pbcFEConstraintElementGroup(l56.begin(),l56.end(),_gX,_cVertices,_v5,_v1); - this->pbcFEConstraintElementGroup(l41.begin(),l41.end(),_gY,_cVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(l41.begin(),l41.end(),_gY,_cVertices,_v1,_v1); this->pbcFEConstraintElementGroup(l23.begin(),l23.end(),_gY,_cVertices,_v2,_v1); this->pbcFEConstraintElementGroup(l67.begin(),l67.end(),_gY,_cVertices,_v6,_v1); this->pbcFEConstraintElementGroup(l85.begin(),l85.end(),_gY,_cVertices,_v5,_v1); - this->pbcFEConstraintElementGroup(l15.begin(),l15.end(),_gZ,_cVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(l15.begin(),l15.end(),_gZ,_cVertices,_v1,_v1); this->pbcFEConstraintElementGroup(l26.begin(),l26.end(),_gZ,_cVertices,_v2,_v1); this->pbcFEConstraintElementGroup(l37.begin(),l37.end(),_gZ,_cVertices,_v3,_v1); this->pbcFEConstraintElementGroup(l48.begin(),l48.end(),_gZ,_cVertices,_v4,_v1); - this->pbcFEConstraintElementGroup(f1234->vbegin(), f1234->vend(),_gXY,_bVertices,_v1,_v1); - this->pbcFEConstraintElementGroup(f1584->vbegin(), f1584->vend(),_gYZ,_bVertices,_v1,_v1); - this->pbcFEConstraintElementGroup(f1562->vbegin(), f1562->vend(),_gZX,_bVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(f1234->vbegin(), f1234->vend(),_gXY,_bVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(f1584->vbegin(), f1584->vend(),_gYZ,_bVertices,_v1,_v1); + this->pbcFormFEConstraintElementGroup(f1562->vbegin(), f1562->vend(),_gZX,_bVertices,_v1,_v1); this->pbcFEConstraintElementGroup(f5678->vbegin(), f5678->vend(),_gXY,_bVertices,_v5,_v1); this->pbcFEConstraintElementGroup(f2673->vbegin(), f2673->vend(),_gYZ,_bVertices,_v2,_v1); @@ -1693,15 +1558,16 @@ void pbcConstraintElementGroup::createProjectConstraintElementGroup(){ this->pbcFEConstraintElementGroup(l23.begin(),l23.end(),bgroup[1],_cVertices,_v2,_v1); } else if (dim == 3){ - if (_gX) delete _gX; - if (_gY) delete _gY; - if (_gZ) delete _gZ; - _gX = new groupOfElements(); - intersectionBetweenTwoFaces(f1234,f1562,_gX); - _gY = new groupOfElements(); - intersectionBetweenTwoFaces(f1234,f1584,_gY); - _gZ = new groupOfElements(); - intersectionBetweenTwoFaces(f1562,f1584,_gZ); + if (_gX == NULL) _gX = new groupOfElements(); + else _gX->clearAll(); + if (_gY == NULL) _gY = new groupOfElements(); + else _gY->clearAll(); + if (_gZ == NULL) _gZ = new groupOfElements(); + else _gZ->clearAll(); + + InterpolationOperations::intersectionBetweenTwoFaces(f1234,f1562,*_gX); + InterpolationOperations::intersectionBetweenTwoFaces(f1234,f1584,*_gY); + InterpolationOperations::intersectionBetweenTwoFaces(f1562,f1584,*_gZ); this->pbcFEConstraintElementGroup(l34.begin(),l34.end(),_gX,_cVertices,_v4,_v1); this->pbcFEConstraintElementGroup(l78.begin(),l78.end(),_gX,_cVertices,_v8,_v1); @@ -1727,29 +1593,6 @@ void pbcConstraintElementGroup::createPeriodicMeshConstraintElementGroup(){ int dim = _solver->getMicroBC()->getDim(); const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); - /**fixed node in case of periodic boundary condition and corner nodes does not exist**/ - if ((_cVertices.size() ==0) and (_solver->getMicroBC()->getOrder()==1)){ - if (dim==2){ - MVertex* v = *(bgroup[0]->vbegin()); - _cVertices.insert(v); - _cVertices.insert(findNearestVertex(bgroup[2],v)); - for (std::set<MVertex*>::iterator it=_cVertices.begin(); it !=_cVertices.end(); it++){ - _bVertices.insert(*it); - } - } - else if (dim==3) { - MVertex* v = *(bgroup[0]->vbegin()); - _cVertices.insert(v); - _cVertices.insert(findNearestVertex(bgroup[3],v)); - v = *(bgroup[1]->vbegin()); - _cVertices.insert(v); - _cVertices.insert(findNearestVertex(bgroup[4],v)); - for (std::set<MVertex*>::iterator it=_cVertices.begin(); it !=_cVertices.end(); it++){ - _bVertices.insert(*it); - }; - }; - }; - if (dim ==3){ // periodic of edges periodicConditionForPeriodicMesh(l56.begin(),l56.end(),l12.begin(),l12.end(),_cVertices,_v5,_v1); @@ -1787,13 +1630,12 @@ void pbcConstraintElementGroup::createPeriodicMeshConstraintElementGroup(){ } void pbcConstraintElementGroup::createCubicSplineConstraintElementGroup(){ - - const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); - nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); int dim = _solver->getMicroBC()->getDim(); - + nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); // create basis - this->createPolynomialBasePoints(); + std::set<MVertex*> newVirVertices; // new vertices created in interpolation basis + InterpolationOperations::createPolynomialBasePoints(pbc,_v1,_v2,_v4,_v5,l12,l41,l15,_xBase,_yBase,_zBase,newVirVertices); + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); if (dim ==2){ this->cubicSplineFormCondition(l12.begin(),l12.end(),_xBase,0); @@ -1803,6 +1645,9 @@ void pbcConstraintElementGroup::createCubicSplineConstraintElementGroup(){ this->cubicSplinePeriodicCondition(l23.begin(),l23.end(),_yBase,1,_cVertices); } else if (dim ==3){ + // in 3D new ver are b-one + _bVertices.insert(newVirVertices.begin(),newVirVertices.end()); + this->cubicSplineFormCondition(l12.begin(),l12.end(),_xBase,0); this->cubicSplineFormCondition(l41.begin(),l41.end(),_yBase,1); this->cubicSplineFormCondition(l15.begin(),l15.end(),_zBase,2); @@ -1845,7 +1690,9 @@ void pbcConstraintElementGroup::createShiftedLagrangeConstraintElementGroup(){ int dim = _solver->getMicroBC()->getDim(); const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); // create base - this->createPolynomialBasePoints(); + std::set<MVertex*> newVirVertices; + InterpolationOperations::createPolynomialBasePoints(pbc,_v1,_v2,_v4,_v5,l12,l41,l15,_xBase,_yBase,_zBase,newVirVertices); + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); if (dim ==2){ this->lagrangeFormCondition(l12.begin(),l12.end(),_xBase); @@ -1893,9 +1740,10 @@ void pbcConstraintElementGroup::createShiftedLagrangeConstraintElementGroup(){ void pbcConstraintElementGroup::createLagrangeConstraintElementGroup(){ int dim = _solver->getMicroBC()->getDim(); nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); // create base - this->createPolynomialBasePoints(); + std::set<MVertex*> newVirVertices; + InterpolationOperations::createPolynomialBasePoints(pbc,_v1,_v2,_v4,_v5,l12,l41,l15,_xBase,_yBase,_zBase,newVirVertices); + _virtualVertices.insert(newVirVertices.begin(),newVirVertices.end()); if (dim ==2){ this->lagrangeFormCondition(l12.begin(),l12.end(),_xBase,_v1,_v1); @@ -1904,6 +1752,8 @@ void pbcConstraintElementGroup::createLagrangeConstraintElementGroup(){ this->lagrangePeriodicCondition(l23.begin(),l23.end(),_yBase,_cVertices,_v2,_v1); } else if (dim ==3){ + _bVertices.insert(newVirVertices.begin(),newVirVertices.end()); + this->lagrangeFormCondition(l12.begin(),l12.end(),_xBase,_v1,_v1); this->lagrangeFormCondition(l41.begin(),l41.end(),_yBase,_v1,_v1); this->lagrangeFormCondition(l15.begin(),l15.end(),_zBase,_v1,_v1); @@ -2216,10 +2066,10 @@ void pbcConstraintElementGroup::createMixBCConstraintElementGroupDirectionFollow constraintElement* ppc = new periodicMeshConstraint(_solver->getMicroBC(), _LagSpace,_LagSpace,_MultSpace,-1,v2); _allConstraint.insert(ppc); - // create local basis - this->getInterpolatioPointsFromExistingVertices(interpDeg[0],v1,v4,bgroup[0]->vbegin(),bgroup[0]->vend(),_xBase); - this->getInterpolatioPointsFromExistingVertices(interpDeg[1],v1,v2,bgroup[1]->vbegin(),bgroup[1]->vend(),_yBase); - + // create local basi + InterpolationOperations::createLinePolynomialBase(interpDeg[0],false,_v1,_v2,l12,_xBase,_virtualVertices); + InterpolationOperations::createLinePolynomialBase(interpDeg[0],false,_v1,_v4,l41,_yBase,_virtualVertices); + for (int i=0; i< _xBase.size(); i++){ Msg::Info("xbase : %d",_xBase[i]->getNum()); } @@ -2377,339 +2227,387 @@ void pbcConstraintElementGroup::createCornerConstraintElementGroupShiftedBPC(){ } void pbcConstraintElementGroup::createCornerConstraintElementGroup(){ - int ndofsPerNode = _solver->getMicroBC()->getNumberOfConstrainedDofsPerVertex(); - - std::vector<int> mechanics(_solver->getMicroBC()->getMechanicsConstrainedComps().begin(), _solver->getMicroBC()->getMechanicsConstrainedComps().end()); // mechanic Dof only - std::vector<int> compConstitutive(_solver->getMicroBC()->getConstitutiveExtraConstrainedComps().begin(), _solver->getMicroBC()->getConstitutiveExtraConstrainedComps().end()); // constitutuive extraDofs - std::vector<int> compNotConstitutive(_solver->getMicroBC()->getNonConstitutiveExtraConstrainedComps().begin(), _solver->getMicroBC()->getNonConstitutiveExtraConstrainedComps().end()); // non-constitutive extraDofs - + if (_solver->getMicroBC()->getType() == nonLinearMicroBC::PBC){ + int ndofsPerNode = _solver->getMicroBC()->getNumberOfConstrainedDofsPerVertex(); + std::vector<int> mechanics(_solver->getMicroBC()->getMechanicsConstrainedComps().begin(), _solver->getMicroBC()->getMechanicsConstrainedComps().end()); // mechanic Dof only + std::vector<int> compConstitutive(_solver->getMicroBC()->getConstitutiveExtraConstrainedComps().begin(), _solver->getMicroBC()->getConstitutiveExtraConstrainedComps().end()); // constitutuive extraDofs + std::vector<int> compNotConstitutive(_solver->getMicroBC()->getNonConstitutiveExtraConstrainedComps().begin(), _solver->getMicroBC()->getNonConstitutiveExtraConstrainedComps().end()); // non-constitutive extraDofs + nonLinearPeriodicBC* pbc = static_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); - if (bgroup.size()>0){ - if (pbc->getPBCMethod() == nonLinearPeriodicBC::CEM or pbc->getPBCMethod() == nonLinearPeriodicBC::PROJECT){ - // for mechanical Dofs - if (_solver->getMicroBC()->getOrder() == 1){ - // fix all corners mechanical Dofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + if (pbc->getPBCMethod() == nonLinearPeriodicBC::CEM or pbc->getPBCMethod() == nonLinearPeriodicBC::PROJECT){ + // for mechanical Dofs + std::set<MVertex*> activeCornerVertices; + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + if (!isVirtual(vp1) or (isVirtual(vp1) and isActive(vp1))){ + activeCornerVertices.insert(vp1); + } + } + if (activeCornerVertices.size() == 0){ + Msg::Info("all corner vertices are not active"); + } + + if (_solver->getMicroBC()->getOrder() == 1){ + // fix all corners mechanical Dofs + if (activeCornerVertices.size() > 0){ + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); - _allConstraint.insert(cel); - } + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); + _allConstraint.insert(cel); + } + } + } + else{ + // fix an arbitrary point + MVertex* v = *(bgroup[0]->vbegin()); + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],v); + _allConstraint.insert(cel); } - } - else if (_solver->getMicroBC()->getOrder() == 2){ - // periodic between - if (_cVertices.size() >0){ - MVertex* vn = *(_cVertices.begin()); - for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - if (it != _cVertices.begin()) - { - MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i], vp1,vn); - _allConstraint.insert(cel); - } + } + } + else if (_solver->getMicroBC()->getOrder() == 2){ + // periodic between + if (activeCornerVertices.size() >0){ + MVertex* vn = *(activeCornerVertices.begin()); + for(std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + if (it != activeCornerVertices.begin()) + { + MVertex* vp1 = *it; + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i], vp1,vn); + _allConstraint.insert(cel); } } } + } - for (int i=0; i<bgroup.size()/2; i++){ - groupOfElements* g = bgroup[i]; - for (int k=0; k< mechanics.size(); k++){ - constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],g); - _allConstraint.insert(ppc); - } - } - } + for (int i=0; i<bgroup.size()/2; i++){ + groupOfElements* g = bgroup[i]; + for (int k=0; k< mechanics.size(); k++){ + constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],g); + _allConstraint.insert(ppc); + } + } + } - // for constitutive extraDofs - if (_cVertices.size() > 0){ - MVertex* oneV = *(_cVertices.begin()); - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - if (vp1 != oneV){ - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,oneV); - _allConstraint.insert(cel); - } - } - } - } - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace,compConstitutive[i],_solver->getDomainVector()); - _allConstraint.insert(celExtra); - } + // for constitutive extraDofs + if (activeCornerVertices.size() > 0){ + MVertex* oneV = *(activeCornerVertices.begin()); + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + MVertex* vp1 = *it; + if (vp1 != oneV){ + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,oneV); + _allConstraint.insert(cel); + } + } + } + } + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace,compConstitutive[i],_solver->getDomainVector()); + _allConstraint.insert(celExtra); + } - // for non-constitutive extraDofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< compNotConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); - _allConstraint.insert(cel); - } + // for non-constitutive extraDofs + if (activeCornerVertices.size() >0){ + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< compNotConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); + _allConstraint.insert(cel); + } + } + } + else{ + MVertex* v = *(bgroup[0]->vbegin()); + for (int i=0; i< compNotConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],v); + _allConstraint.insert(cel); } + } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM){ - // for mechanics - if (_solver->getMicroBC()->getOrder() == 1){ - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); - _allConstraint.insert(cel); - } + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM){ + // for mechanics + if (_solver->getMicroBC()->getOrder() == 1){ + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); + _allConstraint.insert(cel); } - } - else if (_solver->getMicroBC()->getOrder() == 2){ - for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* v = *it; - if ( v != _v1){ - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],v,_v1); - _allConstraint.insert(cel); - } + } + } + else if (_solver->getMicroBC()->getOrder() == 2){ + for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* v = *it; + if ( v != _v1){ + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],v,_v1); + _allConstraint.insert(cel); } } + } - if (_solver->getMicroBC()->getDim() ==2){ - for (int i=0; i< mechanics.size(); i++){ - constraintElement* ppc = new cubicSplineSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_xBase,0); - _allConstraint.insert(ppc); + if (_solver->getMicroBC()->getDim() ==2){ + for (int i=0; i< mechanics.size(); i++){ + constraintElement* ppc = new cubicSplineSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_xBase,0); + _allConstraint.insert(ppc); - ppc = new cubicSplineSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_yBase,1); - _allConstraint.insert(ppc); - } + ppc = new cubicSplineSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_yBase,1); + _allConstraint.insert(ppc); } - else if (_solver->getMicroBC()->getDim() == 3){ - for (int i=0; i<bgroup.size()/2; i++){ - groupOfElements* g = bgroup[i]; - for (int k=0; k< mechanics.size(); k++){ - constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],g); - _allConstraint.insert(ppc); - } + } + else if (_solver->getMicroBC()->getDim() == 3){ + for (int i=0; i<bgroup.size()/2; i++){ + groupOfElements* g = bgroup[i]; + for (int k=0; k< mechanics.size(); k++){ + constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],g); + _allConstraint.insert(ppc); } - }; - }; + } + }; + }; - // - // for constitutive extraDofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - if (vp1 != _v1){ - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,_v1); - _allConstraint.insert(cel); - } - } - } - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, - compConstitutive[i], _solver->getDomainVector()); - _allConstraint.insert(celExtra); - } + // + // for constitutive extraDofs + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + if (vp1 != _v1){ + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,_v1); + _allConstraint.insert(cel); + } + } + } + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, + compConstitutive[i], _solver->getDomainVector()); + _allConstraint.insert(celExtra); + } - // for non-constitutive extraDofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< compNotConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); - _allConstraint.insert(cel); - } + // for non-constitutive extraDofs + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< compNotConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); + _allConstraint.insert(cel); + } + } + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::LIM){ + // for mechanics + if (_solver->getMicroBC()->getOrder() == 1){ + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); + _allConstraint.insert(cel); + } } } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::LIM){ - // for mechanics - if (_solver->getMicroBC()->getOrder() == 1){ - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); - _allConstraint.insert(cel); - } + else if (_solver->getMicroBC()->getOrder() == 2){ + if (pbc->getMaxDegree()>1){ + for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* v = *it; + if ( v != _v1){ + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],v,_v1); + _allConstraint.insert(cel); + } + } } - } - else if (_solver->getMicroBC()->getOrder() == 2){ - if (pbc->getMaxDegree()>1){ - for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* v = *it; - if ( v != _v1){ - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],v,_v1); - _allConstraint.insert(cel); - } - } - } - // - for (int k=0; k< mechanics.size(); k++){ - if (_solver->getMicroBC()->getDim() ==2){ - constraintElement* ppc = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_xBase); - _allConstraint.insert(ppc); - ppc = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_yBase); - _allConstraint.insert(ppc); - } - else if (_solver->getMicroBC()->getDim() ==3){ - std::vector<lagrangeSupplementConstraint*> lconstraint; - lagrangeSupplementConstraint* con = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_xBase); - lconstraint.push_back(con); - con = new lagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],_yBase); - lconstraint.push_back(con); - con = new lagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],_zBase); - lconstraint.push_back(con); - // - constraintElement* ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],lconstraint[0],lconstraint[1]); - _allConstraint.insert(ppc); - ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],lconstraint[1],lconstraint[2]); - _allConstraint.insert(ppc); - ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],lconstraint[0],lconstraint[2]); - _allConstraint.insert(ppc); - } - - } - } - else if (pbc->getMaxDegree() == 1) { - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],vp1); - _allConstraint.insert(cel); - } + // + for (int k=0; k< mechanics.size(); k++){ + if (_solver->getMicroBC()->getDim() ==2){ + constraintElement* ppc = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_xBase); + _allConstraint.insert(ppc); + ppc = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_yBase); + _allConstraint.insert(ppc); + } + else if (_solver->getMicroBC()->getDim() ==3){ + std::vector<lagrangeSupplementConstraint*> lconstraint; + lagrangeSupplementConstraint* con = new lagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],_xBase); + lconstraint.push_back(con); + con = new lagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],_yBase); + lconstraint.push_back(con); + con = new lagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],_zBase); + lconstraint.push_back(con); + // + constraintElement* ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[k],lconstraint[0],lconstraint[1]); + _allConstraint.insert(ppc); + ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],lconstraint[1],lconstraint[2]); + _allConstraint.insert(ppc); + ppc = new CoonsPatchLagrangeSupplementConstraint(_solver->getMicroBC(), _LagSpace,_MultSpace,mechanics[k],lconstraint[0],lconstraint[2]); + _allConstraint.insert(ppc); } - } - } + } + } + else if (pbc->getMaxDegree() == 1) { + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],vp1); + _allConstraint.insert(cel); + } + } + } - // for constitutive extraDofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - if (vp1 != _v1){ - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,_v1); - _allConstraint.insert(cel); - } - } - } - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, - compConstitutive[i], _solver->getDomainVector()); - _allConstraint.insert(celExtra); - } + } - // for non-constitutive extraDofs - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - for (int i=0; i< compNotConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); - _allConstraint.insert(cel); - } + // for constitutive extraDofs + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + if (vp1 != _v1){ + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,_v1); + _allConstraint.insert(cel); + } } - } - else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN or pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, + compConstitutive[i], _solver->getDomainVector()); + _allConstraint.insert(celExtra); + } - std::set<MVertex*> activeCornerVertices; - // all vertual vertices and not appears in any constraint element do not neen to take into account - for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - MVertex* vp1 = *it; - if (!isVirtual(vp1) or (isVirtual(vp1) and isActive(vp1))){ - activeCornerVertices.insert(vp1); - } - } + // for non-constitutive extraDofs + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + for (int i=0; i< compNotConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); + _allConstraint.insert(cel); + } + } - if (activeCornerVertices.size() == 0){ - // need to fix some vertices to avoid rigid body mode - Msg::Info("all corner vertices are virtual and not active"); - for (groupOfElements::vertexContainer::iterator itg = _gX->vbegin(); itg!= _gX->vend(); itg++){ - MVertex* vg = *itg; - if (this->isActive(vg)){ - activeCornerVertices.insert(vg); - break; - } - } - } + } + else if (pbc->getPBCMethod() == nonLinearPeriodicBC::FE_LIN or pbc->getPBCMethod() == nonLinearPeriodicBC::FE_QUA){ + + std::set<MVertex*> activeCornerVertices; + // all vertual vertices and not appears in any constraint element do not neen to take into account + for (std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ + MVertex* vp1 = *it; + if (!isVirtual(vp1) or (isVirtual(vp1) and isActive(vp1))){ + activeCornerVertices.insert(vp1); + } + } + + MVertex* vertexToFix = NULL; + + if (activeCornerVertices.size() == 0){ + // need to fix some vertices to avoid rigid body mode + Msg::Info("all corner vertices are virtual and not active"); + for (groupOfElements::vertexContainer::iterator itg = _gX->vbegin(); itg!= _gX->vend(); itg++){ + MVertex* vg = *itg; + if (this->isActive(vg)){ + vertexToFix = vg; + break; + } + } + } - // for mechanics - if (_solver->getMicroBC()->getOrder() == 1){ - for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + // for mechanics + if (_solver->getMicroBC()->getOrder() == 1){ + if (activeCornerVertices.size() > 0){ + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); - _allConstraint.insert(cel); - } + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vp1); + _allConstraint.insert(cel); + } + } + } + else{ + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,mechanics[i],vertexToFix); + _allConstraint.insert(cel); } + } + + } + else if (_solver->getMicroBC()->getOrder() == 2){ + if (activeCornerVertices.size() >0){ + MVertex* vn = *(activeCornerVertices.begin()); + for(std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + if (it != activeCornerVertices.begin()) + { + MVertex* vp1 = *it; + for (int i=0; i< mechanics.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],vp1,vn); + _allConstraint.insert(cel); - } - else if (_solver->getMicroBC()->getOrder() == 2){ - if (_cVertices.size() >0){ - MVertex* vn = *(_cVertices.begin()); - for(std::set<MVertex*>::iterator it = _cVertices.begin(); it!= _cVertices.end(); it++){ - if (it != _cVertices.begin()) - { - MVertex* vp1 = *it; - for (int i=0; i< mechanics.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],vp1,vn); - _allConstraint.insert(cel); - - } } } } + } - for (int i=0; i< mechanics.size(); i++){ - if (_solver->getMicroBC()->getDim()== 2){ - constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gX); - _allConstraint.insert(ppc); - ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gY); - _allConstraint.insert(ppc); - } - else if (_solver->getMicroBC()->getDim() == 3){ - constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gXY); - _allConstraint.insert(ppc); - ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gYZ); - _allConstraint.insert(ppc); - ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gZX); - _allConstraint.insert(ppc); - } - } - } + for (int i=0; i< mechanics.size(); i++){ + if (_solver->getMicroBC()->getDim()== 2){ + constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gX); + _allConstraint.insert(ppc); + ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gY); + _allConstraint.insert(ppc); + } + else if (_solver->getMicroBC()->getDim() == 3){ + constraintElement* ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gXY); + _allConstraint.insert(ppc); + ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gYZ); + _allConstraint.insert(ppc); + ppc = new supplementConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,mechanics[i],_gZX); + _allConstraint.insert(ppc); + } + } + } - // for constitutive extraDofs - if (activeCornerVertices.size() > 2){ - MVertex* vn1 = *(activeCornerVertices.begin()); - for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ - MVertex* vp1 = *it; - if (vp1 != vn1){ - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,vn1); - _allConstraint.insert(cel); - } - } - } - } - for (int i=0; i< compConstitutive.size(); i++){ - constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, - compConstitutive[i], _solver->getDomainVector()); - _allConstraint.insert(celExtra); - } + // for constitutive extraDofs + if (activeCornerVertices.size() > 0){ + MVertex* vn1 = *(activeCornerVertices.begin()); + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + MVertex* vp1 = *it; + if (vp1 != vn1){ + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC(),_LagSpace,_MultSpace,compConstitutive[i],vp1,vn1); + _allConstraint.insert(cel); + } + } + } + } + for (int i=0; i< compConstitutive.size(); i++){ + constraintElement* celExtra = new supplementConstraintAverageExtraDofValue(_solver->getMicroBC() ,_MultSpace, + compConstitutive[i], _solver->getDomainVector()); + _allConstraint.insert(celExtra); + } - // for non-constitutive extraDofs - for (int i=0; i< compNotConstitutive.size(); i++){ - for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ - MVertex* vp1 = *it; - constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); - _allConstraint.insert(cel); - } + // for non-constitutive extraDofs + if (activeCornerVertices.size() > 0){ + for (int i=0; i< compNotConstitutive.size(); i++){ + for (std::set<MVertex*>::iterator it = activeCornerVertices.begin(); it!= activeCornerVertices.end(); it++){ + MVertex* vp1 = *it; + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vp1); + _allConstraint.insert(cel); + } - } + } + } + else{ + for (int i=0; i< compNotConstitutive.size(); i++){ + constraintElement* cel = new periodicMeshConstraint(_solver->getMicroBC() ,_LagSpace,_MultSpace,compNotConstitutive[i],vertexToFix); + _allConstraint.insert(cel); + } } - else - Msg::Error("pbcConstraintElementGroup::createCornerConstraintElementGroup: case undefined"); + } + else + Msg::Error("pbcConstraintElementGroup::createCornerConstraintElementGroup: case undefined"); } }; @@ -2780,8 +2678,9 @@ void pbcConstraintElementGroup::createConstraintGroup(){ if (pbc->isShifted()){ this->createCornerConstraintElementGroupShiftedBPC(); } - else + else{ this->createCornerConstraintElementGroup(); + } } } else if (_solver->getMicroBC()->getType()==nonLinearMicroBC::LDBC){ @@ -2812,13 +2711,8 @@ void pbcConstraintElementGroup::createConstraintGroup(){ void pbcConstraintElementGroup::clearAllConstraints(){ _allConstraint.clear(); _virtualVertices.clear(); - _pbcNodes.clear(); }; -void pbcConstraintElementGroup::switchMicroBC(){ - this->clearAllConstraints(); // clear all existing constraint elements - this->createConstraintGroup(); // create new groups -}; void pbcConstraintElementGroup::createPBCFromFile(FILE* fp, GModel* pModel){ if (fp == NULL) return; @@ -2876,42 +2770,6 @@ SVector3 pbcConstraintElementGroup::getUniformDisp(MVertex* v){ } return u; }; - -SVector3 pbcConstraintElementGroup::getPerturbation(dofManager<double>* pmanager, MVertex* v){ - SVector3 ubar = this->getUniformDisp(v); - std::vector<Dof> keys; - std::vector<double> val; - std::vector<int> constrainedComp(_solver->getMicroBC()->getConstrainedComps().begin(), _solver->getMicroBC()->getConstrainedComps().end()); - getKeysFromVertex(_LagSpace,v,constrainedComp,keys); - pmanager->getDofValue(keys,val); - ubar *= -1.; - for (int i=0; i<keys.size(); i++){ - ubar[i] += val[i]; - } - return ubar; -}; - -SVector3 pbcConstraintElementGroup::getTangentCubicSpline(dofManager<double>* pmanager, MVertex* v, const int dir){ - SVector3 vec(0.,0.,0.); - std::vector<int> constrainedComp(_solver->getMicroBC()->getConstrainedComps().begin(), _solver->getMicroBC()->getConstrainedComps().end()); - if (_solver->getMicroBC()->getType() != nonLinearMicroBC::PBC) { - Msg::Warning("this used for periodic BC and cubic spline method"); - } - else { - nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); - if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM){ - std::vector<Dof> dofs; - std::vector<double> vals; - cubicSplineConstraintElement::addKeysToVertex(_LagSpace,v,constrainedComp,dofs,dir); - pmanager->getDofValue(dofs,vals); - for (int i=0; i<vals.size(); i++){ - vec[i] += vals[i]; - } - } - } - return vec; -}; - void pbcConstraintElementGroup::cubicSplineToFile(std::vector<MVertex*>& vlist, dofManager<double>* pmanager, FILE* file, const int dir){ if (vlist.size() ==0) return; int N= 100; @@ -2985,6 +2843,43 @@ void pbcConstraintElementGroup::lagrangeToFile(std::vector<MVertex*>& vlist, dof } }; +SVector3 pbcConstraintElementGroup::getPerturbation(dofManager<double>* pmanager, MVertex* v){ + SVector3 ubar = this->getUniformDisp(v); + std::vector<Dof> keys; + std::vector<double> val; + std::vector<int> constrainedComp(_solver->getMicroBC()->getConstrainedComps().begin(), _solver->getMicroBC()->getConstrainedComps().end()); + getKeysFromVertex(_LagSpace,v,constrainedComp,keys); + pmanager->getDofValue(keys,val); + ubar *= -1.; + for (int i=0; i<keys.size(); i++){ + ubar[i] += val[i]; + } + return ubar; +}; + +SVector3 pbcConstraintElementGroup::getTangentCubicSpline(dofManager<double>* pmanager, MVertex* v, const int dir){ + SVector3 vec(0.,0.,0.); + std::vector<int> constrainedComp(_solver->getMicroBC()->getConstrainedComps().begin(), _solver->getMicroBC()->getConstrainedComps().end()); + if (_solver->getMicroBC()->getType() != nonLinearMicroBC::PBC) { + Msg::Warning("this used for periodic BC and cubic spline method"); + } + else { + nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); + if (pbc->getPBCMethod() == nonLinearPeriodicBC::CSIM){ + std::vector<Dof> dofs; + std::vector<double> vals; + cubicSplineConstraintElement::addKeysToVertex(_LagSpace,v,constrainedComp,dofs,dir); + pmanager->getDofValue(dofs,vals); + for (int i=0; i<vals.size(); i++){ + vec[i] += vals[i]; + } + } + } + return vec; +}; + + + void pbcConstraintElementGroup::writePertBoundaryToFile(dofManager<double>* pmanager, const int e, const int g, const int iter ){ if (_solver->getMicroBC()->getType() == nonLinearMicroBC::PBC){ nonLinearPeriodicBC* pbc = dynamic_cast<nonLinearPeriodicBC*>(_solver->getMicroBC()); @@ -3167,17 +3062,6 @@ void pbcConstraintElementGroup::applyLinearConstraintsToSystem(dofManager<double }; }; -void pbcConstraintElementGroup::setLocalBasis(const SVector3& n, const SVector3& t, const SVector3& b){ - _e1 = n; _e1.normalize(); - _e2 = t; _e2.normalize(); - _e3 = b; _e3.normalize(); -}; - -void pbcConstraintElementGroup::setRotatedBasis(const SVector3& n, const SVector3& t, const SVector3 b){ - _e1Rotated = n; _e1Rotated.normalize(); - _e2Rotated = t; _e2Rotated.normalize(); - _e3Rotated = b; _e3Rotated.normalize(); -}; SPoint3 pbcConstraintElementGroup::getRootPoint(){ if (_v1 != NULL) return _v1->point(); @@ -3185,7 +3069,7 @@ SPoint3 pbcConstraintElementGroup::getRootPoint(){ const std::vector<groupOfElements*>& bgroup = _solver->getMicroBC()->getBoundaryGroupOfElements(); if (_solver->getMicroBC()->getDim() == 2){ std::set<MVertex*> vv; - groupIntersection(bgroup[0],bgroup[1],vv); + InterpolationOperations::groupIntersection(bgroup[0],bgroup[1],vv); if (vv.size() == 1){ _v1 = *(vv.begin()); } diff --git a/NonLinearSolver/periodicBC/pbcCreateConstraints.h b/NonLinearSolver/periodicBC/pbcCreateConstraints.h index 273f696486d634cec307952db62d5c1705cf86bd..828895456d82e48bc8b2302adcc0ce13fa9ba1aa 100644 --- a/NonLinearSolver/periodicBC/pbcCreateConstraints.h +++ b/NonLinearSolver/periodicBC/pbcCreateConstraints.h @@ -72,6 +72,47 @@ class GModel; 1--------l12---------2 */ +namespace InterpolationOperations{ + void groupIntersection(groupOfElements* g1, groupOfElements* g2, std::set<MVertex*>& ver); + void groupIntersection(std::set<MVertex*>& g1, std::set<MVertex*>& g2, std::set<MVertex*>& ver); + /* create group of line at intersection of two faces*/ + void intersectionBetweenTwoFaces(const groupOfElements* face1, const groupOfElements* face2, groupOfElements& line); + /* get interpolation points on a line*/ + void createLinePolynomialBase(const int degree, // degree + const bool createNewVer, // true if new vertices are created false if interpolation base is taken from existing vertices + MVertex* vstart, MVertex* vend, // vstart and vend + std::set<MVertex*>& line, // current line + std::vector<MVertex*>& base, // base obtained + std::set<MVertex*>& virtualVertices // virtualVertices to store all virtual virtices which has been created + ); + /* + This function allows to find a nearest vertex in a group vertex to one vertex + by using the minimal distance flag + */ + template<class Iterator> + MVertex* findNearestVertex(Iterator itbegin, Iterator itend, MVertex* vp); + MVertex* findNearestVertex(groupOfElements* g, MVertex* vp); + + + void createGroupLinearLineElementFromVerticesVector(std::vector<MVertex*>& b, groupOfElements& gr); + void createGroupQuadraticLineElementFromVerticesVector(std::vector<MVertex*>& b, groupOfElements& gr, std::set<MVertex*>& virVertices); + + /*create a surface group to interpolate form two boundaries for FE method */ + void createLinearElementBCGroup3DFromTwoEdges(std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, + MVertex* vc, groupOfElements& g, std::set<MVertex*>& newVer); + void createQuadraticElementBCGroup3DFromTwoEdges(std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, + MVertex* vc, groupOfElements& g, std::set<MVertex*>& newVer); + + void createPolynomialBasePoints(nonLinearPeriodicBC* pbc, + MVertex* v1, MVertex* v2, MVertex* v4, MVertex* v5, + std::set<MVertex*>& l12, std::set<MVertex*>& l14,std::set<MVertex*>& l15, + std::vector<MVertex*>& xbase, std::vector<MVertex*>& ybase, std::vector<MVertex*>& zbase, + std::set<MVertex*>& newVer); + bool isInside(MVertex* v, MElement* e); + +}; + + class groupOfElementsDomainDecomposition{ public: int physical; @@ -90,59 +131,36 @@ class pbcConstraintElementGroup{ FunctionSpaceBase* _LagSpace, *_MultSpace; // lagspace and mult space std::set<constraintElement*> _allConstraint; // all constraint + std::set<MVertex*> _cVertices; // corner vertices std::set<MVertex*> _bVertices; // edge vertices, in 2D corner and edger vertices are same std::set<MVertex*> _virtualVertices; // new vertices added to systems for polynomial interpolation - std::vector<MVertex*> _xBase, _yBase, _zBase; // interpolation basis + groupOfElements* _g; /*in case of 2D*/ - groupOfElements* f1234; // surface - std::set<MVertex*> l12, l23, l34,l41; // 4 edges + std::set<MVertex*> l12, l23, l34,l41; // 4 edges //add surfaces of RVE in 3D cases - groupOfElements *f5678, *f1562, *f4873, *f1584, *f2673; + groupOfElements * f1234, *f5678, *f1562, *f4873, *f1584, *f2673; // add 8 edges of RVE in 3D case std::set<MVertex*> l56, l67, l78, l85, l15, l26, l37, l48; MVertex* _v1, *_v2, *_v4, *_v5; // all control points MVertex* _v3, *_v6, *_v7, *_v8; - groupOfElements* _gX, *_gY, *_gZ; // interpolation edges - groupOfElements* _gXY, *_gYZ, *_gZX; // interpolation faces - - SVector3 _periodic12, _periodic14, _periodic15; // - SVector3 _e1, _e2, _e3; // local basis - SVector3 _e1Rotated, _e2Rotated, _e3Rotated; // rotate basis - - // 6 periodic nodes in case of missing corner nodes - std::vector<MVertex*> _pbcNodes; + + SVector3 _periodic12, _periodic14, _periodic15; // periodicity computed from RVE + + std::vector<MVertex*> _xBase, _yBase, _zBase; // default interpolation basis + groupOfElements* _gX, *_gY, *_gZ, *_gXY, *_gYZ, *_gZX; // basis PC based on FE method std::vector<groupOfElementsDomainDecomposition*> _boundaryDGMap; std::map<partDomain*,FunctionSpaceBase*> _allDGMultSpace; // all multspace for DG case - protected: - void groupIntersection(groupOfElements* g1, groupOfElements* g2, std::set<MVertex*>& ver) const; - void groupIntersection(groupOfElements* g1, groupOfElements* g2, groupOfElements* &g) const; - void groupIntersection(std::set<MVertex*>& g1, std::set<MVertex*>& g2, std::set<MVertex*>& ver) const; - /* create group of line at intersection of two faces*/ - void intersectionBetweenTwoFaces(const groupOfElements* face1, const groupOfElements* face2, groupOfElements* &line) const; - void intersectionBetweenTwoLines(const groupOfElements* line1, const groupOfElements* line2, groupOfElements* & pt) const; + private: + + void __init__(); - // add control point in case of missing - void addControlPoints(); - // add other corner nodes - void addOtherCornerPoints(); - // create interpolation basis - void createPolynomialBasePoints(); - /*create a surface group to interpolate form two boundaries for FE method */ - void createBCGroup3D(std::vector<MVertex*>& vlx, std::vector<MVertex*>& vly, - MVertex* vc, groupOfElements* g); - /*create all interpolate surfaces for FE method only*/ - void createAllBCGroups(); - /* - This function allows to find a nearest vertex in a group vertex to one vertex - by using the minimal distance flag - */ - template<class Iterator> - MVertex* findNearestVertex(Iterator itbegin, Iterator itend, MVertex* vp); - MVertex* findNearestVertex(groupOfElements* g, MVertex* vp); + + // in this case, vinit and vend using for constructing the distance function + /* Enforce periodic boundary condition on conformal meshes positive part: posivtiveitbegin-->positiveitend @@ -159,15 +177,7 @@ class pbcConstraintElementGroup{ Iterator negativeitbegin, Iterator negativeitend, std::set<MVertex*>& others, MVertex* vrootP=NULL, MVertex* vrootN=NULL); - /* get interpolation points on a line*/ - void createNewVerticesForInterpolationPoints(int degree, MVertex* vinit, MVertex* vend, - std::vector<MVertex*>& base, - std::set<MVertex*>& others); - // in this case, vinit and vend using for constructing the distance function - template<class Iterator> - void getInterpolatioPointsFromExistingVertices(int degree, MVertex* vinit, MVertex* vend, - Iterator itbegin, Iterator itend, - std::vector<MVertex*>& base); + // for cubic spline template<class Iterator> @@ -216,8 +226,11 @@ class pbcConstraintElementGroup{ void lagrangePeriodicConditionCoonsPatch(Iterator itbegin, Iterator itend, MVertex* vref, std::vector<MVertex*>& xlist,std::vector<MVertex*>& ylist, std::set<MVertex*>& others ,MVertex* vrootP=NULL, MVertex* vrootN = NULL); - - bool isInside(MVertex* v, MElement* e) const; + + template<class Iterator> + void pbcFormFEConstraintElementGroup(Iterator itbegin, Iterator itend, groupOfElements* g, + std::set<MVertex*>& others, MVertex* vrootP=NULL, MVertex* vrootN=NULL); + template<class Iterator> void pbcFEConstraintElementGroup(Iterator itbegin, Iterator itend, groupOfElements* g, std::set<MVertex*>& others, MVertex* vrootP=NULL, MVertex* vrootN=NULL); @@ -248,6 +261,7 @@ class pbcConstraintElementGroup{ SVector3 getUniformDisp(MVertex* v); SVector3 getPerturbation(dofManager<double>* pmanager, MVertex* v); SVector3 getTangentCubicSpline(dofManager<double>* pmanager, MVertex* v,const int dir); + // write perturbation to FILE void cubicSplineToFile(std::vector<MVertex*>& vlist, dofManager<double>* pmanager, FILE* file, const int dir); void lagrangeToFile(std::vector<MVertex*>& vlist, dofManager<double>* pmanager, FILE* file); @@ -256,7 +270,6 @@ class pbcConstraintElementGroup{ FunctionSpaceBase* lagspace, FunctionSpaceBase* multspace); virtual ~pbcConstraintElementGroup(); void createConstraintGroup(); - void switchMicroBC(); void clearAllConstraints(); std::set<constraintElement*>::iterator constraintGroupBegin(){return _allConstraint.begin();}; std::set<constraintElement*>::iterator constraintGroupEnd(){return _allConstraint.end();}; @@ -280,8 +293,6 @@ class pbcConstraintElementGroup{ void numberDof_virtualVertices(dofManager<double>* pmanager); void applyLinearConstraintsToSystem(dofManager<double>* pmanager); - void setLocalBasis(const SVector3& n, const SVector3& t, const SVector3& b); - void setRotatedBasis(const SVector3& n, const SVector3& t, const SVector3 b); SPoint3 getRootPoint(); };