aboutsummaryrefslogtreecommitdiff
path: root/Source/Diagnostics/FieldIO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Diagnostics/FieldIO.cpp')
-rw-r--r--Source/Diagnostics/FieldIO.cpp205
1 files changed, 180 insertions, 25 deletions
diff --git a/Source/Diagnostics/FieldIO.cpp b/Source/Diagnostics/FieldIO.cpp
index e1bb8cb54..9c38f1d68 100644
--- a/Source/Diagnostics/FieldIO.cpp
+++ b/Source/Diagnostics/FieldIO.cpp
@@ -352,6 +352,27 @@ AverageAndPackVectorField( MultiFab& mf_avg,
}
}
+/** \brief Takes all of the components of the three fields and
+ * averages and packs them into the MultiFab mf_avg.
+ */
+void
+AverageAndPackVectorFieldComponents (MultiFab& mf_avg,
+ const std::array< std::unique_ptr<MultiFab>, 3 >& vector_field,
+ const DistributionMapping& dm,
+ int& dcomp, const int ngrow )
+{
+ if (vector_field[0]->nComp() > 1) {
+ std::array<std::unique_ptr<MultiFab>,3> vector_field_component;
+ for (int icomp=0 ; icomp < vector_field[0]->nComp() ; icomp++) {
+ vector_field_component[0].reset(new MultiFab(*vector_field[0], amrex::make_alias, icomp, 1));
+ vector_field_component[1].reset(new MultiFab(*vector_field[1], amrex::make_alias, icomp, 1));
+ vector_field_component[2].reset(new MultiFab(*vector_field[2], amrex::make_alias, icomp, 1));
+ AverageAndPackVectorField(mf_avg, vector_field_component, dm, dcomp, ngrow);
+ dcomp += 3;
+ }
+ }
+}
+
/** \brief Take a MultiFab `scalar_field`
* averages it to the cell center, and stores the
* resulting MultiFab in mf_avg (in the components dcomp)
@@ -378,6 +399,74 @@ AverageAndPackScalarField( MultiFab& mf_avg,
}
}
+/** \brief Takes the specified component of the scalar and
+ * averages and packs it into the MultiFab mf_avg.
+ */
+void
+AverageAndPackScalarFieldComponent (MultiFab& mf_avg,
+ const MultiFab& scalar_field,
+ const int icomp,
+ const int dcomp, const int ngrow )
+{
+ MultiFab scalar_field_component(scalar_field, amrex::make_alias, icomp, 1);
+ AverageAndPackScalarField(mf_avg, scalar_field_component, dcomp, ngrow);
+}
+
+/** \brief Generate mode variable name
+ */
+std::string
+ComponentName(std::string fieldname, int mode, std::string type)
+{
+ if (type == "real") {
+ return fieldname + "_" + std::to_string(mode) + "_" + "real";
+ } else if (type == "imag") {
+ return fieldname + "_" + std::to_string(mode) + "_" + "imag";
+ } else {
+ AMREX_ALWAYS_ASSERT( false );
+ }
+ // This should never be done
+ return "";
+}
+
+/* \brief Copy vector field component data into the MultiFab that will be written out
+ */
+void
+CopyVectorFieldComponentsToMultiFab (int lev, amrex::Vector<MultiFab>& mf_avg, MultiFab& mf_tmp,
+ int icomp, int& dcomp, int ngrow,
+ std::string fieldname, Vector<std::string>& varnames)
+{
+ if (mf_tmp.nComp() > 3) {
+ if (lev==0) varnames.push_back(ComponentName(fieldname, 0, "real"));
+ MultiFab::Copy( mf_avg[lev], mf_tmp, 3+icomp, dcomp++, 1, ngrow);
+ int const nmodes = mf_tmp.nComp()/6;
+ for (int mode=1 ; mode < nmodes ; mode++) {
+ if (lev==0) varnames.push_back(ComponentName(fieldname, mode, "real"));
+ MultiFab::Copy( mf_avg[lev], mf_tmp, 3*2*mode+icomp, dcomp++, 1, ngrow);
+ if (lev==0) varnames.push_back(ComponentName(fieldname, mode, "imag"));
+ MultiFab::Copy( mf_avg[lev], mf_tmp, 3*2*mode+3+icomp, dcomp++, 1, ngrow);
+ }
+ }
+}
+
+/* \brief Copy scalar field component data into the MultiFab that will be written out
+ */
+void
+CopyScalarFieldComponentsToMultiFab (int lev, amrex::Vector<MultiFab>& mf_avg, MultiFab& mf_tmp,
+ int& dcomp, int ngrow, int n_rz_azimuthal_modes,
+ std::string fieldname, Vector<std::string>& varnames)
+{
+ if (n_rz_azimuthal_modes > 1) {
+ if (lev==0) varnames.push_back(ComponentName(fieldname, 0, "real"));
+ AverageAndPackScalarFieldComponent(mf_avg[lev], mf_tmp, 0, dcomp++, ngrow);
+ for (int mode=1 ; mode < n_rz_azimuthal_modes ; mode++) {
+ if (lev==0) varnames.push_back(ComponentName(fieldname, mode, "real"));
+ AverageAndPackScalarFieldComponent(mf_avg[lev], mf_tmp, 2*mode-1, dcomp++, ngrow);
+ if (lev==0) varnames.push_back(ComponentName(fieldname, mode, "imag"));
+ AverageAndPackScalarFieldComponent(mf_avg[lev], mf_tmp, 2*mode , dcomp++, ngrow);
+ }
+ }
+}
+
/** \brief Add variable names to the list.
*/
void
@@ -387,6 +476,15 @@ AddToVarNames (Vector<std::string>& varnames,
for(auto coord:coords) varnames.push_back(name+coord+suffix);
}
+/** \brief Add RZ variable names to the list.
+ */
+void
+AddToVarNamesRZ (Vector<std::string>& varnames,
+ std::string name, std::string suffix) {
+ auto coords = {"r", "theta", "z"};
+ for(auto coord:coords) varnames.push_back(name+coord+suffix);
+}
+
/** \brief Write the different fields that are meant for output,
* into the vector of MultiFab `mf_avg` (one MultiFab per level)
* after averaging them to the cell centers.
@@ -396,11 +494,28 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
amrex::Vector<MultiFab>& mf_avg, const int ngrow) const
{
// Count how many different fields should be written (ncomp)
- const int ncomp = fields_to_plot.size()
+ int ncomp = fields_to_plot.size()
+ static_cast<int>(plot_finepatch)*6
+ static_cast<int>(plot_crsepatch)*6
+ static_cast<int>(costs[0] != nullptr and plot_costs);
+ // Add in the RZ modes
+ if (n_rz_azimuthal_modes > 1) {
+ for (std::string field : fields_to_plot) {
+ if (is_in_vector({"Ex", "Ey", "Ez", "Bx", "By", "Bz", "jx", "jy", "jz", "rho", "F"}, {field})) {
+ ncomp += 2*n_rz_azimuthal_modes - 1;
+ }
+ }
+ if (plot_finepatch) {
+ ncomp += 6*(2*n_rz_azimuthal_modes - 1);
+ }
+ }
+
+ int nvecs = 3;
+ if (n_rz_azimuthal_modes > 1) {
+ nvecs += 3*(2*n_rz_azimuthal_modes - 1);
+ }
+
// Loop over levels of refinement
for (int lev = 0; lev <= finest_level; ++lev)
{
@@ -413,19 +528,25 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
// Build mf_tmp_E is at least one component of E is requested
if (is_in_vector(fields_to_plot, {"Ex", "Ey", "Ez"} )){
// Allocate temp MultiFab with 3 components
- mf_tmp_E = MultiFab(grids[lev], dmap[lev], 3, ngrow);
+ mf_tmp_E = MultiFab(grids[lev], dmap[lev], nvecs, ngrow);
// Fill MultiFab mf_tmp_E with averaged E
AverageAndPackVectorField(mf_tmp_E, Efield_aux[lev], dmap[lev], 0, ngrow);
+ int dcomp = 3;
+ AverageAndPackVectorFieldComponents(mf_tmp_E, Efield_aux[lev], dmap[lev], dcomp, ngrow);
}
// Same for B
if (is_in_vector(fields_to_plot, {"Bx", "By", "Bz"} )){
- mf_tmp_B = MultiFab(grids[lev], dmap[lev], 3, ngrow);
+ mf_tmp_B = MultiFab(grids[lev], dmap[lev], nvecs, ngrow);
AverageAndPackVectorField(mf_tmp_B, Bfield_aux[lev], dmap[lev], 0, ngrow);
+ int dcomp = 3;
+ AverageAndPackVectorFieldComponents(mf_tmp_B, Bfield_aux[lev], dmap[lev], dcomp, ngrow);
}
// Same for J
if (is_in_vector(fields_to_plot, {"jx", "jy", "jz"} )){
- mf_tmp_J = MultiFab(grids[lev], dmap[lev], 3, ngrow);
+ mf_tmp_J = MultiFab(grids[lev], dmap[lev], nvecs, ngrow);
AverageAndPackVectorField(mf_tmp_J, current_fp[lev], dmap[lev], 0, ngrow);
+ int dcomp = 3;
+ AverageAndPackVectorFieldComponents(mf_tmp_J, current_fp[lev], dmap[lev], dcomp, ngrow);
}
int dcomp;
@@ -433,37 +554,51 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
// mf_avg[lev] add the corresponding names to `varnames`.
// plot_fine_patch and plot_coarse_patch are treated separately
// (after this for loop).
- for (dcomp=0; dcomp<fields_to_plot.size(); dcomp++){
- std::string fieldname = fields_to_plot[dcomp];
+ dcomp = 0;
+ for (int ifield=0; ifield<fields_to_plot.size(); ifield++){
+ std::string fieldname = fields_to_plot[ifield];
if(lev==0) varnames.push_back(fieldname);
if (fieldname == "Ex"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_E, 0, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_E, 0, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_E, 0, dcomp, ngrow, "Er", varnames);
} else if (fieldname == "Ey"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_E, 1, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_E, 1, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_E, 1, dcomp, ngrow, "Etheta", varnames);
} else if (fieldname == "Ez"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_E, 2, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_E, 2, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_E, 2, dcomp, ngrow, "Ez", varnames);
} else if (fieldname == "Bx"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_B, 0, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_B, 0, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_B, 0, dcomp, ngrow, "Br", varnames);
} else if (fieldname == "By"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_B, 1, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_B, 1, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_B, 1, dcomp, ngrow, "Btheta", varnames);
} else if (fieldname == "Bz"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_B, 2, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_B, 2, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_B, 2, dcomp, ngrow, "Bz", varnames);
} else if (fieldname == "jx"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_J, 0, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_J, 0, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_J, 0, dcomp, ngrow, "jr", varnames);
} else if (fieldname == "jy"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_J, 1, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_J, 1, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_J, 1, dcomp, ngrow, "jtheta", varnames);
} else if (fieldname == "jz"){
- MultiFab::Copy( mf_avg[lev], mf_tmp_J, 2, dcomp, 1, ngrow);
+ MultiFab::Copy( mf_avg[lev], mf_tmp_J, 2, dcomp++, 1, ngrow);
+ CopyVectorFieldComponentsToMultiFab(lev, mf_avg, mf_tmp_J, 2, dcomp, ngrow, "jz", varnames);
} else if (fieldname == "rho"){
- AverageAndPackScalarField( mf_avg[lev], *rho_fp[lev], dcomp, ngrow );
+ AverageAndPackScalarField( mf_avg[lev], *rho_fp[lev], dcomp++, ngrow );
+ CopyScalarFieldComponentsToMultiFab(lev, mf_avg, *rho_fp[lev], dcomp, ngrow, n_rz_azimuthal_modes,
+ fieldname, varnames);
} else if (fieldname == "F"){
- AverageAndPackScalarField( mf_avg[lev], *F_fp[lev], dcomp, ngrow);
+ AverageAndPackScalarField( mf_avg[lev], *F_fp[lev], dcomp++, ngrow );
+ CopyScalarFieldComponentsToMultiFab(lev, mf_avg, *F_fp[lev], dcomp, ngrow, n_rz_azimuthal_modes,
+ fieldname, varnames);
} else if (fieldname == "part_per_cell") {
MultiFab temp_dat(grids[lev],mf_avg[lev].DistributionMap(),1,0);
temp_dat.setVal(0);
// MultiFab containing number of particles in each cell
mypc->Increment(temp_dat, lev);
- AverageAndPackScalarField( mf_avg[lev], temp_dat, dcomp, ngrow );
+ AverageAndPackScalarField( mf_avg[lev], temp_dat, dcomp++, ngrow );
} else if (fieldname == "part_per_grid"){
const Vector<long>& npart_in_grid = mypc->NumberOfParticlesInGrid(lev);
// MultiFab containing number of particles per grid
@@ -473,7 +608,7 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
#endif
for (MFIter mfi(mf_avg[lev]); mfi.isValid(); ++mfi) {
(mf_avg[lev])[mfi].setVal(static_cast<Real>(npart_in_grid[mfi.index()]),
- dcomp);
+ dcomp++);
}
} else if (fieldname == "part_per_proc"){
const Vector<long>& npart_in_grid = mypc->NumberOfParticlesInGrid(lev);
@@ -486,7 +621,7 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
for (MFIter mfi(mf_avg[lev]); mfi.isValid(); ++mfi) {
n_per_proc += npart_in_grid[mfi.index()];
}
- mf_avg[lev].setVal(static_cast<Real>(n_per_proc), dcomp,1);
+ mf_avg[lev].setVal(static_cast<Real>(n_per_proc), dcomp++,1);
} else if (fieldname == "proc_number"){
// MultiFab containing the Processor ID
#ifdef _OPENMP
@@ -494,11 +629,11 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
#endif
for (MFIter mfi(mf_avg[lev]); mfi.isValid(); ++mfi) {
(mf_avg[lev])[mfi].setVal(static_cast<Real>(ParallelDescriptor::MyProc()),
- dcomp);
+ dcomp++);
}
} else if (fieldname == "divB"){
if (do_nodal) amrex::Abort("TODO: do_nodal && plot divb");
- ComputeDivB(mf_avg[lev], dcomp,
+ ComputeDivB(mf_avg[lev], dcomp++,
{Bfield_aux[lev][0].get(),
Bfield_aux[lev][1].get(),
Bfield_aux[lev][2].get()},
@@ -512,7 +647,7 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
Efield_aux[lev][1].get(),
Efield_aux[lev][2].get()},
WarpX::CellSize(lev) );
- AverageAndPackScalarField( mf_avg[lev], dive, dcomp, ngrow );
+ AverageAndPackScalarField( mf_avg[lev], dive, dcomp++, ngrow );
} else {
amrex::Abort("unknown field in fields_to_plot: " + fieldname);
}
@@ -520,11 +655,31 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames,
if (plot_finepatch)
{
AverageAndPackVectorField( mf_avg[lev], Efield_fp[lev], dmap[lev], dcomp, ngrow );
- if (lev == 0) AddToVarNames(varnames, "E", "_fp");
dcomp += 3;
+ AverageAndPackVectorFieldComponents(mf_avg[lev], Efield_fp[lev], dmap[lev], dcomp, ngrow);
+ if (lev == 0) {
+ AddToVarNames(varnames, "E", "_fp");
+ if (n_rz_azimuthal_modes > 1) {
+ AddToVarNamesRZ(varnames, "E", ComponentName("_fp", 0, "real"));
+ for (int mode=1 ; mode < n_rz_azimuthal_modes ; mode++) {
+ AddToVarNamesRZ(varnames, "E", ComponentName("_fp", mode, "real"));
+ AddToVarNamesRZ(varnames, "E", ComponentName("_fp", mode, "imag"));
+ }
+ }
+ }
AverageAndPackVectorField( mf_avg[lev], Bfield_fp[lev], dmap[lev], dcomp, ngrow );
- if (lev == 0) AddToVarNames(varnames, "B", "_fp");
dcomp += 3;
+ AverageAndPackVectorFieldComponents(mf_avg[lev], Bfield_fp[lev], dmap[lev], dcomp, ngrow);
+ if (lev == 0) {
+ AddToVarNames(varnames, "B", "_fp");
+ if (n_rz_azimuthal_modes > 1) {
+ AddToVarNamesRZ(varnames, "B", ComponentName("_fp", 0, "real"));
+ for (int mode=1 ; mode < n_rz_azimuthal_modes ; mode++) {
+ AddToVarNamesRZ(varnames, "B", ComponentName("_fp", mode, "real"));
+ AddToVarNamesRZ(varnames, "B", ComponentName("_fp", mode, "imag"));
+ }
+ }
+ }
}
if (plot_crsepatch)