void PositivityState::update(double minval_in, double dt_in) { double d_minval = minval_in - minval; double d_dt = dt_in - dt; if(d_minval!=0) { double ratio = d_dt/d_minval; // assumes an approximately linear relationship between dt and minval double suggested_dt = dt-d_dt/d_minval*minval; double suggested_cflChangeFactor = (suggested_dt/dt)*.99; if(minval_in < 0.) dprint1(suggested_cflChangeFactor); } set_minval(minval_in); set_dt(dt_in); if(minval_in<0.) { increaseStringency(); stepsWithoutViolation=0; } else { stepsWithoutViolation++; } //if(stepsWithoutViolation>=1024) //{ // dprint1("resetting stringency"); // resetStringency(); //} }
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; };
bool BDSimulator::step(const Real& upto) { const Real t0(t()), dt0(dt()), tnext(next_time()); if (upto <= t0) { return false; } if (upto >= tnext) { step(); return true; } else { set_dt(upto - t0); step(); set_dt(dt0); return false; } }
void Sub3::actual_read(const std::string & data) { set_dt(toint(data, 256)); }
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; }
// Lax-Wendroff time stepping // // TODO - I guess the idea is to try and incorporate this into DogSolve? I // don't see how this can be done with this method for all dimensions ... (-DS) void DogSolverCart2::DogSolveLxW(double tstart, double tend) { // Data that needs to be updated. qold -> qnew at time t=tend. dTensorBC4& qnew = fetch_state().fetch_q(); dTensorBC4& aux = fetch_state().fetch_aux(); dTensorBC4& qold = fetch_state_old().fetch_q(); dTensorBC4& auxold = fetch_state_old().fetch_aux(); dTensorBC3& smax = fetch_smax(); // access constant data const int time_order = dogParams.get_time_order(); const int nv = dogParams.get_nv(); const double* cflv = dogParams.get_cflv(); // TODO: can use dogParamsCart2 to get these variables: const int mx = qnew.getsize(1); const int my = qnew.getsize(2); const int meqn = qnew.getsize(3); const int kmax = qnew.getsize(4); const int mbc = qnew.getmbc(); const int maux = aux.getsize(3); // ------------------------------------------------------------ // Function definitions void CopyQ(const dTensorBC4& qin,dTensorBC4& qout); // ------------------------------------------------------------ // define local variables int n_step = 0; double t = tstart; double dt = get_dt(); const double CFL_max = cflv[1]; const double CFL_target = cflv[2]; // Example of using extra information and intermediate stages: dTensorBC4 qstar(mx, my, meqn, kmax, mbc); dTensorBC4 auxstar(mx, my, maux, kmax, mbc); // This memory should have already been allocated: // (otherwise, can allocate it here, as in above): dTensorBC4& L = fetch_L(); // Set initialize qstar and auxstar values CopyQ(qold, qstar); CopyQ(aux, auxstar); // User-defined time stepping while (t<tend) { // initialize time step int m_accept = 0; n_step = n_step + 1; // check if max number of time steps exceeded if (n_step>nv) { eprintf(" Error in DogSolveUser.cpp: " " Exceeded allowed # of time steps \n" " n_step = %d\n" " nv = %d\n\n", n_step,nv); } // copy qnew into qold CopyQ(qnew, qold); CopyQ(aux, auxold); // keep trying until we get a dt that does not violate CFL condition while (m_accept==0) { // set current time double told = t; if (told+dt > tend) { dt = tend - told; } t = told + dt; fetch_state().set_time(told); dogParams.set_time(told); // TODO set_dt(dt); // Set initial maximum wave speed to zero // // TODO : CAN CALL reset smax or something ... for (int j=1-mbc; j<=(my+mbc); j++) { for (int i=1-mbc; i<=(mx+mbc); i++) { smax.set(i, j, 1, 0.0e0 ); smax.set(i, j, 2, 0.0e0 ); } } BeforeStep(dt,aux,qnew,*this); void SetBndValues(dTensorBC4&,dTensorBC4&); SetBndValues(qnew,aux); // Construct RHS for LxW formulation: void LaxWendroff(double dt, double alpha1, double beta1, dTensorBC4& aux, dTensorBC4& q, dTensorBC4& Lstar, dTensorBC3& smax); LaxWendroff(dt, 1.0, 0.5, aux, qnew, L, smax); // Take a single "Euler" time step: void StepLxW( double dt, const dTensorBC4& qold, const dTensorBC4& L, dTensorBC4& qnew ); StepLxW(dt, qnew, L, qnew); if(dogParams.using_moment_limiter()) { ::ApplyLimiter(aux,qnew,&ProjectRightEig,&ProjectLeftEig); } AfterStep(dt, aux, qnew, *this); // ---------------------------------------------------------------- // compute cfl number double cfl = GetCFL(dt); // output time step information if (dogParams.get_verbosity()>0) { printf("DogSolve2D ... Step %5d" " CFL =%6.3f" " dt =%11.3e" " t =%11.3e\n", n_step,cfl,dt,t); } // choose new time step if (cfl>0.0) { dt = Min(dogParams.get_max_dt(),dt*CFL_target/cfl); } else { dt = dogParams.get_max_dt(); } // see whether to accept or reject this step if (cfl<=CFL_max) // accept { m_accept = 1; // do any extra work ::AfterFullTimeStep(fetch_solver()); } else //reject { t = told; if (dogParams.get_verbosity()>0) { printf("DogSolve2D rejecting step..." "CFL number too large\n"); } // copy qold into qnew CopyQ(qold, qnew); CopyQ(auxold, aux); } } // compute conservation and print to file ConSoln(aux,qnew,t); } // set initial time step for next call to DogSolveUser set_dt(dt); }
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 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; };
// semi-lagrangian solver void DogSolverCart2::DogSolveUser(double tstart, double tend) { // this accomodates the maximum number of stages allowed for the // split method ... and is a work in progress ... const int MAX_STAGES = 13; const edge_data& EdgeData = Legendre2d::instance().get_edgeData(); dTensorBC3& smax = fetch_smax(); DogStateCart2* dogStateCart2 = &fetch_state(); dTensorBC4& qnew = fetch_state().fetch_q(); dTensorBC4& qold = fetch_state_old().fetch_q(); dTensorBC4& aux = fetch_state().fetch_aux(); const int nv = dogParams.get_nv(); const double* cflv = dogParams.get_cflv(); // -------------------------------------------------------------- // define local variables int m_accept; const int mx = qnew.getsize(1); const int my = qnew.getsize(2); const int maux = aux.getsize(3); const int meqn = qnew.getsize(3); const int kmax = qnew.getsize(4); const int mbc = qnew.getmbc(); const int ndims = 2; int n_step = 0; double t = tstart; double tn = t; double told = 0.0; double dt = get_dt(); const double CFL_max = cflv[1]; const double CFL_target = cflv[2]; double cfl = 0.0; double dtmin = dt; double dtmax = dt; dTensorBC4 qstar(mx,my,meqn,kmax,mbc); //temporary place holder dTensorBC4 aux_old(mx,my,maux,kmax,mbc); ////////////////////////////////////////////////////////////////////////// // Setup for manipulating velocities. Store 2 arrays, 1 for each velocity ////////////////////////////////////////////////////////////////////////// // array for storing advection speeds in each cell const int mpoints = int((1+4*kmax-int(sqrt(1+8*kmax)))/2); const int mpoints1d = int(sqrt(mpoints)); const int morder = mpoints1d; dTensorBC2 u1(my, mpoints1d, mbc, ndims-1); // speed, u(y) (ndims == 1 ) dTensorBC2 u2(mx, mpoints1d, mbc, ndims-1); // speed, v(x) (ndims == 1 ) ////////Set up any extra state variables associated with this problem ///// SL_state sl_state; sl_state.split_time = new dTensor2(MAX_STAGES, 2); sl_state.aux1d = new dTensorBC4( Max(mx,my), 2, 4, mpoints1d, mbc, 1); sl_state.node1d = new dTensor2(mx+1,1); for( int i=1; i <=(mx+1); i++) { sl_state.node1d->set(i, 1, dogParamsCart2.get_xl(i) ); } sl_state.qold = &qold; sl_state.qnew = &qnew; const double dx = dogParamsCart2.get_dx(); const double dy = dogParamsCart2.get_dy(); // sample grid points (gauss points) dTensor2* spts = new dTensor2(mpoints, 2); //legendre polys evaluated at spts dTensor2 phi(mpoints, kmax); dTensor1 x1d(mpoints1d); dTensor1 wgt(mpoints1d); void setGaussPoints1d(dTensor1& w1d, dTensor1& x1d); setGaussPoints1d(wgt, x1d); // Tensor product Gaussian Quadrature // See note at top of code in how mpoints are arranged here... int k=0; for (int m1=1; m1<=(mpoints1d); m1++) for (int m2=1; m2<=(mpoints1d); m2++) { k = k+1; //save gauss quad grid point location on interval [-1,1]^2 spts->set(k,2, x1d.get(m1) ); spts->set(k,1, x1d.get(m2) ); } //evaluate the legendre polynomials at sample points for(int m=1; m <= mpoints; m++) { double xi, xi2,xi3,xi4, eta, eta2,eta3,eta4; //find xi and eta (point to be evaluated) xi = spts->get(m,1); eta = spts->get(m,2); xi2 = xi*xi; xi3 = xi*xi2; xi4 = xi*xi3; eta2 = eta*eta; eta3 = eta*eta2; eta4 = eta*eta3; // Legendre basis functions evaluated at (xi,eta) in the // interval [-1,1]x[-1,1]. switch( mpoints1d ) { case 5: // fifth order phi.set( m,15, 105.0/8.0*eta4 - 45.0/4.0*eta2 + 9.0/8.0 ); phi.set( m,14, 105.0/8.0*xi4 - 45.0/4.0*xi2 + 9.0/8.0 ); phi.set( m,13, 5.0/4.0*(3.0*xi2 - 1.0)*(3.0*eta2 - 1.0) ); phi.set( m,12, sq3*sq7*(2.5*eta3 - 1.5*eta)*xi ); phi.set( m,11, sq3*sq7*(2.5*xi3 - 1.5*xi)*eta ); case 4: // fourth order phi.set( m,10, sq7*(2.5*eta3 - 1.5*eta) ); phi.set( m,9, sq7*(2.5*xi3 - 1.5*xi) ); phi.set( m,8, sq3*sq5*xi*(1.5*eta2 - 0.5) ); phi.set( m,7, sq3*sq5*eta*(1.5*xi2 - 0.5) ); case 3: // third order phi.set( m,6, sq5*(1.5*eta2 - 0.5) ); phi.set( m,5, sq5*(1.5*xi2 - 0.5) ); phi.set( m,4, 3.0*xi*eta ); case 2: // second order phi.set( m,3, sq3*eta ); phi.set( m,2, sq3*xi ); case 1: // first order phi.set( m,1, 1.0 ); } }//end of evaluating legendre polys at sample grid points indexed by spts delete spts; /////////////////////////////////////////////////////////////////////////// double time1, time2; // running time values time1 = GetTime(); //running time for this program (can remove this..) // fourth order splitting coefficients dTensor1* dt_stages; if( dogParams.get_time_order() >= 2 ) { dt_stages = new dTensor1(MAX_STAGES); sl_state.dt_stages = dt_stages; } /////////////////////////////////////////////////////////////////////////// // Main Time Stepping Loop /////////////////////////////////////////////////////////////////////////// while (t<tend) { // initialize time step m_accept = 0; n_step = n_step + 1; // check if max number of time steps exceeded if (n_step>nv) { cout << " Error in DogSolveAdvec.cpp: "<< " Exceeded allowed # of time steps " << endl; cout << " n_step = " << n_step << endl; cout << " nv = " << nv << endl; cout << endl; exit(1); } // copy qnew and aux in case we reject the step CopyQ(qnew,qold); CopyQ(qnew,qstar); CopyQ(aux,aux_old); // keep trying until we get a dt that does not violate CFL condition while (m_accept==0) { // set current time told = t; tn = t; if (told+dt > tend) { dt = tend - told; } t = told + dt; // Set initial maximum wave speed to zero (this will be saved in // SetAdvecSpeed) for (int i=(1-mbc); i<=(mx+mbc); i++) for (int j=(1-mbc); j<=(my+mbc); j++) { smax.set(i,j,1, 0.0e0 ); smax.set(i,j,2, 0.0e0 ); } sl_state.dt = dt; sl_state.t = sl_state.tn = tn; void InitSLState( const dTensorBC4& q, const dTensorBC4& aux, SL_state& sl_state ); InitSLState( qnew, aux, sl_state ); CopyQ(qold, qstar); ///////////////////////////////////// // Perform a full time step ///////////////////////////////////// switch ( dogParams.get_time_order() ) { case 0: // used for testing - dont' take any time steps! BeforeStep (dt, aux, qnew, *this); AfterStep (dt, aux, qnew, *this); perror( " case 0: Not taking a time step! " ); break; case 1: // 1st order in time, no corrections sl_state.t = tn; BeforeStep(dt, aux, qstar, *this); SetAdvecSpeed(phi, qstar, aux, smax, 1, u1, u2, sl_state); SetAdvecSpeed(phi, qstar, aux, smax, 2, u1, u2, sl_state); StepAdvec(dt, qold, qstar, aux, u1, u2, 1, sl_state); StepAdvec(dt, qstar, qnew, aux, u1, u2, 2, sl_state); break; case 2: // 2nd order in time (strang split method) SetSplitTime(dt, 2, tn, sl_state, dt_stages ); sl_state.stage_num = 1; sl_state.t = tn; SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state ); // Poisson solve called in BeforeStep for VP system // BeforeStep(dt, aux, qstar ); sl_state.stage_num = 2; BeforeStep(dt, aux, qnew, *this); sl_state.t = tn; SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(dt, qnew, qstar, aux, u1, u2, 2, sl_state ); sl_state.stage_num = 3; sl_state.t = tn + 0.5*dt; StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state); break; case 4: // 4th order method (Yoshida Splitting) // initial setup ... Save all appropriate times into SL_state SetSplitTime(dt, 4, tn, sl_state, dt_stages ); /////////////////////////////////////////////////////////// ///// There are 7 stages for Yoshida Splitting ///// /////////////////////////////////////////////////////////// ///////// stage 1: A ////////////////////////////////////// sl_state.stage_num = 1; sl_state.t = sl_state.split_time->get(1,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 2: B ////////////////////////////////////// sl_state.stage_num = 2; sl_state.t = sl_state.split_time->get(2,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 3: A ////////////////////////////////////// sl_state.stage_num = 3; sl_state.t = sl_state.split_time->get(3,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 4: B ////////////////////////////////////// sl_state.stage_num = 4; sl_state.t = sl_state.split_time->get(4,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 5: A ////////////////////////////////////// sl_state.stage_num = 5; sl_state.t = sl_state.split_time->get(5,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state); ///////// stage 6: B ////////////////////////////////////// sl_state.stage_num = 6; sl_state.t = sl_state.split_time->get(6,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 7: A ////////////////////////////////////// sl_state.stage_num = 7; sl_state.t = sl_state.split_time->get(7,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); //////////////// --- Experimental New Time Stepping --- /////////////////// // ///////// stage 1: A ////////////////////////////////////// // sl_state.stage_num = 1; // sl_state.t = sl_state.split_time->get(1,1); // SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); // ///////// stage 2: B ////////////////////////////////////// // sl_state.stage_num = 2; // sl_state.t = sl_state.split_time->get(2,2); // SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 3: A ////////////////////////////////////// // sl_state.stage_num = 3; // sl_state.t = sl_state.split_time->get(3,1); // StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 4: B ////////////////////////////////////// // sl_state.stage_num = 4; // sl_state.t = sl_state.split_time->get(4,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 5: A ////////////////////////////////////// // sl_state.stage_num = 5; // sl_state.t = sl_state.split_time->get(5,1); // StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state); // ///////// stage 6: B ////////////////////////////////////// // sl_state.stage_num = 6; // sl_state.t = sl_state.split_time->get(6,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 7: A ////////////////////////////////////// // sl_state.stage_num = 7; // sl_state.t = sl_state.split_time->get(7,1); // StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 8: B ////////////////////////////////////// // sl_state.stage_num = 8; // sl_state.t = sl_state.split_time->get(8,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(8), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 9: A ////////////////////////////////////// // sl_state.stage_num = 9; // sl_state.t = sl_state.split_time->get(9,1); // StepAdvec(sl_state.dt_stages->get(9), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 10: B ////////////////////////////////////// // sl_state.stage_num = 10; // sl_state.t = sl_state.split_time->get(10,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(10), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 11: A ////////////////////////////////////// // sl_state.stage_num = 11; // sl_state.t = sl_state.split_time->get(11,1); // StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 12: B ////////////////////////////////////// // sl_state.stage_num = 12; // sl_state.t = sl_state.split_time->get(12,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(12), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 13: A ////////////////////////////////////// // sl_state.stage_num = 13; // sl_state.t = sl_state.split_time->get(13,1); // StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state); //////////////// --- Experimental New Time Stepping --- /////////////////// break; case 6: // 6th order method (SRKN Splitting) // Added by Pierson Guthrey 5/22/2015 // initial setup ... Save all appropriate times into SL_state SetSplitTime(dt, 6, tn, sl_state, dt_stages ); ///////// stage 1: A ////////////////////////////////////// sl_state.stage_num = 1; sl_state.t = sl_state.split_time->get(1,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 2: B ////////////////////////////////////// sl_state.stage_num = 2; sl_state.t = sl_state.split_time->get(2,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 3: A ////////////////////////////////////// sl_state.stage_num = 3; sl_state.t = sl_state.split_time->get(3,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 4: B ////////////////////////////////////// sl_state.stage_num = 4; sl_state.t = sl_state.split_time->get(4,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 5: A ////////////////////////////////////// sl_state.stage_num = 5; sl_state.t = sl_state.split_time->get(5,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 6: B ////////////////////////////////////// sl_state.stage_num = 6; sl_state.t = sl_state.split_time->get(6,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 7: A ////////////////////////////////////// sl_state.stage_num = 7; sl_state.t = sl_state.split_time->get(7,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 8: B ////////////////////////////////////// sl_state.stage_num = 8; sl_state.t = sl_state.split_time->get(8,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(8), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 9: A ////////////////////////////////////// sl_state.stage_num = 9; sl_state.t = sl_state.split_time->get(9,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(9), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 10: B ////////////////////////////////////// sl_state.stage_num = 10; sl_state.t = sl_state.split_time->get(10,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(10), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 11: A ////////////////////////////////////// sl_state.stage_num = 11; sl_state.t = sl_state.split_time->get(11,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 12: B ////////////////////////////////////// sl_state.stage_num = 12; sl_state.t = sl_state.split_time->get(12,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(12), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 13: A ////////////////////////////////////// sl_state.stage_num = 13; sl_state.t = sl_state.split_time->get(13,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state); default: // still here? too bad! Pick a valid time stepping // method fprintf(stderr, "Bad time stepping method chosen in DogSolveAdvec\n"); fprintf(stderr, "dogParams.get_time_order() = %d\n", dogParams.get_time_order()); exit(1); }// end of taking a full time step // compute cfl number cfl = GetCFL(dt); // output time step information if (dogParams.get_verbosity()>0) { cout << setprecision(3); cout << "DogSolve2D ... Step" << setw(5) << n_step; cout << " CFL =" << setw(6) << fixed << cfl; cout << " dt =" << setw(11) << scientific << dt; cout << " t =" << setw(11) << scientific << t << endl; } if (cfl>0.0) { dt = Min(dogParams.get_max_dt(),dt*CFL_target/cfl); } else { dt = dogParams.get_max_dt(); } // see whether to accept or reject this step if (cfl<=CFL_max) { // accept m_accept = 1; dogStateCart2->set_time(t); dogParams.set_time(t); // time hack } else { //reject t = told; if (dogParams.get_verbosity()>0) { cout<<"DogSolve2D rejecting step..."; cout<<"CFL number too large"; cout<<endl; // find index of larger value... int imax = 1; int jmax = 1; int dmax = 1; for( int i = 1; i <= smax.getsize(1); i++ ) for( int j = 1; j <= smax.getsize(2); j++ ) for( int d = 1; d <= ndims; d++ ) { if( smax.get(i,j,d) > smax.get(imax,jmax,dmax) ) { imax = i; jmax = j; dmax = d;} } printf(" imax = %d, jmax = %d, dmax = %d\n", imax, jmax, dmax ); printf(" smax(imax,jmax,dmax) = %3.2e\n", smax.get(imax, jmax, dmax ) ); } // copy qold into qnew CopyQ(qold,qnew); CopyQ(aux_old,aux); } } void AfterFullSLTimeStep( dTensorBC4& aux, dTensorBC4& qnew, double t ); AfterFullSLTimeStep(aux, qnew, t ); // apply the limiter - This way global integrals stay positive void ApplyPosLimiter(const dTensorBC4& aux, dTensorBC4& q); if(dogParams.using_moment_limiter()) { ApplyPosLimiter(aux, qnew); } // compute conservation and print to file ConSoln(aux,qnew,t); } void AfterSLFrame(double dt, dTensorBC4& aux, dTensorBC4& q, DogSolverCart2& solver, SL_state sl_state ); AfterSLFrame(dt, aux, qnew, *this, sl_state ); // set initial time step for next call to DogSolveAdvec set_dt(dt); // Clock the running time for this call to DogSolveAdvec time2 = GetTime(); if(dogParams.get_verbosity()>0) { cout << " DogSolveAdvec Running Time = " << setw(3) << time2 - time1 << " seconds" << endl << endl; } if( dogParams.get_time_order() >= 2 ) { delete dt_stages; } delete sl_state.split_time; delete sl_state.aux1d; delete sl_state.node1d; }
int TestMHD1D(int argc, char *argv[]) { real cfl = 0.2; real tmax = 1.0; 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=MHDNumFluxRusanov; 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", "MHDNumFluxRusanov"); 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] = 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 //set_vlasov_params(&(f.model)); // Read the gmsh file ReadMacroMesh(&(f.macromesh), "test/testcartesiangrid1d.msh"); //ReadMacroMesh(&(f.macromesh), "test/testcube.msh"); // Try to detect a 2d mesh Detect1DMacroMesh(&(f.macromesh)); bool is1d=f.macromesh.is1d; assert(is1d); f.macromesh.period[0]=10; // 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; if(dt <= 0) dt = set_dt(&f); 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; }