diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 5422ae8296..5922ed2bd4 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -1066,6 +1066,11 @@ Please make sure to always clear or rename the output folder before running a ne available. If both Adios2 and HDF5 are available, ``h5`` is used. Note that ``json`` is extremely slow and is not recommended for production runs. +* ``hipace.output_iteration_offset`` (`integer`) optional (default `0`) + Iteration number of the diagnostic output of the first computed time step. + This applies to both openPMD and in-situ diagnostics. Useful when restarting a simulation and + combining the outputs when used together with ``hipace.initial_time``. + Beam diagnostics ^^^^^^^^^^^^^^^^ diff --git a/src/Hipace.H b/src/Hipace.H index 240e357775..c9b10001df 100644 --- a/src/Hipace.H +++ b/src/Hipace.H @@ -192,8 +192,6 @@ public: inline static Hipace* m_instance = nullptr; /** Whether to use normalized units */ inline static bool m_normalized_units = false; - /** Default location for diagnostics output */ - inline static std::string m_output_folder = "diags"; /** All field data (3D array, slices) and field methods */ Fields m_fields; /** Contains all beam species */ @@ -334,6 +332,13 @@ public: /** Owns data for m_grid_external_fields */ amrex::Array m_grid_external_fields_parser; + // Diagnostic + + /** Default location for diagnostics output */ + inline static std::string m_output_folder = "diags"; + /** iteration number written in diagnostic of first computed step */ + inline static int m_output_iteration_offset = 0; + private: #ifdef AMREX_USE_LINEAR_SOLVERS diff --git a/src/Hipace.cpp b/src/Hipace.cpp index 5d551e7dab..2a4990c0ab 100644 --- a/src/Hipace.cpp +++ b/src/Hipace.cpp @@ -199,6 +199,8 @@ Hipace::ReadParameters () "boundary.field = Dirichlet\n" "boundary.particle = Absorbing\n", true); + queryWithParser(pph, "output_iteration_offset", m_output_iteration_offset); + amrex::ParmParse ppb("boundary"); std::string field_boundary = ""; getWithParser(ppb, "field", field_boundary); @@ -1322,12 +1324,13 @@ Hipace::WriteDiagnostics (const int step) { #ifdef HIPACE_USE_OPENPMD if (m_diags.hasAnyFieldOutput(step, m_max_step, m_physical_time, m_max_time)) { - m_openpmd_writer.WriteFieldDiagnostics(m_diags.getFieldData(), - m_multi_laser, m_physical_time, step); + m_openpmd_writer.WriteFieldDiagnostics(m_diags.getFieldData(), m_multi_laser, + m_physical_time, step + m_output_iteration_offset); } if (m_diags.hasBeamOutput(step, m_max_step, m_physical_time, m_max_time)) { - m_openpmd_writer.WriteBeamDiagnostics(m_multi_beam, m_physical_time, step, + m_openpmd_writer.WriteBeamDiagnostics(m_multi_beam, + m_physical_time, step + m_output_iteration_offset, getDiagBeamNames(), m_3D_geom); } #else diff --git a/src/fields/Fields.cpp b/src/fields/Fields.cpp index 6b2bb175af..b4ce1a7619 100644 --- a/src/fields/Fields.cpp +++ b/src/fields/Fields.cpp @@ -1433,6 +1433,7 @@ Fields::InSituWriteToFile (int step, amrex::Real time, const amrex::Geometry& ge std::ofstream ofs{m_insitu_file_prefix + "/reduced_fields." + pad_rank_num + ".txt", std::ofstream::out | std::ofstream::app | std::ofstream::binary}; + const int out_step = step + Hipace::m_output_iteration_offset; const int nslices_int = geom3D.Domain().length(2); const std::size_t nslices = static_cast(nslices_int); const int is_normalized_units = Hipace::m_normalized_units; @@ -1441,7 +1442,7 @@ Fields::InSituWriteToFile (int step, amrex::Real time, const amrex::Geometry& ge // avoid pointers to temporary objects as second argument, stack variables are ok const amrex::Vector all_data{ {"time" , &time}, - {"step" , &step}, + {"step" , &out_step}, {"n_slices" , &nslices_int}, {"z_lo" , &geom3D.ProbLo()[2]}, {"z_hi" , &geom3D.ProbHi()[2]}, diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 7f5cea1a1e..2580a698cf 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -1064,6 +1064,7 @@ MultiLaser::InSituWriteToFile (int step, amrex::Real time, int max_step, amrex:: std::ofstream ofs{m_insitu_file_prefix + "/reduced_laser." + pad_rank_num + ".txt", std::ofstream::out | std::ofstream::app | std::ofstream::binary}; + const int out_step = step + Hipace::m_output_iteration_offset; const int nslices_int = m_laser_geom_3D.Domain().length(2); const std::size_t nslices = static_cast(nslices_int); const int is_normalized_units = Hipace::m_normalized_units; @@ -1072,7 +1073,7 @@ MultiLaser::InSituWriteToFile (int step, amrex::Real time, int max_step, amrex:: // avoid pointers to temporary objects as second argument, stack variables are ok const amrex::Vector all_data{ {"time" , &time}, - {"step" , &step}, + {"step" , &out_step}, {"n_slices" , &nslices_int}, {"z_lo" , &m_laser_geom_3D.ProbLo()[2]}, {"z_hi" , &m_laser_geom_3D.ProbHi()[2]}, diff --git a/src/particles/beam/BeamParticleContainer.cpp b/src/particles/beam/BeamParticleContainer.cpp index a7d4cdb88d..1fd6248644 100644 --- a/src/particles/beam/BeamParticleContainer.cpp +++ b/src/particles/beam/BeamParticleContainer.cpp @@ -634,6 +634,7 @@ BeamParticleContainer::InSituWriteToFile (int step, amrex::Real time, const amre const amrex::Real sum_w0_inv = m_insitu_sum_rdata[0] <= 0._rt ? 0._rt : 1._rt / m_insitu_sum_rdata[0]; + const int out_step = step + Hipace::m_output_iteration_offset; const std::size_t nslices = static_cast(m_nslices); const amrex::Real normalized_density_factor = Hipace::m_normalized_units ? geom.CellSizeArray().product() : 1; // dx * dy * dz in normalized units, 1 otherwise @@ -643,7 +644,7 @@ BeamParticleContainer::InSituWriteToFile (int step, amrex::Real time, const amre // avoid pointers to temporary objects as second argument, stack variables are ok amrex::Vector all_data{ {"time" , &time}, - {"step" , &step}, + {"step" , &out_step}, {"n_slices", &m_nslices}, {"charge" , &m_charge}, {"mass" , &m_mass}, diff --git a/src/particles/plasma/PlasmaParticleContainer.cpp b/src/particles/plasma/PlasmaParticleContainer.cpp index 03f9b83603..2181762e23 100644 --- a/src/particles/plasma/PlasmaParticleContainer.cpp +++ b/src/particles/plasma/PlasmaParticleContainer.cpp @@ -937,6 +937,7 @@ PlasmaParticleContainer::InSituWriteToFile (int step, amrex::Real time, const am const amrex::Real sum_w0_inv = m_insitu_sum_rdata[0] <= 0._rt ? 0._rt : 1._rt / m_insitu_sum_rdata[0]; + const int out_step = step + Hipace::m_output_iteration_offset; const std::size_t nslices = static_cast(m_nslices); const amrex::Real normalized_density_factor = Hipace::m_normalized_units ? geom.CellSizeArray().product() : 1; // dx * dy * dz in normalized units, 1 otherwise @@ -946,7 +947,7 @@ PlasmaParticleContainer::InSituWriteToFile (int step, amrex::Real time, const am // Avoid pointers to temporary objects as second argument, stack variables are ok const amrex::Vector all_data{ {"time" , &time}, - {"step" , &step}, + {"step" , &out_step}, {"n_slices", &m_nslices}, {"charge" , &m_charge}, {"mass" , &m_mass},