diff options
Diffstat (limited to 'Source/WarpXEvolve.cpp')
-rw-r--r-- | Source/WarpXEvolve.cpp | 169 |
1 files changed, 32 insertions, 137 deletions
diff --git a/Source/WarpXEvolve.cpp b/Source/WarpXEvolve.cpp index 89a73a978..a92f033b5 100644 --- a/Source/WarpXEvolve.cpp +++ b/Source/WarpXEvolve.cpp @@ -13,137 +13,16 @@ void WarpX::Evolve (int numsteps) { BL_PROFILE_REGION("WarpX::Evolve()"); +#ifdef WARPX_DO_ELECTROSTATIC if (do_electrostatic) { EvolveES(numsteps); } else { EvolveEM(numsteps); } -} - -void -WarpX::EvolveES (int numsteps) { - - amrex::Print() << "Running in electrostatic mode \n"; - - BL_PROFILE("WarpX::EvolveES()"); - Real cur_time = t_new[0]; - static int last_plot_file_step = 0; - static int last_check_file_step = 0; - - int numsteps_max; - if (numsteps < 0) { // Note that the default argument is numsteps = -1 - numsteps_max = max_step; - } else { - numsteps_max = std::min(istep[0]+numsteps, max_step); - } - - bool max_time_reached = false; - - // nodal storage for thee electrostatic case - const int num_levels = max_level + 1; - Vector<std::unique_ptr<MultiFab> > rhoNodal(num_levels); - Vector<std::unique_ptr<MultiFab> > phiNodal(num_levels); - Vector<std::array<std::unique_ptr<MultiFab>, 3> > eFieldNodal(num_levels); - const int ng = 1; - for (int lev = 0; lev <= max_level; lev++) { - BoxArray nba = boxArray(lev); - nba.surroundingNodes(); - rhoNodal[lev].reset(new MultiFab(nba, dmap[lev], 1, ng)); - phiNodal[lev].reset(new MultiFab(nba, dmap[lev], 1, 2)); - - eFieldNodal[lev][0].reset(new MultiFab(nba, dmap[lev], 1, ng)); - eFieldNodal[lev][1].reset(new MultiFab(nba, dmap[lev], 1, ng)); - eFieldNodal[lev][2].reset(new MultiFab(nba, dmap[lev], 1, ng)); - } - - const int lev = 0; - for (int step = istep[0]; step < numsteps_max && cur_time < stop_time; ++step) - { - - // Start loop on time steps - amrex::Print() << "\nSTEP " << step+1 << " starts ...\n"; - - // At initialization, particles have p^{n-1/2} and x^{n-1/2}. - // Beyond one step, particles have p^{n-1/2} and x^{n}. - if (is_synchronized) { - // on first step, push X by 0.5*dt - mypc->PushXES(0.5*dt[lev]); - UpdatePlasmaInjectionPosition(0.5*dt[lev]); - mypc->Redistribute(); - mypc->DepositCharge(rhoNodal); - computePhi(rhoNodal, phiNodal); - computeE(eFieldNodal, phiNodal); - is_synchronized = false; - } - - mypc->FieldGatherES(eFieldNodal, gather_masks); - - const std::string& ppltfile = amrex::Concatenate("particles", istep[0], 5); - auto& pc = mypc->GetParticleContainer(0); - pc.WriteAsciiFile(ppltfile); - - // Evolve particles to p^{n+1/2} and x^{n+1} - mypc->EvolveES(eFieldNodal, rhoNodal, cur_time, dt[lev]); - - mypc->DepositCharge(rhoNodal); - - computePhi(rhoNodal, phiNodal); - computeE(eFieldNodal, phiNodal); - - if (cur_time + dt[0] >= stop_time - 1.e-3*dt[0] || step == numsteps_max-1) { - // on last step, push by only 0.5*dt to synchronize all at n+1/2 - mypc->PushXES(-0.5*dt[lev]); - UpdatePlasmaInjectionPosition(-0.5*dt[lev]); - is_synchronized = true; - } - - mypc->Redistribute(); - - ++istep[0]; - - cur_time += dt[0]; - - bool to_make_plot = (plot_int > 0) && ((step+1) % plot_int == 0); - - amrex::Print()<< "STEP " << step+1 << " ends." << " TIME = " - << cur_time << " DT = " << dt[0] << "\n"; - - // sync up time - for (int i = 0; i <= finest_level; ++i) { - t_new[i] = cur_time; - } - - if (to_make_plot) { - // replace with ES field Gather - mypc->DepositCharge(rhoNodal); - computePhi(rhoNodal, phiNodal); - phiNodal[0]->FillBoundary(Geom(0).periodicity()); - computeE(eFieldNodal, phiNodal); - mypc->FieldGatherES(eFieldNodal, gather_masks); - last_plot_file_step = step+1; - WritePlotFileES(rhoNodal, phiNodal, eFieldNodal); - } - - if (check_int > 0 && (step+1) % check_int == 0) { - last_check_file_step = step+1; - WriteCheckPointFile(); - } - - if (cur_time >= stop_time - 1.e-3*dt[0]) { - max_time_reached = true; - break; - } - - // End loop on time steps - } - - if (plot_int > 0 && istep[0] > last_plot_file_step && (max_time_reached || istep[0] >= max_step)) { - WritePlotFileES(rhoNodal, phiNodal, eFieldNodal); - } - - if (check_int > 0 && istep[0] > last_check_file_step && (max_time_reached || istep[0] >= max_step)) { - WriteCheckPointFile(); - } +#else + EvolveEM(numsteps); +#endif // WARPX_DO_ELECTROSTATIC + } void @@ -402,7 +281,7 @@ WarpX::EvolveB (int lev, Real dt, DtType typ) const Box& tbz = mfi.tilebox(Bz_nodal_flag); // Call picsar routine for each tile - WRPX_PXR_PUSH_BVEC( + warpx_push_bvec( tbx.loVect(), tbx.hiVect(), tby.loVect(), tby.hiVect(), tbz.loVect(), tbz.hiVect(), @@ -412,8 +291,8 @@ WarpX::EvolveB (int lev, Real dt, DtType typ) BL_TO_FORTRAN_3D((*Bx)[mfi]), BL_TO_FORTRAN_3D((*By)[mfi]), BL_TO_FORTRAN_3D((*Bz)[mfi]), - &dtsdx[0], &dtsdx[1], &dtsdx[2], - &norder); + &dtsdx[0], &dtsdx[1], &dtsdx[2], + &WarpX::maxwell_fdtd_solver_id); if (cost) { Box cbx = mfi.tilebox(IntVect{AMREX_D_DECL(0,0,0)}); @@ -434,7 +313,9 @@ WarpX::EvolveB (int lev, Real dt, DtType typ) const auto& pml_E = (ipatch==0) ? pml[lev]->GetE_fp() : pml[lev]->GetE_cp(); const auto& sigba = (ipatch==0) ? pml[lev]->GetMultiSigmaBox_fp() : pml[lev]->GetMultiSigmaBox_cp(); - + int patch_level = (ipatch == 0) ? lev : lev-1; + const std::array<Real,3>& dx = WarpX::CellSize(patch_level); + const std::array<Real,3> dtsdx {dt/dx[0], dt/dx[1], dt/dx[2]}; #ifdef _OPENMP #pragma omp parallel #endif @@ -454,7 +335,9 @@ WarpX::EvolveB (int lev, Real dt, DtType typ) BL_TO_FORTRAN_3D((*pml_B[0])[mfi]), BL_TO_FORTRAN_3D((*pml_B[1])[mfi]), BL_TO_FORTRAN_3D((*pml_B[2])[mfi]), - WRPX_PML_SIGMA_STAR_TO_FORTRAN(sigba[mfi],dttype)); + WRPX_PML_SIGMA_STAR_TO_FORTRAN(sigba[mfi],dttype), + &dtsdx[0], &dtsdx[1], &dtsdx[2], + &WarpX::maxwell_fdtd_solver_id); } } } @@ -531,7 +414,7 @@ WarpX::EvolveE (int lev, Real dt, DtType typ) const Box& tez = mfi.tilebox(Ez_nodal_flag); // Call picsar routine for each tile - WRPX_PXR_PUSH_EVEC( + warpx_push_evec( tex.loVect(), tex.hiVect(), tey.loVect(), tey.hiVect(), tez.loVect(), tez.hiVect(), @@ -545,8 +428,7 @@ WarpX::EvolveE (int lev, Real dt, DtType typ) BL_TO_FORTRAN_3D((*jy)[mfi]), BL_TO_FORTRAN_3D((*jz)[mfi]), &mu_c2_dt, - &dtsdx_c2[0], &dtsdx_c2[1], &dtsdx_c2[2], - &norder); + &dtsdx_c2[0], &dtsdx_c2[1], &dtsdx_c2[2]); if (F) { WRPX_CLEAN_EVEC(tex.loVect(), tex.hiVect(), @@ -729,9 +611,22 @@ void WarpX::ComputeDt () { const Real* dx = geom[max_level].CellSize(); - const Real deltat = cfl * 1./( std::sqrt(AMREX_D_TERM( 1./(dx[0]*dx[0]), - + 1./(dx[1]*dx[1]), - + 1./(dx[2]*dx[2]))) * PhysConst::c ); + Real deltat = 0.; + + if (maxwell_fdtd_solver_id == 0) { + // CFL time step Yee solver + deltat = cfl * 1./( std::sqrt(AMREX_D_TERM( 1./(dx[0]*dx[0]), + + 1./(dx[1]*dx[1]), + + 1./(dx[2]*dx[2]))) * PhysConst::c ); + } else { + // CFL time step CKC solver +#if (BL_SPACEDIM == 3) + const Real delta = std::min(dx[0],std::min(dx[1],dx[2])); +#elif (BL_SPACEDIM == 2) + const Real delta = std::min(dx[0],dx[1]); +#endif + deltat = cfl*delta/PhysConst::c; + } dt.resize(0); dt.resize(max_level+1,deltat); |