/* The state routine is given the state of the system as well as the parameters of the model, and returns information in the info array. The return values are as follows: * 0 time * 1 a * 2 Redshift * 3 H = \dot{a}/a * 4 \dot{H} * 5 phi * 6 \dot{phi} * 7 \ddot{phi} * 8 Omega_matter (present value) * 9 Omega_radiation (present value) * 10 Omega_k (present value) * 11 Omega_Q (present value) * 12 w_total * 13 rho_Q / rho_c * 14 P_Q / rho_c * 15 w_Q * 16 Error */ void LambdaCDM::getstate(const double data[], double time, double info[], Parameters ¶ms) { // Extract data for easier reading of the code double a = data[0]; double phi = data[1]; double phidot = data[2]; // Calculate a^2, a^4 double a2 = pow(a, 2.0); double a4 = pow(a, 4.0); // Go and compute the derivatives double derivs[4]; int result = derivatives(data, derivs, params); // Hubble parameter H = \dot{a}/a double hubble = derivs[0] / a; double hubble2 = pow(hubble, 2.0); // Energy density and pressure double energy = energydensity(data); double press = pressure(data); // time info[0] = time; // a info[1] = a; // Redshift info[2] = 1.0 / a - 1.0; // Hubble info[3] = hubble; // phi info[5] = phi; // \dot{phi} info[6] = phidot; // \ddot{phi} info[7] = derivs[2]; // rho_Q / rho_c info[13] = energy; // P_Q / rho_c info[14] = press; // w_Q info[15] = press / energy; // \dot{H} info[4] = - params.OmegaM() / 2 / a - params.OmegaR() / a2 - a2 * (3.0 * press + energy) / 2.0; // Omega_matter (present value) info[8] = params.OmegaM() / a / hubble2; // Omega_radiation (present value) info[9] = params.OmegaR() / a2 / hubble2; // Omega_k (present value) info[10] = params.OmegaK() / hubble2; // Omega_Q (present value) info[11] = a2 / hubble2 * energy; // w_total info[12] = (params.OmegaR() / 3 + a4 * press) / (a * params.OmegaM() + params.OmegaR() + a4 * energy); // Error info[16] = 0; }
void update(MMSP::grid<2,MMSP::vector<double> >& grid, int steps) { int rank=0; #ifdef MPI_VERSION rank = MPI::COMM_WORLD.Get_rank(); #endif for (int d=0; d<2; d++) { dx(grid,d) = deltaX; if (MMSP::x0(grid,d)==MMSP::g0(grid,d)) MMSP::b0(grid,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(grid,d)==MMSP::g1(grid,d)) MMSP::b1(grid,d) = Neumann; // enumerated in MMSP.utility.hpp } ghostswap(grid); MMSP::grid<2,MMSP::vector<double> > update(grid); for (int d=0; d<2; d++) { dx(update,d) = deltaX; if (MMSP::x0(update,d)==MMSP::g0(update,d)) MMSP::b0(update,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(update,d)==MMSP::g1(update,d)) MMSP::b1(update,d) = Neumann; // enumerated in MMSP.utility.hpp } MMSP::grid<2,double> wspace(grid,1); for (int d=0; d<2; d++) { dx(wspace,d) = deltaX; if (MMSP::x0(wspace,d)==MMSP::g0(wspace,d)) MMSP::b0(wspace,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(wspace,d)==MMSP::g1(wspace,d)) MMSP::b1(wspace,d) = Neumann; // enumerated in MMSP.utility.hpp } for (int step=0; step<steps; step++) { for (int n=0; n<nodes(grid); n++) { MMSP::vector<int> x=position(grid,n); double sum = 0.0; for (int i=1; i<fields(grid); i++) sum += std::pow(grid(x)[i],2); double C = grid(x)[0]; double lap = onelap(grid, x, 0); wspace(x) = -A*(C-Cm) + B*std::pow(C-Cm,3) + Da*std::pow(C-Ca,3) + Db*std::pow(C-Cb,3) - g*(C-Ca)*sum - kappa*lap; } ghostswap(wspace); double energy = 0.0; double mass = 0.0; for (int n=0; n<nodes(grid); n++) { MMSP::vector<int> x=position(grid,n); double lap = laplacian(wspace, x); double C = grid(x)[0]; update(x)[0] = C + dt*D*lap; double sum = 0.0; for (int i=1; i<fields(grid); i++) sum += std::pow(grid(x)[i],2); for (int i=1; i<fields(grid); i++) { double phase = grid(x)[i]; lap = onelap(grid, x, i); update(x)[i] = phase - dt*L*(df2deta(C,phase) + df3deta(phase,sum) - kappa*lap); } mass += dx(grid)*dy(grid)*update(x)[0]; energy += dx(grid)*dy(grid)*energydensity(update(x)); } #ifdef MPI_VERSION double myEnergy=energy; double myMass=mass; MPI::COMM_WORLD.Reduce(&myEnergy,&energy,1,MPI_DOUBLE,MPI_SUM,0); MPI::COMM_WORLD.Reduce(&myMass,&mass,1,MPI_DOUBLE,MPI_SUM,0); #endif #ifndef DEBUG if (rank==0) std::cout<<energy<<'\t'<<mass<<'\n'; #endif swap(grid,update); ghostswap(grid); } #ifndef DEBUG if (rank==0) std::cout<<std::flush; #endif }
// The derivatives routine is given the state of the system (a, phi and \dot{\phi}) as well as the parameters of the system, // and returns the derivatives (\dot{a}, \dot{\phi}, \ddot{\phi}) int LambdaCDM::derivatives(const double data[], double derivs[], Parameters ¶ms) { // Extract data for easier reading of the code double a = data[0]; // Calculate a^2 double a2 = pow(a, 2.0); // Temporary variable double temp; // Hubble parameter double hubble; // Computing \dot{a} // This one comes from the Friedmann equation // temp is \dot{a}^2 temp = a * params.OmegaM() + params.OmegaR() + a2 * params.OmegaK() + pow(a2, 2.0) * energydensity(data); derivs[0] = pow(temp, 0.5); hubble = derivs[0] / a; // The scalar field doesn't exist, so don't include it. derivs[1] = 0; derivs[2] = 0; // Also, we don't need to calculate \dot{H} in this model, as we can solve the Friedman equation analytically derivs[3] = 0; return GSL_SUCCESS; }
void update(MMSP::grid<dim,T>& grid, int steps) { int rank=0; #ifdef MPI_VERSION rank = MPI::COMM_WORLD.Get_rank(); #endif // Make sure the grid spacing is correct for (int d=0; d<dim; d++) { dx(grid,d) = deltaX; if (MMSP::x0(grid,d)==MMSP::g0(grid,d)) MMSP::b0(grid,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(grid,d)==MMSP::g1(grid,d)) MMSP::b1(grid,d) = Neumann; // enumerated in MMSP.utility.hpp } ghostswap(grid); // Let's be absolutely explicit about BCs here. MMSP::grid<dim,T> update(grid); for (int d=0; d<dim; d++) { dx(update,d) = deltaX; if (MMSP::x0(update,d)==MMSP::g0(update,d)) MMSP::b0(update,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(update,d)==MMSP::g1(update,d)) MMSP::b1(update,d) = Neumann; // enumerated in MMSP.utility.hpp } MMSP::grid<dim,T> temp(grid); for (int d=0; d<dim; d++) { dx(temp,d) = deltaX; if (MMSP::x0(temp,d)==MMSP::g0(temp,d)) MMSP::b0(temp,d) = Neumann; // enumerated in MMSP.utility.hpp else if (MMSP::x1(temp,d)==MMSP::g1(temp,d)) MMSP::b1(temp,d) = Neumann; // enumerated in MMSP.utility.hpp } for (int step=0; step<steps; step++) { for (int n=0; n<nodes(grid); n++) { MMSP::vector<int> x = position(grid,n); if (isOutside(x)) { temp(x) = 0.0; } else { double c = grid(x); temp(x) = dfdc(c) - K*zfLaplacian(grid,x); } } #ifdef MPI_VERSION MPI::COMM_WORLD.Barrier(); #endif ghostswap(temp); double energy = 0.0; double mass = 0.0; for (int n=0; n<nodes(grid); n++) { MMSP::vector<int> x = position(grid,n); if (isOutside(x)) { update(x) = 0.0; } else { update(x) = grid(x) + dt*D*zfLaplacian(temp,x); energy += dx(grid)*dy(grid)*energydensity(update(x)); mass += dx(grid)*dy(grid)*update(x); } } #ifdef MPI_VERSION MPI::COMM_WORLD.Barrier(); double myEnergy = energy; double myMass = mass; MPI::COMM_WORLD.Reduce(&myEnergy, &energy, 1, MPI_DOUBLE, MPI_SUM, 0); MPI::COMM_WORLD.Reduce(&myMass, &mass, 1, MPI_DOUBLE, MPI_SUM, 0); #endif if (rank==0) std::cout<<energy<<'\t'<<mass<<'\n'; swap(grid,update); ghostswap(grid); } #ifndef DEBUG if (rank==0) std::cout<<std::flush; #endif }