mirror of
https://github.com/cosmo-sims/monofonIC.git
synced 2024-09-19 17:03:45 +02:00
Added convergence test and made testings activable from the config file.
This commit is contained in:
parent
8bc6e5acac
commit
b064928763
4 changed files with 148 additions and 7 deletions
|
@ -8,6 +8,9 @@ DoBaryons = no
|
||||||
DoFixing = no
|
DoFixing = no
|
||||||
BCClattice = no
|
BCClattice = no
|
||||||
|
|
||||||
|
[testing]
|
||||||
|
test = convergence
|
||||||
|
|
||||||
[execution]
|
[execution]
|
||||||
NumThreads = 4
|
NumThreads = 4
|
||||||
|
|
||||||
|
|
|
@ -24,4 +24,13 @@ namespace testing{
|
||||||
Grid_FFT<real_t> &phi3b,
|
Grid_FFT<real_t> &phi3b,
|
||||||
std::array<Grid_FFT<real_t> *, 3> &A3,
|
std::array<Grid_FFT<real_t> *, 3> &A3,
|
||||||
bool bwrite_out_fields=false);
|
bool bwrite_out_fields=false);
|
||||||
|
|
||||||
|
void output_convergence(
|
||||||
|
ConfigFile &the_config,
|
||||||
|
std::size_t ngrid, real_t boxlen, real_t vfac, real_t dplus,
|
||||||
|
Grid_FFT<real_t> &phi,
|
||||||
|
Grid_FFT<real_t> &phi2,
|
||||||
|
Grid_FFT<real_t> &phi3a,
|
||||||
|
Grid_FFT<real_t> &phi3b,
|
||||||
|
std::array<Grid_FFT<real_t> *, 3> &A3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,15 +323,23 @@ int Run( ConfigFile& the_config )
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// we store the densities here if we compute them
|
// we store the densities here if we compute them
|
||||||
//======================================================================
|
//======================================================================
|
||||||
const bool testing_compute_densities = false;
|
|
||||||
if( testing_compute_densities )
|
// Testing
|
||||||
{
|
const std::string testing = the_config.GetValueSafe<std::string>("testing", "test", "none");
|
||||||
|
|
||||||
|
if(testing != "none") {
|
||||||
csoca::wlog << "you are running in testing mode. No ICs, only diagnostic output will be written out!" << std::endl;
|
csoca::wlog << "you are running in testing mode. No ICs, only diagnostic output will be written out!" << std::endl;
|
||||||
// testing::output_potentials_and_densities( the_config, ngrid, boxlen, phi, phi2, phi3a, phi3b, A3 );
|
if(testing == "potentials_and_densities") {
|
||||||
testing::output_velocity_displacement_symmetries( the_config, ngrid, boxlen, vfac, Dplus0, phi, phi2, phi3a, phi3b, A3 );
|
testing::output_potentials_and_densities(the_config, ngrid, boxlen, phi, phi2, phi3a, phi3b, A3);
|
||||||
|
} else if(testing == "velocity_displacement_symmetries") {
|
||||||
|
testing::output_velocity_displacement_symmetries(the_config, ngrid, boxlen, vfac, Dplus0, phi, phi2, phi3a, phi3b, A3);
|
||||||
|
} else if(testing == "convergence") {
|
||||||
|
testing::output_convergence(the_config, ngrid, boxlen, vfac, Dplus0, phi, phi2, phi3a, phi3b, A3);
|
||||||
|
} else {
|
||||||
|
csoca::flog << "unknown test '" << testing << "'" << std::endl;
|
||||||
|
std::abort();
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// temporary storage of data
|
// temporary storage of data
|
||||||
Grid_FFT<real_t> tmp({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
Grid_FFT<real_t> tmp({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
|
||||||
|
|
121
src/testing.cc
121
src/testing.cc
|
@ -1,5 +1,6 @@
|
||||||
#include <testing.hh>
|
#include <testing.hh>
|
||||||
#include <unistd.h> // for unlink
|
#include <unistd.h> // for unlink
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <operators.hh>
|
#include <operators.hh>
|
||||||
#include <convolution.hh>
|
#include <convolution.hh>
|
||||||
|
@ -239,4 +240,124 @@ void output_velocity_displacement_symmetries(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void output_convergence(
|
||||||
|
ConfigFile &the_config,
|
||||||
|
std::size_t ngrid, real_t boxlen, real_t vfac, real_t dplus,
|
||||||
|
Grid_FFT<real_t> &phi,
|
||||||
|
Grid_FFT<real_t> &phi2,
|
||||||
|
Grid_FFT<real_t> &phi3a,
|
||||||
|
Grid_FFT<real_t> &phi3b,
|
||||||
|
std::array<Grid_FFT<real_t> *, 3> &A3)
|
||||||
|
{
|
||||||
|
|
||||||
|
// scale all potentials to remove dplus0
|
||||||
|
phi /= dplus;
|
||||||
|
phi2 /= dplus * dplus;
|
||||||
|
phi3a /= dplus * dplus * dplus;
|
||||||
|
phi3b /= dplus * dplus * dplus;
|
||||||
|
(*A3[0]) /= dplus * dplus * dplus;
|
||||||
|
(*A3[1]) /= dplus * dplus * dplus;
|
||||||
|
(*A3[2]) /= dplus * dplus * dplus;
|
||||||
|
|
||||||
|
// initialize grids to 0
|
||||||
|
Grid_FFT<real_t> psi_1({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
Grid_FFT<real_t> psi_2({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
Grid_FFT<real_t> psi_3({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
#pragma omp parallel for collapse(3)
|
||||||
|
for (std::size_t i = 0; i < psi_1.size(0); ++i) {
|
||||||
|
for (std::size_t j = 0; j < psi_1.size(1); ++j) {
|
||||||
|
for (std::size_t k = 0; k < psi_1.size(2); ++k) {
|
||||||
|
std::size_t idx = psi_1.get_idx(i, j, k);
|
||||||
|
psi_1.relem(idx) = 0.0;
|
||||||
|
psi_2.relem(idx) = 0.0;
|
||||||
|
psi_3.relem(idx) = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// temporaries
|
||||||
|
Grid_FFT<real_t> psi_1_tmp({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
Grid_FFT<real_t> psi_2_tmp({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
Grid_FFT<real_t> psi_3_tmp({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
|
||||||
|
// compute psi 1, 2 and 3
|
||||||
|
for (int idim = 0; idim < 3; ++idim) {
|
||||||
|
// cyclic rotations of indices
|
||||||
|
int idimp = (idim + 1) % 3, idimpp = (idim + 2) % 3;
|
||||||
|
|
||||||
|
psi_1_tmp.FourierTransformForward(false);
|
||||||
|
psi_2_tmp.FourierTransformForward(false);
|
||||||
|
psi_3_tmp.FourierTransformForward(false);
|
||||||
|
|
||||||
|
#pragma omp parallel for collapse(3)
|
||||||
|
for (std::size_t i = 0; i < phi.size(0); ++i) {
|
||||||
|
for (std::size_t j = 0; j < phi.size(1); ++j) {
|
||||||
|
for (std::size_t k = 0; k < phi.size(2); ++k) {
|
||||||
|
auto kk = phi.get_k<real_t>(i, j, k);
|
||||||
|
std::size_t idx = phi.get_idx(i, j, k);
|
||||||
|
psi_1_tmp.kelem(idx) = ccomplex_t(0.0, 1.0) * (kk[idim] * phi.kelem(idx));
|
||||||
|
psi_2_tmp.kelem(idx) = ccomplex_t(0.0, 1.0) * (kk[idim] * phi2.kelem(idx));
|
||||||
|
psi_3_tmp.kelem(idx) = ccomplex_t(0.0, 1.0) * (
|
||||||
|
kk[idim] * (phi3a.kelem(idx) + phi3b.kelem(idx)) +
|
||||||
|
kk[idimp] * A3[idimpp]->kelem(idx) -
|
||||||
|
kk[idimpp] * A3[idimp]->kelem(idx)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
psi_1_tmp.FourierTransformBackward();
|
||||||
|
psi_2_tmp.FourierTransformBackward();
|
||||||
|
psi_3_tmp.FourierTransformBackward();
|
||||||
|
|
||||||
|
// sum of squares
|
||||||
|
#pragma omp parallel for collapse(3)
|
||||||
|
for (std::size_t i = 0; i < psi_1.size(0); ++i) {
|
||||||
|
for (std::size_t j = 0; j < psi_1.size(1); ++j) {
|
||||||
|
for (std::size_t k = 0; k < psi_1.size(2); ++k) {
|
||||||
|
std::size_t idx = psi_1.get_idx(i, j, k);
|
||||||
|
psi_1.relem(idx) += psi_1_tmp.relem(idx) * psi_1_tmp.relem(idx);
|
||||||
|
psi_2.relem(idx) += psi_2_tmp.relem(idx) * psi_2_tmp.relem(idx);
|
||||||
|
psi_3.relem(idx) += psi_3_tmp.relem(idx) * psi_3_tmp.relem(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // loop on dimensions
|
||||||
|
|
||||||
|
// apply square root for the L2 norm
|
||||||
|
#pragma omp parallel for collapse(3)
|
||||||
|
for (std::size_t i = 0; i < psi_1.size(0); ++i) {
|
||||||
|
for (std::size_t j = 0; j < psi_1.size(1); ++j) {
|
||||||
|
for (std::size_t k = 0; k < psi_1.size(2); ++k) {
|
||||||
|
std::size_t idx = psi_1.get_idx(i, j, k);
|
||||||
|
psi_1.relem(idx) = std::sqrt(psi_1.relem(idx));
|
||||||
|
psi_2.relem(idx) = std::sqrt(psi_2.relem(idx));
|
||||||
|
psi_3.relem(idx) = std::sqrt(psi_3.relem(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convergence radius
|
||||||
|
Grid_FFT<real_t> inv_convergence_radius({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
|
||||||
|
#pragma omp parallel for collapse(3)
|
||||||
|
for (std::size_t i = 0; i < psi_1.size(0); ++i) {
|
||||||
|
for (std::size_t j = 0; j < psi_1.size(1); ++j) {
|
||||||
|
for (std::size_t k = 0; k < psi_1.size(2); ++k) {
|
||||||
|
std::size_t idx = psi_1.get_idx(i, j, k);
|
||||||
|
inv_convergence_radius.relem(idx) =
|
||||||
|
3.0 * (std::abs(psi_3.relem(idx)) / std::abs(psi_2.relem(idx))) -
|
||||||
|
2.0 * (std::abs(psi_2.relem(idx)) / std::abs(psi_1.relem(idx)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write results
|
||||||
|
unlink("convergence_test.hdf5");
|
||||||
|
inv_convergence_radius.Write_to_HDF5("convergence_test.hdf5", "inv_convergence_radius");
|
||||||
|
psi_1.Write_to_HDF5("convergence_test.hdf5", "psi_1_norm");
|
||||||
|
psi_2.Write_to_HDF5("convergence_test.hdf5", "psi_2_norm");
|
||||||
|
psi_3.Write_to_HDF5("convergence_test.hdf5", "psi_3_norm");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
Loading…
Reference in a new issue