/* PBHCosmo example (pbhgr project). Massive real scalar field exactly as GRChombo's ScalarField * (Source/Matter/ScalarField.impl.hpp, GRChombo 37e6595) plus one static grid variable fref = K_0(x)/K_0(far), * the gauge reference profile used by PBHGauge: no RHS, carried along on regrid like any evolved variable. */ #ifndef SCALARFIELDREF_HPP_ #define SCALARFIELDREF_HPP_ #include "CCZ4Geometry.hpp" #include "DimensionDefinitions.hpp" #include "FourthOrderDerivatives.hpp" #include "Potential.hpp" #include "Tensor.hpp" #include "TensorAlgebra.hpp" #include "UserVariables.hpp" #include "VarsTools.hpp" class ScalarFieldRef { protected: Potential my_potential; public: ScalarFieldRef(const Potential a_potential) : my_potential(a_potential) {} template struct Vars { data_t phi; data_t Pi; data_t fref; template void enum_mapping(mapping_function_t mapping_function) { VarsTools::define_enum_mapping(mapping_function, c_phi, phi); VarsTools::define_enum_mapping(mapping_function, c_Pi, Pi); VarsTools::define_enum_mapping(mapping_function, c_fref, fref); } }; template struct Diff2Vars { data_t phi; template void enum_mapping(mapping_function_t mapping_function) { VarsTools::define_enum_mapping(mapping_function, c_phi, phi); } }; template class vars_t> emtensor_t compute_emtensor(const vars_t &vars, const vars_t> &d1, const Tensor<2, data_t> &h_UU, const Tensor<3, data_t> &chris_ULL) const { emtensor_t out; data_t Vt = -vars.Pi * vars.Pi; FOR(i, j) { Vt += vars.chi * h_UU[i][j] * d1.phi[i] * d1.phi[j]; } FOR(i, j) { out.Sij[i][j] = -0.5 * vars.h[i][j] * Vt / vars.chi + d1.phi[i] * d1.phi[j]; } out.S = vars.chi * TensorAlgebra::compute_trace(out.Sij, h_UU); FOR(i) { out.Si[i] = -d1.phi[i] * vars.Pi; } out.rho = vars.Pi * vars.Pi + 0.5 * Vt; data_t V_of_phi = 0.0, dVdphi = 0.0; my_potential.compute_potential(V_of_phi, dVdphi, vars); out.rho += V_of_phi; out.S += -3.0 * V_of_phi; FOR(i, j) { out.Sij[i][j] += -vars.h[i][j] * V_of_phi / vars.chi; } return out; } template class vars_t, template class diff2_vars_t, template class rhs_vars_t> void add_matter_rhs(rhs_vars_t &rhs, const vars_t &vars, const vars_t> &d1, const diff2_vars_t> &d2, const vars_t &advec) const { using namespace TensorAlgebra; const auto h_UU = compute_inverse_sym(vars.h); const auto chris = compute_christoffel(d1.h, h_UU); rhs.phi = vars.lapse * vars.Pi + advec.phi; rhs.Pi = vars.lapse * vars.K * vars.Pi + advec.Pi; FOR(i, j) { rhs.Pi += h_UU[i][j] * (-0.5 * d1.chi[j] * vars.lapse * d1.phi[i] + vars.chi * vars.lapse * d2.phi[i][j] + vars.chi * d1.lapse[i] * d1.phi[j]); FOR(k) { rhs.Pi += -vars.chi * vars.lapse * h_UU[i][j] * chris.ULL[k][i][j] * d1.phi[k]; } } data_t V_of_phi = 0.0, dVdphi = 0.0; my_potential.compute_potential(V_of_phi, dVdphi, vars); rhs.Pi += -vars.lapse * dVdphi; rhs.fref = 0.0; // static profile (not advected: it is a coordinate-space reference) } }; #endif /* SCALARFIELDREF_HPP_ */