diff --git a/Solver/dgGroupOfElements.cpp b/Solver/dgGroupOfElements.cpp index 4f68cb58a30a4bf529421d97557e5fdf70c530d1..e1577642b6fd499afe2a5c029723e14997d2a15c 100644 --- a/Solver/dgGroupOfElements.cpp +++ b/Solver/dgGroupOfElements.cpp @@ -148,28 +148,37 @@ dgGroupOfElements::~dgGroupOfElements(){ delete _elementVolume; } +void dgGroupOfConnections::addElement(int iElement, int iClosure) { + _elementId.push_back(iElement); + _closuresId.push_back(iClosure); +} + + + void dgGroupOfFaces::addFace(const MFace &topoFace, int iElLeft, int iElRight){ - // compute all closures - // compute closures for the interpolation - _left.push_back(iElLeft); - MElement &elLeft = *_groupLeft.getElement(iElLeft); - int ithFace, sign, rot; - elLeft.getFaceInfo (topoFace, ithFace, sign, rot); - int closureIdLeft = _fsLeft->getFaceClosureId(ithFace, sign, rot); - _closuresIdLeft.push_back(closureIdLeft); - if(iElRight>=0){ - _right.push_back(iElRight); - MElement &elRight = *_groupRight.getElement(iElRight); - elRight.getFaceInfo (topoFace, ithFace, sign, rot); - _closuresIdRight.push_back(_fsRight->getFaceClosureId(ithFace, sign, rot)); - } // compute the face element that correspond to the geometrical closure // get the vertices of the face std::vector<MVertex*> vertices; - const std::vector<int> & geomClosure = elLeft.getFunctionSpace()->getFaceClosure(closureIdLeft); + int closureId; + const MElement *el; + int ithFace, sign, rot; + if(iElRight>=0){ + el = _connections[1]->getGroupOfElements().getElement(iElRight); + el->getFaceInfo(topoFace, ithFace, sign, rot); + closureId = _connections[1]->getFunctionSpace()->getFaceClosureId(ithFace,sign,rot); + _connections[1]->addElement(iElRight, closureId); + } + + el = _connections[0]->getGroupOfElements().getElement(iElLeft); + el->getFaceInfo(topoFace, ithFace, sign, rot); + closureId = _connections[0]->getFunctionSpace()->getFaceClosureId(ithFace,sign,rot); + _connections[0]->addElement(iElLeft, closureId); + + const std::vector<int> & geomClosure = el->getFunctionSpace()->getFaceClosure(closureId); for (int j=0; j<geomClosure.size() ; j++) - vertices.push_back( elLeft.getVertex(geomClosure[j]) ); + vertices.push_back( const_cast<MElement*>(el)->getVertex(geomClosure[j]) ); + // triangular face if (topoFace.getNumVertices() == 3){ switch(vertices.size()){ @@ -180,8 +189,7 @@ void dgGroupOfFaces::addFace(const MFace &topoFace, int iElLeft, int iElRight){ case 21 : _faces.push_back(new MTriangleN (vertices,5) ); break; default : throw; } - } - else if (topoFace.getNumVertices() == 4){ + } else if (topoFace.getNumVertices() == 4){ switch(vertices.size()){ case 4 : _faces.push_back(new MQuadrangle (vertices) ); break; case 8 : _faces.push_back(new MQuadrangle8 (vertices) ); break; @@ -191,50 +199,50 @@ void dgGroupOfFaces::addFace(const MFace &topoFace, int iElLeft, int iElRight){ default : throw; } } - // quad face 2 do else { throw; } } void dgGroupOfFaces::addEdge(const MEdge &topoEdge, int iElLeft, int iElRight) { - _left.push_back(iElLeft); - MElement &elLeft = *_groupLeft.getElement(iElLeft); - int ithEdge, sign; - elLeft.getEdgeInfo (topoEdge, ithEdge, sign); - _closuresIdLeft.push_back(_fsLeft->getEdgeClosureId(ithEdge, sign)); + std::vector<MVertex*> vertices; + const MElement *el ; + int closureId; + int ithFace, sign; if(iElRight>=0) { - _right.push_back(iElRight); - _groupRight.getElement(iElRight)->getEdgeInfo (topoEdge, ithEdge, sign); - _closuresIdRight.push_back(_fsRight->getEdgeClosureId(ithEdge,sign)); + el = _connections[1]->getGroupOfElements().getElement(iElRight); + el->getEdgeInfo(topoEdge, ithFace, sign); + closureId = _connections[1]->getFunctionSpace()->getEdgeClosureId(ithFace,sign); + _connections[1]->addElement(iElRight, closureId); } - std::vector<MVertex*> vertices; - const std::vector<int> &geomClosure = elLeft.getFunctionSpace()->getEdgeClosure(_closuresIdLeft.back()); + + el = _connections[0]->getGroupOfElements().getElement(iElLeft); + el->getEdgeInfo(topoEdge, ithFace, sign); + closureId = _connections[0]->getFunctionSpace()->getEdgeClosureId(ithFace,sign); + _connections[0]->addElement(iElLeft, closureId); + const std::vector<int> & geomClosure = el->getFunctionSpace()->getEdgeClosure(closureId); for (int j=0; j<geomClosure.size() ; j++) - vertices.push_back( elLeft.getVertex(geomClosure[j]) ); + vertices.push_back( const_cast<MElement*>(el)->getVertex(geomClosure[j]) ); switch(vertices.size()) - { + { case 2 : _faces.push_back(new MLine (vertices) ); break; case 3 : _faces.push_back(new MLine3 (vertices) ); break; default : _faces.push_back(new MLineN (vertices) ); break; - } + } } void dgGroupOfFaces::addVertex(MVertex *topoVertex, int iElLeft, int iElRight){ - _left.push_back(iElLeft); - MElement &elLeft = *_groupLeft.getElement(iElLeft); int ithVertex; - elLeft.getVertexInfo (topoVertex, ithVertex); - _closuresIdLeft.push_back(ithVertex); + _connections[0]->getGroupOfElements().getElement(iElLeft)->getVertexInfo(topoVertex, ithVertex); + _connections[0]->addElement(iElLeft,ithVertex); if(iElRight>=0){ - _right.push_back(iElRight); - MElement &elRight = *_groupRight.getElement(iElRight); - elRight.getVertexInfo (topoVertex, ithVertex); - _closuresIdRight.push_back(ithVertex); + _connections[1]->getGroupOfElements().getElement(iElRight)->getVertexInfo(topoVertex, ithVertex); + _connections[1]->addElement(iElRight, ithVertex); } _faces.push_back(new MPoint(topoVertex) ); } + void dgGroupOfFaces::init(int pOrder) { if (!_faces.size())return; _fsFace = _faces[0]->getFunctionSpace (pOrder); @@ -243,12 +251,10 @@ void dgGroupOfFaces::init(int pOrder) { _collocation = new fullMatrix<double> (_integration->size1(), _fsFace->coefficients.size1()); _detJac = new fullMatrix<double> (_integration->size1(), _faces.size()); _interfaceSurface = new fullMatrix<double>(_faces.size(),1); - for (size_t i=0; i<_closuresLeft.size(); i++) - _integrationPointsLeft.push_back(dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsLeft,_closuresLeft[i])); - for (size_t i=0; i<_closuresRight.size(); i++) - _integrationPointsRight.push_back(dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsRight,_closuresRight[i])); + for(int i=0; i<_connections.size(); i++) { + _connections[i]->init(); + } double f[256]; - for (int j=0;j<_integration->size1();j++) { _fsFace->f((*_integration)(j,0), (*_integration)(j,1), (*_integration)(j,2), f); const double weight = (*_integration)(j,3); @@ -257,7 +263,6 @@ void dgGroupOfFaces::init(int pOrder) { (*_collocation)(j,k) = f[k]; } } - for (int i=0;i<_faces.size();i++){ MElement *f = _faces[i]; for (int j=0;j< _integration->size1() ; j++ ){ @@ -266,70 +271,6 @@ void dgGroupOfFaces::init(int pOrder) { (*_interfaceSurface)(i,0) += (*_integration)(j,3)*(*_detJac)(j,i); } } - - // compute data on quadrature points : normals and dPsidX - double g[256][3]; - _normals = new fullMatrix<double> (3,_integration->size1()*_faces.size()); - _dPsiLeftDxOnQP = new fullMatrix<double> ( _integration->size1()*3,_fsLeft->points.size1()*_faces.size()); - if(_fsRight){ - _dPsiRightDxOnQP = new fullMatrix<double> ( _integration->size1()*3,_fsRight->points.size1()*_faces.size()); - } - int index = 0; - for (size_t i=0; i<_faces.size();i++){ - - const std::vector<int> &closureLeft=getClosureLeft(i); - fullMatrix<double> &intLeft=_integrationPointsLeft[_closuresIdLeft[i]]; - double jac[3][3],ijac[3][3]; - for (int j=0; j<intLeft.size1(); j++){ - _fsLeft->df((intLeft)(j,0),(intLeft)(j,1),(intLeft)(j,2),g); - getElementLeft(i)->getJacobian ((intLeft)(j,0), (intLeft)(j,1), (intLeft)(j,2), jac); - inv3x3(jac,ijac); - //compute dPsiLeftDxOnQP - // (iQP*3+iXYZ , iFace*NPsi+iPsi) - int nPsi = _fsLeft->coefficients.size1(); - for (int iPsi=0; iPsi< nPsi; iPsi++) { - (*_dPsiLeftDxOnQP)(j*3 ,i*nPsi+iPsi) = g[iPsi][0]*ijac[0][0]+g[iPsi][1]*ijac[0][1]+g[iPsi][2]*ijac[0][2]; - (*_dPsiLeftDxOnQP)(j*3+1,i*nPsi+iPsi) = g[iPsi][0]*ijac[1][0]+g[iPsi][1]*ijac[1][1]+g[iPsi][2]*ijac[1][2]; - (*_dPsiLeftDxOnQP)(j*3+2,i*nPsi+iPsi) = g[iPsi][0]*ijac[2][0]+g[iPsi][1]*ijac[2][1]+g[iPsi][2]*ijac[2][2]; - } - //compute face normals - double &nx=(*_normals)(0,index); - double &ny=(*_normals)(1,index); - double &nz=(*_normals)(2,index); - double nu=0,nv=0,nw=0; - for (size_t k=0; k<closureLeft.size(); k++){ - int inode=closureLeft[k]; - nu += g[inode][0]; - nv += g[inode][1]; - nw += g[inode][2]; - } - nx = nu*ijac[0][0]+nv*ijac[0][1]+nw*ijac[0][2]; - ny = nu*ijac[1][0]+nv*ijac[1][1]+nw*ijac[1][2]; - nz = nu*ijac[2][0]+nv*ijac[2][1]+nw*ijac[2][2]; - double norm = sqrt(nx*nx+ny*ny+nz*nz); - nx/=norm; - ny/=norm; - nz/=norm; - index++; - } - // there is nothing on the right for boundary groups - if(_fsRight){ - fullMatrix<double> &intRight=_integrationPointsRight[_closuresIdRight[i]]; - for (int j=0; j<intRight.size1(); j++){ - _fsRight->df((intRight)(j,0),(intRight)(j,1),(intRight)(j,2),g); - getElementRight(i)->getJacobian ((intRight)(j,0), (intRight)(j,1), (intRight)(j,2), jac); - inv3x3(jac,ijac); - //compute dPsiRightDxOnQP - // (iQP*3+iXYZ , iFace*NPsi+iPsi) - int nPsi = _fsRight->coefficients.size1(); - for (int iPsi=0; iPsi< nPsi; iPsi++) { - (*_dPsiRightDxOnQP)(j*3 ,i*nPsi+iPsi) = g[iPsi][0]*ijac[0][0]+g[iPsi][1]*ijac[0][1]+g[iPsi][2]*ijac[0][2]; - (*_dPsiRightDxOnQP)(j*3+1,i*nPsi+iPsi) = g[iPsi][0]*ijac[1][0]+g[iPsi][1]*ijac[1][1]+g[iPsi][2]*ijac[1][2]; - (*_dPsiRightDxOnQP)(j*3+2,i*nPsi+iPsi) = g[iPsi][0]*ijac[2][0]+g[iPsi][1]*ijac[2][1]+g[iPsi][2]*ijac[2][2]; - } - } - } - } } dgGroupOfFaces::~dgGroupOfFaces() @@ -338,23 +279,17 @@ dgGroupOfFaces::~dgGroupOfFaces() delete _redistribution; delete _collocation; delete _detJac; - delete _normals; - delete _dPsiLeftDxOnQP; - delete _dPsiRightDxOnQP; delete _interfaceSurface; } -dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MVertex*> &boundaryVertices): - _groupLeft(elGroup),_groupRight(elGroup) +dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MVertex*> &boundaryVertices) { + _connections.push_back(new dgGroupOfConnections(elGroup, *this, pOrder)); _boundaryTag=boundaryTag; if(boundaryTag==""){ Msg::Warning ("empty boundary tag, group of boundary faces not created"); return; } - _fsLeft=_groupLeft.getElement(0)->getFunctionSpace(pOrder); - _closuresLeft = _fsLeft->vertexClosure; - _fsRight=NULL; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumVertices(); j++){ @@ -366,17 +301,14 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string bo init(pOrder); } -dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MEdge,Less_Edge> &boundaryEdges): - _groupLeft(elGroup),_groupRight(elGroup) +dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MEdge,Less_Edge> &boundaryEdges) { + _connections.push_back(new dgGroupOfConnections(elGroup,*this, pOrder)); _boundaryTag=boundaryTag; if(boundaryTag==""){ Msg::Warning ("empty boundary tag, group of boundary faces not created"); return; } - _fsLeft=_groupLeft.getElement(0)->getFunctionSpace(pOrder); - _closuresLeft = _fsLeft->edgeClosure; - _fsRight=NULL; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumEdges(); j++){ @@ -388,15 +320,12 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string bo init(pOrder); } -dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MFace,Less_Face> &boundaryFaces): - _groupLeft(elGroup),_groupRight(elGroup) +dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MFace,Less_Face> &boundaryFaces) { + _connections.push_back(new dgGroupOfConnections(elGroup, *this, pOrder)); _boundaryTag=boundaryTag; if(boundaryTag=="") throw; - _fsLeft=_groupLeft.getElement(0)->getFunctionSpace(pOrder); - _closuresLeft = _fsLeft->faceClosure; - _fsRight=NULL; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumFaces(); j++){ @@ -408,16 +337,20 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string bo init(pOrder); } -dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, int pOrder, int numVertices): - _groupLeft(elGroup),_groupRight(elGroup) +dgGroupOfConnections::dgGroupOfConnections(const dgGroupOfElements &elementGroup, const dgGroupOfFaces &faceGroup, int pOrder) : + _elementGroup(elementGroup), + _faceGroup(faceGroup) +{ + _fs = _elementGroup.getElement(0)->getFunctionSpace(pOrder); +} + +dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, int pOrder, int numVertices) { - _fsLeft=_groupLeft.getElement(0)->getFunctionSpace(pOrder); - _fsRight=_groupRight.getElement(0)->getFunctionSpace(pOrder); - switch (_groupLeft.getElement(0)->getDim()) { + _connections.push_back(new dgGroupOfConnections(elGroup, *this, pOrder)); + _connections.push_back(new dgGroupOfConnections(elGroup, *this, pOrder)); + switch (_connections[0]->getGroupOfElements().getElement(0)->getDim()) { case 1 : { std::map<MVertex*,int> vertexMap; - _closuresLeft = _fsLeft->vertexClosure; - _closuresRight = _fsRight->vertexClosure; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumVertices(); j++){ @@ -433,8 +366,6 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, int pOrder, in } case 2 : { std::map<MEdge,int,Less_Edge> edgeMap; - _closuresLeft = _fsLeft->edgeClosure; - _closuresRight = _fsRight->edgeClosure; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumEdges(); j++){ @@ -450,8 +381,6 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, int pOrder, in } case 3 : { std::map<MFace,int,Less_Face> faceMap; - _closuresLeft = _fsLeft->faceClosure; - _closuresRight = _fsRight->faceClosure; for(int i=0; i<elGroup.getNbElements(); i++){ MElement &el = *elGroup.getElement(i); for (int j=0; j<el.getNumFaces(); j++){ @@ -472,16 +401,13 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup, int pOrder, in init(pOrder); } -dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup1, const dgGroupOfElements &elGroup2, int pOrder, int numVertices): - _groupLeft(elGroup1),_groupRight(elGroup2) +dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup1, const dgGroupOfElements &elGroup2, int pOrder, int numVertices) { - _fsLeft=_groupLeft.getElement(0)->getFunctionSpace(pOrder); - _fsRight=_groupRight.getElement(0)->getFunctionSpace(pOrder); - switch (_groupLeft.getElement(0)->getDim()) { + _connections.push_back(new dgGroupOfConnections(elGroup1, *this, pOrder)); + _connections.push_back(new dgGroupOfConnections(elGroup2, *this, pOrder)); + switch (_connections[0]->getGroupOfElements().getElement(0)->getDim()) { case 1 : { std::map<MVertex*,int> vertexMap1; - _closuresLeft = _fsLeft->vertexClosure; - _closuresRight = _fsRight->vertexClosure; for(int i=0; i<elGroup1.getNbElements(); i++){ MElement &el = *elGroup1.getElement(i); for (int j=0; j<el.getNumVertices(); j++){ @@ -508,8 +434,6 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup1, const dgGroup break; case 2 : { std::map<MEdge,int,Less_Edge> edgeMap; - _closuresLeft = _fsLeft->edgeClosure; - _closuresRight = _fsRight->edgeClosure; for(int i=0; i<elGroup1.getNbElements(); i++){ MElement &el = *elGroup1.getElement(i); for (int j=0; j<el.getNumEdges(); j++){ @@ -527,12 +451,6 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup1, const dgGroup MEdge edge = el.getEdge(j); std::map<MEdge,int,Less_Edge>::iterator it = edgeMap.find(edge); if(it != edgeMap.end()){ -// MElement &el2 = *elGroup1.getElement(it->second); -// printf("%d %d \n",edge.getVertex(0)->getNum(),edge.getVertex(1)->getNum()); -// for (int k=0;k<el.getNumVertices();k++)printf("%d ",el.getVertex(k)->getNum()); -// printf("\n"); -// for (int k=0;k<el2.getNumVertices();k++)printf("%d ",el2.getVertex(k)->getNum()); -// printf("\n"); addEdge(edge,it->second,i); } } @@ -542,8 +460,6 @@ dgGroupOfFaces::dgGroupOfFaces (const dgGroupOfElements &elGroup1, const dgGroup } case 3 : { std::map<MFace,int,Less_Face> faceMap; - _closuresLeft = _fsLeft->faceClosure; - _closuresRight = _fsRight->faceClosure; for(int i=0; i<elGroup1.getNbElements(); i++){ MElement &el = *elGroup1.getElement(i); for (int j=0; j<el.getNumFaces(); j++){ @@ -583,7 +499,7 @@ void dgGroupOfFaces::mapToInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureLeft.size(); j++){ - v(j, i*nFields + iField) = vLeft(closureLeft[j], _left[i]*nFields + iField); + v(j, i*nFields + iField) = vLeft(closureLeft[j], _connections[0]->getElementId(i)*nFields + iField); } } } @@ -594,10 +510,10 @@ void dgGroupOfFaces::mapToInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureLeft.size(); j++){ - v(j, i*2*nFields + iField) = vLeft(closureLeft[j], _left[i]*nFields + iField); + v(j, i*2*nFields + iField) = vLeft(closureLeft[j],_connections[0]->getElementId(i)*nFields + iField); } for(size_t j =0; j < closureRight.size(); j++) - v(j, (i*2+1)*nFields + iField) = vRight(closureRight[j], _right[i]*nFields + iField); + v(j, (i*2+1)*nFields + iField) = vRight(closureRight[j],_connections[1]->getElementId(i)*nFields + iField); } } } @@ -614,7 +530,7 @@ void dgGroupOfFaces::mapFromInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureLeft.size(); j++) - vLeft(closureLeft[j], _left[i]*nFields + iField) += v(j, i*nFields + iField); + vLeft(closureLeft[j], _connections[0]->getElementId(i)*nFields + iField) += v(j, i*nFields + iField); } } }else{ @@ -623,9 +539,9 @@ void dgGroupOfFaces::mapFromInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureLeft.size(); j++) - vLeft(closureLeft[j], _left[i]*nFields + iField) += v(j, i*2*nFields + iField); + vLeft(closureLeft[j], _connections[0]->getElementId(i)*nFields + iField) += v(j, i*2*nFields + iField); for(size_t j =0; j < closureRight.size(); j++) - vRight(closureRight[j], _right[i]*nFields + iField) += v(j, (i*2+1)*nFields + iField); + vRight(closureRight[j], _connections[1]->getElementId(i)*nFields + iField) += v(j, (i*2+1)*nFields + iField); } } } @@ -640,7 +556,7 @@ void dgGroupOfFaces::mapLeftFromInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureLeft.size(); j++) - vLeft(closureLeft[j], _left[i]*nFields + iField) += v(j, i*2*nFields + iField); + vLeft(closureLeft[j], _connections[0]->getElementId(i)*nFields + iField) += v(j, i*2*nFields + iField); } } } @@ -654,31 +570,69 @@ void dgGroupOfFaces::mapRightFromInterface ( int nFields, const std::vector<int> &closureLeft = getClosureLeft(i); for (int iField=0; iField<nFields; iField++){ for(size_t j =0; j < closureRight.size(); j++) - vRight(closureRight[j], _right[i]*nFields + iField) += v(j, (i*2+1)*nFields + iField); + vRight(closureRight[j], _connections[1]->getElementId(i)*nFields + iField) += v(j, (i*2+1)*nFields + iField); } } } -/* -void dgAlgorithm::buildGroupsOfFaces(GModel *model, int dim, int order, - std::vector<dgGroupOfElements*> &eGroups, - std::vector<dgGroupOfFaces*> &fGroups, - std::vector<dgGroupOfFaces*> &bGroups){ -} - -void dgAlgorithm::buildMandatoryGroups(dgGroupOfElements &eGroup, - std::vector<dgGroupOfElements*> &partitionedGroups){ -} +void dgGroupOfConnections::init() { + switch(getElement(0)->getDim()) { + case 1 : _closures = _fs->vertexClosure; break; + case 2 : _closures = _fs->edgeClosure; break; + case 3 : _closures = _fs->faceClosure; break; + } + for (size_t i=0; i<_closures.size(); i++) + _integrationPoints.push_back(dgGetFaceIntegrationRuleOnElement( + _faceGroup.getPolynomialBasis(), _faceGroup.getIntegrationPointsMatrix(), + _fs,_closures[i])); -void dgAlgorithm::partitionGroup(dgGroupOfElements &eGroup, - std::vector<dgGroupOfElements*> &partitionedGroups){ + int nPsi = _fs->points.size1(); + int nQP = _integrationPoints[0].size1(); + int size = _elementId.size(); + // compute data on quadrature points : normals and dPsidX + double g[256][3]; + _normals = fullMatrix<double> (3, nQP*size); + _dPsiDxOnQP = fullMatrix<double> ( nQP*3, nPsi*size); + int index = 0; + for (size_t i=0; i<size;i++){ + const std::vector<int> &closure = getClosure(i); + const fullMatrix<double> &integration = getIntegrationPointsOnElement(i); + double jac[3][3],ijac[3][3]; + for (int j=0; j<integration.size1(); j++){ + _fs->df(integration(j,0), integration(j,1), integration(j,2),g); + getElement(i)->getJacobian (integration(j,0), integration(j,1), integration(j,2), jac); + inv3x3(jac,ijac); + //compute dPsiDxOnQP + // (iQP*3+iXYZ , iFace*NPsi+iPsi) + for (int iPsi=0; iPsi< nPsi; iPsi++) { + _dPsiDxOnQP(j*3 ,i*nPsi+iPsi) = g[iPsi][0]*ijac[0][0]+g[iPsi][1]*ijac[0][1]+g[iPsi][2]*ijac[0][2]; + _dPsiDxOnQP(j*3+1,i*nPsi+iPsi) = g[iPsi][0]*ijac[1][0]+g[iPsi][1]*ijac[1][1]+g[iPsi][2]*ijac[1][2]; + _dPsiDxOnQP(j*3+2,i*nPsi+iPsi) = g[iPsi][0]*ijac[2][0]+g[iPsi][1]*ijac[2][1]+g[iPsi][2]*ijac[2][2]; + } + //compute face normals + double &nx=_normals(0,index); + double &ny=_normals(1,index); + double &nz=_normals(2,index); + double nu=0,nv=0,nw=0; + for (size_t k=0; k<closure.size(); k++){ + int inode=closure[k]; + nu += g[inode][0]; + nv += g[inode][1]; + nw += g[inode][2]; + } + nx = nu*ijac[0][0]+nv*ijac[0][1]+nw*ijac[0][2]; + ny = nu*ijac[1][0]+nv*ijac[1][1]+nw*ijac[1][2]; + nz = nu*ijac[2][0]+nv*ijac[2][1]+nw*ijac[2][2]; + double norm = sqrt(nx*nx+ny*ny+nz*nz); + nx/=norm; + ny/=norm; + nz/=norm; + index++; + } + } } -*/ - -//static void partitionGroup (std::vector<MElement *>,){ -//} // this function creates groups of elements diff --git a/Solver/dgGroupOfElements.h b/Solver/dgGroupOfElements.h index 042a48c909e776d321bd5ea974ca498b819984b4..1d65932a958d295db8dc00bde7aff3700e6ccc40 100644 --- a/Solver/dgGroupOfElements.h +++ b/Solver/dgGroupOfElements.h @@ -123,19 +123,45 @@ public: friend class dgGroupCollection; }; +class dgGroupOfFaces; + +class dgGroupOfConnections { + std::vector<std::vector<int> > _closures; + std::vector<int> _closuresId; + // face integration point in the coordinate of the left and right element (one fullMatrix per closure) + std::vector<fullMatrix<double> > _integrationPoints; + // XYZ gradient of the shape functions of both elements on the integrations points of the face + // (iQP*3+iXYZ , iFace*NPsi+iPsi) + fullMatrix<double> _dPsiDxOnQP; + const polynomialBasis *_fs; + const dgGroupOfElements &_elementGroup; + const dgGroupOfFaces &_faceGroup; + std::vector<int>_elementId; + // normals at integration points (N*Ni) x 3 + fullMatrix<double> _normals; + public: + void addElement(int iElement, int iClosure); + dgGroupOfConnections(const dgGroupOfElements &elementGroup, const dgGroupOfFaces &face, int pOrder); + inline const polynomialBasis *getFunctionSpace() {return _fs;} + inline const dgGroupOfElements &getGroupOfElements() {return _elementGroup;} + inline int getElementId(int i) {return _elementId[i];} + inline MElement *getElement(int i) {return _elementGroup.getElement(_elementId[i]);} + inline const std::vector<int>& getClosure(int i) {return _closures[_closuresId[i]];} + inline fullMatrix<double>& getIntegrationPointsOnElement(int i) {return _integrationPoints[_closuresId[i]];} + inline fullMatrix<double>& getDPsiDxOnQP() {return _dPsiDxOnQP;} + inline fullMatrix<double>& getNormals() {return _normals;} + void init(); +}; + class dgGroupOfFaces { + std::vector<dgGroupOfConnections*> _connections; // normals always point outside left to right // only used if this is a group of boundary faces std::string _boundaryTag; - const dgGroupOfElements &_groupLeft,&_groupRight; - void addFace(const MFace &topoFace, int iElLeft, int iElRight); - void addEdge(const MEdge &topoEdge, int iElLeft, int iElRight); - void addVertex(MVertex *topoVertex, int iElLeft, int iElRight); // Two polynomialBases for left and right elements // the group has always the same types for left and right - const polynomialBasis *_fsLeft,*_fsRight, *_fsFace; + const polynomialBasis *_fsFace; // N elements in the group - std::vector<int>_left, _right; std::vector<MElement *>_faces; // Ni integration points, matrix of size Ni x 3 (u,v,weight) fullMatrix<double> *_integration; @@ -144,19 +170,6 @@ class dgGroupOfFaces { // is characterized by a single integer which is the combination // this closure is for the interpolation that MAY BE DIFFERENT THAN THE // GEOMETRICAL CLOSURE !!! - std::vector<std::vector<int> > _closuresLeft; - std::vector<std::vector<int> > _closuresRight; - std::vector<int> _closuresIdLeft; - std::vector<int> _closuresIdRight; - // face integration point in the coordinate of the left and right element (one fullMatrix per closure) - std::vector<fullMatrix<double> > _integrationPointsLeft; - std::vector<fullMatrix<double> > _integrationPointsRight; - // XYZ gradient of the shape functions of both elements on the integrations points of the face - // (iQP*3+iXYZ , iFace*NPsi+iPsi) - fullMatrix<double> *_dPsiLeftDxOnQP; - fullMatrix<double> *_dPsiRightDxOnQP; - // normals at integration points (N*Ni) x 3 - fullMatrix<double> *_normals; // detJac at integration points (N*Ni) x 1 fullMatrix<double> *_detJac; // collocation matrices \psi_i (GP_j) @@ -169,21 +182,6 @@ class dgGroupOfFaces { //common part of the 3 constructors void init(int pOrder); public: - inline const dgGroupOfElements &getGroupLeft()const {return _groupLeft; } - inline const dgGroupOfElements &getGroupRight()const {return _groupRight; } - inline int getElementLeftId (int i) const {return _left[i];}; - inline int getElementRightId (int i) const {return _right[i];}; - inline MElement* getElementLeft (int i) const {return _groupLeft.getElement(_left[i]);} - inline MElement* getElementRight (int i) const {return _groupRight.getElement(_right[i]);} - inline double getElementVolumeLeft(int iFace) const {return _groupLeft.getElementVolume(_left[iFace]);} - inline double getElementVolumeRight(int iFace) const {return _groupRight.getElementVolume(_right[iFace]);} - inline MElement* getFace (int iElement) const {return _faces[iElement];} - inline const std::vector<int> &getClosureLeft(int iFace) const{ return _closuresLeft[_closuresIdLeft[iFace]]; } - inline const std::vector<int> &getClosureRight(int iFace) const{ return _closuresRight[_closuresIdRight[iFace]];} - inline fullMatrix<double> &getIntegrationOnElementLeft(int iFace) { return _integrationPointsLeft[_closuresIdLeft[iFace]];} - inline fullMatrix<double> &getIntegrationOnElementRight(int iFace) { return _integrationPointsRight[_closuresIdRight[iFace]];} - - inline fullMatrix<double> &getNormals () const {return *_normals;} dgGroupOfFaces (const dgGroupOfElements &elements,int pOrder, int numVertices = -1); dgGroupOfFaces (const dgGroupOfElements &a, const dgGroupOfElements &b,int pOrder, int numVertices = -1); dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MVertex*> &boundaryVertices); @@ -192,8 +190,6 @@ public: virtual ~dgGroupOfFaces (); inline bool isBoundary() const {return !_boundaryTag.empty();} inline const std::string getBoundaryTag() const {return _boundaryTag;} - inline fullMatrix<double> & getDPsiLeftDxMatrix() const { return *_dPsiLeftDxOnQP;} - inline fullMatrix<double> & getDPsiRightDxMatrix() const { return *_dPsiRightDxOnQP;} //this part is common with dgGroupOfElements, we should try polymorphism inline int getNbElements() const {return _faces.size();} inline int getNbNodes() const {return _collocation->size2();} @@ -203,12 +199,34 @@ public: inline const fullMatrix<double> & getRedistributionMatrix () const {return *_redistribution;} inline double getDetJ (int iElement, int iGaussPoint) const {return (*_detJac)(iGaussPoint,iElement);} inline double getInterfaceSurface (int iFace)const {return (*_interfaceSurface)(iFace,0);} + const polynomialBasis * getPolynomialBasis() const {return _fsFace;} + inline MElement* getFace (int iElement) const {return _faces[iElement];} + // duplicate +private: + void addFace(const MFace &topoFace, int iElLeft, int iElRight); + void addEdge(const MEdge &topoEdge, int iElLeft, int iElRight); + void addVertex(MVertex *topoVertex, int iElLeft, int iElRight); +public: //keep this outside the Algorithm because this is the only place where data overlap + inline fullMatrix<double> &getNormals () const {return _connections[0]->getNormals();} void mapToInterface(int nFields, const fullMatrix<double> &vLeft, const fullMatrix<double> &vRight, fullMatrix<double> &v); void mapFromInterface(int nFields, const fullMatrix<double> &v, fullMatrix<double> &vLeft, fullMatrix<double> &vRight); void mapLeftFromInterface(int nFields, const fullMatrix<double> &v, fullMatrix<double> &vLeft); void mapRightFromInterface(int nFields, const fullMatrix<double> &v, fullMatrix<double> &vRight); - const polynomialBasis * getPolynomialBasis() const {return _fsFace;} + inline fullMatrix<double> & getDPsiLeftDxMatrix() const { return _connections[0]->getDPsiDxOnQP();} + inline fullMatrix<double> & getDPsiRightDxMatrix() const { return _connections[1]->getDPsiDxOnQP();} + inline const dgGroupOfElements &getGroupLeft()const {return _connections[0]->getGroupOfElements(); } + inline const dgGroupOfElements &getGroupRight()const {return _connections[1]->getGroupOfElements(); } + inline int getElementLeftId (int i) const {return _connections[0]->getElementId(i);} + inline int getElementRightId (int i) const {return _connections[1]->getElementId(i);} + inline MElement* getElementLeft (int i) const {return _connections[0]->getElement(i);} + inline MElement* getElementRight (int i) const {return _connections[1]->getElement(i);} + inline double getElementVolumeLeft(int iFace) const {return _connections[0]->getGroupOfElements().getElementVolume(getElementLeftId(iFace));} + inline double getElementVolumeRight(int iFace) const {return _connections[1]->getGroupOfElements().getElementVolume(getElementRightId(iFace));} + inline const std::vector<int> &getClosureLeft(int iFace) const{ return _connections[0]->getClosure(iFace);} + inline const std::vector<int> &getClosureRight(int iFace) const{ return _connections[1]->getClosure(iFace);} + inline fullMatrix<double> &getIntegrationOnElementLeft(int iFace) { return _connections[0]->getIntegrationPointsOnElement(iFace);} + inline fullMatrix<double> &getIntegrationOnElementRight(int iFace) { return _connections[1]->getIntegrationPointsOnElement(iFace);} }; class dgGroupCollection {