1
0
Fork 0
mirror of https://github.com/cosmo-sims/monofonIC.git synced 2024-09-19 17:03:45 +02:00

merge in schroedinger

This commit is contained in:
Oliver Hahn 2019-08-05 18:01:28 +02:00
commit e6434293dd
4 changed files with 154 additions and 21 deletions

1
.gitignore vendored
View file

@ -53,3 +53,4 @@ src/CMakeCache.txt
src/fastLPT
src/input_powerspec.txt
src/Makefile
.DS_Store

View file

@ -11,7 +11,7 @@ BCClattice = no
NumThreads = 4
[output]
fname_hdf5 = output.hdf5
fname_hdf5 = output_sch.hdf5
fbase_analysis = output
#format = gadget2
#filename = ics_gadget.dat
@ -33,3 +33,7 @@ Omega_L = 0.698
H0 = 70.3
sigma_8 = 0.811
nspec = 0.961
[sch]
hbar = 100.0
dt = 5.0

View file

@ -46,7 +46,7 @@ public:
ptrdiff_t local_0_size_, local_1_size_;
Grid_FFT(const std::array<size_t, 3> &N, const std::array<real_t, 3> &L, space_t initialspace = rspace_id)
: n_(N), length_(L), space_(initialspace), data_(nullptr), cdata_(nullptr)
: n_(N), length_(L), space_(initialspace), data_(nullptr), cdata_(nullptr)
{
//invalidated = true;
this->Setup();
@ -68,7 +68,7 @@ public:
bool is_refined( size_t ilevel, size_t i, size_t j, size_t k ) const { return false; }
size_t levelmin() const {return 7;}
size_t levelmax() const {return 7;}
void Setup();
size_t size(size_t i) const { return sizes_[i]; }
@ -88,6 +88,24 @@ public:
data_[i] = 0.0;
}
void copy_from( const Grid_FFT<data_t>& g ){
// make sure the two fields are in the same space
if( g.space_ != this->space_ ){
if( this->space_ == kspace_id ) this->FourierTransformBackward(false);
else this->FourierTransformForward(false);
}
// make sure the two fields have the same dimensions
assert( this->n_[0] == g.n_[0] );
assert( this->n_[1] == g.n_[1] );
assert( this->n_[2] == g.n_[2] );
// now we can copy all the data over
#pragma omp parallel for
for (size_t i = 0; i < ntot_; ++i)
data_[i] = g.data_[i];
}
data_t& operator[]( size_t i ){
return data_[i];
}
@ -356,6 +374,7 @@ public:
}
}
template <typename functional, typename grid1_t, typename grid2_t>
void assign_function_of_grids_r(const functional &f, const grid1_t &g1, const grid2_t &g2)
{
@ -408,6 +427,27 @@ public:
}
}
template <typename functional, typename grid_t>
void assign_function_of_grids_k(const functional &f, const grid_t &g)
{
assert(g.size(0) == size(0) && g.size(1) == size(1)); // && g.size(2) == size(2) );
#pragma omp parallel for
for (size_t i = 0; i < sizes_[0]; ++i)
{
for (size_t j = 0; j < sizes_[1]; ++j)
{
for (size_t k = 0; k < sizes_[2]; ++k)
{
auto &elem = this->kelem(i, j, k);
const auto &elemg = g.kelem(i, j, k);
elem = f(elemg);
}
}
}
}
template <typename functional>
void apply_function_k_dep(const functional &f)
{
@ -495,7 +535,7 @@ public:
#endif
sum /= sizes_[0]*sizes_[1]*sizes_[2];
#pragma omp parallel for
#pragma omp parallel for
for (size_t i = 0; i < sizes_[0]; ++i)
{
for (size_t j = 0; j < sizes_[1]; ++j)
@ -508,4 +548,5 @@ public:
}
}
}
};

View file

@ -38,7 +38,7 @@ int Run( ConfigFile& the_config )
const real_t volfac(std::pow(boxlen / ngrid / 2.0 / M_PI, 1.5));
const bool bDoFixing = the_config.GetValueSafe<bool>("setup", "DoFixing",false);
the_cosmo_calc->WritePowerspectrum(astart, "input_powerspec.txt" );
csoca::ilog << "-----------------------------------------------------------------------------" << std::endl;
@ -74,6 +74,8 @@ int Run( ConfigFile& the_config )
Grid_FFT<real_t> A3x({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
Grid_FFT<real_t> A3y({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
Grid_FFT<real_t> A3z({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
Grid_FFT<ccomplex_t> psi({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
Grid_FFT<real_t> rho({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
//... array [.] access to components of A3:
std::array< Grid_FFT<real_t>*,3 > A3({&A3x,&A3y,&A3z});
@ -84,7 +86,7 @@ int Run( ConfigFile& the_config )
// NaiveConvolver<real_t> Conv({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
//--------------------------------------------------------------------
// Some operators to add or subtract terms
// Some operators to add or subtract terms
auto assign_to = [](auto &g){return [&](auto i, auto v){ g[i] = v; };};
auto add_to = [](auto &g){return [&](auto i, auto v){ g[i] += v; };};
auto add_twice_to = [](auto &g){return [&](auto i, auto v){ g[i] += 2*v; };};
@ -97,7 +99,7 @@ int Run( ConfigFile& the_config )
//... compute 1LPT displacement potential ....
//======================================================================
// phi = - delta / k^2
double wtime = get_wtime();
double wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing phi(1) term" << std::flush;
#if 1 // random ICs
@ -107,7 +109,7 @@ int Run( ConfigFile& the_config )
the_random_number_generator->Fill_Grid( phi );
phi.FourierTransformForward();
phi.apply_function_k_dep([&](auto x, auto k) -> ccomplex_t {
real_t kmod = k.norm();
if( bDoFixing ) x = (std::abs(x)!=0.0)? x / std::abs(x) : x;
@ -141,12 +143,12 @@ int Run( ConfigFile& the_config )
#endif
csoca::ilog << std::setw(20) << std::setfill(' ') << std::right << "took " << get_wtime()-wtime << "s" << std::endl;
//======================================================================
//... compute 2LPT displacement potential ....
//======================================================================
if( LPTorder > 1 || bSymplecticPT ){
wtime = get_wtime();
wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing phi(2) term" << std::flush;
phi2.FourierTransformForward(false);
Conv.convolve_SumOfHessians( phi, {0,0}, phi, {1,1}, {2,2}, assign_to( phi2 ) );
@ -158,12 +160,98 @@ int Run( ConfigFile& the_config )
csoca::ilog << std::setw(20) << std::setfill(' ') << std::right << "took " << get_wtime()-wtime << "s" << std::endl;
}
//======================================================================
// initialise psi = exp(i Phi(1)/hbar)
//======================================================================
real_t hbar= the_config.GetValueSafe<real_t>("sch", "hbar", 0.1);
real_t dt = the_config.GetValueSafe<real_t>("sch", "dt", 0.5);
phi.FourierTransformBackward();
psi.assign_function_of_grids_r([&]( real_t p ){return std::exp(ccomplex_t(0.0,1.0)/hbar*p);}, phi );
//======================================================================
// evolve wave-function (one drift step) psi = psi *exp(-i hbar *k^2 dt / 2)
//======================================================================
psi.FourierTransformForward();
psi.apply_function_k_dep([hbar,dt]( auto epsi, auto k ){
auto k2 = k.norm_squared();
return epsi * std::exp( - ccomplex_t(0.0,0.5)*hbar* k2 * dt);
});
psi.FourierTransformBackward();
//======================================================================
// compute rho
//======================================================================
// psi.assign_function_of_grids_r([&]( auto p ){return p.norm_squared();}, psi );
rho.assign_function_of_grids_r([&]( auto p ){
auto pp = std::real(p)*std::real(p) + std::imag(p)*std::imag(p);
return pp;
}, psi);
//======================================================================
// compute v
//======================================================================
Grid_FFT<real_t>
vx({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen}),
vy({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen}),
vz({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
for( int idim=0; idim<3; ++idim )
{
Grid_FFT<ccomplex_t> grad_psi({ngrid, ngrid, ngrid}, {boxlen, boxlen, boxlen});
grad_psi.copy_from(psi);
grad_psi.FourierTransformForward();
grad_psi.apply_function_k_dep([&](auto x, auto k) {
return x * ccomplex_t(0.0,k[idim]);
});
grad_psi.FourierTransformBackward();
if( idim==0 )
{
vx.assign_function_of_grids_r([&](auto ppsi, auto pgrad_psi, auto prho) {
return std::real((std::conj(ppsi) * pgrad_psi - ppsi * std::conj(pgrad_psi)) / ccomplex_t(0.0, 2.0 / hbar)/prho);
}, psi, grad_psi, rho);
}
else if( idim==1 )
{
vy.assign_function_of_grids_r([&](auto ppsi, auto pgrad_psi, auto prho) {
return std::real((std::conj(ppsi) * pgrad_psi - ppsi * std::conj(pgrad_psi)) / ccomplex_t(0.0, 2.0 / hbar)/prho);
}, psi, grad_psi, rho);
}
else if (idim == 2)
{
vz.assign_function_of_grids_r([&](auto ppsi, auto pgrad_psi, auto prho) {
return std::real((std::conj(ppsi) * pgrad_psi - ppsi * std::conj(pgrad_psi)) / ccomplex_t(0.0, 2.0 / hbar)/prho);
}, psi, grad_psi, rho);
}
}
// std::cout << "RHO " << rho.relem(1,2,3) << std::endl;
// std::cout << "VX " << vx.relem(1,2,3) << std::endl;
// std::cout << "VY " << vy.relem(1,2,3) << std::endl;
// std::cout << "VZ " << vz.relem(1,2,3) << std::endl;
const std::string fname_sch_hdf5 = the_config.GetValueSafe<std::string>("output", "fname_hdf5", "output_sch.hdf5");
#if defined(USE_MPI)
if( CONFIG::MPI_task_rank == 0 )
unlink(fname_sch_hdf5.c_str());
MPI_Barrier( MPI_COMM_WORLD );
#else
unlink(fname_sch_hdf5.c_str());
#endif
rho.Write_to_HDF5(fname_sch_hdf5, "rho");
vx.Write_to_HDF5(fname_sch_hdf5, "vx");
vy.Write_to_HDF5(fname_sch_hdf5, "vy");
vz.Write_to_HDF5(fname_sch_hdf5, "vz");
//======================================================================
//... compute 3LPT displacement potential
//======================================================================
if( LPTorder > 2 && !bSymplecticPT ){
//... 3a term ...
wtime = get_wtime();
wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing phi(3a) term" << std::flush;
phi3a.FourierTransformForward(false);
Conv.convolve_Hessians( phi, {0,0}, phi, {1,1}, phi, {2,2}, assign_to(phi3a) );
@ -173,9 +261,9 @@ int Run( ConfigFile& the_config )
Conv.convolve_Hessians( phi, {0,1}, phi, {0,1}, phi, {2,2}, subtract_from(phi3a) );
phi3a.apply_InverseLaplacian();
csoca::ilog << std::setw(20) << std::setfill(' ') << std::right << "took " << get_wtime()-wtime << "s" << std::endl;
//... 3b term ...
wtime = get_wtime();
wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing phi(3b) term" << std::flush;
phi3b.FourierTransformForward(false);
Conv.convolve_SumOfHessians( phi, {0,0}, phi2, {1,1}, {2,2}, assign_to(phi3b) );
@ -187,9 +275,9 @@ int Run( ConfigFile& the_config )
phi3b.apply_InverseLaplacian();
phi3b *= 0.5; // factor 1/2 from definition of phi(3b)!
csoca::ilog << std::setw(20) << std::setfill(' ') << std::right << "took " << get_wtime()-wtime << "s" << std::endl;
//... transversal term ...
wtime = get_wtime();
wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing A(3) term" << std::flush;
for( int idim=0; idim<3; ++idim ){
// cyclic rotations of indices
@ -206,7 +294,7 @@ int Run( ConfigFile& the_config )
if( bSymplecticPT ){
//... transversal term ...
wtime = get_wtime();
wtime = get_wtime();
csoca::ilog << std::setw(40) << std::setfill('.') << std::left << "Computing vNLO(3) term" << std::flush;
for( int idim=0; idim<3; ++idim ){
// cyclic rotations of indices
@ -222,16 +310,15 @@ int Run( ConfigFile& the_config )
///... scale all potentials with respective growth factors
phi *= g1;
phi2 *= g2;
phi3a *= g3a;
phi3a *= g3a;
phi3b *= g3b;
(*A3[0]) *= g3c;
(*A3[1]) *= g3c;
(*A3[2]) *= g3c;
csoca::ilog << "-----------------------------------------------------------------------------" << std::endl;
// gadget2_output_interface gof( the_config );
///////////////////////////////////////////////////////////////////////
// we store the densities here if we compute them
//======================================================================
@ -305,7 +392,7 @@ int Run( ConfigFile& the_config )
phi2.Write_to_HDF5(fname_hdf5, "phi2");
phi3a.Write_to_HDF5(fname_hdf5, "phi3a");
phi3b.Write_to_HDF5(fname_hdf5, "phi3b");
delta.Write_to_HDF5(fname_hdf5, "delta");
delta2.Write_to_HDF5(fname_hdf5, "delta2");
delta3a.Write_to_HDF5(fname_hdf5, "delta3a");