> 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; }
> 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; } } } }
> void initialize( const Geometries& geometries, Init_Cond& initial_conditions, const Background_Magnetic_Field& bg_B, 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 bool verbose, const Mass_Density_Getter Mas, const Momentum_Density_Getter Mom, const Total_Energy_Density_Getter Nrj, const Magnetic_Field_Getter Mag, const Background_Magnetic_Field_Pos_X_Getter Bg_B_Pos_X, const Background_Magnetic_Field_Pos_Y_Getter Bg_B_Pos_Y, const Background_Magnetic_Field_Pos_Z_Getter Bg_B_Pos_Z, const Mass_Density_Flux_Getter Mas_f, const Momentum_Density_Flux_Getter Mom_f, const Total_Energy_Density_Flux_Getter Nrj_f, const Magnetic_Field_Flux_Getter Mag_f ) { if (verbose and grid.get_rank() == 0) { std::cout << "Setting default MHD state... "; std::cout.flush(); } // set default state for (const auto cell_id: cells) { auto* const cell_data = grid[cell_id]; if (cell_data == nullptr) { std::cerr << __FILE__ << "(" << __LINE__ << ") No data for cell: " << cell_id << std::endl; abort(); } // zero fluxes and background fields Mas_f(*cell_data) = Nrj_f(*cell_data) = Mom_f(*cell_data)[0] = Mom_f(*cell_data)[1] = Mom_f(*cell_data)[2] = Mag_f(*cell_data)[0] = Mag_f(*cell_data)[1] = Mag_f(*cell_data)[2] = 0; const auto c = grid.geometry.get_center(cell_id); const auto r = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); const auto lat = asin(c[2] / r), lon = atan2(c[1], c[0]); const auto mass_density = proton_mass * initial_conditions.get_default_data( Number_Density(), time, c[0], c[1], c[2], r, lat, lon ); const auto velocity = initial_conditions.get_default_data( Velocity(), time, c[0], c[1], c[2], r, lat, lon ); const auto pressure = initial_conditions.get_default_data( Pressure(), time, c[0], c[1], c[2], r, lat, lon ); const auto magnetic_field = initial_conditions.get_default_data( Magnetic_Field(), time, c[0], c[1], c[2], r, lat, lon ); Mas(*cell_data) = mass_density; Mom(*cell_data) = mass_density * velocity; Mag(*cell_data) = magnetic_field; Nrj(*cell_data) = get_total_energy_density( mass_density, velocity, pressure, magnetic_field, adiabatic_index, vacuum_permeability ); const auto cell_end = grid.geometry.get_max(cell_id); Bg_B_Pos_X(*cell_data) = bg_B.get_background_field( {cell_end[0], c[1], c[2]}, vacuum_permeability ); Bg_B_Pos_Y(*cell_data) = bg_B.get_background_field( {c[0], cell_end[1], c[2]}, vacuum_permeability ); Bg_B_Pos_Z(*cell_data) = bg_B.get_background_field( {c[0], c[1], cell_end[2]}, vacuum_permeability ); } // set non-default initial conditions if (verbose and grid.get_rank() == 0) { std::cout << "done\nSetting non-default initial MHD state... "; std::cout.flush(); } /* Set non-default initial conditions */ // mass density for ( size_t i = 0; i < initial_conditions.get_number_of_regions(Number_Density()); i++ ) { const auto& init_cond = initial_conditions.get_initial_condition(Number_Density(), i); const auto& geometry_id = init_cond.get_geometry_id(); const auto& cells = geometries.get_cells(geometry_id); for (const auto& cell: cells) { const auto c = grid.geometry.get_center(cell); const auto r = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); const auto lat = asin(c[2] / r), lon = atan2(c[1], c[0]); const auto mass_density = proton_mass * initial_conditions.get_data( Number_Density(), geometry_id, time, c[0], c[1], c[2], r, lat, lon ); auto* const cell_data = grid[cell]; if (cell_data == NULL) { std::cerr << __FILE__ << "(" << __LINE__ << std::endl; abort(); } Mas(*cell_data) = mass_density; } } // velocity for ( size_t i = 0; i < initial_conditions.get_number_of_regions(Velocity()); i++ ) { const auto& init_cond = initial_conditions.get_initial_condition(Velocity(), i); const auto& geometry_id = init_cond.get_geometry_id(); const auto& cells = geometries.get_cells(geometry_id); for (const auto& cell: cells) { const auto c = grid.geometry.get_center(cell); const auto r = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); const auto lat = asin(c[2] / r), lon = atan2(c[1], c[0]); const auto velocity = initial_conditions.get_data( Velocity(), geometry_id, time, c[0], c[1], c[2], r, lat, lon ); auto* const cell_data = grid[cell]; if (cell_data == NULL) { std::cerr << __FILE__ << "(" << __LINE__ << ") No data for cell: " << cell << std::endl; abort(); } Mom(*cell_data) = Mas(*cell_data) * velocity; } } // magnetic field for ( size_t i = 0; i < initial_conditions.get_number_of_regions(Magnetic_Field()); i++ ) { const auto& init_cond = initial_conditions.get_initial_condition(Magnetic_Field(), i); const auto& geometry_id = init_cond.get_geometry_id(); const auto& cells = geometries.get_cells(geometry_id); for (const auto& cell: cells) { const auto c = grid.geometry.get_center(cell); const auto r = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); const auto lat = asin(c[2] / r), lon = atan2(c[1], c[0]); const auto magnetic_field = initial_conditions.get_data( Magnetic_Field(), geometry_id, time, c[0], c[1], c[2], r, lat, lon ); auto* const cell_data = grid[cell]; if (cell_data == NULL) { std::cerr << __FILE__ << "(" << __LINE__ << ") No data for cell: " << cell << std::endl; abort(); } Mag(*cell_data) = magnetic_field; } } // pressure for ( size_t i = 0; i < initial_conditions.get_number_of_regions(Pressure()); i++ ) { std::cout << std::endl; const auto& init_cond = initial_conditions.get_initial_condition(Pressure(), i); const auto& geometry_id = init_cond.get_geometry_id(); std::cout << geometry_id << std::endl; const auto& cells = geometries.get_cells(geometry_id); std::cout << cells.size() << std::endl; for (const auto& cell: cells) { const auto c = grid.geometry.get_center(cell); const auto r = sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]); const auto lat = asin(c[2] / r), lon = atan2(c[1], c[0]); const auto pressure = initial_conditions.get_data( Pressure(), geometry_id, time, c[0], c[1], c[2], r, lat, lon ); auto* const cell_data = grid[cell]; if (cell_data == NULL) { std::cerr << __FILE__ << "(" << __LINE__ << ") No data for cell: " << cell << std::endl; abort(); } Nrj(*cell_data) = get_total_energy_density( Mas(*cell_data), Mom(*cell_data) / Mas(*cell_data), pressure, Mag(*cell_data), adiabatic_index, vacuum_permeability ); } } if (verbose and grid.get_rank() == 0) { std::cout << "done" << std::endl; } }
> 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; } } } }