예제 #1
0
> void initialize_fluid(
	Init_Cond& init_cond,
	dccrg::Dccrg<Cell, Geometry>& grid,
	const std::vector<uint64_t>& cells,
	const double time,
	const double adiabatic_index,
	const double vacuum_permeability,
	const double proton_mass,
	const Mass_Density_Getter Mas,
	const Momentum_Density_Getter Mom,
	const Total_Energy_Density_Getter Nrj
) {
	// set default state
	for (const auto cell_id: cells) {
		const auto
			cell_start = grid.geometry.get_min(cell_id),
			cell_end = grid.geometry.get_max(cell_id),
			cell_center = grid.geometry.get_center(cell_id);

		init_cond.add_cell(
			cell_id,
			cell_start,
			cell_end
		);

		auto* const cell_data = grid[cell_id];
		if (cell_data == NULL) {
			std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
				<< cell_id
				<< std::endl;
			abort();
		}

		const auto mass_density
			= proton_mass
			* [&](){
				try {
					return init_cond.default_data.get_data(mhd::Number_Density(), cell_center, time);
				} catch (mup::ParserError& e) {
					std::cout << "Couldn't get number density for default initial condition." << std::endl;
					throw;
				}
			}();
		const auto velocity
			= [&](){
				try {
					return init_cond.default_data.get_data(mhd::Velocity(), cell_center, time);
				} catch (mup::ParserError& e) {
					std::cout << "Couldn't get velocity for default initial condition." << std::endl;
					throw;
				}
			}();
		const auto pressure
			= [&](){
				try {
					return init_cond.default_data.get_data(mhd::Pressure(), cell_center, time);
				} catch (mup::ParserError& e) {
					std::cout << "Couldn't get pressure for default initial condition." << std::endl;
					throw;
				}
			}();

		Mas(*cell_data) = mass_density;
		Mom(*cell_data) = mass_density * velocity;
		if (mass_density > 0 and pressure > 0) {
			Nrj(*cell_data) = mhd::get_total_energy_density(
				mass_density,
				velocity,
				pressure,
				std::array<double, 3>{{0, 0, 0}},
				adiabatic_index,
				vacuum_permeability
			);
		} else {
			Nrj(*cell_data) = 0;
		}
	}

	// set non-default initial conditions
	for (size_t bdy_i = 0; bdy_i < init_cond.get_number_of_boundaries(); bdy_i++) {
		const auto& boundary_cells = init_cond.get_cells(bdy_i);

		for (const auto& cell_id: boundary_cells) {
			const auto cell_center = grid.geometry.get_center(cell_id);

			auto* const cell_data = grid[cell_id];
			if (cell_data == NULL) {
				std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
					<< cell_id
					<< std::endl;
				abort();
			}

			const auto mass_density
				= proton_mass
				* [&](){
					try {
						return init_cond.get_data(mhd::Number_Density(), bdy_i, cell_center, time);
					} catch (mup::ParserError& e) {
						std::cout << "Couldn't get density for initial condition geometry " << bdy_i << std::endl;
						throw;
					}
				}();
			const auto velocity
				= [&](){
					try {
						return init_cond.get_data(mhd::Velocity(), bdy_i, cell_center, time);
					} catch (mup::ParserError& e) {
						std::cout << "Couldn't get velocity for initial condition geometry " << bdy_i << std::endl;
						throw;
					}
				}();
			const auto pressure
				= [&](){
					try {
						return init_cond.get_data(mhd::Pressure(), bdy_i, cell_center, time);
					} catch (mup::ParserError& e) {
						std::cout << "Couldn't get pressure for initial condition geometry " << bdy_i << std::endl;
						throw;
					}
				}();

			Mas(*cell_data) = mass_density;
			Mom(*cell_data) = mass_density * velocity;
			if (mass_density > 0 and pressure > 0) {
				Nrj(*cell_data) = mhd::get_total_energy_density(
					mass_density,
					velocity,
					pressure,
					std::array<double, 3>{{0, 0, 0}},
					adiabatic_index,
					vacuum_permeability
				);
			} else {
				Nrj(*cell_data) = 0;
			}
		}
	}
}
예제 #2
0
> size_t initialize(
	Init_Cond& init_cond,
	const double simulation_time,
	const std::vector<uint64_t>& cells,
	Grid& grid,
	std::mt19937_64& random_source,
	const double particle_temp_nrj_ratio,
	const unsigned long long int first_particle_id,
	const unsigned long long int particle_id_increase,
	const bool replace,
	const bool verbose
) {
	if (verbose && grid.get_rank() == 0) {
		std::cout << "Setting default particle state... ";
		std::cout.flush();
	}

	size_t nr_particles_created = 0;
	auto current_id_start = first_particle_id;
	for (const auto cell_id: cells) {
		random_source.seed(cell_id);

		const auto
			cell_start = grid.geometry.get_min(cell_id),
			cell_end = grid.geometry.get_max(cell_id),
			cell_length = grid.geometry.get_length(cell_id),
			cell_center = grid.geometry.get_center(cell_id);

		// classify cells for setting non-default initial state
		init_cond.add_cell(
			cell_id,
			cell_start,
			cell_end
		);

		auto* const cell_data = grid[cell_id];
		if (cell_data == NULL) {
			std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
				<< cell_id
				<< std::endl;
			abort();
		}

		// set default state
		const auto
			number_density
				= init_cond.default_data.get_data(
					Number_Density_T(),
					cell_center,
					simulation_time
				),
			temperature
				= init_cond.default_data.get_data(
					Temperature_T(),
					cell_center,
					simulation_time
				),
			charge_mass_ratio
				= init_cond.default_data.get_data(
					Charge_Mass_Ratio_T(),
					cell_center,
					simulation_time
				),
			species_mass
				= init_cond.default_data.get_data(
					Particle_Species_Mass_T(),
					cell_center,
					simulation_time
				);
		const auto bulk_velocity
			= init_cond.default_data.get_data(
				Bulk_Velocity_T(),
				cell_center,
				simulation_time
			);
		const auto nr_particles
			= init_cond.default_data.get_data(
				Nr_Particles_In_Cell_T(),
				cell_center,
				simulation_time
			);

		auto new_particles
			= create_particles<
				Particle,
				Particle_Mass_T,
				Particle_Charge_Mass_Ratio_T,
				Particle_Position_T,
				Particle_Velocity_T,
				Particle_ID_T,
				Particle_Species_Mass_T
			>(
				bulk_velocity,
				Eigen::Vector3d{cell_start[0], cell_start[1], cell_start[2]},
				Eigen::Vector3d{cell_end[0], cell_end[1], cell_end[2]},
				Eigen::Vector3d{temperature, temperature, temperature},
				nr_particles,
				charge_mass_ratio,
				species_mass * number_density * cell_length[0] * cell_length[1] * cell_length[2],
				species_mass,
				particle_temp_nrj_ratio,
				random_source,
				current_id_start,
				particle_id_increase
			);
		nr_particles_created += nr_particles;

		if (replace) {
			(*cell_data)[Particles_T()] = std::move(new_particles);
		} else {
			(*cell_data)[Particles_T()].insert(
				(*cell_data)[Particles_T()].end(),
				new_particles.begin(),
				new_particles.end()
			);
		}

		current_id_start += nr_particles * particle_id_increase;
	}

	// set non-default initial conditions
	if (verbose && grid.get_rank() == 0) {
		std::cout << "done\nSetting non-default initial particle state... ";
		std::cout.flush();
	}
	for (size_t bdy_id = 0; bdy_id < init_cond.get_number_of_boundaries(); bdy_id++) {
		for (const auto& cell_id: init_cond.get_cells(bdy_id)) {
			const auto
				cell_start = grid.geometry.get_min(cell_id),
				cell_end = grid.geometry.get_max(cell_id),
				cell_length = grid.geometry.get_length(cell_id),
				cell_center = grid.geometry.get_center(cell_id);

			const auto
				number_density
					= init_cond.get_data(
						Number_Density_T(),
						bdy_id,
						cell_center,
						simulation_time
					),
				temperature
					= init_cond.get_data(
						Temperature_T(),
						bdy_id,
						cell_center,
						simulation_time
					),
				charge_mass_ratio
					= init_cond.get_data(
						Charge_Mass_Ratio_T(),
						bdy_id,
						cell_center,
						simulation_time
					),
				species_mass
					= init_cond.get_data(
						Particle_Species_Mass_T(),
						bdy_id,
						cell_center,
						simulation_time
					);
			const auto bulk_velocity
				= init_cond.get_data(
					Bulk_Velocity_T(),
					bdy_id,
					cell_center,
					simulation_time
				);
			const auto nr_particles
				= init_cond.get_data(
					Nr_Particles_In_Cell_T(),
					bdy_id,
					cell_center,
					simulation_time
				);

			auto* const cell_data = grid[cell_id];
			if (cell_data == NULL) {
				std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
					<< cell_id
					<< std::endl;
				abort();
			}

			auto new_particles
				= create_particles<
					Particle,
					Particle_Mass_T,
					Particle_Charge_Mass_Ratio_T,
					Particle_Position_T,
					Particle_Velocity_T,
					Particle_ID_T,
					Particle_Species_Mass_T
				>(
					bulk_velocity,
					Eigen::Vector3d{cell_start[0], cell_start[1], cell_start[2]},
					Eigen::Vector3d{cell_end[0], cell_end[1], cell_end[2]},
					Eigen::Vector3d{temperature, temperature, temperature},
					nr_particles,
					charge_mass_ratio,
					species_mass * number_density * cell_length[0] * cell_length[1] * cell_length[2],
					species_mass,
					particle_temp_nrj_ratio,
					random_source,
					current_id_start,
					particle_id_increase
				);
			nr_particles_created += nr_particles;

			if (replace) {
				(*cell_data)[Particles_T()] = std::move(new_particles);
			} else {
				(*cell_data)[Particles_T()].insert(
					(*cell_data)[Particles_T()].end(),
					new_particles.begin(),
					new_particles.end()
				);
			}

			current_id_start += nr_particles * particle_id_increase;
		}
	}
	if (verbose && grid.get_rank() == 0) {
		std::cout << "done" << std::endl;
	}

	return nr_particles_created;
}
예제 #3
0
> void initialize_field(
	Init_Cond& init_cond,
	dccrg::Dccrg<Cell, Geometry>& grid,
	const std::vector<uint64_t>& cells,
	const double time,
	const Magnetic_Field_Getter Mag
) {
	// set default state
	for (const auto cell_id: cells) {
		const auto
			cell_start = grid.geometry.get_min(cell_id),
			cell_end = grid.geometry.get_max(cell_id),
			cell_center = grid.geometry.get_center(cell_id);

		init_cond.add_cell(
			cell_id,
			cell_start,
			cell_end
		);

		auto* const cell_data = grid[cell_id];
		if (cell_data == NULL) {
			std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
				<< cell_id
				<< std::endl;
			abort();
		}

		try {
			Mag(*cell_data)
				= init_cond.default_data.get_data(
					mhd::Magnetic_Field(),
					cell_center,
					time
				);
		} catch (mup::ParserError& e) {
			std::cout << "Couldn't get magnetic field for default initial condition." << std::endl;
			throw;
		}
	}

	// set non-default initial conditions
	for (size_t bdy_i = 0; bdy_i < init_cond.get_number_of_boundaries(); bdy_i++) {
		const auto& boundary_cells = init_cond.get_cells(bdy_i);

		for (const auto& cell_id: boundary_cells) {
			const auto cell_center = grid.geometry.get_center(cell_id);

			auto* const cell_data = grid[cell_id];
			if (cell_data == NULL) {
				std::cerr <<  __FILE__ << "(" << __LINE__ << ") No data for cell: "
					<< cell_id
					<< std::endl;
				abort();
			}

			try {
				Mag(*cell_data)
					= init_cond.get_data(
						mhd::Magnetic_Field(),
						bdy_i,
						cell_center,
						time
					);
			} catch (mup::ParserError& e) {
				std::cout << "Couldn't get magnetic field for default initial condition." << std::endl;
				throw;
			}
		}
	}
}