void Test_TransportVP_ImposedData(const real *x, const real t, real *w) { for(int i = 0; i <_INDEX_MAX_KIN + 1; i++) { int j = i % _DEG_V; // local connectivity put in function int nel = i / _DEG_V; // element num (TODO : function) real vi = (-_VMAX + nel * _DV + _DV * glop(_DEG_V, j)); w[i] = TransportVP_ImposedKinetic_Data(x, t, vi); } // exact value of the potential and electric field w[_INDEX_PHI] = -x[0]; w[_INDEX_EX] = 1; w[_INDEX_RHO] = 0.; //rho init w[_INDEX_VELOCITY] = 0; // u init w[_INDEX_PRESSURE] = 0; // p init w[_INDEX_TEMP] = 0; // e ou T init }
real local_kinetic_energy(field *f,real *x, real *w) { real wex[_INDEX_MAX]; real l_ke=0; real t=f->tnow; // loop on the finite emlements for(int iel = 0; iel < _NB_ELEM_V; iel++){ // loop on the local glops for(int iloc = 0; iloc < _DEG_V + 1; iloc++){ real omega = wglop(_DEG_V, iloc); real vi = -_VMAX + iel * _DV + _DV * glop(_DEG_V, iloc); int ipg = iloc + iel * _DEG_V; l_ke += omega * _DV * w[ipg] * vi * vi ; } } return l_ke; }
void TestPoisson_ImposedData(const real x[3], const real t,real w[]){ for(int i = 0; i < _INDEX_MAX_KIN + 1; i++){ int j = i%_DEG_V; // local connectivity put in function int nel = i / _DEG_V; // element num (TODO : function) real vi = (-_VMAX + nel * _DV + _DV * glop(_DEG_V, j)); w[i] = 1. / _VMAX; } // exact value of the potential // and electric field w[_INDEX_PHI] = x[0] * (1 - x[0]); w[_INDEX_EX] = -1. + 2. * x[0]; w[_INDEX_RHO] = 2.; //rho init w[_INDEX_VELOCITY] = 0; // u init w[_INDEX_PRESSURE] = 0; // p init w[_INDEX_TEMP] = 0; // e ou T init };
//! \brief compute square of velocity L2 error //! \param[in] w : values of f at glops //! \param[in] x : point of the mesh //! \param[in] t : time //! \param[in] t : type of L2norm. if type_norm=0 this is the //! numerical solution if type_norm=1 this is the error real L2VelError(field *f, real *x, real *w){ real wex[_INDEX_MAX]; real err2 = 0; real t = f->tnow; f->model.ImposedData(x, t, wex); // loop on the finite emlements for(int iel = 0; iel < _NB_ELEM_V; iel++){ // loop on the local glops for(int iloc = 0; iloc < _DEG_V + 1; iloc++){ real omega = wglop(_DEG_V, iloc); real vi = -_VMAX + iel*_DV + _DV * glop(_DEG_V, iloc); int ipg = iloc + iel * _DEG_V; err2 += omega * _DV * (w[ipg] - wex[ipg]) * (w[ipg] - wex[ipg]); } } return err2; }
void TestPeriodic_ImposedData(const real x[3], const real t,real w[]){ real pi=4*atan(1.); for(int i=0;i<_INDEX_MAX_KIN+1;i++){ int j=i%_DEG_V; // local connectivity put in function int nel=i/_DEG_V; // element num (TODO : function) real vi = (-_VMAX+nel*_DV + _DV* glop(_DEG_V,j)); w[i]=cos(2*pi*(x[0]-vi*t)); } // exact value of the potential // and electric field w[_INDEX_PHI]=0; w[_INDEX_EX]=0; w[_INDEX_RHO]=2.; //rho init w[_INDEX_VELOCITY]=0; // u init w[_INDEX_PRESSURE]=0; // p init w[_INDEX_TEMP]=0; // e ou T init };
void VlasovP_Lagrangian_NumFlux(real wL[],real wR[],real* vnorm,real* flux) { for(int i=0;i<_INDEX_MAX_KIN+1;i++){ int j=i%_DEG_V; // local connectivity put in function int nel=i/_DEG_V; // element num (TODO : function) real vn = (-_VMAX+nel*_DV + _DV* glop(_DEG_V,j))*vnorm[0]; real vnp = vn>0 ? vn : 0; real vnm = vn-vnp; flux[i] = vnp * wL[i] + vnm * wR[i]; } // do not change the potential ! // and the electric field flux[_INDEX_PHI]=0; // flux for phi flux[_INDEX_EX]=0; // flux for E flux[_INDEX_RHO]=0; // flux for rho flux[_INDEX_VELOCITY]=0; // flux for u flux[_INDEX_PRESSURE]=0; // flux for p flux[_INDEX_TEMP]=0; // flux for e ou T }
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; }