diff --git a/Solver/CMakeLists.txt b/Solver/CMakeLists.txt index 694438eda9a5a984a2d31052d0c93a38f64d8db4..6d74439f89799caab25ef00ef62645192e83d27e 100644 --- a/Solver/CMakeLists.txt +++ b/Solver/CMakeLists.txt @@ -13,6 +13,7 @@ set(SRC multiscaleLaplace.cpp dgGroupOfElements.cpp dgAlgorithm.cpp + dgConservationLaw.cpp dgConservationLawAdvection.cpp function.cpp ) diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp index ffef08e52305f9c26abbd03127684a4379ccfe60..eb97d9578aef0d1641f07bec07d095480a6df0fc 100644 --- a/Solver/dgAlgorithm.cpp +++ b/Solver/dgAlgorithm.cpp @@ -25,13 +25,7 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe fullMatrix<double> solutionQP (group.getNbIntegrationPoints(),group.getNbElements() * nbFields); // ----- 1.2 --- multiply the solution by the collocation matrix group.getCollocationMatrix().mult(solution , solutionQP); - // ----- 1.3 --- if the conservation law is diffusive, compute the gradients too - fullMatrix<double> *gradientSolutionQP= 0; - if (claw.diffusiveFlux()){ - gradientSolutionQP = new fullMatrix<double> (group.getNbIntegrationPoints(), group.getNbElements() * nbFields * 3); - //group.getGradientOfSolution().mult ( group.getCollocationMatrix() , *gradientSolutionQP); - } - + // ----- 2 ---- compute all fluxes (diffusive and convective) at integration points // ----- 2.1 --- allocate elementary fluxes (compued in XYZ coordinates) fullMatrix<double> fConv[3] = {fullMatrix<double>( group.getNbIntegrationPoints(), nbFields ), @@ -47,22 +41,30 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe fullMatrix<double> (group.getNbIntegrationPoints(), group.getNbElements() * nbFields)}; dataCacheMap cacheMap; dataCacheElement &cacheElement = cacheMap.getElement(); + // provided dataCache cacheMap.provideData("UVW").set(group.getIntegrationPointsMatrix()); + dataCacheDouble &solutionQPe = cacheMap.provideData("Solution"); + dataCacheDouble &gradSolutionQPe = cacheMap.provideData("gradSolution"); + // needed dataCache dataCacheDouble *sourceTerm = claw.newSourceTerm(cacheMap); + // fluxes in XYZ coordinates; + dataCacheDouble *convectiveFlux = claw.newConvectiveFlux(cacheMap); + dataCacheDouble *diffusiveFlux = claw.newDiffusiveFlux(cacheMap); + // compute the gradient of solution if necessary + fullMatrix<double> *gradientSolutionQP= 0; + if (gradSolutionQPe.somethingDependOnMe()) { + gradientSolutionQP = new fullMatrix<double> (group.getNbIntegrationPoints(), group.getNbElements() * nbFields * 3); + //group.getGradientOfSolution().mult ( group.getCollocationMatrix() , *gradientSolutionQP); + } // ----- 2.3 --- iterate on elements for (int iElement=0 ; iElement<group.getNbElements() ;++iElement) { // ----- 2.3.1 --- build a small object that contains elementary solution, jacobians, gmsh element - fullMatrix<double> solutionQPe (solutionQP, iElement*nbFields, nbFields ); - fullMatrix<double> *gradSolutionQPe; - if (claw.diffusiveFlux()) gradSolutionQPe = new fullMatrix<double>(*gradientSolutionQP, 3*iElement*nbFields,3*nbFields ); - else gradSolutionQPe = new fullMatrix<double>; - dgElement DGE( group.getElement(iElement), solutionQPe, *gradSolutionQPe, group.getIntegrationPointsMatrix()); + solutionQPe.set(fullMatrix<double>(solutionQP, iElement*nbFields, nbFields )); + if (gradSolutionQPe.somethingDependOnMe()) + gradSolutionQPe.set(fullMatrix<double>(*gradientSolutionQP, 3*iElement*nbFields,3*nbFields )); cacheElement.set(group.getElement(iElement)); - if(claw.convectiveFlux() || claw.diffusiveFlux()) { - // ----- 2.3.2 --- compute fluxes in XYZ coordinates - if (claw.convectiveFlux()) (*claw.convectiveFlux())(DGE,fConv); - if (claw.diffusiveFlux()) (*claw.diffusiveFlux())(DGE,fDiff); + if(convectiveFlux || diffusiveFlux) { // ----- 2.3.3 --- compute fluxes in UVW coordinates for (int iUVW=0;iUVW<group.getDimUVW();iUVW++) { // ----- 2.3.3.1 --- get a proxy on the big local flux matrix @@ -76,8 +78,12 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe const double detJ = group.getDetJ (iElement, iPt); const double factor = invJ * detJ; // compute fluxes in the reference coordinate system at this integration point - for (int k=0;k<nbFields;k++) - fuvwe(iPt,k) += ( fConv[iXYZ](iPt,k) + fDiff[iXYZ](iPt,k)) * factor; + for (int k=0;k<nbFields;k++){ + if(convectiveFlux) + fuvwe(iPt,k) += ( (*convectiveFlux)(iPt,iXYZ*nbFields+k)) * factor; + if(diffusiveFlux) + fuvwe(iPt,k) += ( (*diffusiveFlux)(iPt,iXYZ*nbFields+k)) * factor; + } } } } @@ -91,13 +97,18 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe } } } - delete gradSolutionQPe; + if(gradientSolutionQP) + delete gradientSolutionQP; } // ----- 3 ---- do the redistribution at nodes using as many BLAS3 operations as there are local coordinates - if(claw.convectiveFlux() || claw.diffusiveFlux()){ + if(convectiveFlux || diffusiveFlux){ for (int iUVW=0;iUVW<group.getDimUVW();iUVW++){ residual.gemm(group.getFluxRedistributionMatrix(iUVW),Fuvw[iUVW]); } + if(convectiveFlux) + delete convectiveFlux; + if(diffusiveFlux) + delete diffusiveFlux; } if(sourceTerm){ residual.gemm(group.getSourceRedistributionMatrix(),Source); @@ -118,23 +129,34 @@ void dgAlgorithm::residualInterface ( //dofManager &dof, // the DOF manager (may group.getCollocationMatrix().mult(solution, solutionQP); // ----- 2 ---- compute normal fluxes at integration points fullMatrix<double> NormalFluxQP ( group.getNbIntegrationPoints(), group.getNbElements()*nbFields*2); + dataCacheMap cacheMapLeft, cacheMapRight; + // provided dataCache + cacheMapLeft.provideData("UVW").set(group.getIntegrationPointsMatrix()); + dataCacheDouble &solutionQPLeft = cacheMapLeft.provideData("Solution"); + dataCacheDouble &solutionQPRight = cacheMapRight.provideData("Solution"); + dataCacheDouble &normals = cacheMapLeft.provideData("Normals"); + dataCacheElement &cacheElementLeft = cacheMapLeft.getElement(); + dataCacheElement &cacheElementRight = cacheMapRight.getElement(); + // required data + dataCacheDouble *riemannSolver = claw.newRiemannSolver(cacheMapLeft,cacheMapRight); for (int iFace=0 ; iFace<group.getNbElements() ;++iFace) { // ----- 2.3.1 --- build a small object that contains elementary solution, jacobians, gmsh element - fullMatrix<double> solutionQPLeft (solutionQP, iFace*2*nbFields, nbFields ); - fullMatrix<double> solutionQPRight (solutionQP, (iFace*2+1)*nbFields, nbFields ); - fullMatrix<double> normalFluxQP (NormalFluxQP, iFace*2*nbFields, nbFields*2); - dgFace DGF( group.getFace(iFace), group.getElementLeft(iFace), group.getElementRight(iFace), - solutionQPLeft, solutionQPRight, group.getIntegrationPointsMatrix(),group.getNormals(iFace)); + solutionQPLeft.set(fullMatrix<double>(solutionQP, iFace*2*nbFields, nbFields)); + solutionQPRight.set(fullMatrix<double>(solutionQP, (iFace*2+1)*nbFields, nbFields)); + normals.set(group.getNormals(iFace)); + cacheElementLeft.set(group.getElementLeft(iFace)); + cacheElementRight.set(group.getElementRight(iFace)); + fullMatrix<double> normalFluxQP (NormalFluxQP, iFace*nbFields*2, nbFields*2); // ----- 2.3.2 --- compute fluxes - (*claw.riemannSolver())(DGF,&normalFluxQP); 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) *= detJ; + normalFluxQP(iPt,k) = (*riemannSolver)(iPt,k)*detJ; } } // ----- 3 ---- do the redistribution at face nodes using BLAS3 residual.gemm(group.getRedistributionMatrix(),NormalFluxQP); + delete riemannSolver; } void dgAlgorithm::multAddInverseMassMatrix ( /*dofManager &dof,*/ @@ -157,40 +179,39 @@ void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (mayb ) { int nbFields = claw.nbFields(); - const dgBoundaryCondition *boundaryCondition = claw.boundaryCondition(group.getBoundaryTag()); + const dgBoundaryCondition *boundaryCondition = claw.getBoundaryCondition(group.getBoundaryTag()); // ----- 1 ---- get the solution at quadrature points fullMatrix<double> solutionQP (group.getNbIntegrationPoints(),group.getNbElements() * nbFields); group.getCollocationMatrix().mult(solution, solutionQP); // ----- 2 ---- compute normal fluxes at integration points fullMatrix<double> NormalFluxQP ( group.getNbIntegrationPoints(), group.getNbElements()*nbFields); - fullMatrix<double> solutionQPRight(group.getNbIntegrationPoints(), nbFields); + + dataCacheMap cacheMapLeft; + // provided dataCache + cacheMapLeft.provideData("UVW").set(group.getIntegrationPointsMatrix()); + dataCacheDouble &solutionQPLeft = cacheMapLeft.provideData("Solution"); + dataCacheDouble &normals = cacheMapLeft.provideData("Normals"); + dataCacheElement &cacheElementLeft = cacheMapLeft.getElement(); + // required data + dataCacheDouble *boundaryTerm = boundaryCondition->newBoundaryTerm(cacheMapLeft); + for (int iFace=0 ; iFace<group.getNbElements() ;++iFace) { - // ----- 2.3.1 --- build a small object that contains elementary solution, jacobians, gmsh element - fullMatrix<double> solutionQPLeft (solutionQP, iFace*nbFields, nbFields); - fullMatrix<double> normalFluxQP (NormalFluxQP, iFace*nbFields, nbFields); - dgFace DGF( group.getFace(iFace), group.getElementLeft(iFace), NULL, - solutionQPLeft, solutionQPRight, group.getIntegrationPointsMatrix(),group.getNormals(iFace)); + // ----- 2.3.1 --- provide the data to the cacheMap + solutionQPLeft.set(fullMatrix<double>(solutionQP, iFace*nbFields, nbFields)); + normals.set(group.getNormals(iFace)); + cacheElementLeft.set(group.getElementLeft(iFace)); + // ----- 2.3.2 --- compute fluxes - switch (boundaryCondition->type()){ - case dgBoundaryCondition::EXTERNAL_VALUES : { - (*boundaryCondition)(DGF, &solutionQPRight); - (*claw.riemannSolver())(DGF, &normalFluxQP); - break; - } - case dgBoundaryCondition::FLUX :{ - (*boundaryCondition)(DGF, &normalFluxQP); - } - default : - throw; - } + fullMatrix<double> normalFluxQP (NormalFluxQP, iFace*nbFields, nbFields); for (int iPt =0; iPt< group.getNbIntegrationPoints(); iPt++) { const double detJ = group.getDetJ (iFace, iPt); for (int k=0;k<nbFields;k++) - normalFluxQP(iPt,k) *= detJ; + normalFluxQP(iPt,k) = (*boundaryTerm)(iPt,k)*detJ; } } // ----- 3 ---- do the redistribution at face nodes using BLAS3 residual.gemm(group.getRedistributionMatrix(),NormalFluxQP); + delete boundaryTerm; } void dgAlgorithm::buildGroups(GModel *model, int dim, int order, diff --git a/Solver/dgConservationLaw.cpp b/Solver/dgConservationLaw.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f979df2e5826d0756e801527321050de0f2d078c --- /dev/null +++ b/Solver/dgConservationLaw.cpp @@ -0,0 +1,65 @@ +#include "dgConservationLaw.h" +#include "function.h" +class dgBoundaryCondition0Out : public dgBoundaryCondition { + dgConservationLaw &_claw; + class term : public dataCacheDouble { + dataCacheMap cacheMapRight; // new cacheMap to pass to the Riemann solver + dataCacheDouble &solutionRight; + dataCacheDouble &solutionLeft; + dataCacheDouble *riemannSolver; + dgConservationLaw &_claw; + public: + term(dgConservationLaw &claw, dataCacheMap &cacheMapLeft): + solutionRight(cacheMapRight.provideData("Solution")), + solutionLeft(cacheMapLeft.get("Solution",this)), + _claw(claw) + { + riemannSolver=_claw.newRiemannSolver(cacheMapLeft,cacheMapRight); + } + + void _eval() { + if(_value.size1()!=solutionLeft().size1()){ + //adjust sizes + solutionRight.set(fullMatrix<double>(solutionLeft().size1(),_claw.nbFields())); + _value = fullMatrix<double>(solutionLeft().size1(),_claw.nbFields()); + } + for(int i=0;i<_value.size1(); i++) + for(int j=0;j<_value.size2(); j++) + _value(i,j) = (*riemannSolver)(i,j*2); + } + }; + public: + dgBoundaryCondition0Out(dgConservationLaw &claw): _claw(claw) {} + dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const { + return new term(_claw,cacheMapLeft); + } +}; + +class dgBoundaryCondition0Flux : public dgBoundaryCondition { + dgConservationLaw &_claw; + class term : public dataCacheDouble { + dataCacheDouble &UVW; + dgConservationLaw &_claw; + public: + term(dgConservationLaw &claw,dataCacheMap &cacheMapLeft): UVW(cacheMapLeft.get("UVW",this)),_claw(claw) {} + void _eval() { + if(_value.size1()!=UVW().size1()){ + //adjust sizes + _value = fullMatrix<double>(UVW().size1(),_claw.nbFields()); + } + } + }; + public: + dgBoundaryCondition0Flux(dgConservationLaw &claw): _claw(claw) {} + dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const { + return new term(_claw,cacheMapLeft); + } +}; + +dgBoundaryCondition *dgBoundaryCondition::new0OutCondition(dgConservationLaw &claw) { + return new dgBoundaryCondition0Out(claw); +} +dgBoundaryCondition *dgBoundaryCondition::new0FluxCondition(dgConservationLaw &claw) { + return new dgBoundaryCondition0Flux(claw); +} + diff --git a/Solver/dgConservationLaw.h b/Solver/dgConservationLaw.h index 481d125f23aaed14e338942f17df178b2f642864..9e72ab9a3745e85d501afb94d67b92df1c131655 100644 --- a/Solver/dgConservationLaw.h +++ b/Solver/dgConservationLaw.h @@ -7,59 +7,50 @@ + r(u,forcings) -> source term r */ #include "fullMatrix.h" -class dgElement; -class dgFace; class dataCacheDouble; +class dataCacheMap; -class dgTerm{ - public: - virtual ~dgTerm () {} - virtual void operator () (const dgElement &, fullMatrix<double> fcx[]) const = 0; -}; - -class dgFaceTerm{ - public: - virtual ~dgFaceTerm () {} - virtual void operator () (const dgFace &, fullMatrix<double> fcx[]) const = 0; -}; +class dgConservationLaw; class dgBoundaryCondition { -public: + public: virtual ~dgBoundaryCondition () {} - typedef enum {FLUX=0,EXTERNAL_VALUES}boundaryType; - virtual void operator () (const dgFace&, fullMatrix<double> fcx[]) const = 0; - virtual boundaryType type() const =0; + virtual dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const = 0; + //a generic boundary condition using the Riemann solver of the conservation Law + static dgBoundaryCondition *new0OutCondition(dgConservationLaw &claw); + static dgBoundaryCondition *new0FluxCondition(dgConservationLaw &claw); }; -class dataCacheMap; class dgConservationLaw { - protected : - int _nbf; - dgTerm *_diffusive, *_convective, *_source, *_maxConvectiveSpeed; - dgFaceTerm *_riemannSolver; std::map<const std::string,dgBoundaryCondition*> _boundaryConditions; -public: - dgConservationLaw () : _diffusive(0), _convective(0), _source (0), - _riemannSolver(0),_maxConvectiveSpeed (0) {} - ~dgConservationLaw () {} + protected : + int _nbf; + public: + virtual ~dgConservationLaw () {} int nbFields() const {return _nbf;} - virtual dataCacheDouble *newSourceTerm(dataCacheMap &cacheMap)const { return NULL; } + virtual dataCacheDouble *newSourceTerm (dataCacheMap &cacheMap) const {return NULL;} + virtual dataCacheDouble *newDiffusiveFlux (dataCacheMap &cacheMap) const {return NULL;} + 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;} - inline const dgTerm * convectiveFlux () const {return _convective;} - inline const dgTerm * diffusiveFlux () const {return _diffusive;} - inline const dgFaceTerm * riemannSolver () const {return _riemannSolver;} - inline const dgTerm * maxConvectiveSpeed () const {return _maxConvectiveSpeed;} - inline const dgBoundaryCondition *boundaryCondition(const std::string tag) const { + inline const dgBoundaryCondition *getBoundaryCondition(const std::string tag) const { std::map<const std::string,dgBoundaryCondition*>::const_iterator it = _boundaryConditions.find(tag); if(it==_boundaryConditions.end()) throw; return it->second; } + inline void addBoundaryCondition(const std::string tag, dgBoundaryCondition * condition) { + if(_boundaryConditions.find(tag)!=_boundaryConditions.end()) + throw; + _boundaryConditions[tag]=condition; + } + }; -dgConservationLaw *dgNewConservationLawAdvection(); +dgConservationLaw *dgNewConservationLawAdvection(const std::string vname); #endif diff --git a/Solver/dgConservationLawAdvection.cpp b/Solver/dgConservationLawAdvection.cpp index 8f4677c9bc248eba70297de1fae432bcf19b7531..a886ef5bf8aeb7c0eb2c3e1088eb1485b8de8d7d 100644 --- a/Solver/dgConservationLawAdvection.cpp +++ b/Solver/dgConservationLawAdvection.cpp @@ -3,95 +3,70 @@ #include "dgGroupOfElements.h" #include "SPoint3.h" #include "MElement.h" -void getV(SPoint3 &p, double (&v)[3]){ - /*double r=hypot(p.x(),p.y()); - double alpha=atan2(p.y(),p.x()); - v[0]=r*sin(alpha); - v[1]=-r*cos(alpha); - v[2]=0;*/ - v[0]=0.15; - v[1]=0; - v[2]=0; -} +#include "function.h" -class dgAdvectionFluxTerm : public dgTerm { - void operator () (const dgElement &el, fullMatrix<double> fcx[]) const - { - const fullMatrix<double> &sol = el.solution(); - const fullMatrix<double> &QP = el.integration(); - for(int i=0; i< sol.size1(); i++) { - SPoint3 p; - el.element()->pnt(QP(i,0),QP(i,1),QP(i,2),p); - double v[3]; - getV(p,v); - fcx[0](i,0) = sol(i,0)*v[0]; - fcx[1](i,0) = sol(i,0)*v[1]; - fcx[2](i,0) = sol(i,0)*v[2]; +class dgConservationLawAdvection : public dgConservationLaw { + std::string _vFunctionName; + class advection : public dataCacheDouble { + dataCacheDouble &sol, &uvw, &v; + public: + advection(std::string vFunctionName, dataCacheMap &cacheMap): + uvw(cacheMap.get("UVW",this)), + sol(cacheMap.get("Solution",this)), + v(cacheMap.get(vFunctionName,this)) + {}; + void _eval () { + if(_value.size1() !=sol().size1()) + _value=fullMatrix<double>(sol().size1(),3); + for(int i=0; i< sol().size1(); i++) { + _value(i,0) = sol(i,0)*v(i,0); + _value(i,1) = sol(i,0)*v(i,1); + _value(i,2) = sol(i,0)*v(i,2); + } } - } -}; - -class dgAdvectionRiemanTerm : public dgFaceTerm{ - public: - void operator () (const dgFace &face, fullMatrix<double> fcx[]) const - { - const fullMatrix<double> &solLeft = face.solutionLeft(); - const fullMatrix<double> &solRight = face.solutionRight(); - const fullMatrix<double> &normals = face.normals(); - const fullMatrix<double> &QP = face.integration(); - for(int i=0; i< solLeft.size1(); i++) { - SPoint3 p; - face.face()->pnt(QP(i,0),QP(i,1),QP(i,2),p); - double v[3]; - getV(p,v); - double un=v[0]*normals(0,i)+v[1]*normals(1,i)+v[2]*normals(2,i); - if(un>0){ - fcx[0](i,0) = -solLeft(i,0)*un; - if(fcx[0].size2()==2) - fcx[0](i,1) = solLeft(i,0)*un; - }else{ - fcx[0](i,0) = -solRight(i,0)*un; - if(fcx[0].size2()==2) - fcx[0](i,1) = solRight(i,0)*un; + }; + class riemann : public dataCacheDouble { + dataCacheDouble &uvw, &normals, &solLeft, &solRight,&v; + public: + riemann(std::string vFunctionName, dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight): + uvw(cacheMapLeft.get("UVW", this)), + normals(cacheMapLeft.get("Normals", this)), + solLeft(cacheMapLeft.get("Solution", this)), + solRight(cacheMapRight.get("Solution", this)), + v(cacheMapLeft.get(vFunctionName,this)) + {}; + void _eval () { + if(_value.size1() !=solLeft().size1()) + _value = fullMatrix<double>(solLeft().size1(),2); + for(int i=0; i< _value.size1(); i++) { + double un=v(i,0)*normals(0,i)+v(i,1)*normals(1,i)+v(i,2)*normals(2,i); + if(un>0){ + _value(i,0) = -solLeft(i,0)*un; + _value(i,1) = solLeft(i,0)*un; + }else{ + _value(i,0) = -solRight(i,0)*un; + _value(i,1) = solRight(i,0)*un; + } } } + }; + public: + dataCacheDouble *newConvectiveFlux( dataCacheMap &cacheMap) const { + return new advection(_vFunctionName,cacheMap); } -}; -class dgAdvectionBoundary0External : public dgBoundaryCondition { - boundaryType type() const { - return EXTERNAL_VALUES; + dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const { + return new riemann(_vFunctionName,cacheMapLeft, cacheMapRight); } - void operator () (const dgFace &face, fullMatrix<double> fcx[]) const{ - const fullMatrix<double> &solLeft = face.solutionLeft(); - for(int i=0; i< solLeft.size1(); i++) { - fcx[0](i,0) = 0; - } + dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const { + return 0; } -}; - -class dgConservationLawAdvection : public dgConservationLaw { - public: - dgConservationLawAdvection() + dgConservationLawAdvection(std::string vFunctionName) { + _vFunctionName = vFunctionName; _nbf = 1; - _convective = new dgAdvectionFluxTerm; - _riemannSolver = new dgAdvectionRiemanTerm; - _boundaryConditions["Left"] = new dgAdvectionBoundary0External(); - _boundaryConditions["Right"] = new dgAdvectionBoundary0External(); - _boundaryConditions["Top"] = new dgAdvectionBoundary0External(); - _boundaryConditions["Bottom"] = new dgAdvectionBoundary0External(); - } - ~dgConservationLawAdvection() - { - delete _convective; - delete _riemannSolver; - delete _boundaryConditions["Left"]; - delete _boundaryConditions["Right"]; - delete _boundaryConditions["Top"]; - delete _boundaryConditions["Bottom"]; } }; -dgConservationLaw *dgNewConservationLawAdvection() { - return new dgConservationLawAdvection; +dgConservationLaw *dgNewConservationLawAdvection(std::string vFunctionName) { + return new dgConservationLawAdvection(vFunctionName); } diff --git a/Solver/dgMainTest.cpp b/Solver/dgMainTest.cpp index 3d75e92b0e62eb7bf32d1ed670e5fe02e3ef3667..8d085e0e6dc502a75b20fdda42437e8c8f28b183 100644 --- a/Solver/dgMainTest.cpp +++ b/Solver/dgMainTest.cpp @@ -44,7 +44,7 @@ int main(int argc, char **argv){ int order=1; int dimension=2; dgAlgorithm algo; - function::registerAllFunctions(); + function::registerDefaultFunctions(); algo.buildGroups(GModel::current(),dimension,order,elementGroups,faceGroups,boundaryGroups); //for now, we suppose there is only one group of elements @@ -58,8 +58,21 @@ int main(int argc, char **argv){ algo.multAddInverseMassMatrix(*elementGroups[0],residu,sol); } print("init.pos",*elementGroups[0],&sol(0,0)); + //advection - dgConservationLaw *law = dgNewConservationLawAdvection(); + fullMatrix<double> advectionSpeed(3,1); + advectionSpeed(0,0)=0.15; + advectionSpeed(1,0)=0.05; + advectionSpeed(2,0)=0.; + + function::add("advectionSpeed",function::newFunctionConstant(advectionSpeed)); + + dgConservationLaw *law = dgNewConservationLawAdvection("advectionSpeed"); + law->addBoundaryCondition("Left",dgBoundaryCondition::new0OutCondition(*law)); + law->addBoundaryCondition("Right",dgBoundaryCondition::new0OutCondition(*law)); + law->addBoundaryCondition("Top",dgBoundaryCondition::new0FluxCondition(*law)); + law->addBoundaryCondition("Bottom",dgBoundaryCondition::new0FluxCondition(*law)); + for(int iT=0; iT<1000; iT++) { algo.residual(*law,elementGroups,faceGroups,boundaryGroups,sol,residu); residu.scale(0.01); diff --git a/Solver/function.cpp b/Solver/function.cpp index 977ed647982820a215a9f79ab8c2a34fd9c409f4..d83696e91dd1df28162d31ca9522f4e9e4069460 100644 --- a/Solver/function.cpp +++ b/Solver/function.cpp @@ -77,6 +77,7 @@ dataCacheMap::~dataCacheMap() // now some example of functions +// get XYZ coordinates class functionXYZ : public function { private: class data : public dataCacheDouble{ @@ -107,8 +108,41 @@ class functionXYZ : public function { } }; +// constant values copied over each line +class functionConstant : public function { + private : + class data : public dataCacheDouble { + const functionConstant *_function; + dataCacheDouble &_uvw; + public: + data(const functionConstant * function,dataCacheMap *m) :_uvw(m->get("UVW",this)){ + _function = function; + } + void _eval() { + if(_value.size1()!=_uvw().size1()){ + _value=fullMatrix<double>(_uvw().size1(),_function->_source.size1()); + } + for(int i=0;i<_value.size1();i++) + for(int j=0;j<_function->_source.size1();j++) + _value(i,j)=_function->_source(j,0); + } + }; + fullMatrix<double> _source; + public: + dataCacheDouble *newDataCache(dataCacheMap *m) + { + return new data(this,m); + } + functionConstant(const fullMatrix<double> &source){ + _source = source; + } +}; + +function *function::newFunctionConstant(const fullMatrix<double> &source){ + return new functionConstant(source); +} -void function::registerAllFunctions() +void function::registerDefaultFunctions() { function::add("XYZ", new functionXYZ); } diff --git a/Solver/function.h b/Solver/function.h index bc756ea772cd913e3d8c7ae5869d3965451335be..4f64dfe1fcc1f5ca5f124c505aa8ba03d2685d94 100644 --- a/Solver/function.h +++ b/Solver/function.h @@ -28,6 +28,10 @@ protected : void addMeAsDependencyOf (dataCache *newDep); dataCache() : _valid(false) {} virtual ~dataCache(){}; +public : + inline bool somethingDependOnMe() { + return !_dependOnMe.empty(); + } }; // A node in the dependency tree for which all the leafs depend on the @@ -70,11 +74,14 @@ class function { static std::map<std::string, function*> _allFunctions; std::string _name; public: - static void registerAllFunctions(); + static void registerDefaultFunctions(); static bool add(const std::string functionName, function *f); static function *get(std::string functionName, bool acceptNull=false); virtual dataCacheDouble *newDataCache(dataCacheMap *m) =0; + + //we need a parser for this + static function *newFunctionConstant(const fullMatrix<double> &source); }; // A special node in the dependency tree for which all the leafs @@ -97,15 +104,19 @@ class dataCacheMap { dataCacheElement _cacheElement; std::map<std::string, dataCacheDouble*> _cacheDoubleMap; class providedDataDouble : public dataCacheDouble + // for data provided by the algorithm and that does not have an _eval function + // (typically "UVW") this class is not stricly necessary, we could write + // a function for each case but I think it's more practical like this { void _eval() {throw;}; + public: + providedDataDouble() { + _valid=true; + } }; public: dataCacheDouble &get(const std::string &functionName, dataCache *caller=0); dataCacheElement &getElement(dataCache *caller=0); - // for data provided by the user and that does not have an _eval function - // (typically "UVW") this class is not stricly necessary, we could write - // a function for each case but I think it's more practical like this dataCacheDouble &provideData(std::string name); ~dataCacheMap(); };