예제 #1
0
void Plot(ADERDG* adg)
{
  FILE * gnufile;
  gnufile = fopen("adgplot.dat", "w" );

  for(int ie = 1; ie <= _NBELEMS_IN; ie++){
    for(int j = 0; j < _NGLOPS; j++){
      double wex[_M];
      double h = adg->face[ie] - adg->face[ie-1];
      double x = adg->face[ie-1] + h * gauss_lob_point[gauss_lob_offset[_D]+j];
      ExactSol(x, adg->tnow, wex);
      fprintf(gnufile, "%f ", x);
      //printf("ie=%d j=%d x=%f\n",ie,j, x);
      // numerical values
      for (int iv = 0; iv < _M; ++iv){
	fprintf(gnufile, "%f ", adg->wnow[ie][j][iv]);	
      }
      // exact values
      for (int iv=0;iv<_M;++iv){
	fprintf(gnufile,"%f ",wex[iv]);	
      }
      // predictor (debug)
      for (int iv = 0; iv < _M; ++iv){
	fprintf(gnufile, "%f ", adg->wpred[ie][j][iv]);	
      }
      fprintf(gnufile,"\n");
    }
  }

  fclose(gnufile);
}
예제 #2
0
void InitADERDG(ADERDG* adg, double xmin, double xmax)
{
  adg->xmin = xmin;
  adg->xmax = xmax;

  for(int i = 0; i < _NBFACES; i++) {
    double xh = (double)i / _NBELEMS_IN;
    double x = stretching(xh);
    adg->face[i] = xmin + x * (xmax - xmin);
    //printf("i=%d x=%f\n",i, adg->face[i]);
  }

  adg->dx = 0.0;
  for(int ie = 1; ie <= _NBELEMS_IN; ie++) {
    adg->dx = _MAX(adg->dx, adg->face[ie] - adg->face[ie - 1]);
  }

  adg->cfl = _CFL;
  adg->dt = adg->cfl * adg->dx;  // TODO: put the velocity
  adg->ncfl = 0;

  for(int ie = 1; ie <= _NBELEMS_IN; ie++) {
    adg->cell_level[ie] =
      (int) (log(adg->dx / (adg->face[ie] - adg->face[ie-1])) / log(2));
    adg->ncfl = _MAX ( adg->ncfl , adg->cell_level[ie] );
  }
  // convention: first and last cell are among the biggest elements
  adg->cell_level[0] = 0;
  adg->cell_level[_NBELEMS_IN + 1] = 0;

  printf("found %d cfl levels\n", adg->ncfl);

  adg->dt_small = adg->dt / (1 << adg->ncfl);

  printf("small dt=%f max cell size=%f\n", adg->dt_small, adg->dx);

  for(int ie = 1; ie <= _NBELEMS_IN; ie++) {
    for(int j = 0;j < _NGLOPS; j++) {
      double h = adg->face[ie] - adg->face[ie-1];
      double x = adg->face[ie-1]
	+ h * gauss_lob_point[gauss_lob_offset[_D] + j];
      ExactSol(x, 0, adg->wnow[ie][j]);
    }
  }
   
  for(int ie = 1;ie <= _NBELEMS; ie++){
    for(int j = 0;j < _NGLOPS; j++){
      for(int iv = 0; iv < _M; iv++){
	adg->wnext[ie][j][iv] = adg->wnow[ie][j][iv];
      }
    }
  }
    
  for(int i=0;i<_NBFACES;i++){
    adg->face_level[i]=_MAX(adg->cell_level[i],adg->cell_level[i+1]);
  }
}
/**
 * @brief
 * Calculate the Norm Error of Numerical Solution at Spicific Time.
 */
void NormErr(structMesh *mesh, physics *phys,
             double time, double **c,
             double *L2, double *Linf) {

    double **temp = Matrix_create(mesh->ndim1, mesh->ndim2);
    ExactSol(mesh, phys, time, temp);

    double err    = 0;
    double maxerr = 0.0;
    int    dim1, dim2;
    for (dim1=0; dim1<mesh->ndim1; dim1++) {
        for (dim2=0; dim2<mesh->ndim2; dim2++) {

            double dc = c[dim1][dim2]-temp[dim1][dim2];
            maxerr = maxf(fabs(dc), maxerr);
            err += dc*dc;
        }
    }
    *L2   = sqrt(err/mesh->ndim1/mesh->ndim2);
    *Linf = maxerr;

    Matrix_free(temp);
    return;
}
예제 #4
0
void ADERTimeStep(ADERDG* adg)
{
  double dt = adg->dt_small;

  // first, predict the values of w at an intermediate time step
  for(int ie = 1;ie <= _NBELEMS_IN; ie++) {
    Predictor(adg, ie, dt / 2);
  }

  // init the derivative to zero
  for(int ie = 1; ie<= _NBELEMS_IN; ie++) {
    for(int i = 0; i < _NGLOPS; i++) {
      for(int iv = 0; iv < _M; iv++) {
	adg->dtw[ie][i][iv]=0;
      }
    }
  }

  // impose the exact values on boundary left and right cells
  double x = adg->face[0];
  double t = adg->tnow + dt / 2 ;
  ExactSol(x, t, adg->wpred[0][_D]); // _D = last point of left cell 

  x = adg->face[_NBFACES-1];

  // 0 = first point of right cell
  ExactSol(x, t, adg->wpred[_NBELEMS_IN + 1][0]); 

  // compute the face flux terms
  // loop on the faces
  for(int i = 0; i < _NBFACES; i++){
    double *wL, *wR;
    double flux[_M];
    int ie = i;
    wL = adg->wpred[ie][_D]; // _D = last point of left cell 
    wR = adg->wpred[ie+1][0];  // 0 = first point of right cell
    NumFlux(wL, wR, flux);
    for (int k = 0; k < _M; k++){
      adg->dtw[ie][_D][k] -=  flux[k];  
      adg->dtw[ie+1][0][k] +=  flux[k];  
    }
  }

  // compute the volume terms
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    double h = adg->face[ie] - adg->face[ie-1];
    // loop on the glops i 
    for(int i = 0; i < _NGLOPS; i++){
      
      // integration weight
      double omega = wglop(_D, i) * h;
      
      // flux at glop i
      double flux[_M];
      NumFlux(adg->wpred[ie][i], adg->wpred[ie][i], flux);
      
      // loop on the basis functions j
      for(int j = 0; j < _D+1; j++){
	// derivative of basis function j at glop i
	double dd = dlag(_D, j, i) / h;
	for (int k = 0; k < _M; k++){
	  adg->dtw[ie][j][k] += omega * dd * flux[k];
	}
      }
    }
  }    
   
  // divide by the mass matrix
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    double h = adg->face[ie] - adg->face[ie-1];
    for(int i = 0; i < _NGLOPS; i++){
      double omega = wglop(_D, i) * h;
      for (int k = 0; k < _M; k++){
	adg->dtw[ie][i][k] /= omega;
      }
    }
    
  }
  
  // update wnext and 
  // copy wnext into wnow for the next time step
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    for(int i = 0; i < _NGLOPS; i++){
      for(int iv = 0; iv < _M; iv++){
	adg->wnext[ie][i][iv] =
	  adg->wnow[ie][i][iv] + dt * adg->dtw[ie][i][iv];
	adg->wnow[ie][i][iv] = adg->wnext[ie][i][iv];
      }
    }
  }
 
}