sandbox/geoffroy/dev/predictor-corrector-source.h

    Generic predictor/corrector time-integration

    #include "utils.h"
    
    // Maximum number of source terms
    #define NSource 10
    
    // Required from solver
    // fields updated by time-integration
    extern scalar * evolving;
    
    // how to compute updates
    double (* update) (scalar * evolving, scalar * updates, double dtmax) = NULL;
    
    // User-provided functions
    // gradient
    double (* gradient)  (double, double, double) = minmod2;
    
    double t = 0., dt = 0.;
    
    static void advance_generic (scalar * output, scalar * input, scalar * updates,
    			     double dt){
      if (input != output)
        trash (output);
      foreach() {
        scalar o, i, u;
        for (o,i,u in output,input,updates)
          o[] = i[] + dt*u[];
      }
      boundary (output);
    }
    
    
    static void (* advance) (scalar * output, scalar * input, scalar * updates,
    			 double dt) = advance_generic;
    
    // how to compute source terms
    void (* updatesource[NSource] ) (scalar * evolving,
    				scalar * sources,
    				double dtmax,
    				int numbersource);
    
    // Fixing minor bug when a pointer is calling NULL
    static void fnull(){
    }
    
    // Because of the additivity of source terms, we need to reset them at each step
    static void resetsource(scalar * evolving,
    				scalar * sources,
    				double dtmax,
    				int numbersource){
      scalar dsh = sources[0];
      vector dshu = { sources[1], sources[2] }; 
      foreach(){
          dsh[] = 0;
          foreach_dimension() dshu.x[] = 0;
        }
      numbersource++;
      updatesource[numbersource](evolving, sources,
    				dtmax, numbersource);
    }
    
    event defaults (i = 0)
    {
      // limiting
      for (scalar s in all)
        s.gradient = gradient;
    
      // default values
      foreach()
        for (scalar s in all)
          s[] = 0.;
      boundary (all);
    }
    
    
    void run()
    {
      t = 0.;
      init_grid (N);
      
      // main loop
      timer start = timer_start();
      int i = 0; long tnc = 0;
     
      while (events (i, t, true)) {
        // list of updates
        scalar * updates = list_clone (evolving);
        scalar * sources = list_clone (evolving);
        dt = dtnext (t, update (evolving, updates, DT));
        if (gradient != zero) {
          /* 2nd-order time-integration */
          scalar * predictor = list_clone (evolving);
          /* predictor */
          advance (predictor, evolving, updates, dt/2.);
    
          updatesource[0](predictor, sources, dt/2.,0);
          advance (predictor, predictor, sources, dt/2.);
          
          /* corrector */
          update (predictor, updates, dt);
          
          delete (predictor);
          free (predictor);
        }
    
        advance (evolving, evolving, updates, dt);
    
        updatesource[0] (evolving, sources, dt,0); 
        advance (evolving, evolving, sources, dt);
        
        delete (updates);
        free (updates);
        delete(sources);
        free(sources);
        
       long nc = 0;
        foreach (reduction(+:nc)) 
          nc++;
        tnc += nc;
        i++; t = tnext;
      }
      timer_print (start, i, tnc);
    
      free_grid();
    }
    
    // Overloading the first updatesource function with resetsource
    int numbersource;
    event initres(i = 0 ){
      numbersource = 0;
      updatesource[numbersource]=resetsource;
      numbersource++;
      updatesource[numbersource] = fnull;
    }