Пример #1
0
/* 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 &params) {
	// 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;

}
Пример #2
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
}
Пример #3
0
// 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 &params) {

	// 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;
}
Пример #4
0
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
}