aboutsummaryrefslogtreecommitdiff
path: root/Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp')
-rw-r--r--Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp b/Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp
new file mode 100644
index 000000000..132ad2165
--- /dev/null
+++ b/Source/Diagnostics/ReducedDiags/ParticleEnergy.cpp
@@ -0,0 +1,166 @@
+/* Copyright 2019-2020 Yinjian Zhao
+ *
+ * This file is part of WarpX.
+ *
+ * License: BSD-3-Clause-LBNL
+ */
+
+#include "ParticleEnergy.H"
+#include "WarpX.H"
+#include "WarpXConst.H"
+#include "AMReX_REAL.H"
+#include "AMReX_ParticleReduce.H"
+#include <iostream>
+#include <cmath>
+#include <limits>
+
+using namespace amrex;
+
+// constructor
+ParticleEnergy::ParticleEnergy (std::string rd_name)
+: ReducedDiags{rd_name}
+{
+ // get WarpX class object
+ auto & warpx = WarpX::GetInstance();
+
+ // get MultiParticleContainer class object
+ auto & mypc = warpx.GetPartContainer();
+
+ // get number of species (int)
+ auto nSpecies = mypc.nSpecies();
+
+ // resize data array
+ m_data.resize(2*nSpecies+2,0.0);
+
+ // get species names (std::vector<std::string>)
+ auto species_names = mypc.GetSpeciesNames();
+
+ if (ParallelDescriptor::IOProcessor())
+ {
+ if ( m_IsNotRestart )
+ {
+ // open file
+ std::ofstream ofs;
+ ofs.open(m_path + m_rd_name + "." + m_extension,
+ std::ofstream::out | std::ofstream::app);
+ // write header row
+ ofs << "#";
+ ofs << "[1]step";
+ ofs << m_sep;
+ ofs << "[2]time(s)";
+ ofs << m_sep;
+ ofs << "[3]total(J)";
+ for (int i = 0; i < nSpecies; ++i)
+ {
+ ofs << m_sep;
+ ofs << "[" + std::to_string(4+i) + "]";
+ ofs << species_names[i]+"(J)";
+ }
+ ofs << m_sep;
+ ofs << "[" + std::to_string(4+nSpecies) + "]";
+ ofs << "total.mean(J)";
+ for (int i = 0; i < nSpecies; ++i)
+ {
+ ofs << m_sep;
+ ofs << "[" + std::to_string(5+nSpecies+i) + "]";
+ ofs << species_names[i]+".mean(J)";
+ }
+ ofs << std::endl;
+ // close file
+ ofs.close();
+ }
+ }
+
+}
+// end constructor
+
+// function that computes kinetic energy
+void ParticleEnergy::ComputeDiags (int step)
+{
+
+ // Judge if the diags should be done
+ if ( (step+1) % m_freq != 0 ) { return; }
+
+ // get MultiParticleContainer class object
+ auto & mypc = WarpX::GetInstance().GetPartContainer();
+
+ // get number of species (int)
+ auto nSpecies = mypc.nSpecies();
+
+ // get species names (std::vector<std::string>)
+ auto species_names = mypc.GetSpeciesNames();
+
+ // speed of light squared
+ auto c2 = PhysConst::c * PhysConst::c;
+
+ // loop over species
+ for (int i_s = 0; i_s < nSpecies; ++i_s)
+ {
+ // get WarpXParticleContainer class object
+ auto & myspc = mypc.GetParticleContainer(i_s);
+
+ // get mass (Real)
+ auto m = myspc.getMass();
+
+ using PType = typename WarpXParticleContainer::SuperParticleType;
+
+ // Use amex::ReduceSum to compute the sum of energies of all particles
+ // held by the current MPI rank, for this species. This involves a loop over all
+ // boxes held by this MPI rank.
+ auto Etot = ReduceSum( myspc,
+ [=] AMREX_GPU_HOST_DEVICE (const PType& p) -> Real
+ {
+ auto w = p.rdata(PIdx::w);
+ auto ux = p.rdata(PIdx::ux);
+ auto uy = p.rdata(PIdx::uy);
+ auto uz = p.rdata(PIdx::uz);
+ auto us = (ux*ux + uy*uy + uz*uz);
+ return ( std::sqrt(us*c2 + c2*c2) - c2 ) * m * w;
+ });
+
+ // Same thing for the particles weights.
+ auto Wtot = ReduceSum( myspc,
+ [=] AMREX_GPU_HOST_DEVICE (const PType& p) -> Real
+ {
+ return p.rdata(PIdx::w);
+ });
+
+ // reduced sum over mpi ranks
+ ParallelDescriptor::ReduceRealSum
+ (Etot, ParallelDescriptor::IOProcessorNumber());
+ ParallelDescriptor::ReduceRealSum
+ (Wtot, ParallelDescriptor::IOProcessorNumber());
+
+ // save results for this species i_s into m_data
+ m_data[i_s+1] = Etot;
+ if ( Wtot > std::numeric_limits<Real>::min() )
+ { m_data[nSpecies+2+i_s] = Etot / Wtot; }
+ else
+ { m_data[nSpecies+2+i_s] = 0.0; }
+
+ }
+ // end loop over species
+
+ // save total energy
+ // loop over species
+ m_data[0] = 0.0; // total energy
+ m_data[nSpecies+1] = 0.0; // total mean energy
+ for (int i_s = 0; i_s < nSpecies; ++i_s)
+ {
+ m_data[0] += m_data[i_s+1];
+ m_data[nSpecies+1] += m_data[nSpecies+2+i_s];
+ }
+ // end loop over species
+
+ /* m_data now contains up-to-date values for:
+ * [total energy (all species),
+ * total energy (species 1),
+ * ...,
+ * total energy (species n),
+ * mean energy (all species),
+ * mean energy (species 1),
+ * ...,
+ * mean energy (species n)] */
+
+}
+// end void ParticleEnergy::ComputeDiags