Ко всем библиотекам · PBHVlasov (GRTeclyn)

grteclyn/PBHVlasov/ParticleMatter.hpp

PBHVlasov example for GRTeclyn (pbhgr project). matter_t for CCZ4RHSWithMatter / ConstraintsWithMatter: the energy-momentum tensor is read from the grid variables deposited from the particles (rho_p, S_i, S_ij, all measured by the…

96 строк · 3.9 KB · pbhgr @ 9e8e13d · как текст

/* PBHVlasov example for GRTeclyn (pbhgr project).
 * matter_t for CCZ4RHSWithMatter / ConstraintsWithMatter: the energy-momentum tensor is read from the grid
 * variables deposited from the particles (rho_p, S_i, S_ij, all measured by the normal observer); the matter
 * variables have no RHS (the particles are pushed separately, see VlasovParticles). */
#ifndef PARTICLEMATTER_HPP_
#define PARTICLEMATTER_HPP_

#include "CCZ4Geometry.hpp"
#include "CCZ4RHSWithMatter.hpp"
#include "DimensionDefinitions.hpp"
#include "FourthOrderDerivatives.hpp"
#include "GRParmParse.hpp"
#include "ParticleMatterVars.hpp"
#include "StateVariables.hpp"
#include "TensorAlgebra.hpp"

template <class deriv_t = FourthOrderDerivatives> class ParticleMatter
{
  protected:
    amrex::Real m_G_Newton{1.0};

  public:
    struct params_t
    {
        amrex::Real G_Newton{1.0};
        static void check_params()
        {
            GRParmParse pp("particle_matter");
            amrex::Real G_Newton{1.0};
            pp.queryAdd("G_Newton", G_Newton);
            if (G_Newton < 0.0)
                pp.error("G_Newton", "must be >= 0.0");
        }
        void fill_params()
        {
            GRParmParse pp("particle_matter");
            pp.query("G_Newton", G_Newton);
        }
    };

    ParticleMatter()
    {
        params_t params;
        params.fill_params();
        m_G_Newton = params.G_Newton;
    }

    using Vars = ParticleMatterVars;

    [[nodiscard]] AMREX_GPU_DEVICE emtensor_t compute_emtensor(const int ix, const int iy, const int iz,
                                                              const amrex::Array4<const amrex::Real> &state,
                                                              const deriv_t & /*a_deriv*/,
                                                              const Tensor::Rank2 &h_UU) const
    {
        emtensor_t out;
        // keep the CellData alive: CCZ4Vars stores a reference to it
        const amrex::CellData<const amrex::Real> &cd = state.cellData(ix, iy, iz);
        const Vars vars(cd);
        // the grid carries the coordinate (densitised) sources sum m Gamma W / dV etc.; the physical ones need
        // 1/sqrt(gamma) = chi^{3/2} of the current state, so that within a step (all RK stages) the sources follow the
        // expansion of the volume element instead of lagging by one step
        const amrex::Real sg = std::pow(vars.chi(), 1.5);
        out.rho = sg * vars.rho_p();
        FOR (i) { out.j(i) = sg * vars.S_i(i); }
        FOR (i, j) { out.S(i, j) = sg * vars.S_ij(i, j); }
        out.trS = vars.chi() * TensorAlgebra::compute_trace(out.S, h_UU);
        return out;
    }

    [[nodiscard]] AMREX_GPU_DEVICE AMREX_FORCE_INLINE einstein_sources_t
    compute_einstein_sources(int ix, int iy, int iz, const amrex::Array4<const amrex::Real> &state,
                             const deriv_t &a_deriv, const Tensor::Rank2 &h_UU) const
    {
        const emtensor_t emtensor = compute_emtensor(ix, iy, iz, state, a_deriv, h_UU);
        const amrex::Real coupling = 8.0 * M_PI * m_G_Newton;
        einstein_sources_t out;
        out.rho = coupling * emtensor.rho;
        out.trS = coupling * emtensor.trS;
        FOR (i) { out.j(i) = coupling * emtensor.j(i); }
        FOR (i, j) { out.S(i, j) = coupling * emtensor.S(i, j); }
        return out;
    }

    AMREX_GPU_DEVICE AMREX_FORCE_INLINE void add_matter_rhs(const int ix, const int iy, const int iz,
                                                            const amrex::Array4<amrex::Real> &rhs_state,
                                                            const amrex::Array4<const amrex::Real> & /*state*/,
                                                            const deriv_t & /*a_deriv*/) const
    {
        const amrex::CellData<amrex::Real> rhs = rhs_state.cellData(ix, iy, iz);
        for (int c = c_rho_p; c < NUM_VARS; ++c)
            rhs[c] = 0.0;
    }
};

#endif /* PARTICLEMATTER_HPP_ */