diff --git a/Solver/dgConservationLaw.h b/Solver/dgConservationLaw.h index 2e8c790735b1e0507e0b9b4f84904253befa8076..b1890cd9ba0720ef1b53456c7a46f82734e923f1 100644 --- a/Solver/dgConservationLaw.h +++ b/Solver/dgConservationLaw.h @@ -45,6 +45,7 @@ class dgConservationLaw { virtual dataCacheDouble *newConvectiveFlux (dataCacheMap &cacheMap) const {return NULL;} virtual dataCacheDouble *newMaxConvectiveSpeed (dataCacheMap &cacheMap) const {return NULL;} virtual dataCacheDouble *newRiemannSolver (dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const {return NULL;} + virtual dataCacheDouble *newBifurcationRiemannSolver (dataCacheMap &cacheMap0, dataCacheMap &cacheMap1, dataCacheMap &cacheMap2) const {return NULL;} virtual dataCacheDouble *newClipToPhysics (dataCacheMap &cacheMap) const {return NULL;} inline const dgBoundaryCondition *getBoundaryCondition(const std::string tag) const { diff --git a/Solver/dgGroupOfElements.cpp b/Solver/dgGroupOfElements.cpp index f9c34e96527994b17b9a3e9f6a4a6959863a2607..c98b9c8b3f32088eb63f0ef0e5a85c70e36a5a3d 100644 --- a/Solver/dgGroupOfElements.cpp +++ b/Solver/dgGroupOfElements.cpp @@ -196,59 +196,32 @@ dgGroupOfConnections::dgGroupOfConnections(const dgGroupOfElements &elementGroup _fs = _elementGroup.getElement(0)->getFunctionSpace(pOrder); } -void dgGroupOfFaces::mapToInterface ( int nFields, - const fullMatrix<double> &vLeft, - const fullMatrix<double> &vRight, - fullMatrix<double> &v) +void dgGroupOfFaces::mapToInterface (int nFields, std::vector<const fullMatrix<double> *> &proxies, fullMatrix<double> &v) { - if(_connections.size()==1){ - for(int i=0; i<getNbElements(); i++) { - const std::vector<int> &closureLeft = _connections[0]->getClosure(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], _connections[0]->getElementId(i)*nFields + iField); - } - } - } - - }else{ - for(int i=0; i<getNbElements(); i++) { - const std::vector<int> &closureLeft = _connections[0]->getClosure(i); - const std::vector<int> &closureRight = _connections[1]->getClosure(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],_connections[0]->getElementId(i)*nFields + iField); + int nbConnections = getNbGroupOfConnections(); + for (int i=0; i<getNbElements(); i++) { + for (int iConnection = 0; iConnection<getNbGroupOfConnections(); iConnection++) { + const std::vector<int> &closure = _connections[iConnection]->getClosure(i); + for (int iField=0; iField<nFields; iField++) { + for(size_t j =0; j < closure.size(); j++) { + v(j, (i*nbConnections+iConnection)*nFields + iField) = + (*proxies[iConnection])(closure[j],_connections[iConnection]->getElementId(i)*nFields + iField); } - for(size_t j =0; j < closureRight.size(); j++) - v(j, (i*2+1)*nFields + iField) = vRight(closureRight[j],_connections[1]->getElementId(i)*nFields + iField); } } } } -void dgGroupOfFaces::mapFromInterface ( int nFields, - const fullMatrix<double> &v, - fullMatrix<double> &vLeft, - fullMatrix<double> &vRight - ) +void dgGroupOfFaces::mapFromInterface (int nFields, const fullMatrix<double> &v, std::vector< fullMatrix<double> *> &proxies) { - if(_connections.size()==1){ - for(int i=0; i<getNbElements(); i++) { - const std::vector<int> &closureLeft = _connections[0]->getClosure(i); - for (int iField=0; iField<nFields; iField++){ - for(size_t j =0; j < closureLeft.size(); j++) - vLeft(closureLeft[j], _connections[0]->getElementId(i)*nFields + iField) += v(j, i*nFields + iField); - } - } - }else{ - for(int i=0; i<getNbElements(); i++) { - const std::vector<int> &closureLeft = _connections[0]->getClosure(i); - const std::vector<int> &closureRight = _connections[1]->getClosure(i); + int nbConnections = getNbGroupOfConnections(); + for (int i=0; i<getNbElements(); i++) { + for (int iConnection = 0; iConnection<getNbGroupOfConnections(); iConnection++) { + const std::vector<int> &closure = _connections[iConnection]->getClosure(i); for (int iField=0; iField<nFields; iField++){ - for(size_t j =0; j < closureLeft.size(); j++) - 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], _connections[1]->getElementId(i)*nFields + iField) += v(j, (i*2+1)*nFields + iField); + for(size_t j =0; j < closure.size(); j++) + (*proxies[iConnection])(closure[j], _connections[iConnection]->getElementId(i)*nFields + iField) += + v(j, (i*nbConnections+iConnection)*nFields + iField); } } } diff --git a/Solver/dgGroupOfElements.h b/Solver/dgGroupOfElements.h index 42c8e1c218cc47d496275b340089284f242f3201..0791de9c301ced2193e6e49661ba93106629c012 100644 --- a/Solver/dgGroupOfElements.h +++ b/Solver/dgGroupOfElements.h @@ -209,8 +209,8 @@ public: const polynomialBasis * getPolynomialBasis() const {return _fsFace;} inline MElement* getFace (int iElement) const {return _faces[iElement];} public: // should be more generic on the number of connections - 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 mapToInterface (int nFields, std::vector<const fullMatrix<double> *> &proxies, fullMatrix<double> &v); + void mapFromInterface (int nFields, const fullMatrix<double> &v, std::vector<fullMatrix<double> *> &proxies); void mapLeftFromInterface(int nFields, const fullMatrix<double> &v, fullMatrix<double> &vLeft); void mapRightFromInterface(int nFields, const fullMatrix<double> &v, fullMatrix<double> &vRight); }; diff --git a/Solver/dgResidual.cpp b/Solver/dgResidual.cpp index 02cecb65bd58f96f0ac6096f4413165c01733efb..26d825742b1f1d21edd241e1146ad00fd903b49f 100644 --- a/Solver/dgResidual.cpp +++ b/Solver/dgResidual.cpp @@ -261,134 +261,127 @@ void dgResidualVolume::computeAndMap1Group(dgGroupOfElements &group, dgDofContai } -dgResidualInterface::dgResidualInterface (const dgConservationLaw &claw) : - _cacheMapLeft (new dataCacheMap), - _cacheMapRight (new dataCacheMap), - _claw(claw), - _nbFields(claw.getNbFields()), - _cacheElementLeft(_cacheMapLeft->getElement()), - _cacheElementRight(_cacheMapRight->getElement()), - _uvwLeft(_cacheMapLeft->provideParametricCoordinates()), - _uvwRight(_cacheMapRight->provideParametricCoordinates()), - _solutionQPLeft(_cacheMapLeft->provideSolution(_nbFields)), - _solutionQPRight(_cacheMapRight->provideSolution(_nbFields)), - _gradientSolutionLeft(_cacheMapLeft->provideSolutionGradient(_nbFields)), - _gradientSolutionRight(_cacheMapRight->provideSolutionGradient(_nbFields)), - _normals(_cacheMapLeft->provideNormals()), - _riemannSolver(claw.newRiemannSolver(*_cacheMapLeft,*_cacheMapRight)), - _diffusiveFluxLeft(claw.newDiffusiveFlux(*_cacheMapLeft)), - _diffusiveFluxRight(claw.newDiffusiveFlux(*_cacheMapRight)), - _maximumDiffusivityLeft(claw.newMaximumDiffusivity(*_cacheMapLeft)), - _maximumDiffusivityRight(claw.newMaximumDiffusivity(*_cacheMapRight)) +dgResidualInterface::dgResidualInterface (const dgConservationLaw &claw): + _claw (claw) { + _nbFields = _claw.getNbFields(); } void dgResidualInterface::compute1Group ( //dofManager &dof, // the DOF manager (maybe useless here) dgGroupOfFaces &group, const fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &solutionLeft, - fullMatrix<double> &solutionRight, + const std::vector<const fullMatrix<double>*> & solutionOnElements, fullMatrix<double> &residual // residual !! at faces nodes ) { // A) global operations before entering the loop over the faces // A1 ) copy locally some references from the group for the sake of lisibility - const dgGroupOfConnections &left = group.getGroupOfConnections(0); - const dgGroupOfConnections &right = group.getGroupOfConnections(1); - const dgGroupOfElements &groupLeft = left.getGroupOfElements(); - const dgGroupOfElements &groupRight = right.getGroupOfElements(); - int nbFaces = group.getNbElements(); - //get matrices needed to compute the gradient on both sides - const fullMatrix<double> &DPsiLeftDx = left.getDPsiDx(); - const fullMatrix<double> &DPsiRightDx = right.getDPsiDx(); + int nbConnections = group.getNbGroupOfConnections(); + std::vector<dataCacheMap> caches(nbConnections); + std::vector<const dgGroupOfConnections*> connections(nbConnections); + std::vector<const dgGroupOfElements*> elementGroups(nbConnections); + std::vector<dataCacheDouble*> diffusiveFluxes(nbConnections), maximumDiffusivities(nbConnections); + for (int i=0; i<nbConnections; i++) { + connections[i] = &group.getGroupOfConnections(i); + elementGroups[i] = &connections[i]->getGroupOfElements(); + caches[i].provideParametricCoordinates(); + caches[i].provideSolution(_nbFields); + caches[i].provideSolutionGradient(_nbFields); + caches[i].provideNormals(); + diffusiveFluxes[i] =_claw.newDiffusiveFlux(caches[i]); + maximumDiffusivities[i] = _claw.newMaximumDiffusivity(caches[i]); + caches[i].setNbEvaluationPoints(group.getNbIntegrationPoints()); + } + dataCacheDouble *riemannSolver = NULL; + if (nbConnections == 2) + riemannSolver = _claw.newRiemannSolver(caches[0], caches[1]); + if (nbConnections == 3) + riemannSolver = _claw.newBifurcationRiemannSolver(caches[0], caches[1], caches[2]); + // ----- 1 ---- get the solution at quadrature points - fullMatrix<double> solutionQP (group.getNbIntegrationPoints(),nbFaces * _nbFields*2); - group.getCollocationMatrix().mult(solution, solutionQP); + int nbFaces = group.getNbElements(); + fullMatrix<double> solutionQP (group.getNbIntegrationPoints(), nbFaces * _nbFields*nbConnections); + group.getCollocationMatrix().mult (solution, solutionQP); // needed tocompute normal fluxes at integration points - fullMatrix<double> NormalFluxQP ( group.getNbIntegrationPoints(), nbFaces*_nbFields*2); - // create one dataCache for each side - _cacheMapLeft->setNbEvaluationPoints(group.getNbIntegrationPoints()); - _cacheMapRight->setNbEvaluationPoints(group.getNbIntegrationPoints()); - fullMatrix<double> dPsiLeftDx,dPsiRightDx,dofsLeft,dofsRight,normalFluxQP; - int p = groupLeft.getOrder(); - int dim = left.getElement(0)->getDim(); + fullMatrix<double> NormalFluxQP (group.getNbIntegrationPoints(), nbFaces*_nbFields*nbConnections); + fullMatrix<double> normalFluxQP, dofs, dPsiDx; + int p = elementGroups[0]->getOrder(); + int dim = connections[0]->getElement(0)->getDim(); for (int iFace=0 ; iFace < nbFaces ; ++iFace) { - // B1 ) adjust the proxies for this element - // NB : the B1 section will almost completely disapear - // if we write a function (from the function class) for moving proxies across big matrices - // give the current elements to the dataCacheMap - _cacheElementLeft.set(left.getElement(iFace)); - _cacheElementRight.set(left.getElement(iFace)); - // proxies for the solution - _solutionQPLeft.setAsProxy(solutionQP, iFace*2*_nbFields, _nbFields); - _solutionQPRight.setAsProxy(solutionQP, (iFace*2+1)*_nbFields, _nbFields); - _normals.setAsProxy(left.getNormals(), iFace*group.getNbIntegrationPoints(),group.getNbIntegrationPoints()); - // proxies needed to compute the gradient of the solution and the IP term - dPsiLeftDx.setAsProxy(DPsiLeftDx,iFace*groupLeft.getNbNodes(),groupLeft.getNbNodes()); - dPsiRightDx.setAsProxy(DPsiRightDx,iFace*groupRight.getNbNodes(),groupRight.getNbNodes()); - dofsLeft.setAsProxy(solutionLeft, _nbFields*left.getElementId(iFace), _nbFields); - dofsRight.setAsProxy(solutionRight, _nbFields*right.getElementId(iFace), _nbFields); - _uvwLeft.setAsProxy(left.getIntegrationPointsOnElement(iFace)); - _uvwRight.setAsProxy(right.getIntegrationPointsOnElement(iFace)); - // proxies for the flux - normalFluxQP.setAsProxy(NormalFluxQP, iFace*_nbFields*2, _nbFields*2); - // B2 ) compute the gradient of the solution - if(_gradientSolutionLeft.somethingDependOnMe()){ - dPsiLeftDx.mult(dofsLeft, _gradientSolutionLeft.set()); - dPsiRightDx.mult(dofsRight, _gradientSolutionRight.set()); + for (int i=0; i<nbConnections; i++) { + // B1 ) adjust the proxies for this element + caches[i].getElement().set(connections[i]->getElement(iFace)); + caches[i].getParametricCoordinates(NULL).setAsProxy(connections[i]->getIntegrationPointsOnElement(iFace)); + caches[i].getSolution(NULL).setAsProxy(solutionQP, (iFace*nbConnections+i)*_nbFields, _nbFields); + caches[i].getNormals(NULL).setAsProxy(connections[i]->getNormals(), iFace*group.getNbIntegrationPoints(), group.getNbIntegrationPoints()); + // B2 ) compute the gradient of the solution + if(caches[i].getSolutionGradient(NULL).somethingDependOnMe()) { + dofs.setAsProxy(*solutionOnElements[i], _nbFields*connections[i]->getElementId(iFace), _nbFields); + dPsiDx.setAsProxy(connections[i]->getDPsiDx(),iFace*elementGroups[i]->getNbNodes(),elementGroups[i]->getNbNodes()); + dPsiDx.mult(dofs, caches[i].getSolutionGradient(NULL).set()); + } } + // proxies for the flux + normalFluxQP.setAsProxy(NormalFluxQP, iFace*_nbFields*nbConnections, _nbFields*nbConnections); // B3 ) compute fluxes - if (_diffusiveFluxLeft) { + if (diffusiveFluxes[0] && nbConnections==2) { // IP only implemented for 2-sides faces (not for bifurcations) for (int iPt =0; iPt< group.getNbIntegrationPoints(); iPt++) { const double detJ = group.getDetJ (iFace, iPt); //just for the lisibility : - const fullMatrix<double> &dfl = (*_diffusiveFluxLeft)(); - const fullMatrix<double> &dfr = (*_diffusiveFluxRight)(); + const fullMatrix<double> &dfl = (*diffusiveFluxes[0])(); + const fullMatrix<double> &dfr = (*diffusiveFluxes[1])(); + const fullMatrix<double> &n = (caches[0].getNormals(NULL))(); for (int k=0;k<_nbFields;k++) { double meanNormalFlux = - ((dfl(iPt,k+_nbFields*0 )+dfr(iPt,k+_nbFields*0)) * _normals(0,iPt) - +(dfl(iPt,k+_nbFields*1 )+dfr(iPt,k+_nbFields*1)) * _normals(1,iPt) - +(dfl(iPt,k+_nbFields*2 )+dfr(iPt,k+_nbFields*2)) * _normals(2,iPt))/2; - double minl = std::min(groupLeft.getElementVolume(left.getElementId(iFace)), - groupRight.getElementVolume(right.getElementId(iFace)) + ((dfl(iPt,k+_nbFields*0)+dfr(iPt,k+_nbFields*0)) * n(0,iPt) + +(dfl(iPt,k+_nbFields*1)+dfr(iPt,k+_nbFields*1)) * n(1,iPt) + +(dfl(iPt,k+_nbFields*2)+dfr(iPt,k+_nbFields*2)) * n(2,iPt))/2; + double minl = std::min(elementGroups[0]->getElementVolume(connections[0]->getElementId(iFace)), + elementGroups[1]->getElementVolume(connections[1]->getElementId(iFace)) )/group.getInterfaceSurface(iFace); - double nu = std::max((*_maximumDiffusivityRight)(iPt,0),(*_maximumDiffusivityLeft)(iPt,0)); + double nu = std::max((*maximumDiffusivities[1])(iPt,0),(*maximumDiffusivities[0])(iPt,0)); double mu = (p+1)*(p+dim)/dim*nu/minl; - double solutionJumpPenalty = (_solutionQPLeft(iPt,k)-_solutionQPRight(iPt,k))/2*mu; + double solutionJumpPenalty = (caches[0].getSolution(NULL)(iPt,k)-caches[1].getSolution(NULL)(iPt,k))/2*mu; normalFluxQP(iPt,k) -= (meanNormalFlux+solutionJumpPenalty)*detJ; normalFluxQP(iPt,k+_nbFields) += (meanNormalFlux+solutionJumpPenalty)*detJ; } } } - if (_riemannSolver) { + if (riemannSolver) { for (int iPt =0; iPt< group.getNbIntegrationPoints(); iPt++) { const double detJ = group.getDetJ (iFace, iPt); - for (int k=0;k<_nbFields*2;k++) - normalFluxQP(iPt,k) += (*_riemannSolver)(iPt,k)*detJ; + for (int k=0;k<_nbFields*nbConnections;k++) + normalFluxQP(iPt,k) += (*riemannSolver)(iPt,k)*detJ; } } } // C ) redistribute the flux to the residual (at Faces nodes) - if(_riemannSolver || _diffusiveFluxLeft) + if(riemannSolver || diffusiveFluxes[0]) residual.gemm(group.getRedistributionMatrix(),NormalFluxQP); } void dgResidualInterface::computeAndMap1Group (dgGroupOfFaces &faces, dgDofContainer &solution, dgDofContainer &residual) { - fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*2*_nbFields); - fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*2*_nbFields); - const dgGroupOfElements *groupLeft = &faces.getGroupOfConnections(0).getGroupOfElements(); - const dgGroupOfElements *groupRight = &faces.getGroupOfConnections(1).getGroupOfElements(); - faces.mapToInterface(_nbFields, solution.getGroupProxy(groupLeft), solution.getGroupProxy(groupRight), solInterface); - compute1Group(faces,solInterface,solution.getGroupProxy(groupLeft), solution.getGroupProxy(groupRight),residuInterface); - faces.mapFromInterface(_nbFields, residuInterface,residual.getGroupProxy(groupLeft), residual.getGroupProxy(groupRight)); + int nbConnections = faces.getNbGroupOfConnections(); + fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*_nbFields*nbConnections); + fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*_nbFields*nbConnections); + + std::vector<const dgGroupOfElements *> elGroups(nbConnections); + std::vector<const fullMatrix<double> *> solutionProxies(nbConnections); + std::vector<fullMatrix<double> *> residualProxies(nbConnections); + for (int i=0; i<nbConnections; i++) { + elGroups[i] = &faces.getGroupOfConnections(i).getGroupOfElements(); + solutionProxies[i] = &solution.getGroupProxy(elGroups[i]); + residualProxies[i] = &residual.getGroupProxy(elGroups[i]); + } + faces.mapToInterface(_nbFields, solutionProxies, solInterface); + compute1Group(faces, solInterface, solutionProxies, residuInterface); + faces.mapFromInterface(_nbFields, residuInterface, residualProxies); } dgResidualInterface::~dgResidualInterface () { - delete _cacheMapLeft; - delete _cacheMapRight; } @@ -398,7 +391,7 @@ dgResidualBoundary::dgResidualBoundary(const dgConservationLaw &claw):_claw(claw void dgResidualBoundary::compute1Group( dgGroupOfFaces &group, const fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &solutionLeft, + const fullMatrix<double> &solutionLeft, fullMatrix<double> &residual // residual !! at faces nodes ) { @@ -486,12 +479,21 @@ void dgResidualBoundary::compute1Group( void dgResidualBoundary::computeAndMap1Group(dgGroupOfFaces &faces, dgDofContainer &solution, dgDofContainer &residual) { int _nbFields = _claw.getNbFields(); - fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*_nbFields); - fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*_nbFields); - const dgGroupOfElements &groupLeft = faces.getGroupOfConnections(0).getGroupOfElements(); - faces.mapToInterface(_nbFields, solution.getGroupProxy(&groupLeft), solution.getGroupProxy(&groupLeft), solInterface); - compute1Group(faces,solInterface,solution.getGroupProxy(&groupLeft),residuInterface); - faces.mapFromInterface(_nbFields, residuInterface, residual.getGroupProxy(&groupLeft), residual.getGroupProxy(&groupLeft)); + int nbConnections = faces.getNbGroupOfConnections(); + fullMatrix<double> solInterface(faces.getNbNodes(), faces.getNbElements()*_nbFields*nbConnections); + fullMatrix<double> residuInterface(faces.getNbNodes(), faces.getNbElements()*_nbFields*nbConnections); + + std::vector<const dgGroupOfElements *> elGroups(nbConnections); + std::vector<const fullMatrix<double> *> solutionProxies(nbConnections); + std::vector<fullMatrix<double> *> residualProxies(nbConnections); + for (int i=0; i<nbConnections; i++) { + elGroups[i] = &faces.getGroupOfConnections(i).getGroupOfElements(); + solutionProxies[i] = &solution.getGroupProxy(elGroups[i]); + residualProxies[i] = &residual.getGroupProxy(elGroups[i]); + } + faces.mapToInterface(_nbFields, solutionProxies, solInterface); + compute1Group(faces, solInterface, *solutionProxies[0],residuInterface); + faces.mapFromInterface(_nbFields, residuInterface, residualProxies); } void dgResidual::compute(dgGroupCollection &groups, dgDofContainer &solution, dgDofContainer &residual) @@ -540,9 +542,9 @@ void dgResidual::registerBindings (binding *b) mb = cb->addMethod("computeAndMap1Group",&dgResidualInterface::computeAndMap1Group); mb->setDescription("compute the residual for one group given a dgDofContainer solution"); mb->setArgNames("group", "solution", "residual", NULL); - mb = cb->addMethod("compute1Group", &dgResidualInterface::compute1Group); - mb->setDescription("compute the residual for one group given fullMatrices with the solution at faces nodes and at element nodes"); - mb->setArgNames("group", "solutionFaces", "solutionGroupLeft", "solutionGroupRight", "residual", NULL); +// mb = cb->addMethod("compute1Group", &dgResidualInterface::compute1Group); + //mb->setDescription("compute the residual for one group given fullMatrices with the solution at faces nodes and at element nodes"); + //mb->setArgNames("group", "solutionFaces", "solutionOnElements", "residual", NULL); cb = b->addClass<dgResidualBoundary>("dgResidualBoundary"); cb->setDescription("compute the residual for one boundary dgGroupOfFaces"); diff --git a/Solver/dgResidual.h b/Solver/dgResidual.h index 47ab9226d2e93fb4f83377dd47c71d67754a8aa2..3b59fecfb9a7decd9a08727fc555c0ea48a7011f 100644 --- a/Solver/dgResidual.h +++ b/Solver/dgResidual.h @@ -10,6 +10,7 @@ class dgGroupOfElements; class dgGroupOfFaces; class binding; #include "fullMatrix.h" +#include <vector> class dgResidualVolume { dataCacheMap *_cacheMap; @@ -27,20 +28,14 @@ class dgResidualVolume { }; class dgResidualInterface { - dataCacheMap *_cacheMapLeft, *_cacheMapRight; const dgConservationLaw &_claw; int _nbFields; - dataCacheElement &_cacheElementLeft, &_cacheElementRight; - dataCacheDouble &_uvwLeft, &_uvwRight, &_solutionQPLeft, &_solutionQPRight, &_gradientSolutionLeft, &_gradientSolutionRight; - dataCacheDouble &_normals; - dataCacheDouble *_riemannSolver, *_maximumDiffusivityLeft,*_maximumDiffusivityRight, *_diffusiveFluxLeft, *_diffusiveFluxRight; public: dgResidualInterface (const dgConservationLaw &claw); void compute1Group ( //dofManager &dof, // the DOF manager (maybe useless here) dgGroupOfFaces &group, const fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &solutionLeft, - fullMatrix<double> &solutionRight, + const std::vector<const fullMatrix<double>*> & solutionOnElements, fullMatrix<double> &residual // residual !! at faces nodes ); void computeAndMap1Group (dgGroupOfFaces &faces, dgDofContainer &solution, dgDofContainer &residual); @@ -53,7 +48,7 @@ class dgResidualBoundary { void compute1Group ( //dofManager &dof, // the DOF manager (maybe useless here) dgGroupOfFaces &group, const fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &solutionLeft, + const fullMatrix<double> &solutionLeft, fullMatrix<double> &residual // residual !! at faces nodes ); void computeAndMap1Group (dgGroupOfFaces &faces, dgDofContainer &solution, dgDofContainer &residual); diff --git a/Solver/dgRungeKuttaMultirate.cpp b/Solver/dgRungeKuttaMultirate.cpp index 9f8238e04418894ee554c1a0226208fcd75e3610..23f41da85b4186e6d29cbc602df10f5c2c5143e3 100644 --- a/Solver/dgRungeKuttaMultirate.cpp +++ b/Solver/dgRungeKuttaMultirate.cpp @@ -198,8 +198,11 @@ void dgRungeKuttaMultirate::computeK(int iK,int exponent,bool isBuffer){ const dgGroupOfElements *gR = &faces->getGroupOfConnections(1).getGroupOfElements(); fullMatrix<double> solInterface(faces->getNbNodes(),faces->getNbElements()*2*_law->getNbFields()); fullMatrix<double> residuInterface(faces->getNbNodes(),faces->getNbElements()*2*_law->getNbFields()); - faces->mapToInterface(_law->getNbFields(), _currentInput->getGroupProxy(gL), _currentInput->getGroupProxy(gR), solInterface); - _residualInterface->compute1Group(*faces,solInterface,_currentInput->getGroupProxy(gL), _currentInput->getGroupProxy(gR),residuInterface); + std::vector<const fullMatrix<double>*> proxies(2); + proxies[0] = &_currentInput->getGroupProxy(gL); + proxies[1] = &_currentInput->getGroupProxy(gR); + faces->mapToInterface(_law->getNbFields(), proxies, solInterface); + _residualInterface->compute1Group(*faces,solInterface, proxies, residuInterface); if(gL->getMultirateExponent()==exponent && gL->getIsMultirateBuffer()){ faces->mapLeftFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gL)); } @@ -247,8 +250,11 @@ void dgRungeKuttaMultirate::computeK(int iK,int exponent,bool isBuffer){ const dgGroupOfElements *gR = &faces->getGroupOfConnections(1).getGroupOfElements(); fullMatrix<double> solInterface(faces->getNbNodes(),faces->getNbElements()*2*_law->getNbFields()); fullMatrix<double> residuInterface(faces->getNbNodes(),faces->getNbElements()*2*_law->getNbFields()); - faces->mapToInterface(_law->getNbFields(), _currentInput->getGroupProxy(gL), _currentInput->getGroupProxy(gR), solInterface); - _residualInterface->compute1Group(*faces,solInterface,_currentInput->getGroupProxy(gL), _currentInput->getGroupProxy(gR),residuInterface); + std::vector<const fullMatrix<double>*> proxies(2); + proxies[0] = &_currentInput->getGroupProxy(gL); + proxies[1] = &_currentInput->getGroupProxy(gR); + faces->mapToInterface(_law->getNbFields(), proxies, solInterface); + _residualInterface->compute1Group(*faces,solInterface, proxies, residuInterface); if(gL->getMultirateExponent()==exponent && !gL->getIsMultirateBuffer()){ faces->mapLeftFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gL)); } diff --git a/Solver/function.cpp b/Solver/function.cpp index 6472f00a7abaaab611cf124e86128dfe17227037..db348626dd7c8118a2085453c7cf5c06079c0506 100644 --- a/Solver/function.cpp +++ b/Solver/function.cpp @@ -58,8 +58,8 @@ function *function::get(std::string functionName, bool acceptNull) dataCacheElement &dataCacheMap::getElement(dataCache *caller) { if(caller) - _cacheElement->addMeAsDependencyOf(caller); - return *_cacheElement; + _cacheElement.addMeAsDependencyOf(caller); + return _cacheElement; } static dataCacheDouble &returnDataCacheDouble(dataCacheDouble *data, dataCache *caller) diff --git a/Solver/function.h b/Solver/function.h index 55ba50b13778ea5ee368df31d69a5c4c43389f13..74764b99cb53cc2fdce355a4fe9845cfe14478b5 100644 --- a/Solver/function.h +++ b/Solver/function.h @@ -164,7 +164,6 @@ class dataCacheMap { int _nbEvaluationPoints; // keep track of the current element and all the dataCaches that // depend on it - dataCacheElement *_cacheElement; std::map<const function*, dataCacheDouble*> _cacheDoubleMap; class providedDataDouble : public dataCacheDouble // for data provided by the algorithm and that does not have an _eval function @@ -179,6 +178,7 @@ class dataCacheMap { std::set<dataCache*> _toDelete; std::set<dataCacheDouble*> _toResize; + dataCacheElement _cacheElement; protected: void addDataCache(dataCache *data){ _toDelete.insert(data); @@ -205,8 +205,8 @@ class dataCacheMap { dataCacheDouble &get(const function *f, dataCache *caller=0); dataCacheElement &getElement(dataCache *caller=0); - dataCacheMap(){ - _cacheElement = new dataCacheElement(this); + dataCacheMap():_cacheElement(this){ + _toDelete.erase(&_cacheElement); _normals = _solution = _solutionGradient = _parametricCoordinates = 0; _nbEvaluationPoints = 0; }