Skip to content

Commit 822034d

Browse files
committed
Add PICMI functionality
1 parent 436cd80 commit 822034d

File tree

6 files changed

+82
-14
lines changed

6 files changed

+82
-14
lines changed

Docs/source/usage/parameters.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2888,7 +2888,11 @@ Time-Averaged Diagnostics
28882888
This type of diagnostics can be created using ``<diag_name>.diag_type = TimeAveraged``.
28892889
We support only field data and related options from the list at `Full Diagnostics`_.
28902890

2891-
In addition, `TimeAveraged` diagnostic options include:
2891+
.. note::
2892+
2893+
As with ``FullDiagnostics``, ``TimeAveraged`` diagnostics output the initial **instantaneous** conditions of the selected fields on step 0 (unless more specific output intervals exclude output for step 0).
2894+
2895+
In addition, ``TimeAveraged`` diagnostic options include:
28922896

28932897
* ``<diag_name>.time_average_mode`` (`string`, default `none`)
28942898
Describes the operating mode for time averaged field output.

Examples/Physics_applications/laser_ion/inputs_test_2d_laser_ion_acc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ diagInst.hydrogen.plot_filter_function(t,x,y,z,ux,uy,uz) = (uz>=0) * (x<1.0e-6)
213213
diagInst.format = openpmd
214214
diagInst.openpmd_backend = h5
215215

216-
diagTimeAvg.intervals = 100::100 # TODO just write 100 and make step 0 an instantaneous diagnostic and do not forget to document
216+
diagTimeAvg.intervals = 100
217217
diagTimeAvg.diag_type = TimeAveraged
218218
diagTimeAvg.time_average_mode = dynamic_start
219219
diagTimeAvg.average_period_time = 2.67e-15 # period of 800 nm light waves

Examples/Physics_applications/laser_ion/inputs_test_2d_laser_ion_acc_picmi.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@
162162
warpx_openpmd_backend="h5",
163163
)
164164

165+
field_time_avg_diag = picmi.TimeAveragedFieldDiagnostic(
166+
name="diagTimeAvg",
167+
grid=grid,
168+
period=100,
169+
number_of_cells=ncell_field,
170+
data_list=["B", "E", "J", "rho", "rho_electrons", "rho_hydrogen"],
171+
warpx_format="openpmd",
172+
warpx_openpmd_backend="h5",
173+
warpx_time_average_mode="dynamic_start",
174+
warpx_average_period_steps=10,
175+
)
176+
165177
particle_fw_diag = picmi.ParticleDiagnostic(
166178
name="openPMDfw",
167179
period=100,
@@ -292,6 +304,7 @@
292304
# Add full diagnostics
293305
sim.add_diagnostic(particle_diag)
294306
sim.add_diagnostic(field_diag)
307+
sim.add_diagnostic(field_time_avg_diag)
295308
sim.add_diagnostic(particle_fw_diag)
296309
sim.add_diagnostic(particle_bw_diag)
297310
# Add reduced diagnostics

Python/pywarpx/picmi.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3270,6 +3270,57 @@ def diagnostic_initialize_inputs(self):
32703270

32713271
ElectrostaticFieldDiagnostic = FieldDiagnostic
32723272

3273+
class TimeAveragedFieldDiagnostic(FieldDiagnostic):
3274+
"""
3275+
See `Input Parameters <https://warpx.readthedocs.io/en/latest/usage/parameters.html>`__ for more information.
3276+
3277+
Parameters
3278+
----------
3279+
warpx_time_average_mode: str
3280+
Type of time averaging diagnostic
3281+
Supported values include ``"none"``, ``"fixed_start"``, and ``"dynamic_start"``
3282+
3283+
* ``"none"`` for no averaging (instantaneous fields)
3284+
* ``"fixed_start"`` for a diagnostic that averages all fields between the current output step and a fixed point in time
3285+
* ``"dynamic_start"`` for a constant averaging period and output at different points in time (non-overlapping)
3286+
3287+
warpx_average_period_steps: int, optional
3288+
Configures the number of time steps in an averaging period.
3289+
Set this only in the ``"dynamic_start"`` mode and only if ``warpx_average_period_time`` has not already been set.
3290+
Will be ignored in the ``"fixed_start"`` mode (with warning).
3291+
3292+
warpx_average_period_time: float, optional
3293+
Configures the time (SI units) in an averaging period.
3294+
Set this only in the ``"dynamic_start"`` mode and only if ``average_period_steps`` has not already been set.
3295+
Will be ignored in the ``"fixed_start"`` mode (with warning).
3296+
3297+
warpx_average_start_steps: int, optional
3298+
Configures the time step at which time-averaging begins.
3299+
Set this only in the ``"fixed_start"`` mode.
3300+
Will be ignored in the ``"dynamic_start"`` mode (with warning).
3301+
"""
3302+
3303+
def init(self, kw):
3304+
super().init(kw)
3305+
self.time_average_mode = kw.pop("warpx_time_average_mode", None)
3306+
self.average_period_steps = kw.pop("warpx_average_period_steps", None)
3307+
self.average_period_time = kw.pop("warpx_average_period_time", None)
3308+
self.average_start_step = kw.pop("warpx_average_start_step", None)
3309+
3310+
def diagnostic_initialize_inputs(self):
3311+
super().diagnostic_initialize_inputs()
3312+
3313+
self.diagnostic.set_or_replace_attr("diag_type", "TimeAveraged")
3314+
3315+
if "write_species" not in self.diagnostic.argvattrs:
3316+
self.diagnostic.write_species = False
3317+
3318+
self.diagnostic.time_average_mode = self.time_average_mode
3319+
self.diagnostic.average_period_steps = self.average_period_steps
3320+
self.diagnostic.average_period_time = self.average_period_time
3321+
self.diagnostic.average_start_step = self.average_start_step
3322+
3323+
32733324

32743325
class Checkpoint(picmistandard.base._ClassWithInit, WarpXDiagnosticBase):
32753326
"""

Source/Diagnostics/FullDiagnostics.H

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private:
3636
*/
3737
bool m_solver_deposits_current = true;
3838
/** Whether the diagnostics are averaging data over time or not */
39-
TimeAverageType m_time_average_type = TimeAverageType::None;
39+
TimeAverageType m_time_average_mode = TimeAverageType::None;
4040
/** Period to average fields over: in steps */
4141
int m_average_period_steps = -1;
4242
/** Period to average fields over: in seconds */

Source/Diagnostics/FullDiagnostics.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void
5959
FullDiagnostics::DerivedInitData() {
6060
if (m_diag_type == DiagTypes::TimeAveraged) {
6161
auto & warpx = WarpX::GetInstance();
62-
if (m_time_average_type == TimeAverageType::Dynamic) {
62+
if (m_time_average_mode == TimeAverageType::Dynamic) {
6363

6464
// already checked in ReadParameters that only one of the parameters is set
6565
// calculate the other averaging period parameter from the other one, respectively
@@ -128,11 +128,11 @@ FullDiagnostics::ReadParameters ()
128128
pp_diag_name.get("time_average_mode", m_time_average_mode_str);
129129

130130
if (m_time_average_mode_str == "fixed_start") {
131-
m_time_average_type = TimeAverageType::Static;
131+
m_time_average_mode = TimeAverageType::Static;
132132
} else if (m_time_average_mode_str == "dynamic_start") {
133-
m_time_average_type = TimeAverageType::Dynamic;
133+
m_time_average_mode = TimeAverageType::Dynamic;
134134
} else if (m_time_average_mode_str == "none") {
135-
m_time_average_type = TimeAverageType::None;
135+
m_time_average_mode = TimeAverageType::None;
136136
} else {
137137
WARPX_ABORT_WITH_MESSAGE(
138138
"Unknown time averaging mode. Valid entries are: none, fixed_start, dynamic_start"
@@ -146,7 +146,7 @@ FullDiagnostics::ReadParameters ()
146146
"average_period_time", m_average_period_time
147147
);
148148

149-
if (m_time_average_type == TimeAverageType::Static) {
149+
if (m_time_average_mode == TimeAverageType::Static) {
150150
// This fails if users do not specify a start.
151151
pp_diag_name.get("average_start_step", m_average_start_step);
152152
if (m_average_start_step == 0) {
@@ -170,7 +170,7 @@ FullDiagnostics::ReadParameters ()
170170

171171
}
172172

173-
if (m_time_average_type == TimeAverageType::Dynamic) {
173+
if (m_time_average_mode == TimeAverageType::Dynamic) {
174174
// one of the two averaging period options must be set but neither none nor both
175175
if (
176176
(averaging_period_steps_specified && averaging_period_time_specified)
@@ -238,7 +238,7 @@ FullDiagnostics::Flush ( int i_buffer, bool /* force_flush */ )
238238
// to accommodate a user workflow that only uses that type of diagnostic.
239239
// This allows for quicker turnaround in setup by avoiding having to set an additional instantaneous diagnostic.
240240
if (m_diag_type == DiagTypes::TimeAveraged && step > 0) {
241-
if (m_time_average_type == TimeAverageType::Static || m_time_average_type == TimeAverageType::Dynamic) {
241+
if (m_time_average_mode == TimeAverageType::Static || m_time_average_mode == TimeAverageType::Dynamic) {
242242
// Loop over the output levels and divide by the number of steps in the averaging period
243243
for (int lev = 0; lev < nlev_output; ++lev) {
244244
m_sum_mf_output.at(i_buffer).at(lev).mult(1._rt/static_cast<amrex::Real>(m_average_period_steps));
@@ -251,7 +251,7 @@ FullDiagnostics::Flush ( int i_buffer, bool /* force_flush */ )
251251
m_file_min_digits, m_plot_raw_fields, m_plot_raw_fields_guards);
252252

253253
// Reset the values in the dynamic start time-averaged diagnostics after flush
254-
if (m_time_average_type == TimeAverageType::Dynamic) {
254+
if (m_time_average_mode == TimeAverageType::Dynamic) {
255255
for (int lev = 0; lev < nlev_output; ++lev) {
256256
m_sum_mf_output.at(i_buffer).at(lev).setVal(0.);
257257
}
@@ -298,12 +298,12 @@ FullDiagnostics::DoComputeAndPack (int step, bool force_flush)
298298

299299
if (step > 0) {
300300

301-
if (m_time_average_type == TimeAverageType::Dynamic) {
301+
if (m_time_average_mode == TimeAverageType::Dynamic) {
302302
m_average_start_step = m_intervals.nextContains(step) - m_average_period_steps;
303303
// check that the periods do not overlap and that the start step is not negative
304304
if (m_average_start_step > 0) {
305305
// The start step cannot be on an interval step because then we would begin a new period and also output the old one
306-
if (m_average_start_step <= m_intervals.previousContains(step)) {
306+
if (m_average_start_step < m_intervals.previousContains(step)) {
307307
WARPX_ABORT_WITH_MESSAGE(
308308
"Averaging periods may not overlap within a single diagnostic. "
309309
"Please create a second diagnostic for overlapping time averaging periods "
@@ -321,7 +321,7 @@ FullDiagnostics::DoComputeAndPack (int step, bool force_flush)
321321
if (step >= m_average_start_step && step <= m_intervals.nextContains(step)) {
322322
in_averaging_period = true;
323323

324-
if (m_time_average_type == TimeAverageType::Static) {
324+
if (m_time_average_mode == TimeAverageType::Static) {
325325
// Update time averaging period to current step
326326
m_average_period_steps = step - m_average_start_step;
327327
}

0 commit comments

Comments
 (0)