From 51ab77058a856ebba67f942a69dfb61161a8d102 Mon Sep 17 00:00:00 2001
From: Richard Comblen <richard.comblen@uclouvain.be>
Date: Tue, 2 Mar 2010 10:49:57 +0000
Subject: [PATCH] Splitted multirate rk class

---
 Solver/CMakeLists.txt                   |   1 +
 Solver/TESTCASES/MultirateAdvection.lua |   2 +-
 Solver/dgRungeKutta.cpp                 | 354 ------------------------
 Solver/dgRungeKutta.h                   |  28 --
 4 files changed, 2 insertions(+), 383 deletions(-)

diff --git a/Solver/CMakeLists.txt b/Solver/CMakeLists.txt
index e7a29aefc2..1ce5fa3a7b 100644
--- a/Solver/CMakeLists.txt
+++ b/Solver/CMakeLists.txt
@@ -14,6 +14,7 @@ set(SRC
   dgGroupOfElements.cpp
   dgAlgorithm.cpp
   dgRungeKutta.cpp
+  dgRungeKuttaMultirate.cpp
   dgConservationLaw.cpp
   dgConservationLawAdvection.cpp
   dgSystemOfEquations.cpp
diff --git a/Solver/TESTCASES/MultirateAdvection.lua b/Solver/TESTCASES/MultirateAdvection.lua
index 3316a21e5a..34dfde0c54 100644
--- a/Solver/TESTCASES/MultirateAdvection.lua
+++ b/Solver/TESTCASES/MultirateAdvection.lua
@@ -78,7 +78,7 @@ LC = 0.1*.1
 dt=dt
 print('DT=',dt)
 RK=dgRungeKutta()
-multirateRK=dgRungeKuttaMultirate(GC,law)
+multirateRK=dgRungeKuttaMultirate43(GC,law)
 norm1=solution:norm()
 norm2=solution2:norm()
 print('Norm: ',norm1,norm2)
diff --git a/Solver/dgRungeKutta.cpp b/Solver/dgRungeKutta.cpp
index f8391bc006..4f22873c08 100644
--- a/Solver/dgRungeKutta.cpp
+++ b/Solver/dgRungeKutta.cpp
@@ -5,8 +5,6 @@
 #include "dgLimiter.h"
 #include "dgResidual.h"
 #include "dgGroupOfElements.h"
-#include <stdio.h>
-#include <algorithm>
 
 double dgRungeKutta::iterateEuler(const dgConservationLaw *claw, double dt, dgDofContainer *solution) {
   double A[] = {0};
@@ -245,355 +243,3 @@ void dgRungeKutta::registerBindings(binding *b) {
   cm->setDescription("if a limiter is set, it is applied after each RK stage");
 }
 
-dgRungeKuttaMultirate::dgRungeKuttaMultirate(dgGroupCollection* gc,dgConservationLaw *law){
-  _law=law;
-  _residualVolume=new dgResidualVolume(*_law);
-  _residualInterface=new dgResidualInterface(*_law);
-  _residualBoundary=new dgResidualBoundary(*_law);
-  _K=new dgDofContainer*[10];
-  for(int i=0;i<10;i++){
-    _K[i]=new dgDofContainer(gc,_law->getNbFields());
-    _K[i]->setAll(0.0);
-  }
-  _currentInput=new dgDofContainer(gc,_law->getNbFields());
-  _currentInput->setAll(0.0);
-  _residual=new dgDofContainer(gc,_law->getNbFields());
-  _residual->setAll(0.0);
-  _minExponent=INT_MAX;
-  _maxExponent=0;
-  for(int iGroup=0;iGroup<gc->getNbElementGroups();iGroup++){
-    dgGroupOfElements *ge=gc->getElementGroup(iGroup);
-    _minExponent=std::min(_minExponent,ge->getMultirateExponent());
-    _maxExponent=std::max(_maxExponent,ge->getMultirateExponent());
-    _innerBufferGroupsOfElements.resize(_maxExponent+1);
-    _outerBufferGroupsOfElements.resize(_maxExponent+1);
-    _bulkGroupsOfElements.resize(_maxExponent+1);
-    if(ge->getIsInnerMultirateBuffer()){
-      _innerBufferGroupsOfElements[ge->getMultirateExponent()].first.push_back(ge);
-    }
-    else if(ge->getIsOuterMultirateBuffer()){
-      _outerBufferGroupsOfElements[ge->getMultirateExponent()].first.push_back(ge);
-    }
-    else{
-      _bulkGroupsOfElements[ge->getMultirateExponent()].first.push_back(ge);
-    }
-  }
-//  std::vector<std::set<dgGroupOfFaces*> >bulkFacesSet;
-//  std::vector<std::set<dgGroupOfFaces*> >innerBufferFacesSet;
-//  std::vector<std::set<dgGroupOfFaces*> >outerBufferFacesSet;
-//  bulkFacesSet.resize(_maxExponent+1);
-//  innerBufferFacesSet.resize(_maxExponent+1);
-//  outerBufferFacesSet.resize(_maxExponent+1);
-  for(int iGroup=0;iGroup<gc->getNbFaceGroups();iGroup++){
-    dgGroupOfFaces *gf=gc->getFaceGroup(iGroup);
-    const dgGroupOfElements *ge[2];
-    ge[0]=&gf->getGroupLeft();
-    ge[1]=&gf->getGroupRight();
-    for(int i=0;i<2;i++){
-      if(ge[i]->getIsInnerMultirateBuffer()){
-        _innerBufferGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }
-      else if(ge[i]->getIsOuterMultirateBuffer()){
-        _outerBufferGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }else{
-        _bulkGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }
-    }
-  }
-  for(int iGroup=0;iGroup<gc->getNbBoundaryGroups();iGroup++){
-    dgGroupOfFaces *gf=gc->getBoundaryGroup(iGroup);
-    const dgGroupOfElements *ge[1];
-    ge[0]=&gf->getGroupLeft();
-    //ge[1]=&gf->getGroupRight();
-    for(int i=0;i<1;i++){
-      if(ge[i]->getIsInnerMultirateBuffer()){
-        _innerBufferGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }
-      else if(ge[i]->getIsOuterMultirateBuffer()){
-        _outerBufferGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }else{
-        _bulkGroupsOfElements[ge[i]->getMultirateExponent()].second.push_back(gf);
-      }
-    }
-  }
-  // Removing duplicate entries
-  for(int iExp=0;iExp<=_maxExponent;iExp++){
-    std::vector<dgGroupOfFaces*>*v[3];
-    v[0]=&_innerBufferGroupsOfElements[iExp].second;
-    v[1]=&_outerBufferGroupsOfElements[iExp].second;
-    v[2]=&_bulkGroupsOfElements[iExp].second;
-    for(int i=0;i<3;i++){
-      sort(v[i]->begin(),v[i]->end());
-      v[i]->erase(unique(v[i]->begin(),v[i]->end()),v[i]->end());
-    }
-  }
-}
-dgRungeKuttaMultirate::~dgRungeKuttaMultirate(){
-  for(int i=0;i>10;i++){
-    delete _K[i];
-  }
-  delete []_K;
-  delete _residual;
-  delete _currentInput;
-  delete _residualVolume;
-  delete _residualInterface;
-  delete _residualBoundary;
-}
-
-void dgRungeKuttaMultirate::computeInputForK(int iK,int exponent,bool isBuffer){
-  if(exponent>_maxExponent){
-    return;
-  }
-  //Msg::Info("Input for K%d at level %d %s",iK,exponent,isBuffer?"Buffer":"Bulk");
-  double localDt=_dt/pow(2.0,(double)exponent);
-  double _A[4][4]={
-     {0, 0, 0, 0},
-     {1.0/2.0, 0, 0 ,0},
-     {-1.0/6.0, 2.0/3.0, 0, 0},
-     {1.0/3.0, -1.0/3.0, 1, 0}
-  };
-  double _AInner[10][10]={
-    {0,         0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/4.0   ,0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {-1.0/12.0, 1.0/3.0,   0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/6.0,   -1.0/6.0,  1.0/2.0,   0,         0,         0,         0,         0,         0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         0,         0,         0,         0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         0,         0,         0,         0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         1.0/4.0,   0,         0,         0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         -1.0/12.0, 1.0/3.0,   0,         0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         1.0/6.0,   -1.0/6.0,  1.0/2.0,   0,         0},
-    {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0, 0}
-  };
-
-  // Big step RK43
-  double _AOuter[10][10]={
-    {0,         0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-    {-1.0/6.0,  0,         0,         0,         2.0/3.0,   0,         0,         0,         0,         0},
-    {1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
-    {1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
-    {1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
-    {1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
-  };
-//  Msg::Info("K%d, %d, %s",iK,exponent,isBuffer?"Buffer":"Bulk");
-  // compute K[iK] for this exponent and buffer
-  if(isBuffer){
-    std::vector<dgGroupOfElements *>&gVi=_innerBufferGroupsOfElements[exponent].first;
-    std::vector<dgGroupOfElements *>&gVo=_outerBufferGroupsOfElements[exponent].first;
-    _currentInput->scale(gVi,0.0);
-    _currentInput->scale(gVo,0.0);
-    _currentInput->axpy(gVi,*_solution,1.0);
-    _currentInput->axpy(gVo,*_solution,1.0);
-    for(int i=0;i<iK;i++){
-      if(_AInner[iK][i]!=0.0)
-        _currentInput->axpy(gVi,*_K[i],_AInner[iK][i]*localDt*2);
-      if(_AOuter[iK][i]!=0.0)
-        _currentInput->axpy(gVo,*_K[i],_AOuter[iK][i]*localDt*2);
-    }
-  }
-  else{
-    std::vector<dgGroupOfElements *> &gV=_bulkGroupsOfElements[exponent].first;
-    _currentInput->scale(gV,0.0);
-    _currentInput->axpy(gV,*_solution,1.0);
-    for(int i=0;i<iK;i++){
-      if(_A[iK][i]!=0.0){
-        _currentInput->axpy(gV,*_K[i],_A[iK][i]*localDt);
-      }
-    }
-  }
-
-  if(!isBuffer){
-    switch(iK){
-      case 0:
-        computeInputForK(0,exponent+1,true);
-        break;
-      case 1:
-        computeInputForK(4,exponent+1,true);
-        break;
-      case 2:
-        computeInputForK(5,exponent+1,true);
-        break;
-      case 3:
-        computeInputForK(9,exponent+1,true);
-        break;
-    }
-  }
-  else{
-    if( (iK%5)<4 ){
-      computeInputForK(iK%5,exponent,false);
-    }
-  }
-  computeK(iK,exponent,isBuffer);
-//  Msg::Info("Multirate %d %0.16e",iK,_K[iK]->norm());
-  if( (iK==3 && !isBuffer) || (iK==9 && isBuffer) ){
-    updateSolution(exponent,isBuffer);
-  }
-  if(!isBuffer){
-    switch(iK){
-      case 0:
-        for(int i=1;i<4;i++){
-          computeInputForK(i,exponent+1,true);
-        }
-        break;
-      case 2:
-        for(int i=6;i<9;i++){
-          computeInputForK(i,exponent+1,true);
-        }
-        break;
-    }
-  }
-}
-void dgRungeKuttaMultirate::updateSolution(int exponent,bool isBuffer){
-  //Msg::Info("Updating solution at level %d %s",exponent,isBuffer?"Buffer":"Bulk");
-  double localDt=_dt/pow(2.0,(double)exponent);
-  double b[4]={1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
-  double c[4]={0, 1.0/2.0, 1.0/2.0, 1};
-  double bInner[10]={1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0,1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0};
-  double cInner[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
-  double bOuter[10]={1.0/6.0, 0 , 0 , 0 , 1.0/3.0,1.0/3.0, 0 , 0 , 0 , 1.0/6.0};
-  double cOuter[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
-  if(isBuffer){
-    std::vector<dgGroupOfElements *>&gVi=_innerBufferGroupsOfElements[exponent].first;
-    std::vector<dgGroupOfElements *>&gVo=_outerBufferGroupsOfElements[exponent].first;
-    for(int i=0;i<10;i++){
-      if(bInner[i]!=0.0)
-        _solution->axpy(gVi,*_K[i],bInner[i]*localDt*2);
-      if(bOuter[i]!=0.0)
-        _solution->axpy(gVo,*_K[i],bOuter[i]*localDt*2);
-    }
-  }
-  else{
-    std::vector<dgGroupOfElements *>&gV=_bulkGroupsOfElements[exponent].first;
-    for(int i=0;i<4;i++){
-      if(b[i]!=0.0)
-        _solution->axpy(gV,*_K[i],b[i]*localDt);
-    }
-  }
-}
-void dgRungeKuttaMultirate::computeK(int iK,int exponent,bool isBuffer){
-  //Msg::Info("Compute K%d at level %d %s",iK,exponent,isBuffer?"Buffer":"Bulk");
-  if(isBuffer){
-    std::vector<dgGroupOfElements *>&vei=_innerBufferGroupsOfElements[exponent].first;
-    std::vector<dgGroupOfElements *>&veo=_outerBufferGroupsOfElements[exponent].first;
-    _residual->scale(vei,0.0);
-    _residual->scale(veo,0.0);
-    for(int i=0;i<vei.size();i++){
-      _residualVolume->computeAndMap1Group(*vei[i], *_currentInput, *_residual);
-    }
-    for(int i=0;i<veo.size();i++){
-      _residualVolume->computeAndMap1Group(*veo[i], *_currentInput, *_residual);
-    }
-    std::vector<dgGroupOfFaces *>& vfi=_innerBufferGroupsOfElements[exponent].second;
-    std::vector<dgGroupOfFaces *>& vfo=_outerBufferGroupsOfElements[exponent].second;
-    std::set<dgGroupOfFaces *>gOFSet;
-    gOFSet.insert(vfo.begin(),vfo.end());
-    gOFSet.insert(vfi.begin(),vfi.end());
-    for(std::set<dgGroupOfFaces *>::iterator it=gOFSet.begin();it!=gOFSet.end();it++){
-      dgGroupOfFaces *faces=*it;
-      if(faces->isBoundary()){
-        _residualBoundary->computeAndMap1Group(*faces,*_currentInput,*_residual);
-        //Msg::Info("Buffer face group %p is boundary in multirate",faces);
-      }
-      else{
-        const dgGroupOfElements *gL=&faces->getGroupLeft();
-        const dgGroupOfElements *gR=&faces->getGroupRight();
-        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);
-        //Msg::Info("Buffer face group %p is mapped left or right in multirate",faces);
-        if(gL->getMultirateExponent()==exponent && gL->getIsMultirateBuffer())
-          faces->mapLeftFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gL));
-        if(gR->getMultirateExponent()==exponent && gR->getIsMultirateBuffer())
-          faces->mapRightFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gR));
-      }
-    }
-    fullMatrix<double> iMassEl, KEl,residuEl;
-    for(int iGroup=0;iGroup<vei.size();iGroup++){
-      dgGroupOfElements *group=vei[iGroup];
-      int nbNodes = group->getNbNodes();
-      for(int iElem=0;iElem<group->getNbElements();iElem++){
-        residuEl.setAsProxy(_residual->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        KEl.setAsProxy(_K[iK]->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        iMassEl.setAsProxy(group->getInverseMassMatrix(),iElem*nbNodes,nbNodes);
-        iMassEl.mult(residuEl,KEl);
-      }
-    }
-    for(int iGroup=0;iGroup<veo.size();iGroup++){
-      dgGroupOfElements *group=veo[iGroup];
-      int nbNodes = group->getNbNodes();
-      for(int iElem=0;iElem<group->getNbElements();iElem++){
-        residuEl.setAsProxy(_residual->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        KEl.setAsProxy(_K[iK]->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        iMassEl.setAsProxy(group->getInverseMassMatrix(),iElem*nbNodes,nbNodes);
-        iMassEl.mult(residuEl,KEl);
-      }
-    }
-  }
-  else{
-    std::vector<dgGroupOfElements *> &ve=_bulkGroupsOfElements[exponent].first;
-    _residual->scale(ve,0.0);
-    for(int i=0;i<ve.size();i++){
-      _residualVolume->computeAndMap1Group(*ve[i], *_currentInput, *_residual);
-    }
-    std::vector<dgGroupOfFaces *> &vf=_bulkGroupsOfElements[exponent].second;
-    for(int i=0;i<vf.size();i++){
-      dgGroupOfFaces *faces=vf[i];
-      if(faces->isBoundary()){
-        _residualBoundary->computeAndMap1Group(*faces,*_currentInput,*_residual);
-      }
-      else{
-        const dgGroupOfElements *gL=&faces->getGroupLeft();
-        const dgGroupOfElements *gR=&faces->getGroupRight();
-        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);
-        if(gL->getMultirateExponent()==exponent && !gL->getIsMultirateBuffer()){
-          faces->mapLeftFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gL));
-        }
-        if(gR->getMultirateExponent()==exponent && !gR->getIsMultirateBuffer()){
-          faces->mapRightFromInterface(_law->getNbFields(), residuInterface,_residual->getGroupProxy(gR));
-        }
-      }
-    }
-    fullMatrix<double> iMassEl, KEl,residuEl;
-    for(int iGroup=0;iGroup<ve.size();iGroup++){
-      dgGroupOfElements *group=ve[iGroup];
-      int nbNodes = group->getNbNodes();
-      for(int iElem=0;iElem<group->getNbElements();iElem++){
-        residuEl.setAsProxy(_residual->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        KEl.setAsProxy(_K[iK]->getGroupProxy(group),iElem*_law->getNbFields(),_law->getNbFields());
-        iMassEl.setAsProxy(group->getInverseMassMatrix(),iElem*nbNodes,nbNodes);
-        iMassEl.mult(residuEl,KEl);
-      }
-    }
-  }
-}
-
-double dgRungeKuttaMultirate::iterate(double dt, dgDofContainer *solution){
-  _solution=solution;
-  _dt=dt;
-  computeInputForK(0,0,false);
-  computeInputForK(1,0,false);
-  computeInputForK(2,0,false);
-  computeInputForK(3,0,false);
-  
-  return solution->norm();
-}
-
-void dgRungeKuttaMultirate::registerBindings(binding *b) {
-  classBinding *cb = b->addClass<dgRungeKuttaMultirate>("dgRungeKuttaMultirate");
-  cb->setDescription("Multirate explicit Runge-Kutta");
-  methodBinding *cm;
-  cm = cb->setConstructor<dgRungeKuttaMultirate,dgGroupCollection *,dgConservationLaw*>();
-  cm->setArgNames("groupCollection","law",NULL);
-  cm->setDescription("A new multirate explicit runge kutta, pass parameters to the iterate function");
-  cm = cb->addMethod("iterate",&dgRungeKuttaMultirate::iterate);
-  cm->setArgNames("dt","solution",NULL);
-  cm->setDescription("update solution by doing a multirate RK43 (from Schlegel et al. Journal of Computational and Applied Mathematics, 2009) step of base time step dt for the conservation law");
-  cb->setParentClass<dgRungeKutta>();
-}
diff --git a/Solver/dgRungeKutta.h b/Solver/dgRungeKutta.h
index fcf4b54c89..6c9ec32a9c 100644
--- a/Solver/dgRungeKutta.h
+++ b/Solver/dgRungeKutta.h
@@ -30,32 +30,4 @@ class dgRungeKutta {
   dgRungeKutta();
 };
 
-class dgRungeKuttaMultirate: public dgRungeKutta{
-  private:
-  int _maxExponent;
-  int _minExponent;
-  double _dt;
-  dgConservationLaw *_law;
-  dgDofContainer *_solution;
-  dgDofContainer **_K;
-  dgDofContainer *_currentInput;
-  dgDofContainer *_residual;
-  dgResidualVolume *_residualVolume;
-  dgResidualInterface *_residualInterface;
-  dgResidualBoundary *_residualBoundary;
-  std::vector<std::pair<std::vector<dgGroupOfElements*>,std::vector<dgGroupOfFaces*> > >_bulkGroupsOfElements;// int is the multirateExponent
-  std::vector<std::pair<std::vector<dgGroupOfElements*>,std::vector<dgGroupOfFaces*> > >_innerBufferGroupsOfElements;// int is the multirateExponent
-  std::vector<std::pair<std::vector<dgGroupOfElements*>,std::vector<dgGroupOfFaces*> > >_outerBufferGroupsOfElements;// int is the multirateExponent
-  void computeInputForK(int iK,int exponent,bool isBuffer);
-  void computeK(int iK,int exponent,bool isBuffer);
-  void updateSolution(int exponent,bool isBuffer);
-  void computeResidual(int exponent,bool isBuffer,dgDofContainer *solution, dgDofContainer *residual);
-  public:
-  dgRungeKuttaMultirate(dgGroupCollection *gc,dgConservationLaw* law);
-  ~dgRungeKuttaMultirate();
-
-
-  double iterate(double dt, dgDofContainer *solution);
-  static void registerBindings(binding *b);
-};
 #endif
-- 
GitLab