From da7e203f5263dc74114cb4993cf3df100a5e53ca Mon Sep 17 00:00:00 2001 From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be> Date: Tue, 2 Feb 2010 18:24:14 +0000 Subject: [PATCH] dg: limiter can use more than one group and works in parallel --- Solver/TESTCASES/supra.lua | 4 +- Solver/dgAlgorithm.cpp | 4 +- Solver/dgDofContainer.cpp | 8 ++ Solver/dgDofContainer.h | 4 + Solver/dgSlopeLimiter.cpp | 149 ++++++++++++++++++++----------------- 5 files changed, 95 insertions(+), 74 deletions(-) diff --git a/Solver/TESTCASES/supra.lua b/Solver/TESTCASES/supra.lua index 5b6a7e476c..7ad6ccc051 100644 --- a/Solver/TESTCASES/supra.lua +++ b/Solver/TESTCASES/supra.lua @@ -18,13 +18,13 @@ end function valueRight(f) for i=0,f:size1()-1 do - f:set(i,0,math.sin(2*math.pi*t/T)) + f:set(i,0,math.sin(2*math.pi*t/T+math.pi/2)) end end function valueLeft(f) for i=0,f:size1()-1 do - f:set(i,0,-math.sin(2*math.pi*t/T)) + f:set(i,0,-math.sin(2*math.pi*t/T+math.pi/2)) end end diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp index 4e4c426205..db458c85e6 100644 --- a/Solver/dgAlgorithm.cpp +++ b/Solver/dgAlgorithm.cpp @@ -293,9 +293,7 @@ void dgAlgorithm::rungeKutta (const dgConservationLaw &claw, // conservation l K.axpy(sol); } - if (limiter){ - limiter->apply(K, groups); - } + if (limiter) limiter->apply(K, groups); this->residual(claw,groups,K,resd); K.scale(0.); for(int k=0; k < groups.getNbElementGroups(); k++) { diff --git a/Solver/dgDofContainer.cpp b/Solver/dgDofContainer.cpp index 34aa06db1c..fe13a95aad 100644 --- a/Solver/dgDofContainer.cpp +++ b/Solver/dgDofContainer.cpp @@ -28,6 +28,7 @@ dgDofContainer::dgDofContainer (dgGroupCollection &groups, int nbFields): _dataProxys.resize(_groups.getNbElementGroups()+_groups.getNbGhostGroups()); for (int i=0;i<_groups.getNbElementGroups();i++){ dgGroupOfElements *group = _groups.getElementGroup(i); + _groupId[group] = i; int nbNodes = group->getNbNodes(); int nbElements = group->getNbElements(); _dataProxys[i] = new fullMatrix<double> (&(*_data)(offset),nbNodes, _nbFields*nbElements); @@ -51,6 +52,7 @@ dgDofContainer::dgDofContainer (dgGroupCollection &groups, int nbFields): dgGroupOfElements *group = _groups.getGhostGroup(i); int nbNodes = group->getNbNodes(); int nbElements = group->getNbElements(); + _groupId[group] = i+_groups.getNbElementGroups(); _dataProxys[i+_groups.getNbElementGroups()] = new fullMatrix<double> (&(*_ghostData)(offset),nbNodes, _nbFields*nbElements); offset += nbNodes*_nbFields*nbElements; } @@ -142,6 +144,12 @@ void dgDofContainer::scatter() { sol.setAll(recvProxy); } } +void dgDofContainer::setAll(double v) { + for(int i=0;i<_data->size();i++) + (*_data)(i)=v; + for(int i=0;i<_ghostData->size();i++) + (*_ghostData)(i)=v; +} void dgDofContainer::scale(double f) { _data->scale(f); diff --git a/Solver/dgDofContainer.h b/Solver/dgDofContainer.h index 8eaf22b0e3..6c21641777 100644 --- a/Solver/dgDofContainer.h +++ b/Solver/dgDofContainer.h @@ -4,6 +4,7 @@ #include <vector> #include "fullMatrix.h" class dgGroupCollection; +class dgGroupOfElements; struct dgDofContainer { private: @@ -21,16 +22,19 @@ private: int *countSend,*countRecv,*shiftSend,*shiftRecv,*groupShiftRecv; double *sendBuf, *recvBuf; std::vector<fullMatrix<double> *> _dataProxys; // proxys + std::map<const dgGroupOfElements*,int> _groupId; public: void scale(double f); double norm(); void axpy(dgDofContainer &x, double a=1.); inline fullMatrix<double> &getGroupProxy(int gId){ return *(_dataProxys[gId]); } + inline fullMatrix<double> &getGroupProxy(const dgGroupOfElements* g){ return *(_dataProxys[_groupId[g]]); } dgDofContainer (dgGroupCollection &groups, int nbFields); ~dgDofContainer (); int getNbElements() {return _totalNbElements;} void scatter(); void save(const std::string name); void load(const std::string name); + void setAll(double v); }; #endif diff --git a/Solver/dgSlopeLimiter.cpp b/Solver/dgSlopeLimiter.cpp index adcdd9355d..6f1009f33b 100644 --- a/Solver/dgSlopeLimiter.cpp +++ b/Solver/dgSlopeLimiter.cpp @@ -6,89 +6,101 @@ //---------------------------------------------------------------------------------- bool dgSlopeLimiter::apply ( dgDofContainer &solution, dgGroupCollection &groups) { - //WARNING: ONLY FOR 1 GROUP OF FACES - //TODO: make this more general - - dgGroupOfFaces* group = groups.getFaceGroup(0); - fullMatrix<double> &solleft = solution.getGroupProxy(0); - fullMatrix<double> &solright = solution.getGroupProxy(0); + solution.scatter(); int nbFields =_claw->nbFields(); - int totNbElems = solution.getNbElements(); // first compute max and min of all fields for all stencils //---------------------------------------------------------- + dgDofContainer MIN(groups, nbFields); + dgDofContainer MAX(groups, nbFields); - fullMatrix<double> MIN (totNbElems,nbFields ); - fullMatrix<double> MAX (totNbElems, nbFields); MIN.setAll ( 1.e22); MAX.setAll (-1.e22); int iElementL, iElementR, fSize; - for(int iFace=0 ; iFace<group->getNbElements();iFace++) { - - iElementL = group->getElementLeftId(iFace); - iElementR = group->getElementRightId(iFace); - - fullMatrix<double> TempL, TempR; - TempL.setAsProxy(solleft, nbFields*iElementL, nbFields ); - TempR.setAsProxy(solright, nbFields*iElementR, nbFields ); - - fSize = TempL.size1(); - for (int k=0; k< nbFields; ++k){ - double AVGL = 0; - double AVGR = 0; - for (int i=0; i<fSize; ++i) { - AVGL += TempL(i,k); - AVGR += TempR(i,k); - } - AVGL /= (double) fSize; - AVGR /= (double) fSize; - MIN ( iElementL , k ) = std::min ( AVGR , MIN ( iElementL , k ) ); - MAX ( iElementL , k ) = std::max ( AVGR , MAX ( iElementL , k ) ); - MIN ( iElementR , k ) = std::min ( AVGL , MIN ( iElementR , k ) ); - MAX ( iElementR , k ) = std::max ( AVGL , MAX ( iElementR , k ) ); - } + fullMatrix<double> TempL, TempR; + for( int iGFace=0; iGFace<groups.getNbFaceGroups(); iGFace++) { + dgGroupOfFaces* group = groups.getFaceGroup(iGFace); + const dgGroupOfElements *groupLeft = &group->getGroupLeft(); + const dgGroupOfElements *groupRight = &group->getGroupRight(); + + fullMatrix<double> &solleft = solution.getGroupProxy(groupLeft); + fullMatrix<double> &solright = solution.getGroupProxy(groupRight); + fullMatrix<double> &MINLeft = MIN.getGroupProxy(groupLeft); + fullMatrix<double> &MAXLeft = MAX.getGroupProxy(groupLeft); + fullMatrix<double> &MINRight = MIN.getGroupProxy(groupRight); + fullMatrix<double> &MAXRight = MAX.getGroupProxy(groupRight); + + for(int iFace=0 ; iFace<group->getNbElements();iFace++) { + + iElementL = group->getElementLeftId(iFace); + iElementR = group->getElementRightId(iFace); + + TempL.setAsProxy(solleft, nbFields*iElementL, nbFields ); + TempR.setAsProxy(solright, nbFields*iElementR, nbFields ); + + fSize = TempL.size1(); + for (int k=0; k< nbFields; ++k){ + double AVGL = 0; + double AVGR = 0; + for (int i=0; i<fSize; ++i) { + AVGL += TempL(i,k); + AVGR += TempR(i,k); + } + AVGL /= (double) fSize; + AVGR /= (double) fSize; + MINLeft ( iElementL , k ) = std::min ( AVGR , MINLeft ( iElementL , k ) ); + MAXLeft ( iElementL , k ) = std::max ( AVGR , MAXLeft ( iElementL , k ) ); + MINRight ( iElementR , k ) = std::min ( AVGL , MINRight ( iElementR , k ) ); + MAXRight ( iElementR , k ) = std::max ( AVGL , MAXRight ( iElementR , k ) ); + } + } } //---------------------------------------------------------- // then limit the solution //---------------------------------------------------------- - for (int iElement=0 ; iElement<totNbElems; ++iElement) { + for (int iGroup=0 ; iGroup<groups.getNbElementGroups() ; iGroup++) { + dgGroupOfElements &group = *groups.getElementGroup(iGroup); + fullMatrix<double> &sol = solution.getGroupProxy(iGroup); + fullMatrix<double> &MAXG = MAX.getGroupProxy(iGroup); + fullMatrix<double> &MING = MIN.getGroupProxy(iGroup); fullMatrix<double> Temp; - Temp.setAsProxy(solleft, nbFields*iElement, nbFields ); - for (int k=0; k<nbFields; ++k) - { - double AVG = 0.; - double locMax = -1.e22; - double locMin = 1.e22; - double neighMax = MAX (iElement,k); - double neighMin = MIN (iElement,k); - for (int i=0; i<fSize; ++i) + for (int iElement=0 ; iElement<group.getNbElements() ; ++iElement) { + Temp.setAsProxy(sol, nbFields*iElement, nbFields ); + for (int k=0; k<nbFields; ++k) { - AVG += Temp(i,k); - locMax = std::max (locMax, Temp (i,k)); - locMin = std::min (locMin, Temp (i,k)); - } - AVG /= (double) fSize; - - //SLOPE LIMITING DG - //------------------- - for (int i=0; i<fSize; ++i)Temp(i,k) -= AVG; - - double slopeLimiterValue = 1.0; - if (locMax != AVG && locMax > neighMax) slopeLimiterValue = (neighMax-AVG) / (locMax-AVG); - if (locMin != AVG && locMin < neighMin) slopeLimiterValue = std::min ( slopeLimiterValue , (AVG-neighMin) / (AVG-locMin) ); - if (AVG < neighMin) slopeLimiterValue = 0; - if (AVG > neighMax) slopeLimiterValue = 0; - - // if (slopeLimiterValue != 1.0) printf("LIMTING %g\n",slopeLimiterValue); - // slopeLimiterValue = 0.0; - - for (int i=0; i<fSize; ++i) Temp(i,k) = AVG + Temp(i,k)*slopeLimiterValue; + double AVG = 0.; + double locMax = -1.e22; + double locMin = 1.e22; + double neighMax = MAXG (iElement,k); + double neighMin = MING (iElement,k); + for (int i=0; i<fSize; ++i) + { + AVG += Temp(i,k); + locMax = std::max (locMax, Temp (i,k)); + locMin = std::min (locMin, Temp (i,k)); + } + AVG /= (double) fSize; - } - } + //SLOPE LIMITING DG + //------------------- + for (int i=0; i<fSize; ++i)Temp(i,k) -= AVG; + + double slopeLimiterValue = 1.0; + if (locMax != AVG && locMax > neighMax) slopeLimiterValue = (neighMax-AVG) / (locMax-AVG); + if (locMin != AVG && locMin < neighMin) slopeLimiterValue = std::min ( slopeLimiterValue , (AVG-neighMin) / (AVG-locMin) ); + if (AVG < neighMin) slopeLimiterValue = 0; + if (AVG > neighMax) slopeLimiterValue = 0; + + // if (slopeLimiterValue != 1.0) printf("LIMTING %g\n",slopeLimiterValue); + // slopeLimiterValue = 0.0; + + for (int i=0; i<fSize; ++i) Temp(i,k) = AVG + Temp(i,k)*slopeLimiterValue; + } + } + } // --- CLIPPING: check unphysical values for (int iG = 0; iG < groups.getNbElementGroups(); iG++){ dgGroupOfElements* egroup = groups.getElementGroup(iG); @@ -100,12 +112,11 @@ bool dgSlopeLimiter::apply ( dgDofContainer &solution, dgGroupCollection &groups dataCacheDouble *solutionEClipped = _claw->newClipToPhysics(cacheMap); if (solutionEClipped){ for (int iElement=0 ; iElement<egroup->getNbElements() ;++iElement) { - solutionE.setAsProxy(solGroup, iElement*nbFields, nbFields ); - solutionE.set((*solutionEClipped)()); - } + solutionE.setAsProxy(solGroup, iElement*nbFields, nbFields ); + solutionE.set((*solutionEClipped)()); + } } } return true; - } -- GitLab