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); }
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; }
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]; } } } }