Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
datareducer.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include <cstdlib>
24#include <iostream>
25
26#include "datareducer.h"
27#include "../common.h"
29#include "dro_populations.h"
32
33using namespace std;
34
35void initializeDataReducers(DataReducer * outputReducer, DataReducer * diagnosticReducer)
36{
37 typedef Parameters P;
38
39 vector<string>::const_iterator it;
40 for (it = P::outputVariableList.begin();
41 it != P::outputVariableList.end();
42 it++) {
43
44 /* Note: Each data reducer generation should be followed by a call to setUnitMetaData
45 with the following arguments:
46 unit, unit in LaTeX formulation, variable in LaTeX formulation, conversion factor
47 */
48
49 // Sidestep mixed case errors
50 std::string lowercase = *it;
51 for(auto& c : lowercase) c = tolower(c);
52
53 if(P::systemWriteAllDROs || lowercase == "fg_b" || lowercase == "b") { // Bulk magnetic field at Yee-Lattice locations
54 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_b",[](
55 const FieldSolverData& fieldSolverData)->std::vector<double> {
56 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
57 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
58
59 // Iterate through fsgrid cells and extract total magnetic field
60 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
61 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
62 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
63 const auto lid = stencil.ooo();
64 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
65 retval[3*ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBX] + fieldSolverData.perB[lid][fsgrids::bfield::PERBX];
66 retval[3*ri+1] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBY] + fieldSolverData.perB[lid][fsgrids::bfield::PERBY];
67 retval[3*ri+2] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBZ] + fieldSolverData.perB[lid][fsgrids::bfield::PERBZ];
68 });
69 return retval;
70 }
71 ));
72 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{fg}$","1.0");
74 continue;
75 }
76 }
77 if(P::systemWriteAllDROs || lowercase == "fg_backgroundb" || lowercase == "backgroundb" || lowercase == "fg_b_background") { // Static (typically dipole) magnetic field part
78 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_b_background",[](
79 const FieldSolverData& fieldSolverData)->std::vector<double> {
80 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
81 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
82
83 // Iterate through fsgrid cells and extract background B
84 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
85 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
86 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
87 const auto lid = stencil.ooo();
88 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
89 retval[3*ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBX];
90 retval[3*ri+1] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBY];
91 retval[3*ri+2] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBZ];
92 });
93 return retval;
94 }
95 ));
96 outputReducer->addMetadata(outputReducer->size() - 1, "T", "$\\mathrm{T}$", "$B_\\mathrm{bg,fg}$", "1.0");
98 continue;
99 }
100 }
101 if(P::systemWriteAllDROs || lowercase == "fg_backgroundbvol" || lowercase == "backgroundbvol" || lowercase == "fg_b_background_vol") { // Static (typically dipole) magnetic field part, volume-averaged
102 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_b_background_vol",[](
103 const FieldSolverData& fieldSolverData)->std::vector<double> {
104 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
105 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
106
107 // Iterate through fsgrid cells and extract total BVOL
108 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
109 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
110 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
111 const auto lid = stencil.ooo();
112 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
113 retval[3*ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBXVOL];
114 retval[3*ri+1] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBYVOL];
115 retval[3*ri+2] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBZVOL];
116 });
117 return retval;
118 }
119 ));
120 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{bg,vol,fg}$","1.0");
122 continue;
123 }
124 }
125
126 if(P::systemWriteAllDROs || lowercase == "fg_perturbedb" || lowercase == "perturbedb" || lowercase == "fg_b_perturbed") { // Fluctuating magnetic field part
127 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_b_perturbed",[](
128 const FieldSolverData& fieldSolverData)->std::vector<double> {
129 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
130 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
131
132 // Iterate through fsgrid cells and extract values
133 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
134 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
135 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
136 const auto lid = stencil.ooo();
137 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
138 retval[3*ri] = fieldSolverData.perB[lid][fsgrids::bfield::PERBX];
139 retval[3*ri+1] = fieldSolverData.perB[lid][fsgrids::bfield::PERBY];
140 retval[3*ri+2] = fieldSolverData.perB[lid][fsgrids::bfield::PERBZ];
141 });
142 return retval;
143 }
144 ));
145 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{per,fg}$","1.0");
147 continue;
148 }
149 }
150 if(P::systemWriteAllDROs || lowercase == "fg_e" || lowercase == "e") { // Bulk electric field at Yee-lattice locations
151 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_e",[](
152 const FieldSolverData& fieldSolverData)->std::vector<double> {
153 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
154 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
155
156 // Iterate through fsgrid cells and extract E values
157 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
158 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
159 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
160 const auto lid = stencil.ooo();
161 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
162 retval[3*ri] = fieldSolverData.E[lid][fsgrids::efield::EX];
163 retval[3*ri+1] = fieldSolverData.E[lid][fsgrids::efield::EY];
164 retval[3*ri+2] = fieldSolverData.E[lid][fsgrids::efield::EZ];
165 });
166 return retval;
167 }
168 ));
169 outputReducer->addMetadata(outputReducer->size()-1,"V/m","$\\mathrm{V}\\,\\mathrm{m}^{-1}$","$E$","1.0");
171 continue;
172 }
173 }
174 if(P::systemWriteAllDROs || lowercase == "vg_rhom" || lowercase == "rhom") { // Overall mass density (summed over all populations)
176 outputReducer->addMetadata(outputReducer->size()-1,"kg/m^3","$\\mathrm{kg}\\,\\mathrm{m}^{-3}$","$\\rho_\\mathrm{m}$","1.0");
178 continue;
179 }
180 }
181 if(P::systemWriteAllDROs || lowercase == "vg_drift") { // Nudge velocity drift near ionosphere
183 outputReducer->addMetadata(outputReducer->size()-1,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V$","1.0");
185 continue;
186 }
187 }
188 if(P::systemWriteAllDROs || lowercase == "fg_rhom") { // Overall mass density (summed over all populations)
189 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_rhom",[](
190 const FieldSolverData& fieldSolverData)->std::vector<double> {
191 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
192 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
193
194 // Iterate through fsgrid cells and extract rho valuesg
195 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
196 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
197 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
198 const auto lid = stencil.ooo();
199 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
200 retval[ri] = fieldSolverData.moments[lid][fsgrids::moments::RHOM];
201 });
202 return retval;
203 }
204 ));
205 outputReducer->addMetadata(outputReducer->size()-1,"kg/m^3","$\\mathrm{kg}\\,\\mathrm{m}^{-3}$","$\\rho_\\mathrm{m}$","1.0");
207 continue;
208 }
209 }
210 if(P::systemWriteAllDROs || lowercase == "vg_rhoq" || lowercase == "rhoq") { // Overall charge density (summed over all populations)
212 outputReducer->addMetadata(outputReducer->size()-1,"C/m^3","$\\mathrm{C}\\,\\mathrm{m}^{-3}$","$\\rho_\\mathrm{q}$","1.0");
214 continue;
215 }
216 }
217 if(P::systemWriteAllDROs || lowercase == "fg_rhoq") { // Overall charge density (summed over all populations)
218 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_rhoq",[](
219 const FieldSolverData& fieldSolverData)->std::vector<double> {
220 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
221 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
222
223 // Iterate through fsgrid cells and extract charge density
224 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
225 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
226 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
227 const auto lid = stencil.ooo();
228 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
229 retval[ri] = fieldSolverData.moments[lid][fsgrids::moments::RHOQ];
230 });
231 return retval;
232 }
233 ));
234 outputReducer->addMetadata(outputReducer->size()-1,"C/m^3","$\\mathrm{C}\\,\\mathrm{m}^{-3}$","$\\rho_\\mathrm{q}$","1.0");
236 continue;
237 }
238 }
239 if(P::systemWriteAllDROs || lowercase == "populations_rho" || lowercase == "populations_vg_rho") { // Per-population particle number density
240 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
242 const std::string& pop = species.name;
243 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_rho", i, offsetof(spatial_cell::Population, RHO), 1));
244 outputReducer->addMetadata(outputReducer->size()-1,"1/m^3","$\\mathrm{m}^{-3}$","$n_\\mathrm{"+pop+"}$","1.0");
245 }
247 continue;
248 }
249 }
250
251 if(P::systemWriteAllDROs || lowercase == "v" || lowercase == "vg_v") { // Overall effective bulk density defining the center-of-mass frame from all populations
253 outputReducer->addMetadata(outputReducer->size()-1,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V$","1.0");
255 continue;
256 }
257 }
258 if(P::systemWriteAllDROs || lowercase == "fg_v") { // Overall effective bulk density defining the center-of-mass frame from all populations
259 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_v",[](
260 const FieldSolverData& fieldSolverData)->std::vector<double> {
261 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
262 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
263
264 // Iterate through fsgrid cells and extract bulk Velocity
265 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
266 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
267 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
268 const auto lid = stencil.ooo();
269 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
270 retval[3*ri] = fieldSolverData.moments[lid][fsgrids::moments::VX];
271 retval[3*ri+1] = fieldSolverData.moments[lid][fsgrids::moments::VY];
272 retval[3*ri+2] = fieldSolverData.moments[lid][fsgrids::moments::VZ];
273 });
274 return retval;
275 }
276 ));
277 outputReducer->addMetadata(outputReducer->size()-1,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V$","1.0");
279 continue;
280 }
281 }
282 if(P::systemWriteAllDROs || lowercase == "vg_nu0" || lowercase == "nu0") { // nu0 for sub-grid diffusion
284 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\nu_0$","1.0");
286 continue;
287 }
288 }
289 if(P::systemWriteAllDROs || lowercase == "populations_v" || lowercase == "populations_vg_v") { // Per population bulk velocities
290 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
292 const std::string& pop = species.name;
293 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_v", i, offsetof(spatial_cell::Population, V), 3));
294 outputReducer->addMetadata(outputReducer->size()-1,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V_\\mathrm{"+pop+"}$","1.0");
295 }
297 continue;
298 }
299 }
300 if(P::systemWriteAllDROs || lowercase == "populations_moments_backstream" || lowercase == "populations_moments_nonthermal" || lowercase == "populations_vg_moments_nonthermal") { // Per-population moments of the backstreaming part
301 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
303 const std::string& pop = species.name;
304 outputReducer->addOperator(new DRO::VariableRhoNonthermal(i));
305 outputReducer->addOperator(new DRO::VariableVNonthermal(i));
308 outputReducer->addMetadata(outputReducer->size()-4,"1/m^3","$\\mathrm{m}^{-3}$","$n_\\mathrm{"+pop+",nt}$","1.0");
309 outputReducer->addMetadata(outputReducer->size()-3,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V_\\mathrm{"+pop+",nt}$","1.0");
310 outputReducer->addMetadata(outputReducer->size()-2,"Pa","$\\mathrm{Pa}$","$\\mathcal{P}_\\mathrm{"+pop+",nt}$","1.0");
311 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$\\mathcal{\\tilde{P}}_\\mathrm{"+pop+",nt}$","1.0");
312 }
314 continue;
315 }
316 }
317 if(P::systemWriteAllDROs || lowercase == "populations_moments_nonbackstream" || lowercase == "populations_moments_thermal" || lowercase == "populations_vg_moments_thermal") { // Per-population moments of the non-backstreaming (thermal?) part.
318 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
320 const std::string& pop = species.name;
321 outputReducer->addOperator(new DRO::VariableRhoThermal(i));
322 outputReducer->addOperator(new DRO::VariableVThermal(i));
325 outputReducer->addMetadata(outputReducer->size()-4,"1/m^3","$\\mathrm{m}^{-3}$","$n_\\mathrm{"+pop+",th}$","1.0");
326 outputReducer->addMetadata(outputReducer->size()-3,"m/s","$\\mathrm{m}\\,\\mathrm{s}^{-1}$","$V_\\mathrm{"+pop+",th}$","1.0");
327 outputReducer->addMetadata(outputReducer->size()-2,"Pa","$\\mathrm{Pa}$","$\\mathcal{P}_\\mathrm{"+pop+",th}$","1.0");
328 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$\\mathcal{\\tilde{P}}_\\mathrm{"+pop+",th}$","1.0");
329 }
331 continue;
332 }
333 }
334 if(P::systemWriteAllDROs || lowercase == "populations_minvalue" || lowercase == "populations_effectivesparsitythreshold" || lowercase == "populations_vg_effectivesparsitythreshold") {
335 // Effective sparsity threshold affecting each cell, if dynamic threshould algorithm is used
336 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
338 const std::string& pop = species.name;
340 outputReducer->addMetadata(outputReducer->size()-1,"s^3/m^6","$\\mathrm{m}^{-6}\\,\\mathrm{s}^{3}$","$f_\\mathrm{"+pop+",min}$","1.0");
341 }
343 continue;
344 }
345 }
346 if(P::systemWriteAllDROs || lowercase == "populations_rholossadjust" || lowercase == "populations_rho_loss_adjust" || lowercase == "populations_vg_rho_loss_adjust") {
347 // Accumulated lost particle number, per population, in each cell, since last restart
348 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
350 const std::string& pop = species.name;
351 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_rho_loss_adjust", i, offsetof(spatial_cell::Population, RHOLOSSADJUST), 1));
352 outputReducer->addMetadata(outputReducer->size()-1,"1/m^3","$\\mathrm{m}^{-3}$","$\\Delta_\\mathrm{loss} n_\\mathrm{"+pop+"}$","1.0");
353 }
355 continue;
356 }
357 }
358 if(P::systemWriteAllDROs || lowercase == "lbweight" || lowercase == "vg_lbweight" || lowercase == "vg_loadbalanceweight" || lowercase == "vg_loadbalance_weight") {
359 // Load balance metric for LB debugging
360 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_loadbalance_weight",CellParams::LBWEIGHTCOUNTER,1));
361 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{LB weight}$","");
363 continue;
364 }
365 }
366 if(P::systemWriteAllDROs || lowercase == "maxvdt" || lowercase == "vg_maxdt_acceleration") {
367 // Overall maximum timestep constraint as calculated by the velocity space vlasov update
368 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_maxdt_acceleration",CellParams::MAXVDT,1));
369 outputReducer->addMetadata(outputReducer->size()-1,"s","$\\mathrm{s}$","$\\Delta t_\\mathrm{V,max}$","1.0");
371 continue;
372 }
373 }
374 if(P::systemWriteAllDROs || lowercase == "populations_maxvdt" || lowercase == "populations_vg_maxdt_acceleration" || lowercase == "populations_maxdt_acceleration") {
375 // Per-population maximum timestep constraint as calculated by the velocity space vlasov update
376 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
378 const std::string& pop = species.name;
379 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_maxdt_acceleration", i, offsetof(spatial_cell::Population, max_dt[1]), 1));
380 outputReducer->addMetadata(outputReducer->size()-1,"s","$\\mathrm{s}$","$\\Delta t_\\mathrm{"+pop+",V,max}$","1.0");
381 }
383 continue;
384 }
385 }
386 if(P::systemWriteAllDROs || lowercase == "maxrdt" || lowercase == "vg_maxdt_translation") {
387 // Overall maximum timestep constraint as calculated by the real space vlasov update
388 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_maxdt_translation",CellParams::MAXRDT,1));
389 outputReducer->addMetadata(outputReducer->size()-1,"s","$\\mathrm{s}$","$\\Delta t_\\mathrm{R,max}$","1.0");
391 continue;
392 }
393 }
394 if(P::systemWriteAllDROs || lowercase == "populations_maxrdt" || lowercase == "populations_vg_maxdt_translation" || lowercase == "populations_maxdt_translation") {
395 // Per-population maximum timestep constraint as calculated by the real space vlasov update
396 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
398 const std::string& pop = species.name;
399 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_maxdt_translation", i, offsetof(spatial_cell::Population, max_dt[0]), 1));
400 outputReducer->addMetadata(outputReducer->size()-1,"s","$\\mathrm{s}$","$\\Delta t_\\mathrm{"+pop+",R,max}$","1.0");
401 }
403 continue;
404 }
405 }
406 if(P::systemWriteAllDROs || lowercase == "populations_energydensity" || lowercase == "populations_vg_energydensity") {
407 // Per-population energy density in three energy ranges
408 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
410 const std::string& pop = species.name;
411 outputReducer->addOperator(new DRO::VariableEnergyDensity(i));
412 std::stringstream conversion;
413 conversion << (1.0e-6)/physicalconstants::CHARGE;
414 outputReducer->addMetadata(outputReducer->size()-1,"eV/cm^3","$\\mathrm{eV}\\,\\mathrm{cm}^{-3}$","$U_\\mathrm{"+pop+"}$",conversion.str());
415 }
417 continue;
418 }
419 }
420 if(P::systemWriteAllDROs || lowercase == "populations_precipitationflux" || lowercase == "populations_vg_precipitationdifferentialflux" || lowercase == "populations_precipitationdifferentialflux") {
421 // Per-population precipitation differential flux (within loss cone)
422 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
424 const std::string& pop = species.name;
426 std::stringstream conversion;
427 conversion << (1.0e-4)*physicalconstants::CHARGE;
428 outputReducer->addMetadata(outputReducer->size()-1,"1/(cm^2 sr s eV)","$\\mathrm{cm}^{-2}\\,\\mathrm{sr}^{-1}\\,\\mathrm{s}^{-1}\\,\\mathrm{eV}^{-1}$","$\\mathcal{F}_\\mathrm{"+pop+"}$",conversion.str());
429 }
431 continue;
432 }
433 }
434 if(P::systemWriteAllDROs || lowercase == "populations_1dmuspace" || lowercase == "populations_vg_1dmuspace") {
435 // Per-population 1d muspace
436 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
438 const std::string& pop = species.name;
439 outputReducer->addOperator(new DRO::VariableMuSpace(i));
440 outputReducer->addMetadata(outputReducer->size()-1,"1/m^3","$\\mathrm{m}^{-3}$","$f(\\mu)_\\mathrm{"+pop+"}$","1.0");
441 }
443 continue;
444 }
445 }
446 if(P::systemWriteAllDROs || lowercase == "populations_precipitationlineflux" || lowercase == "populations_vg_precipitationlinedifferentialflux" || lowercase == "populations_precipitationlinedifferentialflux") {
447 // Per-population precipitation differential flux (along line)
448 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
450 const std::string& pop = species.name;
452 std::stringstream conversion;
453 conversion << (1.0e-4)*physicalconstants::CHARGE;
454 outputReducer->addMetadata(outputReducer->size()-1,"1/(cm^2 sr s eV)","$\\mathrm{cm}^{-2}\\,\\mathrm{sr}^{-1}\\,\\mathrm{s}^{-1}\\,\\mathrm{eV}^{-1}$","$\\mathcal{F}_\\mathrm{"+pop+"}$",conversion.str());
455 }
457 continue;
458 }
459 }
460 if(P::systemWriteAllDROs || lowercase == "populations_heatflux" || lowercase == "populations_vg_heatflux") {
461 // Per-population heat flux vector
462 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
464 const std::string& pop = species.name;
465 outputReducer->addOperator(new DRO::VariableHeatFluxVector(i));
466 outputReducer->addMetadata(outputReducer->size()-1,"W/m^2","$\\mathrm{W}\\,\\mathrm{m}^{-2}$","$q_\\mathrm{"+pop+"}$","1.0");
467 }
469 continue;
470 }
471 }
472 if (P::systemWriteAllDROs || lowercase == "populations_nonmaxwellianity" || lowercase == "populations_vg_nonmaxwellianity") {
473 // Per-population dimensionless non-maxwellianity parameter
474 for (unsigned int i = 0; i < getObjectWrapper().particleSpecies.size(); i++) {
476 const std::string& pop = species.name;
477 outputReducer->addOperator(new DRO::VariableNonMaxwellianity(i));
478 outputReducer->addMetadata(outputReducer->size() - 1, "", "",
479 "$\\tilde{\\epsilon}_\\mathrm{M," + pop + "}$", "1.0");
480 }
482 continue;
483 }
484 }
485 if(P::systemWriteAllDROs || lowercase == "maxfieldsdt" || lowercase == "fg_maxfieldsdt" || lowercase == "fg_maxdt_fieldsolver") {
486 // Maximum timestep constraint as calculated by the fieldsolver
488 "fg_maxdt_fieldsolver", [](const FieldSolverData& fieldSolverData)->std::vector<double> {
489 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
490 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
491
492 // Iterate through fsgrid cells and extract field solver timestep limit
493 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
494 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
495 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
496 const auto lid = stencil.ooo();
497 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
498 retval[ri] = fieldSolverData.technical[lid].maxFsDt;
499 });
500 return retval;
501 }
502 ));
503 outputReducer->addMetadata(outputReducer->size()-1,"s","$\\mathrm{s}$","$\\Delta t_\\mathrm{f,max}$","1.0");
505 continue;
506 }
507 }
508 if(P::systemWriteAllDROs || lowercase == "mpirank" || lowercase == "vg_rank") {
509 // Map of spatial decomposition of the DCCRG grid into MPI ranks
510 outputReducer->addOperator(new DRO::MPIrank);
511 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{MPI rank}$","");
513 continue;
514 }
515 }
516 if(P::systemWriteAllDROs || lowercase == "fsgridrank" || lowercase == "fg_rank") {
517 // Map of spatial decomposition of the FsGrid into MPI ranks
518 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_rank",[](
519 const FieldSolverData& fieldSolverData)->std::vector<double> {
520 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
521 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2], fieldSolverData.fsgrid.getRank());
522 return retval;
523 }
524 ));
525 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{fGrid rank}$","");
527 continue;
528 }
529 }
530 if(P::systemWriteAllDROs || lowercase == "fg_amr_level") {
531 // Map of spatial decomposition of the FsGrid into MPI ranks
532 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_amr_level",[](
533 const FieldSolverData& fieldSolverData)->std::vector<double> {
534 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
535 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
536
537 // Iterate through fsgrid cells and extract corresponding AMR level
538 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
539 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
540 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
541 const auto lid = stencil.ooo();
542 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
543 retval[ri] = fieldSolverData.technical[lid].refLevel;
544 });
545 return retval;
546 }
547 ));
548 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{fGrid rank}$","");
550 continue;
551 }
552 }
553 if(P::systemWriteAllDROs || lowercase == "boundarytype" || lowercase == "vg_boundarytype") {
554 // Type of boundarycells
555 outputReducer->addOperator(new DRO::BoundaryType);
556 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{vGrid Boundary type}$","");
558 continue;
559 }
560 }
561 if(P::systemWriteAllDROs || lowercase == "fsgridboundarytype" || lowercase == "fg_boundarytype") {
562 // Type of boundarycells as stored in FSGrid
563 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_boundarytype",[](
564 const FieldSolverData& fieldSolverData)->std::vector<double> {
565 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
566 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
567
568 // Iterate through fsgrid cells and extract boundary flag
569 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
570 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
571 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
572 const auto lid = stencil.ooo();
573 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
574 retval[ri] = fieldSolverData.technical[lid].sysBoundaryFlag;
575 });
576 return retval;
577 }
578 ));
579 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{fGrid Boundary type}$","");
581 continue;
582 }
583 }
584 if(P::systemWriteAllDROs || lowercase == "boundarylayer" || lowercase == "vg_boundarylayer") {
585 // For boundaries with multiple layers: layer count per cell
586 outputReducer->addOperator(new DRO::BoundaryLayer);
587 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{vGrid Boundary layer}$","");
589 continue;
590 }
591 }
592 if(P::systemWriteAllDROs || lowercase == "fsgridboundarylayer" || lowercase == "fg_boundarylayer") {
593 // Type of boundarycells as stored in FSGrid
594 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_boundarylayer",[](
595 const FieldSolverData& fieldSolverData)->std::vector<double> {
596 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
597 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
598
599 // Iterate through fsgrid cells and extract boundary layer
600 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
601 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
602 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
603 const auto lid = stencil.ooo();
604 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
605 retval[ri] = fieldSolverData.technical[lid].sysBoundaryLayer;
606 });
607 return retval;
608 }
609 ));
610 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{fGrid Boundary layer}$","");
612 continue;
613 }
614 }
615 if(P::systemWriteAllDROs || lowercase == "populations_blocks" || lowercase == "populations_vg_blocks") {
616 // Per-population velocity space block counts
617 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
619 const std::string& pop = species.name;
620 outputReducer->addOperator(new DRO::Blocks(i));
621 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{"+pop+" blocks}$","");
622 }
624 continue;
625 }
626 }
627 //MLP error per pop
628 if(P::systemWriteAllDROs || lowercase == "populations_mlp_error") {
629 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
631 const std::string& pop = species.name;
632 outputReducer->addOperator(new DRO::MLPerror(i));
633 outputReducer->addMetadata(outputReducer->size()-1,"","","","");
634 }
636 continue;
637 }
638 }
639 //MLP epochs per pop
640 if(P::systemWriteAllDROs || lowercase == "populations_mlp_epochs") {
641 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
643 const std::string& pop = species.name;
644 outputReducer->addOperator(new DRO::MLPepochs(i));
645 outputReducer->addMetadata(outputReducer->size()-1,"","","","");
646 }
648 continue;
649 }
650 }
651 if(P::systemWriteAllDROs || lowercase == "fsaved" || lowercase == "vg_fsaved" || lowercase == "vg_f_saved") {
652 // Boolean marker whether a velocity space is saved in a given spatial cell
654 outputReducer->addMetadata(outputReducer->size()-1,"","","$f(v)_\\mathrm{saved}$","");
656 continue;
657 }
658 }
659 if(P::systemWriteAllDROs || lowercase == "populations_accsubcycles" || lowercase == "populations_acceleration_subcycles" || lowercase == "populations_vg_acceleration_subcycles") {
660 // Per-population number of subcycles performed for velocity space update
661 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
663 const std::string& pop = species.name;
664 outputReducer->addOperator(new DRO::DataReductionOperatorPopulations<uint>(pop + "/vg_acceleration_subcycles", i, offsetof(spatial_cell::Population, ACCSUBCYCLES), 1));
665 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\mathrm{"+pop+" Acc subcycles}$","");
666 }
668 continue;
669 }
670 }
671 if(P::systemWriteAllDROs || lowercase == "vole" || lowercase == "vg_vole" || lowercase == "evol" || lowercase == "vg_e_vol" || lowercase == "e_vol") {
672 // Volume-averaged E field
674 outputReducer->addMetadata(outputReducer->size()-1,"V/m","$\\mathrm{V}\\,\\mathrm{m}^{-1}$","$E_\\mathrm{vol,vg}$","1.0");
676 continue;
677 }
678 }
679 if(P::systemWriteAllDROs || lowercase == "fg_vole" || lowercase == "fg_e_vol" || lowercase == "fg_evol") { // Volume-averaged E field from the fieldSolver grid
680 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_e_vol",[](
681 const FieldSolverData& fieldSolverData)->std::vector<double> {
682 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
683 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
684
685 // Iterate through fsgrid cells and extract EVOL
686 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
687 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
688 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
689 const auto lid = stencil.ooo();
690 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
691 retval[3*ri] = fieldSolverData.vol[lid][fsgrids::volfields::EXVOL];
692 retval[3*ri+1] = fieldSolverData.vol[lid][fsgrids::volfields::EYVOL];
693 retval[3*ri+2] = fieldSolverData.vol[lid][fsgrids::volfields::EZVOL];
694 });
695 return retval;
696 }
697 ));
698 outputReducer->addMetadata(outputReducer->size()-1,"V/m","$\\mathrm{V}\\,\\mathrm{m}^{-1}$","$E_\\mathrm{vol,fg}$","1.0");
700 continue;
701 }
702 }
703 if(P::systemWriteAllDROs || lowercase == "halle" || lowercase == "fg_halle" || lowercase == "fg_e_hall") {
704 for(int index=0; index<fsgrids::N_EHALL; index++) {
705 std::string reducer_name = "fg_e_hall_" + std::to_string(index);
706 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid(reducer_name,[index](
707 const FieldSolverData& fieldSolverData)->std::vector<double> {
708 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
709 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
710
711 // Iterate through fsgrid cells and extract EHall
712 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
713 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
714 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
715 const auto lid = stencil.ooo();
716 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
717 retval[ri] = fieldSolverData.EHall[lid][index];
718 });
719 return retval;
720 }
721 ));
722 outputReducer->addMetadata(outputReducer->size()-1,"V/m","$\\mathrm{V}\\,\\mathrm{m}^{-1}$","$E_\\mathrm{Hall,"+std::to_string(index)+"}$","1.0");
723 }
725 continue;
726 }
727 }
728 if(P::systemWriteAllDROs || lowercase =="gradpee" || lowercase == "e_gradpe" || lowercase == "vg_e_gradpe") {
729 // Electron pressure gradient contribution to the generalized ohm's law
730 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_e_gradpe",CellParams::EXGRADPE,3));
731 outputReducer->addMetadata(outputReducer->size()-1,"V/m","$\\mathrm{V}\\,\\mathrm{m}^{-1}$","$E_{\\nabla P_\\mathrm{e}}$","1.0");
733 continue;
734 }
735 }
736 if(P::systemWriteAllDROs || lowercase == "volb" || lowercase == "vg_volb" || lowercase == "b_vol" || lowercase == "bvol" || lowercase == "vg_bvol" || lowercase == "vg_b_vol") {
737 // Volume-averaged magnetic field
738 outputReducer->addOperator(new DRO::VariableBVol);
739 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{vol,vg}$","1.0");
741 continue;
742 }
743 }
744 if(P::systemWriteAllDROs || lowercase == "fg_volb" || lowercase == "fg_bvol" || lowercase == "fg_b_vol") { // Static (typically dipole) magnetic field part
745 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_b_vol",[](
746 const FieldSolverData& fieldSolverData)->std::vector<double> {
747 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
748 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
749
750 // Iterate through fsgrid cells and extract total BVOL
751 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
752 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
753 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
754 const auto lid = stencil.ooo();
755 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
756 retval[3*ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBXVOL] + fieldSolverData.vol[lid][fsgrids::volfields::PERBXVOL];
757 retval[3*ri+1] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBYVOL] + fieldSolverData.vol[lid][fsgrids::volfields::PERBYVOL];
758 retval[3*ri+2] = fieldSolverData.BgB[lid][fsgrids::bgbfield::BGBZVOL] + fieldSolverData.vol[lid][fsgrids::volfields::PERBZVOL];
759 });
760 return retval;
761 }
762 ));
763 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{vol,fg}$","1.0");
765 continue;
766 }
767 }
768 if(P::systemWriteAllDROs || lowercase == "backgroundvolb" || lowercase == "vg_b_background_vol") {
769 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_b_background_vol",CellParams::BGBXVOL,3));
770 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{vol,vg,bg}$","1.0");
772 continue;
773 }
774 }
775 if(P::systemWriteAllDROs || lowercase == "perturbedvolb" || lowercase == "vg_b_perturbed_vol") {
776 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_b_perturbed_vol",CellParams::PERBXVOL,3));
777 outputReducer->addMetadata(outputReducer->size()-1,"T","$\\mathrm{T}$","$B_\\mathrm{vol,vg,per}$","1.0");
779 continue;
780 }
781 }
782 if(P::systemWriteAllDROs || lowercase == "pressure" || lowercase == "vg_pressure") {
783 // Overall scalar pressure from all populations
784 outputReducer->addOperator(new DRO::VariablePressureSolver);
785 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$P_\\mathrm{solver}$","1.0");
787 continue;
788 }
789 }
790 if(P::systemWriteAllDROs || lowercase == "fg_pressure") {
791 // Overall scalar pressure from all populations
792 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_pressure", [](
793 const FieldSolverData& fieldSolverData)->std::vector<double> {
794 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
795 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
796
797 // Iterate through fsgrid cells and extract boundary flag
798 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
799 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
800 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
801 const auto lid = stencil.ooo();
802 const auto ri = gridSize[1] * gridSize[0] * stencil.k + gridSize[0] * stencil.j + stencil.i;
803 auto& moments = fieldSolverData.moments[lid];
804 retval[ri] = 1./3. * (moments[fsgrids::P_11] + moments[fsgrids::P_22] + moments[fsgrids::P_33]);
805 });
806 return retval;
807 }
808 ));
809 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$P_\\mathrm{fg}$","1.0");
811 continue;
812 }
813 }
814 if(P::systemWriteAllDROs || lowercase == "populations_ptensor" || lowercase == "populations_vg_ptensor") {
815 // Per-population pressure tensor, stored as diagonal and offdiagonal components
816 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
818 const std::string& pop = species.name;
819 outputReducer->addOperator(new DRO::VariablePTensorDiagonal(i));
820 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$\\mathcal{P}_\\mathrm{"+pop+"}$","1.0");
821 outputReducer->addOperator(new DRO::VariablePTensorOffDiagonal(i));
822 outputReducer->addMetadata(outputReducer->size()-1,"Pa","$\\mathrm{Pa}$","$\\mathcal{\\tilde{P}}_\\mathrm{"+pop+"}$","1.0");
823 }
825 continue;
826 }
827 }
828 if(P::systemWriteAllDROs || lowercase == "bvolderivs" || lowercase == "b_vol_derivs" || lowercase == "b_vol_derivatives" || lowercase == "vg_b_vol_derivatives" || lowercase == "derivs") {
829 // Volume-averaged derivatives
830 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbxvoldx",bvolderivatives::dPERBXVOLdx,1));
831 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbxvoldy",bvolderivatives::dPERBXVOLdy,1));
832 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbxvoldz",bvolderivatives::dPERBXVOLdz,1));
833 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbyvoldx",bvolderivatives::dPERBYVOLdx,1));
834 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbyvoldy",bvolderivatives::dPERBYVOLdy,1));
835 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbyvoldz",bvolderivatives::dPERBYVOLdz,1));
836 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbzvoldx",bvolderivatives::dPERBZVOLdx,1));
837 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbzvoldy",bvolderivatives::dPERBZVOLdy,1));
838 outputReducer->addOperator(new DRO::DataReductionOperatorBVOLDerivatives("vg_derivatives/vg_dperbzvoldz",bvolderivatives::dPERBZVOLdz,1));
839 outputReducer->addMetadata(outputReducer->size()-9,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,vg}} (\\Delta X)^{-1}$","1.0");
840 outputReducer->addMetadata(outputReducer->size()-8,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,vg}} (\\Delta Y)^{-1}$","1.0");
841 outputReducer->addMetadata(outputReducer->size()-7,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,vg}} (\\Delta Z)^{-1}$","1.0");
842 outputReducer->addMetadata(outputReducer->size()-6,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,vg}} (\\Delta X)^{-1}$","1.0");
843 outputReducer->addMetadata(outputReducer->size()-5,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,vg}} (\\Delta Y)^{-1}$","1.0");
844 outputReducer->addMetadata(outputReducer->size()-4,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,vg}} (\\Delta Z)^{-1}$","1.0");
845 outputReducer->addMetadata(outputReducer->size()-3,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,vg}} (\\Delta X)^{-1}$","1.0");
846 outputReducer->addMetadata(outputReducer->size()-2,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,vg}} (\\Delta Y)^{-1}$","1.0");
847 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,vg}} (\\Delta Z)^{-1}$","1.0");
849 continue;
850 }
851 }
852
853
854 // This long block is writing all the derivatives we are storing on the fsgrids
855 // !! EXCEPT background b !!
856 // that is, derivatives of perturbed b, perturbed bvol, rhom, rhoq, v, p11, p22, p33, and pe.
857 // Note that so far we are not computing nor storing the fg_dperbidi components, hence we cannot write them out!
858 // We do have the background ones, as well as the fg_dperbivoldi and their vg equivalent (elsewhere) as those are computed from the perbivol components.
859 // As of summer 2023 they are proper derivatives in DROs, unlike in the code where they are differences.
860 // Search for "fg_derivs" to find the end of this block.
861 if(P::systemWriteAllDROs || lowercase == "fg_derivs") {
862 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxdy",[](
863 const FieldSolverData& fieldSolverData)->std::vector<double> {
864 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
865 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
866
867 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
868 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
869 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
870 const auto lid = stencil.ooo();
871 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
872 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBxdy] / coordinates.physicalGridSpacing[1];
873 });
874 return retval;
875 }
876 ));
877 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,fg}} (\\Delta Y)^{-1}$","1.0");
878 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxdz",[](
879 const FieldSolverData& fieldSolverData)->std::vector<double> {
880 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
881 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
882
883 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
884 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
885 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
886 const auto lid = stencil.ooo();
887 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
888 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBxdz] / coordinates.physicalGridSpacing[2];
889 });
890 return retval;
891 }
892 ));
893 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,fg}} (\\Delta Z)^{-1}$","1.0");
894 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbydx",[](
895 const FieldSolverData& fieldSolverData)->std::vector<double> {
896 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
897 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
898
899 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
900 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
901 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
902 const auto lid = stencil.ooo();
903 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
904 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBydx] / coordinates.physicalGridSpacing[0];
905 });
906 return retval;
907 }
908 ));
909 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,fg}} (\\Delta X)^{-1}$","1.0");
910 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbydz",[](
911 const FieldSolverData& fieldSolverData)->std::vector<double> {
912 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
913 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
914
915 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
916 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
917 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
918 const auto lid = stencil.ooo();
919 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
920 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBydz] / coordinates.physicalGridSpacing[2];
921 });
922 return retval;
923 }
924 ));
925 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,fg}} (\\Delta Z)^{-1}$","1.0");
926 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzdx",[](
927 const FieldSolverData& fieldSolverData)->std::vector<double> {
928 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
929 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
930
931 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
932 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
933 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
934 const auto lid = stencil.ooo();
935 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
936 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBzdx] / coordinates.physicalGridSpacing[0];
937 });
938 return retval;
939 }
940 ));
941 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,fg}} (\\Delta X)^{-1}$","1.0");
942 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzdy",[](
943 const FieldSolverData& fieldSolverData)->std::vector<double> {
944 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
945 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
946
947 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
948 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
949 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
950 const auto lid = stencil.ooo();
951 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
952 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBzdy] / coordinates.physicalGridSpacing[1];
953 });
954 return retval;
955 }
956 ));
957 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,fg}} (\\Delta Y)^{-1}$","1.0");
958 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxdyy",[](
959 const FieldSolverData& fieldSolverData)->std::vector<double> {
960 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
961 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
962
963 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
964 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
965 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
966 const auto lid = stencil.ooo();
967 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
968 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBxdyy] / coordinates.physicalGridSpacing[1] / coordinates.physicalGridSpacing[1];
969 });
970 return retval;
971 }
972 ));
973 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{X,\\mathrm{per,fg}} (\\Delta Y)^{-2}$","1.0");
974 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxdzz",[](
975 const FieldSolverData& fieldSolverData)->std::vector<double> {
976 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
977 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
978
979 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
980 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
981 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
982 const auto lid = stencil.ooo();
983 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
984 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBxdzz] / coordinates.physicalGridSpacing[2] / coordinates.physicalGridSpacing[2];
985 });
986 return retval;
987 }
988 ));
989 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{X,\\mathrm{per,fg}} (\\Delta Z)^{-2}$","1.0");
990 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxdyz",[](
991 const FieldSolverData& fieldSolverData)->std::vector<double> {
992 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
993 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
994
995 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
996 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
997 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
998 const auto lid = stencil.ooo();
999 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1000 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBxdyz] / coordinates.physicalGridSpacing[1] / coordinates.physicalGridSpacing[2];
1001 });
1002 return retval;
1003 }
1004 ));
1005 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{X,\\mathrm{per,fg}} (\\Delta Y \\Delta Z)^{-1}$","1.0");
1006 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbydxx",[](
1007 const FieldSolverData& fieldSolverData)->std::vector<double> {
1008 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1009 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1010
1011 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1012 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1013 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1014 const auto lid = stencil.ooo();
1015 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1016 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBydxx] / coordinates.physicalGridSpacing[0] / coordinates.physicalGridSpacing[0];
1017 });
1018 return retval;
1019 }
1020 ));
1021 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Y,\\mathrm{per,fg}} (\\Delta X)^{-2}$","1.0");
1022 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbydzz",[](
1023 const FieldSolverData& fieldSolverData)->std::vector<double> {
1024 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1025 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1026
1027 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1028 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1029 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1030 const auto lid = stencil.ooo();
1031 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1032 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBydzz] / coordinates.physicalGridSpacing[2] / coordinates.physicalGridSpacing[2];
1033 });
1034 return retval;
1035 }
1036 ));
1037 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Y,\\mathrm{per,fg}} (\\Delta Z)^{-2}$","1.0");
1038 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbydxz",[](
1039 const FieldSolverData& fieldSolverData)->std::vector<double> {
1040 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1041 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1042
1043 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1044 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1045 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1046 const auto lid = stencil.ooo();
1047 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1048 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBydxz] / coordinates.physicalGridSpacing[0] / coordinates.physicalGridSpacing[2];
1049 });
1050 return retval;
1051 }
1052 ));
1053 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Y,\\mathrm{per,fg}} (\\Delta X \\Delta Z)^{-1}$","1.0");
1054 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzdxx",[](
1055 const FieldSolverData& fieldSolverData)->std::vector<double> {
1056 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1057 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1058
1059 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1060 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1061 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1062 const auto lid = stencil.ooo();
1063 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1064 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBzdxx] / coordinates.physicalGridSpacing[0] / coordinates.physicalGridSpacing[0];
1065 });
1066 return retval;
1067 }
1068 ));
1069 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Z,\\mathrm{per,fg}} (\\Delta Z)^{-2}$","1.0");
1070 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzdyy",[](
1071 const FieldSolverData& fieldSolverData)->std::vector<double> {
1072 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1073 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1074
1075 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1076 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1077 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1078 const auto lid = stencil.ooo();
1079 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1080 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBzdyy] / coordinates.physicalGridSpacing[1] / coordinates.physicalGridSpacing[1];
1081 });
1082 return retval;
1083 }
1084 ));
1085 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Z,\\mathrm{per,fg}} (\\Delta Y)^{-2}$","1.0");
1086 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzdxy",[](
1087 const FieldSolverData& fieldSolverData)->std::vector<double> {
1088 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1089 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1090
1091 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1092 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1093 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1094 const auto lid = stencil.ooo();
1095 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1096 retval[ri] = fieldSolverData.dPerB[lid][fsgrids::dperb::dPERBzdxy] / coordinates.physicalGridSpacing[0] / coordinates.physicalGridSpacing[1];
1097 });
1098 return retval;
1099 }
1100 ));
1101 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-2}$","$\\Delta B_{Z,\\mathrm{per,fg}} (\\Delta X \\Delta Y)^{-1}$","1.0");
1102 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhomdx",[](
1103 const FieldSolverData& fieldSolverData)->std::vector<double> {
1104 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1105 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1106
1107 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1108 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1109 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1110 const auto lid = stencil.ooo();
1111 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1112 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhomdx] / coordinates.physicalGridSpacing[0];
1113 });
1114 return retval;
1115 }
1116 ));
1117 outputReducer->addMetadata(outputReducer->size()-1,"kg/m^4","$\\mathrm{kg}\\mathrm{m}^{-4}$","$\\Delta \\rho_{m,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1118 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhomdy",[](
1119 const FieldSolverData& fieldSolverData)->std::vector<double> {
1120 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1121 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1122
1123 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1124 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1125 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1126 const auto lid = stencil.ooo();
1127 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1128 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhomdy] / coordinates.physicalGridSpacing[1];
1129 });
1130 return retval;
1131 }
1132 ));
1133 outputReducer->addMetadata(outputReducer->size()-1,"kg/m^4","$\\mathrm{kg}\\mathrm{m}^{-4}$","$\\Delta \\rho_{m,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1134 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhomdz",[](
1135 const FieldSolverData& fieldSolverData)->std::vector<double> {
1136 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1137 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1138
1139 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1140 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1141 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1142 const auto lid = stencil.ooo();
1143 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1144 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhomdz] / coordinates.physicalGridSpacing[2];
1145 });
1146 return retval;
1147 }
1148 ));
1149 outputReducer->addMetadata(outputReducer->size()-1,"kg/m^4","$\\mathrm{kg}\\mathrm{m}^{-4}$","$\\Delta \\rho_{m,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1150 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhoqdx",[](
1151 const FieldSolverData& fieldSolverData)->std::vector<double> {
1152 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1153 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1154
1155 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1156 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1157 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1158 const auto lid = stencil.ooo();
1159 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1160 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhoqdx] / coordinates.physicalGridSpacing[0];
1161 });
1162 return retval;
1163 }
1164 ));
1165 outputReducer->addMetadata(outputReducer->size()-1,"C/m^4","$\\mathrm{C}\\mathrm{m}^{-4}$","$\\Delta \\rho_{q,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1166 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhoqdy",[](
1167 const FieldSolverData& fieldSolverData)->std::vector<double> {
1168 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1169 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1170
1171 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1172 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1173 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1174 const auto lid = stencil.ooo();
1175 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1176 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhoqdy] / coordinates.physicalGridSpacing[1];
1177 });
1178 return retval;
1179 }
1180 ));
1181 outputReducer->addMetadata(outputReducer->size()-1,"C/m^4","$\\mathrm{C}\\mathrm{m}^{-4}$","$\\Delta \\rho_{q,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1182 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_drhoqdz",[](
1183 const FieldSolverData& fieldSolverData)->std::vector<double> {
1184 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1185 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1186
1187 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1188 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1189 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1190 const auto lid = stencil.ooo();
1191 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1192 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::drhoqdz] / coordinates.physicalGridSpacing[2];
1193 });
1194 return retval;
1195 }
1196 ));
1197 outputReducer->addMetadata(outputReducer->size()-1,"C/m^4","$\\mathrm{C}\\mathrm{m}^{-4}$","$\\Delta \\rho_{q,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1198 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp11dx",[](
1199 const FieldSolverData& fieldSolverData)->std::vector<double> {
1200 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1201 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1202
1203 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1204 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1205 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1206 const auto lid = stencil.ooo();
1207 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1208 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp11dx] / coordinates.physicalGridSpacing[0];
1209 });
1210 return retval;
1211 }
1212 ));
1213 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{11,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1214 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp11dy",[](
1215 const FieldSolverData& fieldSolverData)->std::vector<double> {
1216 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1217 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1218
1219 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1220 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1221 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1222 const auto lid = stencil.ooo();
1223 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1224 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp11dy] / coordinates.physicalGridSpacing[1];
1225 });
1226 return retval;
1227 }
1228 ));
1229 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{11,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1230 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp11dz",[](
1231 const FieldSolverData& fieldSolverData)->std::vector<double> {
1232 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1233 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1234
1235 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1236 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1237 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1238 const auto lid = stencil.ooo();
1239 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1240 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp11dz] / coordinates.physicalGridSpacing[2];
1241 });
1242 return retval;
1243 }
1244 ));
1245 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{11,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1246 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp22dx",[](
1247 const FieldSolverData& fieldSolverData)->std::vector<double> {
1248 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1249 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1250
1251 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1252 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1253 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1254 const auto lid = stencil.ooo();
1255 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1256 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp22dx] / coordinates.physicalGridSpacing[0];
1257 });
1258 return retval;
1259 }
1260 ));
1261 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{22,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1262 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp22dy",[](
1263 const FieldSolverData& fieldSolverData)->std::vector<double> {
1264 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1265 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1266
1267 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1268 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1269 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1270 const auto lid = stencil.ooo();
1271 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1272 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp22dy] / coordinates.physicalGridSpacing[1];
1273 });
1274 return retval;
1275 }
1276 ));
1277 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{22,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1278 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp22dz",[](
1279 const FieldSolverData& fieldSolverData)->std::vector<double> {
1280 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1281 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1282
1283 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1284 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1285 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1286 const auto lid = stencil.ooo();
1287 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1288 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp22dz] / coordinates.physicalGridSpacing[2];
1289 });
1290 return retval;
1291 }
1292 ));
1293 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{22,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1294 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp33dx",[](
1295 const FieldSolverData& fieldSolverData)->std::vector<double> {
1296 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1297 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1298
1299 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1300 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1301 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1302 const auto lid = stencil.ooo();
1303 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1304 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp33dx] / coordinates.physicalGridSpacing[0];
1305 });
1306 return retval;
1307 }
1308 ));
1309 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{33,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1310 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp33dy",[](
1311 const FieldSolverData& fieldSolverData)->std::vector<double> {
1312 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1313 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1314
1315 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1316 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1317 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1318 const auto lid = stencil.ooo();
1319 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1320 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp33dy] / coordinates.physicalGridSpacing[1];
1321 });
1322 return retval;
1323 }
1324 ));
1325 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{33,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1326 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dp33dz",[](
1327 const FieldSolverData& fieldSolverData)->std::vector<double> {
1328 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1329 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1330
1331 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1332 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1333 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1334 const auto lid = stencil.ooo();
1335 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1336 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dp33dz] / coordinates.physicalGridSpacing[2];
1337 });
1338 return retval;
1339 }
1340 ));
1341 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_{33,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1342 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvxdx",[](
1343 const FieldSolverData& fieldSolverData)->std::vector<double> {
1344 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1345 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1346
1347 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1348 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1349 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1350 const auto lid = stencil.ooo();
1351 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1352 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVxdx] / coordinates.physicalGridSpacing[0];
1353 });
1354 return retval;
1355 }
1356 ));
1357 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{X,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1358 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvxdy",[](
1359 const FieldSolverData& fieldSolverData)->std::vector<double> {
1360 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1361 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1362
1363 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1364 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1365 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1366 const auto lid = stencil.ooo();
1367 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1368 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVxdy] / coordinates.physicalGridSpacing[1];
1369 });
1370 return retval;
1371 }
1372 ));
1373 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{X,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1374 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvxdz",[](
1375 const FieldSolverData& fieldSolverData)->std::vector<double> {
1376 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1377 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1378
1379 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1380 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1381 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1382 const auto lid = stencil.ooo();
1383 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1384 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVxdz] / coordinates.physicalGridSpacing[2];
1385 });
1386 return retval;
1387 }
1388 ));
1389 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{X,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1390 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvydx",[](
1391 const FieldSolverData& fieldSolverData)->std::vector<double> {
1392 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1393 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1394
1395 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1396 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1397 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1398 const auto lid = stencil.ooo();
1399 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1400 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVydx] / coordinates.physicalGridSpacing[0];
1401 });
1402 return retval;
1403 }
1404 ));
1405 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Y,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1406 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvydy",[](
1407 const FieldSolverData& fieldSolverData)->std::vector<double> {
1408 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1409 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1410
1411 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1412 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1413 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1414 const auto lid = stencil.ooo();
1415 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1416 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVydy] / coordinates.physicalGridSpacing[1];
1417 });
1418 return retval;
1419 }
1420 ));
1421 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Y,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1422 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvydz",[](
1423 const FieldSolverData& fieldSolverData)->std::vector<double> {
1424 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1425 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1426
1427 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1428 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1429 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1430 const auto lid = stencil.ooo();
1431 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1432 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVydz] / coordinates.physicalGridSpacing[2];
1433 });
1434 return retval;
1435 }
1436 ));
1437 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Y,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1438 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvzdx",[](
1439 const FieldSolverData& fieldSolverData)->std::vector<double> {
1440 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1441 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1442
1443 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1444 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1445 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1446 const auto lid = stencil.ooo();
1447 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1448 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVzdx] / coordinates.physicalGridSpacing[0];
1449 });
1450 return retval;
1451 }
1452 ));
1453 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Z,\\mathrm{fg}} (\\Delta X)^{-1}$","1.0");
1454 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvzdy",[](
1455 const FieldSolverData& fieldSolverData)->std::vector<double> {
1456 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1457 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1458
1459 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1460 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1461 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1462 const auto lid = stencil.ooo();
1463 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1464 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVzdy] / coordinates.physicalGridSpacing[1];
1465 });
1466 return retval;
1467 }
1468 ));
1469 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Z,\\mathrm{fg}} (\\Delta Y)^{-1}$","1.0");
1470 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dvzdz",[](
1471 const FieldSolverData& fieldSolverData)->std::vector<double> {
1472 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1473 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1474
1475 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1476 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1477 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1478 const auto lid = stencil.ooo();
1479 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1480 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dVzdz] / coordinates.physicalGridSpacing[2];
1481 });
1482 return retval;
1483 }
1484 ));
1485 outputReducer->addMetadata(outputReducer->size()-1,"1/s","$\\mathrm{s}^{-1}$","$\\Delta V_{Z,\\mathrm{fg}} (\\Delta Z)^{-1}$","1.0");
1486 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dpedx",[](
1487 const FieldSolverData& fieldSolverData)->std::vector<double> {
1488 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1489 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1490
1491 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1492 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1493 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1494 const auto lid = stencil.ooo();
1495 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1496 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dPedx] / coordinates.physicalGridSpacing[0];
1497 });
1498 return retval;
1499 }
1500 ));
1501 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_\\mathrm{e,fg} (\\Delta X)^{-1}$","1.0");
1502 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dpedy",[](
1503 const FieldSolverData& fieldSolverData)->std::vector<double> {
1504 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1505 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1506
1507 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1508 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1509 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1510 const auto lid = stencil.ooo();
1511 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1512 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dPedy] / coordinates.physicalGridSpacing[1];
1513 });
1514 return retval;
1515 }
1516 ));
1517 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_\\mathrm{e,fg} (\\Delta Y)^{-1}$","1.0");
1518 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dpedz",[](
1519 const FieldSolverData& fieldSolverData)->std::vector<double> {
1520 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1521 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1522
1523 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1524 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1525 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1526 const auto lid = stencil.ooo();
1527 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1528 retval[ri] = fieldSolverData.dMoments[lid][fsgrids::dmoments::dPedz] / coordinates.physicalGridSpacing[2];
1529 });
1530 return retval;
1531 }
1532 ));
1533 outputReducer->addMetadata(outputReducer->size()-1,"Pa/m","$\\mathrm{Pa}\\mathrm{m}^{-1}$","$\\Delta P_\\mathrm{e,fg} (\\Delta Z)^{-1}$","1.0");
1534 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxvoldx",[](
1535 const FieldSolverData& fieldSolverData)->std::vector<double> {
1536 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1537 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1538
1539 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1540 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1541 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1542 const auto lid = stencil.ooo();
1543 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1544 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBXVOLdx] / coordinates.physicalGridSpacing[0];
1545 });
1546 return retval;
1547 }
1548 ));
1549 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,fg}} (\\Delta X)^{-1}$","1.0");
1550 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxvoldy",[](
1551 const FieldSolverData& fieldSolverData)->std::vector<double> {
1552 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1553 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1554
1555 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1556 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1557 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1558 const auto lid = stencil.ooo();
1559 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1560 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBXVOLdy] / coordinates.physicalGridSpacing[1];
1561 });
1562 return retval;
1563 }
1564 ));
1565 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1566 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbxvoldz",[](
1567 const FieldSolverData& fieldSolverData)->std::vector<double> {
1568 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1569 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1570
1571 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1572 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1573 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1574 const auto lid = stencil.ooo();
1575 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1576 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBXVOLdz] / coordinates.physicalGridSpacing[2];
1577 });
1578 return retval;
1579 }
1580 ));
1581 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{per,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1582 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbyvoldx",[](
1583 const FieldSolverData& fieldSolverData)->std::vector<double> {
1584 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1585 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1586
1587 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1588 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1589 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1590 const auto lid = stencil.ooo();
1591 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1592 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBYVOLdx] / coordinates.physicalGridSpacing[0];
1593 });
1594 return retval;
1595 }
1596 ));
1597 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,fg}} (\\Delta X)^{-1}$","1.0");
1598 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbyvoldy",[](
1599 const FieldSolverData& fieldSolverData)->std::vector<double> {
1600 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1601 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1602
1603 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1604 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1605 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1606 const auto lid = stencil.ooo();
1607 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1608 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBYVOLdy] / coordinates.physicalGridSpacing[1];
1609 });
1610 return retval;
1611 }
1612 ));
1613 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1614 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbyvoldz",[](
1615 const FieldSolverData& fieldSolverData)->std::vector<double> {
1616 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1617 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1618
1619 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1620 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1621 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1622 const auto lid = stencil.ooo();
1623 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1624 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBYVOLdz] / coordinates.physicalGridSpacing[2];
1625 });
1626 return retval;
1627 }
1628 ));
1629 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{per,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1630 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzvoldx",[](
1631 const FieldSolverData& fieldSolverData)->std::vector<double> {
1632 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1633 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1634
1635 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1636 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1637 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1638 const auto lid = stencil.ooo();
1639 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1640 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBZVOLdx] / coordinates.physicalGridSpacing[0];
1641 });
1642 return retval;
1643 }
1644 ));
1645 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,fg}} (\\Delta X)^{-1}$","1.0");
1646 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzvoldy",[](
1647 const FieldSolverData& fieldSolverData)->std::vector<double> {
1648 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1649 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1650
1651 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1652 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1653 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1654 const auto lid = stencil.ooo();
1655 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1656 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBZVOLdy] / coordinates.physicalGridSpacing[1];
1657 });
1658 return retval;
1659 }
1660 ));
1661 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1662 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dperbzvoldz",[](
1663 const FieldSolverData& fieldSolverData)->std::vector<double> {
1664 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1665 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1666
1667 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1668 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1669 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1670 const auto lid = stencil.ooo();
1671 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1672 retval[ri] = fieldSolverData.vol[lid][fsgrids::volfields::dPERBZVOLdz] / coordinates.physicalGridSpacing[2];
1673 });
1674 return retval;
1675 }
1676 ));
1677 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{per,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1678
1680 continue;
1681 }
1682 }
1683 // End of the long block for fg_derivs
1684 // that writes all the fsgrid-stored derivatives.
1685
1686 // The following long block writes all the background magnetic field derivatives
1687 // we store on fsgrid, that is fg_dbgbidj and fg_dbgbivoldj (also i==j).
1688 // They are derivatives in these DROs, not differences as in the code.
1689 // Search for "fg_derivs_b_background" to find the end of the block.
1690 if(P::systemWriteAllDROs || lowercase == "fg_derivs_b_background") { // includes all face and volume-averaged derivatives of BGB on fg
1691 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbxdy",[](
1692 const FieldSolverData& fieldSolverData)->std::vector<double> {
1693 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1694 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1695
1696 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1697 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1698 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1699 const auto lid = stencil.ooo();
1700 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1701 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBxdy] / coordinates.physicalGridSpacing[1];
1702 });
1703 return retval;
1704 }
1705 ));
1706 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{bg,fg}} (\\Delta Y)^{-1}$","1.0");
1707
1708 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbxdz",[](
1709 const FieldSolverData& fieldSolverData)->std::vector<double> {
1710 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1711 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1712
1713 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1714 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1715 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1716 const auto lid = stencil.ooo();
1717 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1718 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBxdz] / coordinates.physicalGridSpacing[2];
1719 });
1720 return retval;
1721 }
1722 ));
1723 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{bg,fg}} (\\Delta Z)^{-1}$","1.0");
1724
1725 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbydx",[](
1726 const FieldSolverData& fieldSolverData)->std::vector<double> {
1727 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1728 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1729
1730 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1731 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1732 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1733 const auto lid = stencil.ooo();
1734 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1735 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBydx] / coordinates.physicalGridSpacing[0];
1736 });
1737 return retval;
1738 }
1739 ));
1740 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{bg,fg}} (\\Delta X)^{-1}$","1.0");
1741
1742 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbydz",[](
1743 const FieldSolverData& fieldSolverData)->std::vector<double> {
1744 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1745 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1746
1747 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1748 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1749 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1750 const auto lid = stencil.ooo();
1751 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1752 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBydz] / coordinates.physicalGridSpacing[2];
1753 });
1754 return retval;
1755 }
1756 ));
1757 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{bg,fg}} (\\Delta Z)^{-1}$","1.0");
1758
1759 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbzdx",[](
1760 const FieldSolverData& fieldSolverData)->std::vector<double> {
1761 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1762 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1763
1764 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1765 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1766 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1767 const auto lid = stencil.ooo();
1768 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1769 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBzdx] / coordinates.physicalGridSpacing[0];
1770 });
1771 return retval;
1772 }
1773 ));
1774 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{bg,fg}} (\\Delta X)^{-1}$","1.0");
1775
1776 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbzdy",[](
1777 const FieldSolverData& fieldSolverData)->std::vector<double> {
1778 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1779 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1780
1781 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1782 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1783 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1784 const auto lid = stencil.ooo();
1785 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1786 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBzdy] / coordinates.physicalGridSpacing[1];
1787 });
1788 return retval;
1789 }
1790 ));
1791 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{bg,fg}} (\\Delta Y)^{-1}$","1.0");
1792
1793 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbxvoldx",[](
1794 const FieldSolverData& fieldSolverData)->std::vector<double> {
1795 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1796 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1797
1798 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1799 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1800 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1801 const auto lid = stencil.ooo();
1802 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1803 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBXVOLdx] / coordinates.physicalGridSpacing[0];
1804 });
1805 return retval;
1806 }
1807 ));
1808 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{bg,vol,fg}} (\\Delta X)^{-1}$","1.0");
1809
1810 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbxvoldy",[](
1811 const FieldSolverData& fieldSolverData)->std::vector<double> {
1812 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1813 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1814
1815 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1816 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1817 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1818 const auto lid = stencil.ooo();
1819 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1820 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBXVOLdy] / coordinates.physicalGridSpacing[1];
1821 });
1822 return retval;
1823 }
1824 ));
1825 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{bg,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1826
1827 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbxvoldz",[](
1828 const FieldSolverData& fieldSolverData)->std::vector<double> {
1829 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1830 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1831
1832 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1833 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1834 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1835 const auto lid = stencil.ooo();
1836 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1837 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBXVOLdz] / coordinates.physicalGridSpacing[2];
1838 });
1839 return retval;
1840 }
1841 ));
1842 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{X,\\mathrm{bg,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1843
1844 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbyvoldx",[](
1845 const FieldSolverData& fieldSolverData)->std::vector<double> {
1846 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1847 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1848
1849 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1850 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1851 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1852 const auto lid = stencil.ooo();
1853 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1854 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBYVOLdx] / coordinates.physicalGridSpacing[0];
1855 });
1856 return retval;
1857 }
1858 ));
1859 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{bg,vol,fg}} (\\Delta X)^{-1}$","1.0");
1860
1861 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbyvoldy",[](
1862 const FieldSolverData& fieldSolverData)->std::vector<double> {
1863 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1864 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1865
1866 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1867 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1868 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1869 const auto lid = stencil.ooo();
1870 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1871 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBYVOLdy] / coordinates.physicalGridSpacing[1];
1872 });
1873 return retval;
1874 }
1875 ));
1876 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{bg,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1877
1878 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbyvoldz",[](
1879 const FieldSolverData& fieldSolverData)->std::vector<double> {
1880 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1881 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1882
1883 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1884 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1885 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1886 const auto lid = stencil.ooo();
1887 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1888 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBYVOLdz] / coordinates.physicalGridSpacing[2];
1889 });
1890 return retval;
1891 }
1892 ));
1893 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Y,\\mathrm{bg,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1894
1895 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbzvoldx",[](
1896 const FieldSolverData& fieldSolverData)->std::vector<double> {
1897 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1898 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1899
1900 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1901 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1902 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1903 const auto lid = stencil.ooo();
1904 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1905 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBZVOLdx] / coordinates.physicalGridSpacing[0];
1906 });
1907 return retval;
1908 }
1909 ));
1910 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{bg,vol,fg}} (\\Delta X)^{-1}$","1.0");
1911
1912 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbzvoldy",[](
1913 const FieldSolverData& fieldSolverData)->std::vector<double> {
1914 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1915 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1916
1917 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1918 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1919 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1920 const auto lid = stencil.ooo();
1921 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1922 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBZVOLdy] / coordinates.physicalGridSpacing[1];
1923 });
1924 return retval;
1925 }
1926 ));
1927 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{bg,vol,fg}} (\\Delta Y)^{-1}$","1.0");
1928
1929 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_derivatives/fg_dbgbzvoldz",[](
1930 const FieldSolverData& fieldSolverData)->std::vector<double> {
1931 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1932 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1933
1934 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1935 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1936 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1937 const auto lid = stencil.ooo();
1938 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1939 retval[ri] = fieldSolverData.BgB[lid][fsgrids::bgbfield::dBGBZVOLdz] / coordinates.physicalGridSpacing[2];
1940 });
1941 return retval;
1942 }
1943 ));
1944 outputReducer->addMetadata(outputReducer->size()-1,"T/m","$\\mathrm{T}\\,\\mathrm{m}^{-1}$","$\\Delta B_{Z,\\mathrm{bg,vol,fg}} (\\Delta Z)^{-1}$","1.0");
1946 continue;
1947 }
1948 }
1949 // fg_derivs_b_background
1950 // End fo the long block writing out all the background magnetic field derivatives from fsgrid.
1951
1952 if(P::systemWriteAllDROs || lowercase == "vg_gridcoordinates") {
1953 // Spatial coordinates for each cell
1960 outputReducer->addMetadata(outputReducer->size()-6,"m","$\\mathrm{m}$","$X_\\mathrm{vg}$","1.0");
1961 outputReducer->addMetadata(outputReducer->size()-5,"m","$\\mathrm{m}$","$Y_\\mathrm{vg}$","1.0");
1962 outputReducer->addMetadata(outputReducer->size()-4,"m","$\\mathrm{m}$","$Z_\\mathrm{vg}$","1.0");
1963 outputReducer->addMetadata(outputReducer->size()-3,"m","$\\mathrm{m}$","$\\delta X_\\mathrm{vg}$","1.0");
1964 outputReducer->addMetadata(outputReducer->size()-2,"m","$\\mathrm{m}$","$\\delta Y_\\mathrm{vg}$","1.0");
1965 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$\\delta Z_\\mathrm{vg}$","1.0");
1967 continue;
1968 }
1969 }
1970 if(P::systemWriteAllDROs || lowercase == "fg_gridcoordinates") {
1971 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_x",[](
1972 const FieldSolverData& fieldSolverData)->std::vector<double> {
1973 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1974 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1975
1976 // Iterate through fsgrid cells and extract X coordinate
1977 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1978 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1979 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1980 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1981 retval[ri] = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k)[0];
1982 });
1983 return retval;
1984 }
1985 ));
1986 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$X_\\mathrm{fg}$","1.0");
1987 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_y",[](
1988 const FieldSolverData& fieldSolverData)->std::vector<double> {
1989 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
1990 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
1991
1992 // Iterate through fsgrid cells and extract Y coordinate
1993 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
1994 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
1995 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
1996 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
1997 retval[ri] = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k)[1];
1998 });
1999 return retval;
2000 }
2001 ));
2002 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$Y_\\mathrm{fg}$","1.0");
2003 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_z",[](
2004 const FieldSolverData& fieldSolverData)->std::vector<double> {
2005 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
2006 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]);
2007
2008 // Iterate through fsgrid cells and extract Z coordinate
2009 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
2010 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
2011 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
2012 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
2013 retval[ri] = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k)[2];
2014 });
2015 return retval;
2016 }
2017 ));
2018 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$Z_\\mathrm{fg}$","1.0");
2019 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_dx",[](
2020 const FieldSolverData& fieldSolverData)->std::vector<double> {
2021 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
2022 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2], fieldSolverData.fsgrid.getGridSpacing()[0]);
2023 return retval;
2024 }
2025 ));
2026 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$\\delta X_\\mathrm{fg}$","1.0");
2027 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_dy",[](
2028 const FieldSolverData& fieldSolverData)->std::vector<double> {
2029 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
2030 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2], fieldSolverData.fsgrid.getGridSpacing()[1]);
2031 return retval;
2032 }
2033 ));
2034 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$\\delta Y_\\mathrm{fg}$","1.0");
2035 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_dz",[](
2036 const FieldSolverData& fieldSolverData)->std::vector<double> {
2037 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
2038 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2], fieldSolverData.fsgrid.getGridSpacing()[2]);
2039 return retval;
2040 }
2041 ));
2042 outputReducer->addMetadata(outputReducer->size()-1,"m","$\\mathrm{m}$","$\\delta Z_\\mathrm{fg}$","1.0");
2044 continue;
2045 }
2046 }
2047 if(P::systemWriteAllDROs || lowercase == "vg_amr_drho") {
2048 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_drho",CellParams::AMR_DRHO,1));
2049 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\frac{\\Delta \\rho}{\\hat{rho}}$","");
2051 continue;
2052 }
2053 }
2054 if(P::systemWriteAllDROs || lowercase == "vg_amr_du") {
2055 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_du",CellParams::AMR_DU,1));
2056 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\frac{\\Delta U_1}{\\hat{U}_1}$","");
2058 continue;
2059 }
2060 }
2061 if(P::systemWriteAllDROs || lowercase == "vg_amr_dpsq") {
2062 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_dpsq",CellParams::AMR_DPSQ,1));
2063 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\frac{(\\Delta P)^2}{2 \\rho \\hat{U}_1}$","");
2065 continue;
2066 }
2067 }
2068 if(P::systemWriteAllDROs || lowercase == "vg_amr_dbsq") {
2069 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_dbsq",CellParams::AMR_DBSQ,1));
2070 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\frac{(\\Delta B_1)^2}{2 \\mu_0 \\hat{U}_1}$","");
2072 continue;
2073 }
2074 }
2075 if(P::systemWriteAllDROs || lowercase == "vg_amr_db") {
2076 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_db",CellParams::AMR_DB,1));
2077 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\frac{|\\Delta B_1|}{\\hat{B}_1}$","");
2079 continue;
2080 }
2081 }
2082 if(P::systemWriteAllDROs || lowercase == "vg_amr_alpha1") {
2083 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_alpha1",CellParams::AMR_ALPHA1,1));
2084 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\alpha_1$","");
2086 continue;
2087 }
2088 }
2089 if(P::systemWriteAllDROs || lowercase == "vg_amr_reflevel") {
2090 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_reflevel",CellParams::REFINEMENT_LEVEL,1));
2091 outputReducer->addMetadata(outputReducer->size()-1,"","","ref","");
2093 continue;
2094 }
2095 }
2096 if(P::systemWriteAllDROs || lowercase == "vg_amr_alpha2") {
2097 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_alpha2",CellParams::AMR_ALPHA2,1));
2098 outputReducer->addMetadata(outputReducer->size()-1,"","","$\\alpha_2$","");
2100 continue;
2101 }
2102 }
2103 if(P::systemWriteAllDROs || lowercase == "vg_pressure_anisotropy") {
2104 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_pressure_anisotropy",CellParams::P_ANISOTROPY,1));
2105 outputReducer->addMetadata(outputReducer->size()-1,"","","$P_\\perp / P_\\parallel$","");
2107 continue;
2108 }
2109 }
2110 if(P::systemWriteAllDROs || lowercase == "vg_amr_vorticity") {
2111 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_amr_vorticity",CellParams::AMR_VORTICITY,1));
2112 outputReducer->addMetadata(outputReducer->size()-1,"","","Vorticity","");
2114 continue;
2115 }
2116 }
2117 if(P::systemWriteAllDROs || lowercase == "ig_latitude") {
2118 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_latitude", [](
2119 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2120
2121 std::vector<Real> retval(grid.nodes.size());
2122
2123 for(uint i=0; i<grid.nodes.size(); i++) {
2124
2125 // TODO: This is geographic latitude. Should it be magnetic?
2126 Real z = grid.nodes[i].x[2];
2127 retval[i] = acos(z/SBC::Ionosphere::innerRadius) / M_PI * 180.;
2128 }
2129
2130 return retval;
2131 }));
2132 outputReducer->addMetadata(outputReducer->size()-1, "Degrees", "$^\\circ$", "L", "");
2134 continue;
2135 }
2136 }
2137 if(P::systemWriteAllDROs || lowercase == "ig_chi0") {
2138 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_chi0", [](
2139 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2140
2141 std::vector<Real> retval(grid.nodes.size());
2142
2143 for(uint n=0; n<grid.nodes.size(); n++) {
2144 Real theta = acos(grid.nodes[n].x[2] / sqrt(grid.nodes[n].x[0] * grid.nodes[n].x[0] +
2145 grid.nodes[n].x[1] * grid.nodes[n].x[1] +
2146 grid.nodes[n].x[2] * grid.nodes[n].x[2])); // Latitude
2147 if(theta > M_PI/2.) {
2148 theta = M_PI - theta;
2149 }
2150 // Smoothstep with an edge at about 67 deg.
2151 Real Chi0 = 0.01 + 0.99 * .5 * (1 + tanh((23. - theta * (180. / M_PI)) / 6));
2152 retval[n] = Chi0;
2153 }
2154
2155 return retval;
2156 }));
2157 outputReducer->addMetadata(outputReducer->size()-1, "arb.unit.", "", "Chi0", "");
2159 continue;
2160 }
2161 }
2162 if(P::systemWriteAllDROs || lowercase == "ig_cellarea") {
2163 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_cellarea", [](
2164 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2165
2166 std::vector<Real> retval(grid.elements.size());
2167
2168 for(uint i=0; i<grid.elements.size(); i++) {
2169 retval[i] = grid.elementArea(i);
2170 }
2171
2172 return retval;
2173 }));
2174 outputReducer->addMetadata(outputReducer->size()-1, "m^2", "$\\mathrm{m}^2$", "$A_m$", "1.0");
2176 continue;
2177 }
2178 }
2179 if(P::systemWriteAllDROs || lowercase == "ig_b") {
2180 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_b", [](
2181 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2182
2183 std::vector<Real> retval(grid.nodes.size()*3);
2184
2185 for(uint i=0; i<grid.nodes.size(); i++) {
2186 retval[3*i] = grid.nodes[i].parameters[ionosphereParameters::NODE_BX];
2187 retval[3*i+1] = grid.nodes[i].parameters[ionosphereParameters::NODE_BY];
2188 retval[3*i+2] = grid.nodes[i].parameters[ionosphereParameters::NODE_BZ];
2189 }
2190
2191 return retval;
2192 }));
2193 outputReducer->addMetadata(outputReducer->size()-1, "T", "$\\mathrm{T}$", "$B$", "1.0");
2195 continue;
2196 }
2197 }
2198
2199 if(P::systemWriteAllDROs || lowercase == "ig_e") {
2200 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_e", [](
2201 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2202
2203 std::vector<Real> retval(grid.elements.size()*3);
2204
2205 for(uint i=0; i<grid.elements.size(); i++) {
2206 // Calculate E from element basis functions
2207 const std::array<Real, 3>& c1 = grid.nodes[grid.elements[i].corners[0]].x;
2208 const std::array<Real, 3>& c2 = grid.nodes[grid.elements[i].corners[1]].x;
2209 const std::array<Real, 3>& c3 = grid.nodes[grid.elements[i].corners[2]].x;
2210
2211 // ET contains the test function gradient vectors (normalized to potential 1)
2212 std::array<std::array<Real,3>, 3> ET({grid.computeGradT(c2,c3,c1), grid.computeGradT(c3,c1,c2), grid.computeGradT(c1,c2,c3)});
2213 for(int n=0; n<3; n++) {
2214 // Multiply with the corresponding node potentials to get E vector
2215 ET[0][n] *= -grid.nodes[grid.elements[i].corners[0]].parameters[ionosphereParameters::SOLUTION];
2216 ET[1][n] *= -grid.nodes[grid.elements[i].corners[1]].parameters[ionosphereParameters::SOLUTION];
2217 ET[2][n] *= -grid.nodes[grid.elements[i].corners[2]].parameters[ionosphereParameters::SOLUTION];
2218 }
2219 // Sum up element gradient functions to yield complete E inside this element.
2220 for(int n=0; n<3; n++) {
2221 retval[3*i + n] = ET[0][n] + ET[1][n] + ET[2][n];
2222 }
2223 }
2224
2225 return retval;
2226 }));
2227 outputReducer->addMetadata(outputReducer->size()-1, "V/m", "$\\mathrm{V/m}$", "$E$", "1.0");
2229 continue;
2230 }
2231 }
2232 if(P::systemWriteAllDROs || lowercase == "ig_jfromdivj") {
2233 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_jFromDivJ", [&](SBC::SphericalTriGrid& grid)->std::vector<Real> {
2234
2235 std::vector<Real> retval(3*grid.elements.size());
2236
2237
2238 for(uint el=0; el<grid.elementDivFreeCurrent.size(); el++) {
2239 Eigen::Vector3d J = grid.elementDivFreeCurrent[el];
2240 retval[3*el] = J[0];
2241 retval[3*el+1] = J[1];
2242 retval[3*el+2] = J[2];
2243 }
2244
2245 return retval;
2246
2247 }));
2248
2249 outputReducer->addMetadata(outputReducer->size()-1, "A", "$\\mathrm{A}$", "$J_{\\text{divJ}}$", "1.0");
2251 continue;
2252 }
2253 }
2254
2255 if(P::systemWriteAllDROs || lowercase == "ig_jfromcurlj") {
2256 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_jFromCurlJ", [&](SBC::SphericalTriGrid& grid)->std::vector<Real> {
2257
2258 std::vector<Real> retval(3*grid.elements.size());
2259
2260 for(uint el=0; el<grid.elementCurlFreeCurrent.size(); el++) {
2261 Eigen::Vector3d J = grid.elementCurlFreeCurrent[el];
2262 retval[3*el] = J[0];
2263 retval[3*el+1] = J[1];
2264 retval[3*el+2] = J[2];
2265 }
2266
2267 return retval;
2268 }));
2269
2270 outputReducer->addMetadata(outputReducer->size()-1, "A", "$\\mathrm{A}$", "$J_{\\text{curlJ}}$", "1.0");
2272 continue;
2273 }
2274 }
2275
2276 if(P::systemWriteAllDROs || lowercase == "ig_inplanecurrent") {
2277 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_inplanecurrent", [](
2278 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2279
2280 std::vector<Real> retval(grid.elements.size()*3);
2281
2282 for(uint i=0; i<grid.elements.size(); i++) {
2283 // Get effective sigma tensor for this element
2284 std::array<Real, 9> sigma = grid.sigmaAverage(i);
2285
2286 // Calculate E from element basis functions
2287 std::array<Real, 3> E({0,0,0});
2288 const std::array<Real, 3>& c1 = grid.nodes[grid.elements[i].corners[0]].x;
2289 const std::array<Real, 3>& c2 = grid.nodes[grid.elements[i].corners[1]].x;
2290 const std::array<Real, 3>& c3 = grid.nodes[grid.elements[i].corners[2]].x;
2291
2292 // ET contains the test function gradient vectors (normalized to potential 1)
2293 std::array<std::array<Real,3>, 3> ET({grid.computeGradT(c2,c3,c1), grid.computeGradT(c3,c1,c2), grid.computeGradT(c1,c2,c3)});
2294 for(int n=0; n<3; n++) {
2295 // Multiply with the corresponding node potentials to get E vector
2296 ET[0][n] *= -grid.nodes[grid.elements[i].corners[0]].parameters[ionosphereParameters::SOLUTION];
2297 ET[1][n] *= -grid.nodes[grid.elements[i].corners[1]].parameters[ionosphereParameters::SOLUTION];
2298 ET[2][n] *= -grid.nodes[grid.elements[i].corners[2]].parameters[ionosphereParameters::SOLUTION];
2299 }
2300 // Sum up element gradient functions to yield complete E inside this element.
2301 for(int n=0; n<3; n++) {
2302 E[n] = ET[0][n] + ET[1][n] + ET[2][n];
2303 }
2304
2305 // Get J from Ohm's law (J = sigma * E)
2306 for(int n=0; n<3; n++) {
2307 for(int m=0; m<3; m++) {
2308 retval[3*i + n] += sigma[3*n+m] * E[m];
2309 }
2310 }
2311 }
2312
2313 return retval;
2314 }));
2315 outputReducer->addMetadata(outputReducer->size()-1, "A/m^2", "$\\mathrm{A/m}^2$", "$J$", "1.0");
2317 continue;
2318 }
2319 }
2320 if(P::systemWriteAllDROs || lowercase == "ig_upmappedarea") {
2321 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereElement("ig_upmappedarea", [](
2322 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2323
2324 std::vector<Real> retval(grid.elements.size()*3);
2325
2326 for(uint i=0; i<grid.elements.size(); i++) {
2327 std::array<Real, 3> area = grid.mappedElementArea(i);
2328 retval[3*i] = area[0];
2329 retval[3*i+1] = area[1];
2330 retval[3*i+2] = area[2];
2331 }
2332
2333 return retval;
2334 }));
2335 outputReducer->addMetadata(outputReducer->size()-1, "m^2", "$\\mathrm{m}^2$", "$A_m$", "1.0");
2337 continue;
2338 }
2339 }
2340 if(P::systemWriteAllDROs || lowercase == "ig_sigmap") {
2341 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_sigmap", [](
2342 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2343
2344 std::vector<Real> retval(grid.nodes.size());
2345
2346 for(uint i=0; i<grid.nodes.size(); i++) {
2347 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SIGMAP];
2348 }
2349
2350 return retval;
2351 }));
2352 outputReducer->addMetadata(outputReducer->size()-1, "mho", "$\\mathrm{\\Omega^{-1}}$", "$\\Sigma_P$", "1.0");
2354 continue;
2355 }
2356 }
2357 if(P::systemWriteAllDROs || lowercase == "ig_sigmah") {
2358 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_sigmah", [](
2359 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2360
2361 std::vector<Real> retval(grid.nodes.size());
2362
2363 for(uint i=0; i<grid.nodes.size(); i++) {
2364 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SIGMAH];
2365 }
2366
2367 return retval;
2368 }));
2369 outputReducer->addMetadata(outputReducer->size()-1, "mho", "$\\mathrm{\\Omega^{-1}}$", "$\\Sigma_H$", "1.0");
2371 continue;
2372 }
2373 }
2374 if(P::systemWriteAllDROs || lowercase == "ig_sigmaparallel") {
2375 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_sigmaparallel", [](
2376 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2377
2378 std::vector<Real> retval(grid.nodes.size());
2379
2380 for(uint i=0; i<grid.nodes.size(); i++) {
2381 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SIGMAPARALLEL];
2382 }
2383
2384 return retval;
2385 }));
2386 outputReducer->addMetadata(outputReducer->size()-1, "mho", "$\\mathrm{\\Omega^{-1}}$", "$\\Sigma_\\parallel$", "1.0");
2388 continue;
2389 }
2390 }
2391 if(P::systemWriteAllDROs || lowercase == "ig_rhon") {
2392 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_rhon", [](
2393 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2394
2395 std::vector<Real> retval(grid.nodes.size());
2396
2397 for(uint i=0; i<grid.nodes.size(); i++) {
2398 retval[i] = grid.nodes[i].parameters[ionosphereParameters::RHON];
2399 }
2400
2401 return retval;
2402 }));
2403 outputReducer->addMetadata(outputReducer->size()-1, "m^-3", "$\\mathrm{m^{-3}}$", "$\\n_e$", "1.0");
2405 continue;
2406 }
2407 }
2408 if(P::systemWriteAllDROs || lowercase == "ig_electrontemp") {
2409 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_electrontemp", [](
2410 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2411
2412 std::vector<Real> retval(grid.nodes.size());
2413
2414 for(uint i=0; i<grid.nodes.size(); i++) {
2415 retval[i] = grid.nodes[i].electronTemperature();
2416 }
2417
2418 return retval;
2419 }));
2420 outputReducer->addMetadata(outputReducer->size()-1, "K", "$\\mathrm{K}$", "$T_e$", "1.0");
2422 continue;
2423 }
2424 }
2425 if(P::systemWriteAllDROs || lowercase == "ig_deltaphi") {
2426 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_deltaphi", [](
2427 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2428
2429 std::vector<Real> retval(grid.nodes.size());
2430
2431 for(uint i=0; i<grid.nodes.size(); i++) {
2432 retval[i] = grid.nodes[i].deltaPhi();
2433 }
2434
2435 return retval;
2436 }));
2437 outputReducer->addMetadata(outputReducer->size()-1, "eV", "$\\mathrm{eV}$", "$\\Delta\\Phi$", "1.0");
2439 continue;
2440 }
2441 }
2442 if(P::systemWriteAllDROs || lowercase == "ig_precipitation") {
2443 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_precipitation", [](
2444 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2445
2446 std::vector<Real> retval(grid.nodes.size());
2447
2448 for(uint i=0; i<grid.nodes.size(); i++) {
2449 retval[i] = grid.nodes[i].parameters[ionosphereParameters::PRECIP];
2450 }
2451
2452 return retval;
2453 }));
2454 outputReducer->addMetadata(outputReducer->size()-1, "W/m^2", "$\\mathrm{W m^{-2}}$", "$W_\\mathrm{precipitation}$", "1.0");
2456 continue;
2457 }
2458 }
2459 if(P::systemWriteAllDROs || lowercase == "ig_precipnumflux") {
2460 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_precipnumflux", [](SBC::SphericalTriGrid& grid)->std::vector<Real> {
2461
2462 std::array< Real, SBC::productionNumParticleEnergies+1 > particle_energy;
2463 // Precalculate effective energy bins
2464 // Make sure this stays in sync with sysboundary/ionosphere.cpp
2465 for(int e=0; e<SBC::productionNumParticleEnergies; e++) {
2466 particle_energy[e] = pow(10.0, -1.+e*(2.3+1.)/(SBC::productionNumParticleEnergies-1));
2467 }
2469
2471
2472 std::vector<Real> retval(grid.nodes.size());
2473 for(uint i=0; i<grid.nodes.size(); i++) {
2474 Real temp_keV = physicalconstants::K_B * grid.nodes[i].electronTemperature() / physicalconstants::CHARGE / 1000;
2475
2476 for(int p=0; p<SBC::productionNumParticleEnergies; p++) {
2477 Real energyparam = (particle_energy[p]-accenergy)/temp_keV; // = E_p / (kB T)
2478 Real deltaE = (particle_energy[p+1] - particle_energy[p])* 1e3*physicalconstants::CHARGE; // dE in J
2479 retval[i] += grid.nodes[i].parameters[ionosphereParameters::RHON] * sqrt(1. / (2. * M_PI * physicalconstants::MASS_ELECTRON))
2480 * particle_energy[p] / temp_keV / sqrt(temp_keV * 1e3 *physicalconstants::CHARGE)
2481 * deltaE * exp(-energyparam); // Flux 1/m^2/s
2482 }
2483 }
2484 return retval;
2485 }));
2486 outputReducer->addMetadata(outputReducer->size()-1, "1/m^2/s", "$m^{-2} s^{-1}$", "$\\bar{F}_\\mathrm{precip}$", "1.0");
2488 continue;
2489 }
2490 }
2491 if(P::systemWriteAllDROs || lowercase == "ig_precipavgenergy") {
2492 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_precipavgenergy", [](SBC::SphericalTriGrid& grid)->std::vector<Real> {
2493
2494 std::array< Real, SBC::productionNumParticleEnergies+1 > particle_energy;
2495 // Precalculate effective energy bins
2496 // Make sure this stays in sync with sysboundary/ionosphere.cpp
2497 for(int e=0; e<SBC::productionNumParticleEnergies; e++) {
2498 particle_energy[e] = pow(10.0, -1.+e*(2.3+1.)/(SBC::productionNumParticleEnergies-1));
2499 }
2501
2503
2504 std::vector<Real> retval(grid.nodes.size());
2505 for(uint i=0; i<grid.nodes.size(); i++) {
2506 Real numberFlux = 0;
2507
2508 // Calculate precipitating number flux at this node
2509 // (TODO: this is completely copy'n'pasted from the
2510 // ig_precipnumflux reducer above. Share code?)
2511 Real temp_keV = physicalconstants::K_B * grid.nodes[i].electronTemperature() / physicalconstants::CHARGE / 1000;
2512
2513 for(int p=0; p<SBC::productionNumParticleEnergies; p++) {
2514 Real energyparam = (particle_energy[p]-accenergy)/temp_keV; // = E_p / (kB T)
2515 Real deltaE = (particle_energy[p+1] - particle_energy[p])* 1e3*physicalconstants::CHARGE; // dE in J
2516 numberFlux += grid.nodes[i].parameters[ionosphereParameters::RHON] * sqrt(1. / (2. * M_PI * physicalconstants::MASS_ELECTRON))
2517 * particle_energy[p] / temp_keV / sqrt(temp_keV * 1e3 *physicalconstants::CHARGE)
2518 * deltaE * exp(-energyparam); // Flux 1/m^2/s
2519 }
2520
2521 // Average precipitating energy = energyFlux / numberFlux (in eV)
2522 retval[i] = grid.nodes[i].parameters[ionosphereParameters::PRECIP] / numberFlux / physicalconstants::CHARGE;
2523 }
2524 return retval;
2525 }));
2526 outputReducer->addMetadata(outputReducer->size()-1, "eV", "eV", "$\\bar{E}_\\mathrm{precip}$", "1.0");
2528 continue;
2529 }
2530 }
2531 if(P::systemWriteAllDROs || lowercase == "ig_potential") {
2532 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_potential", [](
2533 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2534
2535 std::vector<Real> retval(grid.nodes.size());
2536
2537 for(uint i=0; i<grid.nodes.size(); i++) {
2538 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SOLUTION];
2539 }
2540
2541 return retval;
2542 }));
2543 outputReducer->addMetadata(outputReducer->size()-1, "V", "$\\mathrm{V}$", "$\\phi_I$", "1.0");
2545 continue;
2546 }
2547 }
2548 if(P::systemWriteAllDROs || lowercase == "ig_solverinternals") {
2549 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_source", [](
2550 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2551
2552 std::vector<Real> retval(grid.nodes.size());
2553
2554 for(uint i=0; i<grid.nodes.size(); i++) {
2555 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SOURCE];
2556 }
2557
2558 return retval;
2559 }));
2560 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_residual", [](
2561 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2562
2563 std::vector<Real> retval(grid.nodes.size());
2564
2565 for(uint i=0; i<grid.nodes.size(); i++) {
2566 retval[i] = grid.nodes[i].parameters[ionosphereParameters::RESIDUAL];
2567 }
2568
2569 return retval;
2570 }));
2571 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_p", [](
2572 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2573
2574 std::vector<Real> retval(grid.nodes.size());
2575
2576 for(uint i=0; i<grid.nodes.size(); i++) {
2577 retval[i] = grid.nodes[i].parameters[ionosphereParameters::PPARAM];
2578 }
2579
2580 return retval;
2581 }));
2582 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_pp", [](
2583 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2584
2585 std::vector<Real> retval(grid.nodes.size());
2586
2587 for(uint i=0; i<grid.nodes.size(); i++) {
2588 retval[i] = grid.nodes[i].parameters[ionosphereParameters::PPPARAM];
2589 }
2590
2591 return retval;
2592 }));
2593 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_z", [](
2594 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2595
2596 std::vector<Real> retval(grid.nodes.size());
2597
2598 for(uint i=0; i<grid.nodes.size(); i++) {
2599 retval[i] = grid.nodes[i].parameters[ionosphereParameters::ZPARAM];
2600 }
2601
2602 return retval;
2603 }));
2604 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_zz", [](
2605 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2606
2607 std::vector<Real> retval(grid.nodes.size());
2608
2609 for(uint i=0; i<grid.nodes.size(); i++) {
2610 retval[i] = grid.nodes[i].parameters[ionosphereParameters::ZZPARAM];
2611 }
2612
2613 return retval;
2614 }));
2615
2617 continue;
2618 }
2619 }
2620 if(P::systemWriteAllDROs || lowercase == "ig_upmappednodecoords") {
2621 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_upmappednodecoords", [](
2622 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2623
2624 std::vector<Real> retval(grid.nodes.size()*3);
2625
2626 for(uint i=0; i<grid.nodes.size(); i++) {
2627 retval[3*i] = grid.nodes[i].xMapped[0];
2628 retval[3*i+1] = grid.nodes[i].xMapped[1];
2629 retval[3*i+2] = grid.nodes[i].xMapped[2];
2630 }
2631
2632 return retval;
2633 }));
2634 outputReducer->addMetadata(outputReducer->size()-1, "m", "m", "$x_\\mathrm{mapped}$", "1.0");
2636 continue;
2637 }
2638 }
2639 if(P::systemWriteAllDROs || lowercase == "ig_upmappedb") {
2640 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_upmappedb", [](
2641 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2642
2643 std::vector<Real> retval(grid.nodes.size()*3);
2644
2645 for(uint i=0; i<grid.nodes.size(); i++) {
2646 retval[3*i] = grid.nodes[i].parameters[ionosphereParameters::UPMAPPED_BX];
2647 retval[3*i+1] = grid.nodes[i].parameters[ionosphereParameters::UPMAPPED_BY];
2648 retval[3*i+2] = grid.nodes[i].parameters[ionosphereParameters::UPMAPPED_BZ];
2649 }
2650
2651 return retval;
2652 }));
2653 outputReducer->addMetadata(outputReducer->size()-1, "T", "T", "$B_\\mathrm{mapped}$", "1.0");
2655 continue;
2656 }
2657 }
2658 if(P::systemWriteAllDROs || lowercase == "ig_openclosed") {
2659 FieldTracing::fieldTracingParameters.doTraceOpenClosed = true;
2660 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_openclosed", [](
2661 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2662
2663 std::vector<Real> retval(grid.nodes.size());
2664
2665 for(uint i=0; i<grid.nodes.size(); i++) {
2666 retval[i] = (Real)grid.nodes[i].openFieldLine;
2667 }
2668
2669 return retval;
2670 }));
2672 continue;
2673 }
2674 }
2675 if(P::systemWriteAllDROs || lowercase == "ig_fac") {
2676 outputReducer->addOperator(new DRO::DataReductionOperatorIonosphereNode("ig_fac", [](
2677 SBC::SphericalTriGrid& grid)->std::vector<Real> {
2678
2679 std::vector<Real> retval(grid.nodes.size());
2680
2681 for(uint i=0; i<grid.nodes.size(); i++) {
2682 Real area = 0;
2683 for(uint e=0; e<grid.nodes[i].numTouchingElements; e++) {
2684 area += grid.elementArea(grid.nodes[i].touchingElements[e]);
2685 }
2686 area /= 3.; // As every element has 3 corners, don't double-count areas
2687 retval[i] = grid.nodes[i].parameters[ionosphereParameters::SOURCE]/area;
2688 }
2689
2690 return retval;
2691 }));
2692 outputReducer->addMetadata(outputReducer->size()-1, "A/m^2", "$\\mathrm{A m}^{-2}$", "$I_\\mathrm{FAC}$", "1.0");
2694 continue;
2695 }
2696 }
2697 if(P::systemWriteAllDROs || lowercase == "vg_ionospherecoupling") {
2698 outputReducer->addOperator(new DRO::DataReductionOperatorMPIGridCell("vg_ionospherecoupling", 3, [](
2699 const SpatialCell* cell)->std::vector<Real> {
2700
2701 std::vector<Real> retval(3);
2702
2703 // Just return a 0,0,0 vector for non-ionosphere cells
2705 retval[0]=0;
2706 retval[1]=0;
2707 retval[2]=0;
2708 return retval;
2709 }
2710
2711 std::array<Real, 3> x;
2715
2716 std::array<std::pair<int, Real>, 3> coupling = FieldTracing::calculateIonosphereVlasovGridCoupling(x, SBC::ionosphereGrid.nodes, SBC::Ionosphere::radius);
2717 for(int i=0; i<3; i++) {
2718 uint coupledNode = coupling[i].first;
2719 Real a = coupling[i].second;
2720 retval[0] += a*SBC::ionosphereGrid.nodes[coupledNode].x[0] - (cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX]);
2721 retval[1] = a*SBC::ionosphereGrid.nodes[coupledNode].x[1] - (cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY]);
2722 retval[2] = a*SBC::ionosphereGrid.nodes[coupledNode].x[2] - (cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ]);
2723 }
2724
2725 return retval;
2726 }));
2727 outputReducer->addMetadata(outputReducer->size()-1, "m", "m", "$x_\\mathrm{coupled}$", "1.0");
2729 continue;
2730 }
2731 }
2732 if(P::systemWriteAllDROs || lowercase == "vg_connection") {
2733 FieldTracing::fieldTracingParameters.doTraceFullBox = true;
2734 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_connection",CellParams::CONNECTION,1));
2735 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_connection_coordinates_fw",CellParams::CONNECTION_FW_X,3));
2736 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_connection_coordinates_bw",CellParams::CONNECTION_BW_X,3));
2738 continue;
2739 }
2740 }
2741 if(P::systemWriteAllDROs || lowercase == "vg_fluxrope" || lowercase == "vg_curvature") {
2743 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_curvature",CellParams::CURVATUREX,3));
2744 if(P::systemWriteAllDROs || lowercase == "vg_fluxrope") {
2745 FieldTracing::fieldTracingParameters.doTraceFullBox = true;
2746 outputReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_fluxrope",CellParams::FLUXROPE,1));
2747 }
2749 continue;
2750 }
2751 }
2752 if(P::systemWriteAllDROs || lowercase == "fg_curvature") {
2754 outputReducer->addOperator(new DRO::DataReductionOperatorFsGrid("fg_curvature",[](
2755 const FieldSolverData& fieldSolverData)->std::vector<double> {
2756 const auto* gridSize = &fieldSolverData.fsgrid.getLocalSize()[0];
2757 std::vector<double> retval(gridSize[0]*gridSize[1]*gridSize[2]*3);
2758
2759 fieldSolverData.fsgrid.serial_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
2760 phiprof::initializeTimer("DRO_fg"), fieldSolverData.technical,
2761 [=, &retval](const fsgrid::Coordinates coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
2762 const auto lid = stencil.ooo();
2763 const auto ri = gridSize[1]*gridSize[0]*stencil.k + gridSize[0]*stencil.j + stencil.i;
2764 retval[3*ri] = fieldSolverData.vol[lid][fsgrids::volfields::CURVATUREX];
2765 retval[3*ri+1] = fieldSolverData.vol[lid][fsgrids::volfields::CURVATUREY];
2766 retval[3*ri+2] = fieldSolverData.vol[lid][fsgrids::volfields::CURVATUREZ];
2767 });
2768 return retval;
2769 }
2770 ));
2772 continue;
2773 }
2774 }
2776 break; // from the loop
2777 }
2778 // After all the continue; statements one should never land here.
2779 int myRank;
2780 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
2781 if (myRank == MASTER_RANK) {
2782 std::cerr << __FILE__ << ":" << __LINE__ << ": The output variable " << *it << " is not defined." << std::endl;
2783 }
2784 MPI_Finalize();
2785 exit(1);
2786 }
2787
2788 for (it = P::diagnosticVariableList.begin();
2789 it != P::diagnosticVariableList.end();
2790 it++) {
2791
2792 // Sidestep mixed case errors
2793 std::string lowercase = *it;
2794 for(auto& c : lowercase) c = tolower(c);
2795
2796 if(P::diagnosticWriteAllDROs || lowercase == "populations_blocks" || lowercase == "populations_vg_blocks") {
2797 // Per-population total block counts
2798 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
2799 diagnosticReducer->addOperator(new DRO::Blocks(i));
2800 }
2802 continue;
2803 }
2804 }
2805 if(P::diagnosticWriteAllDROs || lowercase == "vg_rhom" || lowercase == "rhom") {
2806 // Overall mass density
2807 diagnosticReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_rhom",CellParams::RHOM,1));
2809 continue;
2810 }
2811 }
2812 if(P::diagnosticWriteAllDROs || lowercase == "populations_rholossadjust" || lowercase == "populations_rho_loss_adjust" || lowercase == "populations_vg_rho_loss_adjust") {
2813 // Per-particle overall lost particle number
2814 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
2816 const std::string& pop = species.name;
2817 diagnosticReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_rho_loss_adjust", i, offsetof(spatial_cell::Population, RHOLOSSADJUST), 1));
2818 }
2820 continue;
2821 }
2822 }
2823 if(P::diagnosticWriteAllDROs || lowercase == "lbweight" || lowercase == "vg_lbweight" || lowercase == "vg_loadbalanceweight" || lowercase == "vg_loadbalance_weight" || lowercase == "loadbalance_weight") {
2824 diagnosticReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_loadbalance_weight",CellParams::LBWEIGHTCOUNTER,1));
2826 continue;
2827 }
2828 }
2829 if(P::diagnosticWriteAllDROs || lowercase == "maxvdt" || lowercase == "maxdt_acceleration" || lowercase == "vg_maxdt_acceleration") {
2830 diagnosticReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_maxdt_acceleration",CellParams::MAXVDT,1));
2832 continue;
2833 }
2834 }
2835 if(P::diagnosticWriteAllDROs || lowercase == "maxrdt" || lowercase == "maxdt_translation" || lowercase == "vg_maxdt_translation") {
2836 diagnosticReducer->addOperator(new DRO::DataReductionOperatorCellParams("vg_maxdt_translation",CellParams::MAXRDT,1));
2838 continue;
2839 }
2840 }
2841 if(P::diagnosticWriteAllDROs || lowercase == "maxfieldsdt" || lowercase == "maxdt_fieldsolver" || lowercase == "fg_maxfieldsdt" || lowercase == "fg_maxdt_fieldsolver") {
2842 diagnosticReducer->addOperator(new DRO::DataReductionOperatorCellParams("fg_maxdt_fieldsolver",CellParams::MAXFDT,1));
2844 continue;
2845 }
2846 }
2847 if(P::diagnosticWriteAllDROs || lowercase == "populations_maxrdt" || lowercase == "populations_maxdt_translation" || lowercase == "populations_vg_maxdt_translation") {
2848 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
2850 const std::string& pop = species.name;
2851 diagnosticReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_maxdt_translation", i, offsetof(spatial_cell::Population, max_dt[0]), 1));
2852 }
2854 continue;
2855 }
2856 }
2857 if(P::diagnosticWriteAllDROs || lowercase == "populations_maxvdt" || lowercase == "populations_maxdt_acceleration" || lowercase == "populations_vg_maxdt_acceleration") {
2858 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
2860 const std::string& pop = species.name;
2861 diagnosticReducer->addOperator(new DRO::DataReductionOperatorPopulations<Real>(pop + "/vg_maxdt_acceleration", i, offsetof(spatial_cell::Population, max_dt[1]), 1));
2862 }
2864 continue;
2865 }
2866 }
2868 break; // from the loop
2869 }
2870 // After all the continue; statements one should never land here.
2871 int myRank;
2872 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
2873 if (myRank == MASTER_RANK) {
2874 std::cerr << __FILE__ << ":" << __LINE__ << ": The diagnostic variable " << *it << " is not defined." << std::endl;
2875 }
2876 MPI_Finalize();
2877 exit(1);
2878 }
2879}
2880
2881// ************************************************************
2882// ***** DEFINITIONS FOR DATAREDUCER CLASS *****
2883// ************************************************************
2884
2888
2893 // Call delete for each DataReductionOperator:
2894 for (vector<DRO::DataReductionOperator*>::iterator it=operators.begin(); it!=operators.end(); ++it) {
2895 delete *it;
2896 *it = NULL;
2897 }
2898}
2899
2905 operators.push_back(op);
2906 return true;
2907}
2908
2913std::string DataReducer::getName(const unsigned int& operatorID) const {
2914 if (operatorID >= operators.size()) return "";
2915 return operators[operatorID]->getName();
2916}
2917
2928bool DataReducer::getDataVectorInfo(const unsigned int& operatorID,std::string& dataType,unsigned int& dataSize,unsigned int& vectorSize) const {
2929 if (operatorID >= operators.size()) return false;
2930 return operators[operatorID]->getDataVectorInfo(dataType,dataSize,vectorSize);
2931}
2932
2941bool DataReducer::addMetadata(const unsigned int operatorID, std::string unit,std::string unitLaTeX,std::string variableLaTeX,std::string unitConversion) {
2942 if (operatorID >= operators.size()) return false;
2943 return operators[operatorID]->setUnitMetadata(unit,unitLaTeX,variableLaTeX,unitConversion);
2944}
2945
2953bool DataReducer::getMetadata(const unsigned int& operatorID,std::string& unit,std::string& unitLaTeX,std::string& variableLaTeX,std::string& unitConversion) const {
2954 if (operatorID >= operators.size()) return false;
2955 return operators[operatorID]->getUnitMetadata(unit, unitLaTeX, variableLaTeX, unitConversion);
2956}
2957
2961bool DataReducer::hasParameters(const unsigned int& operatorID) const {
2962 if (operatorID >= operators.size()) return false;
2963 return dynamic_cast<DRO::DataReductionOperatorHasParameters*>(operators[operatorID]) != nullptr;
2964}
2965
2972bool DataReducer::reduceData(const SpatialCell* cell,const unsigned int& operatorID,char* buffer) {
2973 // Tell the chosen operator which spatial cell we are counting:
2974 if (operatorID >= operators.size()) return false;
2975 if (operators[operatorID]->setSpatialCell(cell) == false) return false;
2976
2977 if (operators[operatorID]->reduceData(cell,buffer) == false) return false;
2978 return true;
2979}
2980
2987bool DataReducer::reduceDiagnostic(const SpatialCell* cell,const unsigned int& operatorID,Real * result) {
2988 // Tell the chosen operator which spatial cell we are counting:
2989 if (operatorID >= operators.size()) return false;
2990 if (operators[operatorID]->setSpatialCell(cell) == false) return false;
2991
2992 if (operators[operatorID]->reduceDiagnostic(cell,result) == false) return false;
2993 return true;
2994}
2995
2999unsigned int DataReducer::size() const {return operators.size();}
3000
3005bool DataReducer::writeParameters(const unsigned int& operatorID, vlsv::Writer& vlsvWriter) {
3006 if (operatorID >= operators.size()) return false;
3007 DRO::DataReductionOperatorHasParameters* parameterOperator = dynamic_cast<DRO::DataReductionOperatorHasParameters*>(operators[operatorID]);
3008 if(parameterOperator == nullptr) {
3009 return false;
3010 }
3011 return parameterOperator->writeParameters(vlsvWriter);
3012}
3013
3016 const FieldSolverData& fieldSolverData,
3017 const std::string& meshName, const unsigned int operatorID,
3018 vlsv::Writer& vlsvWriter,
3019 const bool writeAsFloat) {
3020
3021 if (operatorID >= operators.size()) return false;
3023 if(!DROf) {
3024 return false;
3025 } else {
3026 return DROf->writeFsGridData(fieldSolverData, meshName, vlsvWriter, writeAsFloat);
3027 }
3028}
3029
3031 SBC::SphericalTriGrid& grid, const std::string& meshName,
3032 const unsigned int operatorID, vlsv::Writer& vlsvWriter) {
3033
3034 if (operatorID >= operators.size()) return false;
3037 if(DROe) {
3038 return DROe->writeIonosphereData(grid, vlsvWriter);
3039 } else if(DROn) {
3040 return DROn->writeIonosphereData(grid, vlsvWriter);
3041 } else {
3042 return false;
3043 }
3044
3045}
for i
Definition Dispersion.m:24
Numerical propagation V
Definition Dispersion.m:98
sqrt(1.0+vA *vA/(c *c))) % Ion-acoustic wave cS
Constants c
Definition Dispersion.m:45
virtual bool writeFsGridData(const FieldSolverData &fieldSolverData, const std::string &meshName, vlsv::Writer &vlsvWriter, const bool writeAsFloat=false)
virtual bool writeParameters(vlsv::Writer &vlsvWriter)=0
virtual bool writeIonosphereData(SBC::SphericalTriGrid &grid, vlsv::Writer &vlsvWriter)
virtual bool writeIonosphereData(SBC::SphericalTriGrid &grid, vlsv::Writer &vlsvWriter)
bool reduceDiagnostic(const SpatialCell *cell, const unsigned int &operatorID, Real *result)
bool getMetadata(const unsigned int &operatorID, std::string &unit, std::string &unitLaTeX, std::string &variableLaTeX, std::string &unitConversion) const
unsigned int size() const
bool writeFsGridData(const FieldSolverData &fieldSolverData, const std::string &meshName, const unsigned int operatorID, vlsv::Writer &vlsvWriter, const bool writeAsFloat=false)
bool addOperator(DRO::DataReductionOperator *op)
bool hasParameters(const unsigned int &operatorID) const
bool addMetadata(const unsigned int operatorID, std::string unit, std::string unitLaTeX, std::string variableLaTeX, std::string unitConversion)
bool writeParameters(const unsigned int &operatorID, vlsv::Writer &vlsvWriter)
std::string getName(const unsigned int &operatorID) const
bool reduceData(const SpatialCell *cell, const unsigned int &operatorID, char *buffer)
std::vector< DRO::DataReductionOperator * > operators
Definition datareducer.h:69
bool writeIonosphereGridData(SBC::SphericalTriGrid &grid, const std::string &meshName, const unsigned int operatorID, vlsv::Writer &vlsvWriter)
bool getDataVectorInfo(const unsigned int &operatorID, std::string &dataType, unsigned int &dataSize, unsigned int &vectorSize) const
static Real innerRadius
Definition ionosphere.h:622
static Real radius
Definition ionosphere.h:618
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
@ SOURCE
Definition common.h:459
@ SIGMAP
Definition common.h:464
@ SOLUTION
Definition common.h:472
@ PPARAM
Definition common.h:477
@ NODE_BX
Definition common.h:470
@ SIGMAPARALLEL
Definition common.h:466
@ PPPARAM
Definition common.h:477
@ RESIDUAL
Definition common.h:474
@ ZZPARAM
Definition common.h:476
@ UPMAPPED_BX
Definition common.h:471
@ ZPARAM
Definition common.h:476
@ NODE_BY
Definition common.h:470
@ SIGMAH
Definition common.h:465
@ UPMAPPED_BZ
Definition common.h:471
@ PRECIP
Definition common.h:467
@ RHON
Definition common.h:468
@ UPMAPPED_BY
Definition common.h:471
@ NODE_BZ
Definition common.h:470
#define MASTER_RANK
Definition common.h:67
void initializeDataReducers(DataReducer *outputReducer, DataReducer *diagnosticReducer)
Parameters P
const uint32_t cuint
Definition definitions.h:50
float Real
Definition definitions.h:41
std::array< Real, productionNumParticleEnergies+1 > particle_energy
int myRank
Definition gpu_base.cpp:48
ObjectWrapper & getObjectWrapper()
Definition main.cpp:33
#define index(i, j, k)
@ CONNECTION_BW_X
Definition common.h:208
@ CONNECTION_FW_X
Definition common.h:205
@ BULKV_FORCING_X
Definition common.h:225
@ REFINEMENT_LEVEL
Definition common.h:203
@ CURVATUREX
Definition common.h:211
@ AMR_ALPHA2
Definition common.h:221
@ ISCELLSAVINGF
Definition common.h:199
@ CONNECTION
Definition common.h:204
@ P_ANISOTROPY
Definition common.h:222
@ AMR_ALPHA1
Definition common.h:220
@ LBWEIGHTCOUNTER
Definition common.h:198
@ AMR_VORTICITY
Definition common.h:223
FieldTracingParameters fieldTracingParameters
std::array< std::pair< int, Real >, 3 > calculateIonosphereVlasovGridCoupling(std::array< Real, 3 > x, std::vector< SBC::SphericalTriGrid::Node > &nodes, creal couplingRadius)
static constexpr Real productionMinAccEnergy
Definition ionosphere.h:49
static constexpr int productionNumParticleEnergies
Definition ionosphere.h:48
SphericalTriGrid ionosphereGrid
@ BGBYVOL
Definition common.h:379
@ dBGBYVOLdx
Definition common.h:393
@ dBGBZVOLdx
Definition common.h:396
@ BGBY
Definition common.h:376
@ dBGBxdz
Definition common.h:385
@ dBGBydx
Definition common.h:386
@ BGBZ
Definition common.h:377
@ dBGBYVOLdz
Definition common.h:395
@ BGBXVOL
Definition common.h:378
@ dBGBXVOLdx
Definition common.h:390
@ dBGBydz
Definition common.h:387
@ dBGBZVOLdz
Definition common.h:398
@ dBGBZVOLdy
Definition common.h:397
@ BGBX
Definition common.h:375
@ dBGBXVOLdy
Definition common.h:391
@ dBGBzdx
Definition common.h:388
@ dBGBYVOLdy
Definition common.h:394
@ dBGBxdy
Definition common.h:384
@ dBGBzdy
Definition common.h:389
@ dBGBXVOLdz
Definition common.h:392
@ BGBZVOL
Definition common.h:380
@ P_22
Definition common.h:318
@ P_33
Definition common.h:319
@ RHOM
Definition common.h:312
@ P_11
Definition common.h:317
@ RHOQ
Definition common.h:313
@ N_EHALL
Definition common.h:301
@ dPERBZVOLdx
Definition common.h:413
@ dPERBXVOLdz
Definition common.h:409
@ dPERBZVOLdy
Definition common.h:414
@ dPERBZVOLdz
Definition common.h:415
@ PERBYVOL
Definition common.h:405
@ EZVOL
Definition common.h:418
@ dPERBYVOLdx
Definition common.h:410
@ EXVOL
Definition common.h:416
@ dPERBYVOLdy
Definition common.h:411
@ dPERBXVOLdy
Definition common.h:408
@ CURVATUREZ
Definition common.h:421
@ dPERBYVOLdz
Definition common.h:412
@ CURVATUREX
Definition common.h:419
@ PERBXVOL
Definition common.h:404
@ CURVATUREY
Definition common.h:420
@ dPERBXVOLdx
Definition common.h:407
@ EYVOL
Definition common.h:417
@ PERBZVOL
Definition common.h:406
@ dVydz
Definition common.h:363
@ dPedz
Definition common.h:369
@ dp11dz
Definition common.h:351
@ dVydx
Definition common.h:361
@ dp22dy
Definition common.h:353
@ drhomdy
Definition common.h:344
@ dp33dy
Definition common.h:356
@ dVzdz
Definition common.h:366
@ dVzdx
Definition common.h:364
@ dp11dy
Definition common.h:350
@ drhoqdz
Definition common.h:348
@ dp22dx
Definition common.h:352
@ dVxdy
Definition common.h:359
@ dp22dz
Definition common.h:354
@ dp11dx
Definition common.h:349
@ drhomdz
Definition common.h:345
@ dp33dz
Definition common.h:357
@ dPedx
Definition common.h:367
@ dPedy
Definition common.h:368
@ dp33dx
Definition common.h:355
@ dVxdz
Definition common.h:360
@ drhoqdx
Definition common.h:346
@ drhomdx
Definition common.h:343
@ dVzdy
Definition common.h:365
@ drhoqdy
Definition common.h:347
@ dVydy
Definition common.h:362
@ dVxdx
Definition common.h:358
@ PERBY
Definition common.h:276
@ PERBZ
Definition common.h:277
@ PERBX
Definition common.h:275
@ dPERBzdxy
Definition common.h:338
@ dPERBzdy
Definition common.h:329
@ dPERBzdyy
Definition common.h:337
@ dPERBzdxx
Definition common.h:336
@ dPERBydxx
Definition common.h:333
@ dPERBydx
Definition common.h:326
@ dPERBydxz
Definition common.h:335
@ dPERBzdx
Definition common.h:328
@ dPERBxdzz
Definition common.h:331
@ dPERBxdyz
Definition common.h:332
@ dPERBydzz
Definition common.h:334
@ dPERBxdy
Definition common.h:324
@ dPERBxdyy
Definition common.h:330
@ dPERBxdz
Definition common.h:325
@ dPERBydz
Definition common.h:327
const Real CHARGE
Definition common.h:572
const Real K_B
Definition common.h:571
const Real MASS_ELECTRON
Definition common.h:573
fsgrids::consttechnicalspan technical
Definition grid.h:52
fsgrids::constbgbspan BgB
Definition grid.h:50
fsgrids::constefieldspan E
Definition grid.h:40
FieldSolverGrid & fsgrid
Definition grid.h:36
fsgrids::constehallspan EHall
Definition grid.h:42
fsgrids::constmomentsspan moments
Definition grid.h:45
fsgrids::constdperbspan dPerB
Definition grid.h:47
fsgrids::constdmomentsspan dMoments
Definition grid.h:48
fsgrids::constperbspan perB
Definition grid.h:38
fsgrids::constvolspan vol
Definition grid.h:51
std::vector< species::Species > particleSpecies
static bool diagnosticWriteAllDROs
Definition parameters.h:107
static std::vector< std::string > outputVariableList
Definition parameters.h:171
static bool computeCurvature
Definition parameters.h:268
static std::vector< std::string > diagnosticVariableList
Definition parameters.h:173
static bool systemWriteAllDROs
Definition parameters.h:106