aboutsummaryrefslogtreecommitdiff
path: root/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H
diff options
context:
space:
mode:
Diffstat (limited to 'Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H')
-rw-r--r--Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H181
1 files changed, 181 insertions, 0 deletions
diff --git a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H
new file mode 100644
index 000000000..0793b3b27
--- /dev/null
+++ b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H
@@ -0,0 +1,181 @@
+/* Copyright 2023 The WarpX Community
+ *
+ * This file is part of WarpX.
+ *
+ * Authors: Roelof Groenewald (TAE Technologies)
+ *
+ * License: BSD-3-Clause-LBNL
+ */
+
+#ifndef WARPX_HYBRIDPICMODEL_H_
+#define WARPX_HYBRIDPICMODEL_H_
+
+#include "HybridPICModel_fwd.H"
+
+#include "FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H"
+#include "Utils/Parser/ParserUtils.H"
+#include "Utils/WarpXConst.H"
+#include "Utils/WarpXProfilerWrapper.H"
+#include "WarpX.H"
+
+#include <AMReX_Array.H>
+#include <AMReX_REAL.H>
+
+
+/**
+ * \brief This class contains the parameters needed to evaluate hybrid field
+ * solutions (kinetic ions with fluid electrons).
+ */
+class HybridPICModel
+{
+public:
+ HybridPICModel (int nlevs_max); // constructor
+
+ /** Read user-defined model parameters. Called in constructor. */
+ void ReadParameters ();
+
+ /** Allocate hybrid-PIC specific multifabs. Called in constructor. */
+ void AllocateMFs (int nlevs_max);
+ void AllocateLevelMFs (int lev, const amrex::BoxArray& ba, const amrex::DistributionMapping& dm,
+ const int ncomps, const amrex::IntVect& ngJ, const amrex::IntVect& ngRho,
+ const amrex::IntVect& jx_nodal_flag, const amrex::IntVect& jy_nodal_flag,
+ const amrex::IntVect& jz_nodal_flag, const amrex::IntVect& rho_nodal_flag);
+
+ /** Helper function to clear values from hybrid-PIC specific multifabs. */
+ void ClearLevel (int lev);
+
+ void InitData ();
+
+ /**
+ * \brief
+ * Function to calculate the total current based on Ampere's law while
+ * neglecting displacement current (J = curl x B). Used in the Ohm's law
+ * solver (kinetic-fluid hybrid model).
+ *
+ * \param[in] Bfield Magnetic field from which the current is calculated.
+ * \param[in] edge_lengths Length of cell edges taking embedded boundaries into account
+ */
+ void CalculateCurrentAmpere (
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>> const& Bfield,
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>> const& edge_lengths
+ );
+ void CalculateCurrentAmpere (
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& Bfield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& edge_lengths,
+ const int lev
+ );
+
+ /**
+ * \brief
+ * Function to update the E-field using Ohm's law (hybrid-PIC model).
+ */
+ void HybridPICSolveE (
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>>& Efield,
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>> const& Jfield,
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>> const& Bfield,
+ amrex::Vector<std::unique_ptr<amrex::MultiFab>> const& rhofield,
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3>> const& edge_lengths,
+ DtType dt_type);
+ void HybridPICSolveE (
+ std::array< std::unique_ptr<amrex::MultiFab>, 3>& Efield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& Jfield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& Bfield,
+ std::unique_ptr<amrex::MultiFab> const& rhofield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& edge_lengths,
+ const int lev, DtType dt_type);
+ void HybridPICSolveE (
+ std::array< std::unique_ptr<amrex::MultiFab>, 3>& Efield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& Jfield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& Bfield,
+ std::unique_ptr<amrex::MultiFab> const& rhofield,
+ std::array< std::unique_ptr<amrex::MultiFab>, 3> const& edge_lengths,
+ const int lev, PatchType patch_type, DtType dt_type);
+
+ /**
+ * \brief
+ * Function to calculate the electron pressure at a given timestep type
+ * using the simulation charge density. Used in the Ohm's law solver
+ * (kinetic-fluid hybrid model).
+ */
+ void CalculateElectronPressure ( DtType a_dt_type);
+ void CalculateElectronPressure (const int lev, DtType a_dt_type);
+
+ /**
+ * \brief Fill the electron pressure multifab given the kinetic particle
+ * charge density (and assumption of quasi-neutrality) using the user
+ * specified electron equation of state.
+ *
+ * \param[out] Pe scalar electron pressure MultiFab at a given level
+ * \param[in] rhofield scalar ion chrge density Multifab at a given level
+ */
+ void FillElectronPressureMF (
+ std::unique_ptr<amrex::MultiFab> const& Pe,
+ amrex::MultiFab* const& rhofield );
+
+ // Declare variables to hold hybrid-PIC model parameters
+ /** Number of substeps to take when evolving B */
+ int m_substeps = 100;
+
+ /** Electron temperature in eV */
+ amrex::Real m_elec_temp;
+ /** Reference electron density */
+ amrex::Real m_n0_ref = 1.0;
+ /** Electron pressure scaling exponent */
+ amrex::Real m_gamma = 5.0/3.0;
+
+ /** Plasma density floor - if n < n_floor it will be set to n_floor */
+ amrex::Real m_n_floor = 1.0;
+
+ /** Plasma resistivity */
+ std::string m_eta_expression = "0.0";
+ std::unique_ptr<amrex::Parser> m_resistivity_parser;
+ amrex::ParserExecutor<1> m_eta;
+
+ // Declare multifabs specifically needed for the hybrid-PIC model
+ amrex::Vector< std::unique_ptr<amrex::MultiFab> > rho_fp_temp;
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > current_fp_temp;
+ amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > > current_fp_ampere;
+ amrex::Vector< std::unique_ptr<amrex::MultiFab> > electron_pressure_fp;
+
+ // Helper functions to retrieve hybrid-PIC multifabs
+ amrex::MultiFab * get_pointer_current_fp_ampere (int lev, int direction) const { return current_fp_ampere[lev][direction].get(); }
+ amrex::MultiFab * get_pointer_electron_pressure_fp (int lev) const { return electron_pressure_fp[lev].get(); }
+
+ /** Gpu Vector with index type of the Jx multifab */
+ amrex::GpuArray<int, 3> Jx_IndexType;
+ /** Gpu Vector with index type of the Jy multifab */
+ amrex::GpuArray<int, 3> Jy_IndexType;
+ /** Gpu Vector with index type of the Jz multifab */
+ amrex::GpuArray<int, 3> Jz_IndexType;
+ /** Gpu Vector with index type of the Bx multifab */
+ amrex::GpuArray<int, 3> Bx_IndexType;
+ /** Gpu Vector with index type of the By multifab */
+ amrex::GpuArray<int, 3> By_IndexType;
+ /** Gpu Vector with index type of the Bz multifab */
+ amrex::GpuArray<int, 3> Bz_IndexType;
+ /** Gpu Vector with index type of the Ex multifab */
+ amrex::GpuArray<int, 3> Ex_IndexType;
+ /** Gpu Vector with index type of the Ey multifab */
+ amrex::GpuArray<int, 3> Ey_IndexType;
+ /** Gpu Vector with index type of the Ez multifab */
+ amrex::GpuArray<int, 3> Ez_IndexType;
+};
+
+/**
+ * \brief
+ * This struct contains only static functions to compute the electron pressure
+ * using the particle density at a given point and the user provided reference
+ * density and temperatures.
+ */
+struct ElectronPressure {
+
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
+ static amrex::Real get_pressure (amrex::Real const n0,
+ amrex::Real const T0,
+ amrex::Real const gamma,
+ amrex::Real const rho) {
+ return n0 * T0 * pow((rho/PhysConst::q_e)/n0, gamma);
+ }
+};
+
+#endif // WARPX_HYBRIDPICMODEL_H_