int main(void) { field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 3; // only one conservative variable f.model.NumFlux = TransNumFlux2dwav; f.model.BoundaryFlux = TransBoundaryFlux2dwav; f.model.InitData = TransInitData2dwav; f.model.ImposedData = TransImposedData2dwav; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 3; // x direction degree f.interp.interp_param[2] = 3; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 4; // x direction refinement f.interp.interp_param[5] = 4; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // Read the gmsh file ReadMacroMesh(&(f.macromesh), "disquetrou.msh"); //ReadMacroMesh(&(f.macromesh), "geo/cube.msh"); // Try to detect a 2d mesh Detect2DMacroMesh(&(f.macromesh)); assert(f.macromesh.is2d); //PrintMacroMesh(&(f.macromesh)); // Mesh preparation BuildConnectivity(&(f.macromesh)); // AffineMapMacroMesh(&(f.macromesh)); // Prepare the initial fields Initfield(&f); // prudence... CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); printf("cfl param =%f\n", f.hmin); // Apply the DG scheme time integration by RK2 scheme up to final // time tmax. real tmax = 0.5; real dt = 0.; f.vmax = 0.1; if(dt <= 0.0) dt = set_dt(&f); RK2(&f, tmax, dt); // Save the results and the error Plotfield(0, false, &f, NULL, "dgvisu.msh"); Plotfield(0, true, &f, "Error", "dgerror.msh"); real dd = L2error(&f); printf("erreur L2=%f\n", dd); return 0; };
int TestFieldDG(void){ int test = (1==1); Field f; f.model.m=1; // only one conservative variable f.model.NumFlux=TransportNumFlux; f.model.BoundaryFlux=TestTransportBoundaryFlux; f.model.InitData=TestTransportInitData; f.model.ImposedData=TestTransportImposedData; f.varindex=GenericVarindex; f.interp.interp_param[0]=1; // _M f.interp.interp_param[1]=2; // x direction degree f.interp.interp_param[2]=2; // y direction degree f.interp.interp_param[3]=2; // z direction degree f.interp.interp_param[4]=1; // x direction refinement f.interp.interp_param[5]=1; // y direction refinement f.interp.interp_param[6]=1; // z direction refinement ReadMacroMesh(&(f.macromesh),"test/testcube.msh"); BuildConnectivity(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); //AffineMapMacroMesh(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); InitField(&f); CheckMacroMesh(&(f.macromesh),f.interp.interp_param+1); dtField(&f); DisplayField(&f); int yes_compare = 1; int no_compare = 0; PlotField(0,no_compare,&f,"visu.msh"); PlotField(0,yes_compare,&f,"error.msh"); // test the time derivative with the exact solution for(int i=0;i<f.model.m * f.macromesh.nbelems * NPG(f.interp.interp_param+1);i++){ test = test && fabs(4*f.wn[i]-pow(f.dtwn[i],2))<1e-2; assert(test); } return test; };
int TestfieldDG() { int test = true; field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 1; // only one conservative variable f.model.NumFlux = TransNumFlux; f.model.BoundaryFlux = TestTransBoundaryFlux; f.model.InitData = TestTransInitData; f.model.ImposedData = TestTransImposedData; f.model.Source = NULL; f.varindex = GenericVarindex; f.interp.interp_param[0] = 1; // _M f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 2; // z direction degree f.interp.interp_param[4] = 2; // x direction refinement f.interp.interp_param[5] = 2; // y direction refinement f.interp.interp_param[6] = 2; // z direction refinement ReadMacroMesh(&(f.macromesh), "../test/testcube2.msh"); //ReadMacroMesh(&(f.macromesh),"test/testmacromesh.msh"); BuildConnectivity(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); //AffineMapMacroMesh(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); real tnow = 0.0; Initfield(&f); CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); dtfield(&f, tnow, f.wn, f.dtwn); Displayfield(&f); /* Plotfield(0, false, &f, NULL, "visu.msh"); */ /* Plotfield(0, true, &f, "error", "error.msh"); */ // Test the time derivative with the exact solution int *raf = f.interp.interp_param + 4; int *deg = f.interp.interp_param + 1; for(int i = 0; i < f.model.m * f.macromesh.nbelems * NPG(raf, deg); i++){ test = test && fabs(4 * f.wn[i] - pow(f.dtwn[i], 2)) < 1e-2; printf("i=%d err=%f \n",i,4 * f.wn[i] - pow(f.dtwn[i], 2)); assert(test); } return test; };
// some unit tests of the macromesh code int TestMacroMesh(void) { MacroMesh m; int param[]={4, 4, 4, 1, 1, 1, 0}; // test gmsh file reading ReadMacroMesh(&m, "test/testmacromesh.msh"); BuildConnectivity(&m); CheckMacroMesh(&m, param); PrintMacroMesh(&m); int test = (m.nbelems == 5); test = (test && m.nbnodes == 50); // test search methods real xphy[3]={1,1.1,0.5}; real xref[3]; test= test && IsInElem(&m,0,xphy,xref); printf("xphy=%f %f %f xref=%f %f %f \n",xphy[0],xphy[1],xphy[2], xref[0],xref[1],xref[2]); xphy[2]=-0.5; test= test && !IsInElem(&m,0,xphy,xref); int num=NumElemFromPoint(&m,xphy,NULL); printf("xphy=%f %f %f is in elem=%d\n",xphy[0],xphy[1],xphy[2],num); test=test && (num == -1); xphy[2]=0.5; num=NumElemFromPoint(&m,xphy,NULL); printf("xphy=%f %f %f is in elem=%d\n",xphy[0],xphy[1],xphy[2],num); test=test && (num == 0); real xphy2[3]={1,0,0.33}; num=NumElemFromPoint(&m,xphy2,NULL); printf("xphy=%f %f %f is in elem=%d\n",xphy2[0],xphy2[1],xphy2[2],num); test=test && (num == 3); return test; }
int TestfieldRK2_2D() { bool test = true; field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 1; f.model.NumFlux = TransNumFlux2d; f.model.BoundaryFlux = TransBoundaryFlux2d; f.model.InitData = TransInitData2d; f.model.ImposedData = TransImposedData2d; f.varindex = GenericVarindex; f.interp.interp_param[0] = 1; // _M f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 1; // x direction refinement f.interp.interp_param[5] = 1; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement ReadMacroMesh(&f.macromesh, "../test/testdisque2d.msh"); Detect2DMacroMesh(&f.macromesh); assert(f.macromesh.is2d); BuildConnectivity(&f.macromesh); Initfield(&f); CheckMacroMesh(&f.macromesh, f.interp.interp_param + 1); printf("cfl param =%f\n",f.hmin); real tmax = 0.1; f.vmax=1; real dt = 0; RK2(&f, tmax, dt); //Plotfield(0, false, &f, NULL, "dgvisu.msh"); //Plotfield(0, true, &f, "error", "dgerror.msh"); real dd = L2error(&f); printf("erreur L2=%f\n", dd); test = test && (dd < 0.01); return test; }
int TestCoil2D(void) { bool test = true; field f; init_empty_field(&f); init_empty_field(&f); f.model.cfl = 0.2; f.model.m = 7; // num of conservative variables f.model.NumFlux = Maxwell2DCleanNumFlux_upwind; f.model.BoundaryFlux = Coil2DBoundaryFlux; f.model.InitData = Coil2DInitData; f.model.ImposedData = Coil2DImposedData; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 4; // x direction refinement f.interp.interp_param[5] = 4; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // Read the gmsh file ReadMacroMesh(&f.macromesh, "../test/testmacromesh.msh"); // Try to detect a 2d mesh Detect2DMacroMesh(&f.macromesh); assert(f.macromesh.is2d); // Mesh preparation BuildConnectivity(&(f.macromesh)); //AffineMapMacroMesh(&(f.macromesh)); // Prepare the initial fields Initfield(&f); f.model.Source = Coil2DSource; f.pre_dtfield = coil_pre_dtfield; //f.dt = 1e-3; // Prudence... CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); printf("cfl param =%f\n", f.hmin); // time derivative //dtfield(&f); //Displayfield(&f); // init the particles on a circle PIC pic; InitPIC(&pic, 100); CreateCoil2DParticles(&pic, &f.macromesh); PlotParticles(&pic, &f.macromesh); f.pic = &pic; // time evolution real tmax = 0.1; f.vmax = 1; real dt = set_dt(&f); RK2(&f, tmax, dt); // Save the results and the error //Plotfield(2, false, &f, NULL, "dgvisu.msh"); //Plotfield(2, true, &f, "error", "dgerror.msh"); real dd = L2error(&f); real tolerance = 0.3; test = test && (dd < tolerance); printf("L2 error: %f\n", dd); return test; }
int TestPeriodic(void) { bool test=true; field f; init_empty_field(&f); f.model.m=_INDEX_MAX; // num of conservative variables f.vmax = _VMAX; // maximal wave speed f.model.NumFlux=VlasovP_Lagrangian_NumFlux; f.model.Source = NULL; f.model.BoundaryFlux = TestPeriodic_BoundaryFlux; f.model.InitData = TestPeriodic_InitData; f.model.ImposedData = TestPeriodic_ImposedData; f.varindex=GenericVarindex; f.pre_dtfield=NULL; f.post_dtfield=NULL; f.update_after_rk=NULL; f.model.cfl=0.05; f.interp.interp_param[0]=f.model.m; // _M f.interp.interp_param[1]=3; // x direction degree f.interp.interp_param[2]=0; // y direction degree f.interp.interp_param[3]=0; // z direction degree f.interp.interp_param[4]=10; // x direction refinement f.interp.interp_param[5]=1; // y direction refinement f.interp.interp_param[6]=1; // z direction refinement // read the gmsh file ReadMacroMesh(&(f.macromesh), "test/testcube.msh"); // try to detect a 2d mesh Detect1DMacroMesh(&(f.macromesh)); assert(f.macromesh.is1d); // mesh preparation f.macromesh.period[0]=1; BuildConnectivity(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); //assert(1==2); //AffineMapMacroMesh(&(f.macromesh)); // prepare the initial fields Initfield(&f); f.nb_diags = 0; // prudence... CheckMacroMesh(&(f.macromesh),f.interp.interp_param+1); printf("cfl param =%f\n",f.hmin); // time derivative //dtField(&f); //DisplayField(&f); //assert(1==2); // apply the DG scheme // time integration by RK2 scheme // up to final time = 1. //RK2(&f,0.5,0.1); f.vmax=_VMAX; real dt = set_dt(&f); RK2(&f,0.5, dt); // save the results and the error Plotfield(0,(1==0),&f,"sol","dgvisu.msh"); Plotfield(0,(1==1),&f,"error","dgerror.msh"); real dd=L2error(&f); real dd_Kinetic=L2_Kinetic_error(&f); printf("erreur kinetic L2=%lf\n",dd_Kinetic); printf("erreur L2=%lf\n",dd); test= test && (dd<3e-3); //SolvePoisson(&f); return test; }
int Test_TransportVP() { bool test = true; field f; init_empty_field(&f); int vec=1; f.model.m=_INDEX_MAX; // num of conservative variables f(vi) for // each vi, phi, E, rho, u, p, e (ou T) f.model.NumFlux=VlasovP_Lagrangian_NumFlux; //f.model.Source = NULL; f.model.InitData = Test_TransportVP_InitData; f.model.ImposedData = Test_TransportVP_ImposedData; f.model.BoundaryFlux = Test_TransportVP_BoundaryFlux; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 0; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 16; // x direction refinement f.interp.interp_param[5] = 1; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // read the gmsh file ReadMacroMesh(&(f.macromesh), "../test/testcube.msh"); // try to detect a 2d mesh Detect1DMacroMesh(&(f.macromesh)); bool is1d = f.macromesh.is1d; assert(is1d); // mesh preparation BuildConnectivity(&(f.macromesh)); //AffineMapMacroMesh(&(f.macromesh)); // prepare the initial fields f.model.cfl = 0.05; Initfield(&f); f.vmax = _VMAX; // maximal wave speed f.nb_diags = 3; f.pre_dtfield = UpdateVlasovPoisson; f.post_dtfield=NULL; f.update_after_rk = PlotVlasovPoisson; f.model.Source = VlasovP_Lagrangian_Source; // prudence... CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); printf("cfl param =%f\n", f.hmin); real tmax = 0.03; real dt = set_dt(&f); RK2(&f, tmax, dt); //RK2(&f,0.03,0.05); // save the results and the error int iel = 2 * _NB_ELEM_V / 3; int iloc = _DEG_V; printf("Trace vi=%f\n", -_VMAX + iel * _DV + _DV * glop(_DEG_V, iloc)); Plotfield(iloc + iel * _DEG_V, false, &f, "sol","dgvisu.msh"); Plotfield(iloc + iel * _DEG_V, true, &f, "error","dgerror.msh"); Plot_Energies(&f, dt); real dd_Kinetic = L2_Kinetic_error(&f); printf("erreur kinetic L2=%lf\n", dd_Kinetic); test= test && (dd_Kinetic < 1e-2); return test; }
int TestDtfield_CL(void){ bool test = true; if(!cldevice_is_acceptable(nplatform_cl, ndevice_cl)) { printf("OpenCL device not acceptable.\n"); return true; } field f; // 2D meshes: // test/disque2d.msh // test/testdisque2d.msh // test/testmacromesh.msh // test/unit-cube.msh char *mshname = "test/disque2d.msh"; ReadMacroMesh(&(f.macromesh), mshname); Detect2DMacroMesh(&f.macromesh); BuildConnectivity(&f.macromesh); #if 1 // 2D version assert(f.macromesh.is2d); f.model.cfl = 0.05; f.model.m = 1; m = f.model.m; f.model.NumFlux = TransNumFlux2d; f.model.BoundaryFlux = TransBoundaryFlux2d; f.model.InitData = TransInitData2d; f.model.ImposedData = TransImposedData2d; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 4; // x direction refinement f.interp.interp_param[5] = 4; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement #else // 3D version f.model.cfl = 0.05; f.model.m = 1; f.model.NumFlux = TransNumFlux; f.model.BoundaryFlux = TestTransBoundaryFlux; f.model.InitData = TestTransInitData; f.model.ImposedData = TestTransImposedData; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 2; // z direction degree f.interp.interp_param[4] = 3; // x direction refinement f.interp.interp_param[5] = 3; // y direction refinement f.interp.interp_param[6] = 3; // z direction refinement #endif set_global_m(f.model.m); set_source_CL(&f, "OneSource"); Initfield(&f); cl_event clv_dtfield = clCreateUserEvent(f.cli.context, NULL); dtfield_CL(&f, &f.wn_cl, 0, NULL, &clv_dtfield); clWaitForEvents(1, &clv_dtfield); CopyfieldtoCPU(&f); // Displayfield(&f); show_cl_timing(&f); real *saveptr = f.dtwn; f.dtwn = calloc(f.wsize, sizeof(real)); f.model.Source = OneSource; dtfield(&f, f.wn, f.dtwn); real maxerr = 0; for(int i = 0; i < f.wsize; i++) { real error = f.dtwn[i] - saveptr[i]; //printf("error= \t%f\t%f\t%f\n", error, f.dtwn[i], saveptr[i]); maxerr = fmax(fabs(error), maxerr); } printf("max error: %f\n", maxerr); test = (maxerr < 1e-8); return test; }
int TestPoisson2d(void) { bool test = true; field f; init_empty_field(&f); int vec=1; // num of conservative variables f(vi) for each vi, phi, E, rho, u, // p, e (ou T) f.model.m=_INDEX_MAX; f.vmax = _VMAX; // maximal wave speed f.model.NumFlux = VlasovP_Lagrangian_NumFlux; f.model.Source = VlasovP_Lagrangian_Source; //f.model.Source = NULL; f.model.BoundaryFlux = TestPoisson_BoundaryFlux; f.model.InitData = TestPoisson_InitData; f.model.ImposedData = TestPoisson_ImposedData; f.model.Source = NULL; f.varindex = GenericVarindex; f.pre_dtfield = NULL; f.update_after_rk = NULL; f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 3; // x direction degree f.interp.interp_param[2] = 3; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 2; // x direction refinement f.interp.interp_param[5] = 2; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // read the gmsh file ReadMacroMesh(&(f.macromesh),"test/testdisque2d.msh"); //ReadMacroMesh(&(f.macromesh),"geo/square.msh"); // try to detect a 2d mesh //bool is1d=Detect1DMacroMesh(&(f.macromesh)); Detect2DMacroMesh(&(f.macromesh)); bool is2d=f.macromesh.is2d; assert(is2d); // mesh preparation BuildConnectivity(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); //assert(1==2); //AffineMapMacroMesh(&(f.macromesh)); // prepare the initial fields Initfield(&f); f.nb_diags=0; // prudence... CheckMacroMesh(&(f.macromesh),f.interp.interp_param+1); printf("cfl param =%f\n",f.hmin); PoissonSolver ps; InitPoissonSolver(&ps,&f,_INDEX_PHI); SolvePoisson2D(&ps,_Dirichlet_Poisson_BC); real errl2 = L2error(&f); printf("Erreur L2=%f\n",errl2); test = test && (errl2 < 4e-4); printf("Plot...\n"); Plotfield(_INDEX_PHI, false, &f, NULL, "dgvisu.msh"); Plotfield(_INDEX_EX, false, &f, NULL, "dgex.msh"); return test; }
int TestMaxwell2D() { bool test = true; field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 7; // num of conservative variables f.model.NumFlux = Maxwell2DNumFlux_uncentered; //f.model.NumFlux = Maxwell2DNumFlux_centered; f.model.BoundaryFlux = Maxwell2DBoundaryFlux_uncentered; f.model.InitData = Maxwell2DInitData; f.model.ImposedData = Maxwell2DImposedData; f.varindex = GenericVarindex; f.model.Source = Maxwell2DSource; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 3; // x direction degree f.interp.interp_param[2] = 3; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 4; // x direction refinement f.interp.interp_param[5] = 4; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement ReadMacroMesh(&(f.macromesh), "../test/testcube.msh"); Detect2DMacroMesh(&(f.macromesh)); assert(f.macromesh.is2d); BuildConnectivity(&(f.macromesh)); char buf[1000]; sprintf(buf, "-D _M=%d", f.model.m); strcat(cl_buildoptions, buf); set_source_CL(&f, "Maxwell2DSource"); sprintf(numflux_cl_name, "%s", "Maxwell2DNumFlux_uncentered"); sprintf(buf," -D NUMFLUX="); strcat(buf, numflux_cl_name); strcat(cl_buildoptions, buf); sprintf(buf, " -D BOUNDARYFLUX=%s", "Maxwell2DBoundaryFlux_uncentered"); strcat(cl_buildoptions, buf); Initfield(&f); CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); real tmax = 0.1; f.vmax = 1; real dt = set_dt(&f); #if 0 // C version RK2(&f, tmax, dt); #else // OpenCL version CopyfieldtoGPU(&f); RK2_CL(&f, tmax, dt, 0, 0, 0); CopyfieldtoCPU(&f); printf("\nOpenCL Kernel time:\n"); show_cl_timing(&f); printf("\n"); #endif // Save the results and the error /* Plotfield(0, false, &f, NULL, "dgvisu.msh"); */ /* Plotfield(0, true, &f, "error", "dgerror.msh"); */ real dd = L2error(&f); real tolerance = 1.1e-2; test = test && (dd < tolerance); printf("L2 error: %f\n", dd); return test; }
int TestKernelFlux() { bool test=true; if(!cldevice_is_acceptable(nplatform_cl, ndevice_cl)) { printf("OpenCL device not acceptable.\n"); return true; } field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 1; // only one conservative variable f.model.NumFlux = TransNumFlux2d; f.model.BoundaryFlux = TransBoundaryFlux2d; f.model.InitData = TransInitData2d; f.model.ImposedData = TransImposedData2d; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 3; // x direction refinement f.interp.interp_param[5] = 3; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement ReadMacroMesh(&f.macromesh,"../test/testmacromesh.msh"); //ReadMacroMesh(&f.macromesh,"test/testcube.msh"); Detect2DMacroMesh(&f.macromesh); assert(f.macromesh.is2d); BuildConnectivity(&f.macromesh); Initfield(&f); CopyfieldtoGPU(&f); clFinish(f.cli.commandqueue); for(int ie = 0; ie < f.macromesh.nbelems; ++ie) { MacroCell *mcell = f.mcell + ie; DGFlux_CL(mcell, &f, 0, f.wn_cl + ie, 0, NULL, NULL); clFinish(f.cli.commandqueue); DGFlux_CL(mcell, &f, 1, f.wn_cl + ie, 0, NULL, NULL); clFinish(f.cli.commandqueue); if(!f.macromesh.is2d) { DGFlux_CL(mcell, &f, 2, f.wn_cl + ie, 0, NULL, NULL); clFinish(f.cli.commandqueue); } } CopyfieldtoCPU(&f); //Displayfield(&f); // save the dtwn pointer real *dtwn_cl = f.dtwn; // malloc a new dtwn. f.dtwn = calloc(f.wsize, sizeof(real)); for(int ie = 0; ie < f.macromesh.nbelems; ++ie) { MacroCell *mcell = f.mcell + ie; real *wmc = f.wn + mcell->woffset; real *dtwmc = f.dtwn + mcell->woffset; DGSubCellInterface(f.mcell + ie, &f, wmc, dtwmc); //DGVolume((void*) &f.mcell[ie], &f, f.wn, f.dtwn); } //Displayfield(&f); //check that the results are the same real maxerr = 0.0; printf("\nDifference\tC\t\tOpenCL\n"); for(int i = 0; i < f.wsize; ++i) { printf("%f\t%f\t%f\n", f.dtwn[i] - dtwn_cl[i], f.dtwn[i], dtwn_cl[i]); maxerr = fmax(fabs(f.dtwn[i] - dtwn_cl[i]), maxerr); } printf("max error: %f\n",maxerr); real tolerance; if(sizeof(real) == sizeof(double)) tolerance = 1e-8; else tolerance = 1e-4; test = (maxerr < tolerance); return test; }
int TestKernelVolume(void){ bool test=true; if(!cldevice_is_acceptable(nplatform_cl, ndevice_cl)) { printf("OpenCL device not acceptable.\n"); return true; } field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 1; // only one conservative variable f.model.NumFlux = TransNumFlux2d; f.model.BoundaryFlux = TransBoundaryFlux2d; f.model.InitData = TransInitData2d; f.model.ImposedData = TransImposedData2d; f.varindex = GenericVarindex; f.interp.interp_param[0] = 1; // _M f.interp.interp_param[1] = 1; // x direction degree f.interp.interp_param[2] = 1; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 3; // x direction refinement f.interp.interp_param[5] = 3; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement ReadMacroMesh(&f.macromesh,"../test/testmacromesh.msh"); //ReadMacroMesh(&f.macromesh,"test/testcube.msh"); Detect2DMacroMesh(&f.macromesh); assert(f.macromesh.is2d); BuildConnectivity(&f.macromesh); //PrintMacroMesh(&f.macromesh); //AffineMapMacroMesh(&f.macromesh); Initfield(&f); CopyfieldtoGPU(&f); /* // set dtwn to 1 for testing */ /* void* chkptr; */ /* cl_int status; */ /* chkptr=clEnqueueMapBuffer(f.cli.commandqueue, */ /* f.dtwn_cl, // buffer to copy from */ /* CL_TRUE, // block until the buffer is available */ /* CL_MAP_WRITE, */ /* 0, // offset */ /* sizeof(real)*(f.wsize), // buffersize */ /* 0,NULL,NULL, // events management */ /* &status); */ /* assert(status == CL_SUCCESS); */ /* assert(chkptr == f.dtwn); */ /* for(int i=0;i<f.wsize;i++){ */ /* f.dtwn[i]=1; */ /* } */ /* status=clEnqueueUnmapMemObject (f.cli.commandqueue, */ /* f.dtwn_cl, */ /* f.dtwn, */ /* 0,NULL,NULL); */ /* assert(status == CL_SUCCESS); */ /* status=clFinish(f.cli.commandqueue); */ /* assert(status == CL_SUCCESS); */ clFinish(f.cli.commandqueue); for(int ie = 0; ie < f.macromesh.nbelems; ++ie) { DGVolume_CL(f.mcell + ie, &f, f.wn_cl + ie, 0, NULL, NULL); clFinish(f.cli.commandqueue); } clFinish(f.cli.commandqueue); CopyfieldtoCPU(&f); //Displayfield(&f); // save the dtwn pointer real *dtwn_cl = f.dtwn; // malloc a new dtwn. f.dtwn = calloc(f.wsize, sizeof(real)); for(int ie = 0; ie < f.macromesh.nbelems; ++ie) { MacroCell *mcell = f.mcell + ie; real *dtwmc = f.dtwn + mcell->woffset; real *wmc = f.wn + mcell->woffset; DGVolume(f.mcell + ie, &f, wmc, dtwmc); } //Displayfield(&f); //check that the results are the same real maxerr = 0.0; //printf("\nDifference\tC\t\tOpenCL\n"); for(int i = 0; i < f.wsize; ++i) { real err = fabs(f.dtwn[i] - dtwn_cl[i]); //printf("%f\t%f\t%f\n", err, f.dtwn[i], dtwn_cl[i]); maxerr = fmax(err, maxerr); } printf("max error: %f\n",maxerr); real tolerance; if(sizeof(real) == sizeof(double)) tolerance = 1e-8; else tolerance = 1e-4; test = (maxerr < tolerance); return test; }
int TestOrszagTang(int argc, char *argv[]) { real cfl = 0.2; real tmax = 0.1; bool writemsh = false; real vmax = 6.0; bool usegpu = false; real dt = 0.0; real periodsize = 6.2831853; for (;;) { int cc = getopt(argc, argv, "c:t:w:D:P:g:s:"); if (cc == -1) break; switch (cc) { case 0: break; case 'c': cfl = atof(optarg); break; case 'g': usegpu = atoi(optarg); break; case 't': tmax = atof(optarg); break; case 'w': writemsh = true; break; case 'D': ndevice_cl= atoi(optarg); break; case 'P': nplatform_cl = atoi(optarg); break; default: printf("Error: invalid option.\n"); printf("Usage:\n"); printf("./testmanyv -c <cfl> -d <deg> -n <nraf> -t <tmax> -C\n -P <cl platform number> -D <cl device number> FIXME"); exit(1); } } bool test = true; field f; init_empty_field(&f); f.varindex = GenericVarindex; f.model.m = 9; f.model.cfl = cfl; strcpy(f.model.name,"MHD"); f.model.NumFlux=MHDNumFluxRusanov; f.model.BoundaryFlux=MHDBoundaryFluxOrszagTang; f.model.InitData=MHDInitDataOrszagTang; f.model.ImposedData=MHDImposedDataOrszagTang; char buf[1000]; sprintf(buf, "-D _M=%d -D _PERIODX=%f -D _PERIODY=%f", f.model.m, periodsize, periodsize); strcat(cl_buildoptions, buf); sprintf(numflux_cl_name, "%s", "MHDNumFluxRusanov"); sprintf(buf," -D NUMFLUX="); strcat(buf, numflux_cl_name); strcat(cl_buildoptions, buf); sprintf(buf, " -D BOUNDARYFLUX=%s", "MHDBoundaryFluxOrszagTang"); strcat(cl_buildoptions, buf); // Set the global parameters for the Vlasov equation f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 1; // x direction degree f.interp.interp_param[2] = 1; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 10; // x direction refinement f.interp.interp_param[5] = 10; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement //set_vlasov_params(&f.model); // Read the gmsh file ReadMacroMesh(&f.macromesh, "../test/testOTgrid.msh"); // Try to detect a 2d mesh Detect2DMacroMesh(&f.macromesh); bool is2d=f.macromesh.is2d; assert(is2d); // FIXME: this code doesn't detect that 1D mesh? //Detect1DMacroMesh(&f.macromesh); //bool is1d=f.macromesh.is1d; //assert(is1d); f.macromesh.period[0]=periodsize; f.macromesh.period[1]=periodsize; // Mesh preparation BuildConnectivity(&f.macromesh); // Prepare the initial fields Initfield(&f); // Prudence... CheckMacroMesh(&f.macromesh, f.interp.interp_param + 1); //Plotfield(0, (1==0), &f, "Rho", "dginit.msh"); f.vmax=vmax; real executiontime; if(usegpu) { printf("Using OpenCL:\n"); RK4_CL(&f, tmax, dt, 0, NULL, NULL); CopyfieldtoCPU(&f); show_cl_timing(&f); } else { printf("Using C:\n"); RK4(&f, tmax, dt); } //Plotfield(0,false,&f, "Rho", "dgvisu.msh"); //Gnuplot(&f,0,0.0,"data1D.dat"); return test; }
int TestMHD(int argc, char *argv[]) { real cfl = 0.2; real tmax = 0.1; bool writemsh = false; real vmax = 6.0; bool usegpu = false; real dt = 0.0; for (;;) { int cc = getopt(argc, argv, "c:t:w:D:P:g:s:"); if (cc == -1) break; switch (cc) { case 0: break; case 'c': cfl = atof(optarg); break; case 'g': usegpu = atoi(optarg); break; case 't': tmax = atof(optarg); break; case 'w': writemsh = true; break; case 'D': ndevice_cl= atoi(optarg); break; case 'P': nplatform_cl = atoi(optarg); break; default: printf("Error: invalid option.\n"); printf("Usage:\n"); printf("./testmanyv -c <cfl> -d <deg> -n <nraf> -t <tmax> -C\n -P <cl platform number> -D <cl device number> FIXME"); exit(1); } } bool test = true; field f; init_empty_field(&f); f.varindex = GenericVarindex; f.model.m = 9; f.model.cfl = cfl; strcpy(f.model.name,"MHD"); f.model.NumFlux=MHDNumFluxP2; f.model.BoundaryFlux=MHDBoundaryFlux; f.model.InitData=MHDInitData; f.model.ImposedData=MHDImposedData; char buf[1000]; sprintf(buf, "-D _M=%d", f.model.m); strcat(cl_buildoptions, buf); sprintf(numflux_cl_name, "%s", "MHDNumFluxP2"); sprintf(buf," -D NUMFLUX="); strcat(buf, numflux_cl_name); strcat(cl_buildoptions, buf); sprintf(buf, " -D BOUNDARYFLUX=%s", "MHDBoundaryFlux"); strcat(cl_buildoptions, buf); // Set the global parameters for the Vlasov equation f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 1; // x direction degree f.interp.interp_param[2] = 1; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 10; // x direction refinement f.interp.interp_param[5] = 10; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement //set_vlasov_params(&(f.model)); // Read the gmsh file //ReadMacroMesh(&(f.macromesh), "test/testcartesiangrid2d2.msh"); ReadMacroMesh(&(f.macromesh), "test/testOTgrid.msh"); //ReadMacroMesh(&(f.macromesh), "test/testcube.msh"); // Try to detect a 2d mesh Detect2DMacroMesh(&(f.macromesh)); bool is2d=f.macromesh.is2d; assert(is2d); f.macromesh.period[0]=6.2831853; f.macromesh.period[1]=6.2831853; // Mesh preparation BuildConnectivity(&(f.macromesh)); // Prepare the initial fields Initfield(&f); // Prudence... CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); Plotfield(0, (1==0), &f, "Rho", "dginit.msh"); f.vmax=vmax; real executiontime; if(usegpu) { printf("Using OpenCL:\n"); //executiontime = seconds(); //assert(1==2); RK2(&f, tmax, dt); //executiontime = seconds() - executiontime; } else { printf("Using C:\n"); //executiontime = seconds(); RK2(&f, tmax, dt); //executiontime = seconds() - executiontime; } Plotfield(0,false,&f, "Rho", "dgvisu.msh"); Gnuplot(&f,0,0.0,"data1D.dat"); printf("tmax: %f, cfl: %f\n", tmax, f.model.cfl); printf("deltax:\n"); printf("%f\n", f.hmin); printf("deltat:\n"); printf("%f\n", dt); printf("DOF:\n"); printf("%d\n", f.wsize); printf("executiontime (s):\n"); printf("%f\n", executiontime); printf("time per RK2 (s):\n"); printf("%f\n", executiontime / (real)f.itermax); return test; }
int TestfieldSubCellDGVol() { int test = true; field f; init_empty_field(&f); f.model.cfl = 0.05; f.model.m = 1; // only one conservative variable f.model.NumFlux = TransNumFlux; f.model.BoundaryFlux = TestTransBoundaryFlux; f.model.InitData = TestTransInitData; f.model.ImposedData = TestTransImposedData; f.varindex = GenericVarindex; f.interp.interp_param[0] = 1; // _M f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 2; // z direction degree f.interp.interp_param[4] = 2; // x direction refinement f.interp.interp_param[5] = 2; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement ReadMacroMesh(&f.macromesh, "../test/testcube.msh"); //ReadMacroMesh(&f.macromesh,"test/testdisque.msh"); BuildConnectivity(&f.macromesh); PrintMacroMesh(&f.macromesh); //AffineMapMacroMesh(&f.macromesh); PrintMacroMesh(&f.macromesh); Initfield(&f); CheckMacroMesh(&f.macromesh, f.interp.interp_param + 1); real tnow = 0.0; for(int ie = 0;ie < f.macromesh.nbelems; ie++) DGMacroCellInterfaceSlow((void*) (f.mcell+ie), &f, f.wn, f.dtwn); for(int ie = 0; ie < f.macromesh.nbelems; ie++) { DGSubCellInterface((void*) (f.mcell+ie), &f, f.wn, f.dtwn); DGVolume((void*) (f.mcell+ie), &f, f.wn, f.dtwn); DGMass((void*) (f.mcell+ie), &f, f.dtwn); DGSource((void*) (f.mcell+ie), &f, tnow, f.wn, f.dtwn); } /* DGMacroCellInterfaceSlow(&f); */ /* DGSubCellInterface(&f); */ /* DGVolume(&f); */ /* DGMass(&f); */ Displayfield(&f); /* Plotfield(0, false, &f, NULL, "visu.msh"); */ /* Plotfield(0, true, &f, "error", "error.msh"); */ // test the time derivative with the exact solution int *raf = f.interp.interp_param + 4; int *deg = f.interp.interp_param + 1; for(int i=0; i < f.model.m * f.macromesh.nbelems * NPG(raf, deg); i++) { test = test && fabs(4 * f.wn[i] - pow(f.dtwn[i] , 2)) < 1e-2; assert(test); } return test; }
// some unit tests of the macromesh code int TestPICAccumulate(void) { MacroMesh m; bool test=true; int param[]={4, 4, 4, 1, 1, 1, 0}; field f; init_empty_field(&f); // test gmsh file reading ReadMacroMesh(&(f.macromesh), "test/testmacromesh.msh"); BuildConnectivity(&(f.macromesh)); CheckMacroMesh(&(f.macromesh), param); //PrintMacroMesh(&m); PIC pic; InitPIC(&pic,1); CreateParticles(&pic,&(f.macromesh)); PlotParticles(&pic,&(f.macromesh)); f.model.m = 7; // num of conservative variables /* f.model.NumFlux = Maxwell2DNumFlux; */ /* f.model.BoundaryFlux = Maxwell2DBoundaryFlux; */ f.model.InitData = Maxwell2DConstInitData; /* f.model.ImposedData = Maxwell2DImposedData; */ f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 1; // x direction degree f.interp.interp_param[2] = 1; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 1; // x direction refinement f.interp.interp_param[5] = 1; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement Initfield(&f); // place the particle at (0,1,0) and v=(1,0,0) pic.xv[0]=0; pic.xv[1]=0; pic.xv[2]=0.5; real xref[3]; pic.cell_id[0]=NumElemFromPoint(&f.macromesh,pic.xv,xref); pic.xv[0]=xref[0]; pic.xv[1]=xref[1]; pic.xv[2]=xref[2]; pic.xv[3]=1; pic.xv[4]=0; pic.xv[5]=0; PlotParticles(&pic,&(f.macromesh)); int ie=2; int ipg=2; int iv=4; int imem=f.varindex(f.interp_param, ie, ipg, iv); AccumulateParticles(&pic,&f); printf("w=%f wex=%f\n",f.wn[imem],1/1.96); test = test && (fabs(f.wn[imem]-1/1.96) < 1e-8); Displayfield(&f); return test; }
int TestPoisson(void) { bool test = true; field f; init_empty_field(&f); int vec=1; // num of conservative variables f(vi) for each vi, phi, E, rho, u, // p, e (ou T) f.model.m=_MV+6; f.vmax = _VMAX; // maximal wave speed f.model.NumFlux = VlasovP_Lagrangian_NumFlux; f.model.Source = VlasovP_Lagrangian_Source; //f.model.Source = NULL; f.model.BoundaryFlux = TestPoisson_BoundaryFlux; f.model.InitData = TestPoisson_InitData; f.model.ImposedData = TestPoisson_ImposedData; f.varindex = GenericVarindex; f.pre_dtfield = NULL; f.update_after_rk = NULL; f.interp.interp_param[0] = f.model.m; // _M f.interp.interp_param[1] = 3; // x direction degree f.interp.interp_param[2] = 0; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 32; // x direction refinement f.interp.interp_param[5] = 1; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // read the gmsh file ReadMacroMesh(&(f.macromesh),"../test/testcube.msh"); // try to detect a 2d mesh //bool is1d=Detect1DMacroMesh(&(f.macromesh)); Detect1DMacroMesh(&(f.macromesh)); bool is1d=f.macromesh.is1d; assert(is1d); // mesh preparation BuildConnectivity(&(f.macromesh)); PrintMacroMesh(&(f.macromesh)); //assert(1==2); //AffineMapMacroMesh(&(f.macromesh)); // prepare the initial fields Initfield(&f); f.nb_diags=0; // prudence... CheckMacroMesh(&(f.macromesh),f.interp.interp_param+1); printf("cfl param =%f\n",f.hmin); // time derivative //dtField(&f); //DisplayField(&f); //assert(1==2); // apply the DG scheme // time integration by RK2 scheme // up to final time = 1. /*Compute_electric_field(&f); // check the gradient on every glop for(int ie=0;ie<f.macromesh.nbelems;ie++){ printf("elem %d\n",ie); for(int ipg=0;ipg<NPG(f.interp_param+1);ipg++){ real xref[3],wpg; ref_pg_vol(f.interp_param+1,ipg,xref,&wpg,NULL); printf("Gauss point %d %f %f %f \n",ipg,xref[0],xref[1],xref[2]); int imem=f.varindex(f.interp_param,ie,ipg,_MV+1); printf("gradphi exact=%f gradphinum=%f\n",1-2*xref[0],f.wn[imem]); test=test && (fabs(f.wn[imem]-(1-2*xref[0]))<1e-10); } }*/ //Computation_charge_density(f); SolvePoisson1D(&f,f.wn,1,0.0,0.0,LU,NONE); // check the gradient given by the poisson solver for(int ie=0;ie<f.macromesh.nbelems;ie++){ MacroCell *mcell = f.mcell + ie; for(int ipg=0;ipg<NPG(mcell->raf, mcell->deg);ipg++){ real xref[3],wpg; int *raf = f.interp_param+4; int *deg = f.interp_param+1; ref_pg_vol(raf, deg, ipg, xref, &wpg, NULL); //printf("Gauss point %d %f %f %f \n",ipg,xref[0],xref[1],xref[2]); int imem=f.varindex(f.interp_param, ipg, _MV + 1) + mcell->woffset; // printf("gradphi exact=%f gradphinum=%f rap=%f\n", //1-2*xref[0],f.wn[imem],(1-2*xref[0])/f.wn[imem]); real tolerance; if(sizeof(real) == sizeof(double)) tolerance = 1e-8; else tolerance = 1e-4; test=test && (fabs(f.wn[imem]-(-1+2*xref[0])) < tolerance); } } return test; }
int TestmEq2(void) { bool test = true; field f; init_empty_field(&f); int vec = 2; f.model.cfl = 0.05; if(vec == 2) { f.model.m = 2; // num of conservative variables } else { f.model.m = 1; // num of conservative variables } f.model.NumFlux = VecTransNumFlux2d; f.model.BoundaryFlux = VecTransBoundaryFlux2d; f.model.InitData = VecTransInitData2d; f.model.ImposedData = VecTransImposedData2d; f.varindex = GenericVarindex; f.interp.interp_param[0] = f.model.m; f.interp.interp_param[1] = 2; // x direction degree f.interp.interp_param[2] = 2; // y direction degree f.interp.interp_param[3] = 0; // z direction degree f.interp.interp_param[4] = 4; // x direction refinement f.interp.interp_param[5] = 4; // y direction refinement f.interp.interp_param[6] = 1; // z direction refinement // Read the gmsh file ReadMacroMesh(&(f.macromesh), "test/testcube.msh"); // Try to detect a 2d mesh Detect2DMacroMesh(&(f.macromesh)); assert(f.macromesh.is2d); // Mesh preparation BuildConnectivity(&(f.macromesh)); //AffineMapMacroMesh(&(f.macromesh)); // Prepare the initial fields Initfield(&f); //f.dt = 1e-3; // Prudence... CheckMacroMesh(&(f.macromesh), f.interp.interp_param + 1); printf("cfl param =%f\n", f.hmin); // time derivative //dtfield(&f); //Displayfield(&f); real tmax = 0.1; f.vmax=1; real dt = set_dt(&f); RK2(&f, tmax, dt); // Save the results and the error Plotfield(0, false, &f, NULL, "dgvisu.msh"); Plotfield(0, true, &f, "error", "dgerror.msh"); real dd = L2error(&f); real tolerance = 1e-4; test = test && (dd < tolerance); printf("L2 error: %f\n", dd); return test; };