From 4be90823c72c7068fe0cc48bec893551cf8cb437 Mon Sep 17 00:00:00 2001
From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be>
Date: Wed, 2 Dec 2009 10:49:54 +0000
Subject: [PATCH] dg : inviscid non conservative linear shallow water equation

---
 Solver/dgConservationLaw.h                 |   1 +
 Solver/dgConservationLawShallowWater2d.cpp |  96 ++++++++++------
 Solver/dgConservationLawWaveEquation.cpp   |   4 +-
 Solver/dgMainShallowWater2d.cpp            | 126 ++-------------------
 4 files changed, 74 insertions(+), 153 deletions(-)

diff --git a/Solver/dgConservationLaw.h b/Solver/dgConservationLaw.h
index f2370de706..93df46b575 100644
--- a/Solver/dgConservationLaw.h
+++ b/Solver/dgConservationLaw.h
@@ -55,5 +55,6 @@ dgConservationLaw *dgNewConservationLawAdvection(const std::string vname);
 dgConservationLaw *dgNewConservationLawShallowWater2d();
 dgConservationLaw *dgNewConservationLawWaveEquation();
 dgBoundaryCondition *dgNewBoundaryConditionWaveEquationWall();
+dgBoundaryCondition *dgNewBoundaryConditionShallowWater2dWall();
 
 #endif
diff --git a/Solver/dgConservationLawShallowWater2d.cpp b/Solver/dgConservationLawShallowWater2d.cpp
index cb2caa2052..dbf70dded9 100644
--- a/Solver/dgConservationLawShallowWater2d.cpp
+++ b/Solver/dgConservationLawShallowWater2d.cpp
@@ -1,6 +1,8 @@
 #include "dgConservationLaw.h"
 #include "function.h"
 static double g = 9.81;
+static double h = 1000;
+
 class dgConservationLawShallowWater2d : public dgConservationLaw {
   class advection : public dataCacheDouble {
     dataCacheDouble &sol;
@@ -13,23 +15,22 @@ class dgConservationLawShallowWater2d : public dgConservationLaw {
       if(_value.size1() != nQP)
         _value=fullMatrix<double>(nQP,9);
       for(int i=0; i< nQP; i++) {
-        double H = sol(i,0);
-        double U = sol(i,1);
-        double V = sol(i,2);
+        double eta = sol(i,0);
+        double u = sol(i,1);
+        double v = sol(i,2);
         // flux_x
-        _value(i,0) = U;
-        _value(i,1) = U*U/H + g*H*H/2;
-        _value(i,2) = U*V/H;
+        _value(i,0) = h*u;
+        _value(i,1) = g*eta;
+        _value(i,2) = 0;
         // flux_y
-        _value(i,3) = V;
-        _value(i,4) = V*U/H;
-        _value(i,5) = V*V/H + g*H*H/2;
+        _value(i,3) = h*v;
+        _value(i,4) = 0;
+        _value(i,5) = g*eta;
         // flux_z
         _value(i,6) = 0;
         _value(i,7) = 0;
         _value(i,8) = 0;
       }
-      _value.scale(0);
     }
   };
   class source : public dataCacheDouble {
@@ -44,16 +45,15 @@ class dgConservationLawShallowWater2d : public dgConservationLaw {
       if(_value.size1() != nQP)
         _value = fullMatrix<double>(nQP,3);
       for (int i=0; i<nQP; i++) {
-        double H = solution(i,0);
-        double U = solution(i,1);
-        double V = solution(i,2);
-        double wind = 0.1*sin(xyz(i,1)/1e6*M_PI)/H/1000;
+        double eta = solution(i,0);
+        double u = solution(i,1);
+        double v = solution(i,2);
+        double wind = 0.1*sin(xyz(i,1)/1e6*M_PI)/1000/h;
         double f = 1e-4+xyz(i,1)*2e-11;
         double gamma = 1e-6;
-        f=0;
         _value (i,0) = 0;
-        _value (i,1) = -gamma*U - f*V + wind;
-        _value (i,2) = -gamma*V + f*U;
+        _value (i,1) = f*v + - gamma*u + wind;
+        _value (i,2) = -f*u - gamma*v ;
       }
     }
   };
@@ -72,22 +72,21 @@ class dgConservationLawShallowWater2d : public dgConservationLaw {
       for(int i=0; i< nQP; i++) {
         double nx = normals(0,i);
         double ny = normals(1,i);
-        double UnL = nx*solL(i,1) + ny*solL(i,2);
-        double UnR = nx*solR(i,1) + ny*solR(i,2);
-        double UtL = ny*solL(i,1) - nx*solL(i,2);
-        double UtR = ny*solR(i,1) - nx*solR(i,2);
-        double HR = solR(i,0);
-        double HL = solL(i,0);
-        double c = sqrt(g*(HR+HL)/2);
-        double FUn = -(UnL*UnL/HL + g*HL*HL/2 + UnR*UnR/HR + g*HR*HR/2)/2 + c*(UnL-UnR)/2;
-        double FUt = -(UnL*UtL/HL + UnR*UtR/HR)/2 + c*(UtL-UtR)/2;
-        double FH = -(UnL+UnR)/2 + c*(HL-HR)/2;
-        _value(i,0) = FH;
-        _value(i,1) = FUn*nx + FUt*ny;
-        _value(i,2) = FUn*ny - FUt*nx;
+        double unL = nx*solL(i,1) + ny*solL(i,2);
+        double unR = nx*solR(i,1) + ny*solR(i,2);
+        double utL = ny*solL(i,1) - nx*solL(i,2);
+        double utR = ny*solR(i,1) - nx*solR(i,2);
+        double etaR = solR(i,0);
+        double etaL = solL(i,0);
+        double sq_g_h = sqrt(g/h);
+        double etaRiemann = (etaL+etaR + (unL-unR)/sq_g_h)/2;
+        double unRiemann = (unL+unR + (etaL-etaR)*sq_g_h)/2;
+        double Fun = -g*etaRiemann;
+        double Feta = -h*unRiemann;
+        _value(i,0) = Feta;
+        _value(i,1) = Fun*nx;
+        _value(i,2) = Fun*ny;
 
-      _value(i,1)=0;
-      _value(i,2)=0;
         _value(i,3) = -_value(i,0);
         _value(i,4) = -_value(i,1);
         _value(i,5) = -_value(i,2);
@@ -113,6 +112,39 @@ class dgConservationLawShallowWater2d : public dgConservationLaw {
   }
 };
 
+class dgBoundaryConditionShallowWater2dWall : public dgBoundaryCondition {
+  class term : public dataCacheDouble {
+    dataCacheDouble &sol,&normals;
+    public:
+    term(dataCacheMap &cacheMap):
+    sol(cacheMap.get("Solution",this)),
+    normals(cacheMap.get("Normals",this)){}
+    void _eval () { 
+      int nQP = sol().size1();
+      if(_value.size1() != nQP)
+        _value = fullMatrix<double>(nQP,3);
+      for(int i=0; i< nQP; i++) {
+        double nx = normals(0,i);
+        double ny = normals(1,i);
+        double eta = sol(i,0);
+
+        _value(i,0) = 0;
+        _value(i,1) = -g*eta*nx;
+        _value(i,2) = -g*eta*ny;
+      }
+    }
+  };
+  public:
+  dgBoundaryConditionShallowWater2dWall(){}
+  dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const {
+    return new term(cacheMapLeft);
+  }
+};
+
+dgBoundaryCondition *dgNewBoundaryConditionShallowWater2dWall() {
+  return new dgBoundaryConditionShallowWater2dWall();
+}
+
 dgConservationLaw *dgNewConservationLawShallowWater2d() {
   return new dgConservationLawShallowWater2d();
 }
diff --git a/Solver/dgConservationLawWaveEquation.cpp b/Solver/dgConservationLawWaveEquation.cpp
index cb9223c232..b5d2e457fb 100644
--- a/Solver/dgConservationLawWaveEquation.cpp
+++ b/Solver/dgConservationLawWaveEquation.cpp
@@ -55,8 +55,8 @@ class dgConservationLawWaveEquation : public dgConservationLaw {
         double pR = solR(i,0);
         double pL = solL(i,0);
 
-        double pRiemann =  0.5 * (pL+pR - (unR-unL)*(rho*c));
-        double unRiemann =  0.5 * (unL+unR - (pR-pL)/(rho*c));
+        double pRiemann =  0.5 * (pL+pR + (unL-unR)*(rho*c));
+        double unRiemann =  0.5 * (unL+unR + (pL-pR)/(rho*c));
 
         double Fp = -rho*c*c*unRiemann;
         double Fun = -pRiemann/rho;
diff --git a/Solver/dgMainShallowWater2d.cpp b/Solver/dgMainShallowWater2d.cpp
index efb8462689..e3aed3f67d 100644
--- a/Solver/dgMainShallowWater2d.cpp
+++ b/Solver/dgMainShallowWater2d.cpp
@@ -11,108 +11,6 @@
 #include "MElement.h"
 void print (const char *filename,const dgGroupOfElements &els, double *v,int iField=1, int nbFields=1);
 
-class dgConservationLawInitialCondition : public dgConservationLaw {
-  class gaussian : public dataCacheDouble {
-    dataCacheDouble &xyz;
-    double _xc,_yc;
-    public:
-    gaussian(dataCacheMap &cacheMap,double xc, double yc):xyz(cacheMap.get("XYZ",this)),_xc(xc),_yc(yc){};
-    void _eval () { 
-      if(_value.size1() != xyz().size1())
-        _value=fullMatrix<double>(xyz().size1(),1);
-      for(int i=0; i< _value.size1(); i++) {
-        _value(i,0)=exp(-(pow(xyz(i,0)-_xc,2)+pow(xyz(i,1)-_yc,2))*100);
-      }
-    }
-  };
-  public:
-  dgConservationLawInitialCondition() {
-    _nbf = 1;
-  }
-  dataCacheDouble *newSourceTerm(dataCacheMap &cacheMap)const {
-    return new gaussian(cacheMap,0.2,0.3);
-  }
-};
-
-/*int main(int argc, char **argv) {
-  GmshMergeFile("input/square1.msh");
-  //we probably need a class to group those three ones
-  std::vector<dgGroupOfElements*> elementGroups;
-  std::vector<dgGroupOfFaces*> faceGroups;
-  std::vector<dgGroupOfFaces*> boundaryGroups;
-  int order=1;
-  int dimension=2;
-  dgAlgorithm algo;
-  function::registerDefaultFunctions();
-  algo.buildGroups(GModel::current(),dimension,order,elementGroups,faceGroups,boundaryGroups);
-
-  //for now, we suppose there is only one group of elements
-  int nbNodes = elementGroups[0]->getNbNodes();
-  fullMatrix<double> sol(nbNodes,elementGroups[0]->getNbElements());
-  fullMatrix<double> residu(nbNodes,elementGroups[0]->getNbElements());
-  // initial condition
-  {
-    dgConservationLawInitialCondition initLaw;
-    algo.residualVolume(initLaw,*elementGroups[0],sol,residu);
-    algo.multAddInverseMassMatrix(*elementGroups[0],residu,sol);
-  }
-
-  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");
-
-  fullMatrix<double> outsideValue(1,1);
-  outsideValue(0,0)=0;
-  function::add("outsideValue",function::newFunctionConstant(outsideValue));
-  law->addBoundaryCondition("Left",dgBoundaryCondition::newOutsideValueCondition(*law,"outsideValue"));
-  law->addBoundaryCondition("Right",dgBoundaryCondition::newOutsideValueCondition(*law,"outsideValue"));
-
-  law->addBoundaryCondition("Top",dgBoundaryCondition::new0FluxCondition(*law));
-  law->addBoundaryCondition("Bottom",dgBoundaryCondition::new0FluxCondition(*law));
-
-  
-  
- print("output/init.pos",*elementGroups[0],&sol(0,0));
-  for(int iT=0; iT<100; iT++) {
-    algo.rungeKutta(*law,elementGroups,faceGroups,boundaryGroups,0.01,residu,sol);
-    if(iT%10==0){
-      char name[100];
-      sprintf(name,"output/test_%05i.pos",iT/10);
-      printf("%i\n",iT);
-      print(name,*elementGroups[0],&sol(0,0));
-    }
-  }
-  delete law;
-}*/
-class dgConservationLawStommel : public dgConservationLaw {
-  class initbath : public dataCacheDouble {
-    dataCacheDouble &uvw;
-    public:
-    initbath(dataCacheMap &cacheMap):
-      uvw(cacheMap.get("UVW"))
-    {}
-    void _eval () { 
-      if(_value.size1() != uvw().size1())
-        _value=fullMatrix<double>(uvw().size1(),3);
-      for(int i=0; i< _value.size1(); i++) {
-        _value(i,0)=1000;
-        _value(i,1)=0;
-        _value(i,2)=0;
-      }
-    }
-  };
-  public:
-  dgConservationLawStommel() {
-    _nbf = 3;
-  }
-  dataCacheDouble *newSourceTerm(dataCacheMap &cacheMap)const {
-    return new initbath(cacheMap);
-  }
-};
 int main(int argc, char **argv) {
   GmshMergeFile("input/stommel.msh");
   //we probably need a class to group those three ones
@@ -129,32 +27,22 @@ int main(int argc, char **argv) {
   int nbNodes = elementGroups[0]->getNbNodes();
   fullMatrix<double> sol(nbNodes,elementGroups[0]->getNbElements()*3);
   fullMatrix<double> residu(nbNodes,elementGroups[0]->getNbElements()*3);
-  // initial condition
-  {
-    dgConservationLawStommel initLaw;
-    algo.residualVolume(initLaw,*elementGroups[0],sol,residu);
-    algo.multAddInverseMassMatrix(*elementGroups[0],residu,sol);
-  }
 
   dgConservationLaw *law = dgNewConservationLawShallowWater2d();
-
-  law->addBoundaryCondition("Top",dgBoundaryCondition::new0FluxCondition(*law));
-  law->addBoundaryCondition("Bottom",dgBoundaryCondition::new0FluxCondition(*law));
-  law->addBoundaryCondition("Left",dgBoundaryCondition::new0FluxCondition(*law));
-  law->addBoundaryCondition("Right",dgBoundaryCondition::new0FluxCondition(*law));
+  law->addBoundaryCondition("Wall",dgNewBoundaryConditionShallowWater2dWall());
   
-  for(int iT=0; iT<100; iT++) {
-    if(iT%10==0){
+  for(int iT=0; iT<10000; iT++) {
+    if(iT%100==0){
       printf("%i\n",iT);
       char name[100];
-      sprintf(name,"output/H_%05i.pos",iT/10);
+      sprintf(name,"output/eta_%05i.pos",iT/100);
       print(name,*elementGroups[0],&sol(0,0),0,3);
-      sprintf(name,"output/U_%05i.pos",iT/10);
+      sprintf(name,"output/u_%05i.pos",iT/100);
       print(name,*elementGroups[0],&sol(0,0),1,3);
-      sprintf(name,"output/V_%05i.pos",iT/10);
+      sprintf(name,"output/v_%05i.pos",iT/100);
       print(name,*elementGroups[0],&sol(0,0),2,3);
     }
-    algo.rungeKutta(*law,elementGroups,faceGroups,boundaryGroups,1e-8,residu,sol);
+    algo.rungeKutta(*law,elementGroups,faceGroups,boundaryGroups,50,residu,sol);
   }
   delete law;
 }
-- 
GitLab