Head compute_index( std::vector<std::size_t> const& extent , std::vector<std::size_t> const& offsets , std::size_t n , Head head , Tail... tail ) { if (sizeof...(tail)) { head += offsets[n]; //std::cout << "(s{" << n << "} + " << offsets[n] << ")"; for (std::size_t i = 0; i < n; ++i) { //std::cout << "(d{" << i << "})"; head *= extent[i]; } //std::cout << " + "; head += compute_index(extent, offsets, n + 1, tail...); } return head; }
void compute_point_emission() { t_mesh *mesh = get_mesh(); unsigned int i,j,point_id; int i_t_le,i_t_kappa,i_t_fQ,i_h2o; double kappa,emission=0; mesh->max_emission = 0; for(i=0;i<mesh->nb_points;i++) { mesh->points[i].emission = 0; } for(i=0;i<mesh->nb_point_to_compute;i++) { point_id = mesh->point_to_compute[i]; compute_index(mesh->points[point_id].temperature, mesh->points[point_id].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o); for(j=0;j<NB_BAND;j++) { kappa = mesh->point_presure * mesh->points[i].h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[j][i_t_kappa][i_h2o] + mesh->point_presure * mesh->points[i].co2 * mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[j][i_t_kappa]; emission = emission + kappa*mesh->ckmodel.le_store[j][i_t_le]; } mesh->points[i].emission = FOUR_PI * emission; if(mesh->points[i].emission > mesh->max_emission) mesh->max_emission = mesh->points[i].emission; } }
double percentile_keeper_emit(percentile_keeper_t* ppercentile_keeper, double percentile) { if (!ppercentile_keeper->sorted) { qsort(ppercentile_keeper->data, ppercentile_keeper->size, sizeof(double), double_comparator); ppercentile_keeper->sorted = TRUE; } return ppercentile_keeper->data[compute_index(ppercentile_keeper->size, percentile)]; }
Head index( std::vector<std::size_t> const& extent , std::vector<std::size_t> const& offsets , Head head , Tail... tail ) { BOOST_ASSERT(extent.size() != 0); return compute_index(extent, offsets, 0, head, tail...); }
void compute_kappa_le_simple(int nu, double temperature, double co2, double h2o, double *kappa, double *le) { t_mesh *mesh = get_mesh(); int i_t_le, i_t_kappa, i_t_fQ, i_h2o; double t, x_h2o, x_co2; t = temperature; x_h2o = h2o; x_co2 = co2; compute_index(t, x_h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o); *kappa = mesh->point_presure * x_h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[nu][i_t_kappa][i_h2o] + mesh->point_presure * x_co2 *mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[nu][i_t_kappa]; *le = mesh->ckmodel.le_store[nu][i_t_le]; }
int get_nu_face(int point) { t_mesh *mesh = get_mesh(); int i_t_le, i_t_kappa, i_t_fQ, i_h2o, nu; unsigned int i_nu; double cumulative_energy, cumulative_energy_old, rand_number; rand_number = nrand() * mesh->points[point].emission_surface / FOUR_PI / mesh->point_presure; cumulative_energy = 0; nu = 0; for(i_nu=0;i_nu<NB_BAND;i_nu++) { compute_index(mesh->points[point].temperature, mesh->points[point].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o); cumulative_energy_old = cumulative_energy; cumulative_energy = cumulative_energy + mesh->epsilon_paro * mesh->ckmodel.le_store[i_nu][i_t_le]; if(rand_number <= cumulative_energy && rand_number > cumulative_energy_old) { nu = i_nu; break; } } return nu; }
void doCollision(double *collideField, int *flagField,const double * const tau, int *subdomain){ double density; double velocity[D]; double feq[Q]; double *currentCell = NULL; // currentCell points to the first distribution function within the respective cell for (int iz=1; iz<=subdomain[2]; iz++){ for (int iy=1; iy<=subdomain[1]; iy++){ for (int ix=1; ix<=subdomain[0]; ix++){ // set pointer to current cell currentCell = collideField + Q * compute_index(ix, iy, iz, subdomain); // compute density, velocity and equilibrium prob. distrib. for this cell computeDensity ( currentCell, &density ); computeVelocity ( currentCell, &density, velocity ); computeFeq ( &density, velocity, feq ); computePostCollisionDistributions ( currentCell, tau, feq ); } } } }
int get_nu(int point) { t_mesh *mesh = get_mesh(); int i_t_le, i_t_kappa, i_t_fQ, i_h2o, nu; unsigned int i_nu; double cumulative_energy, cumulative_energy_old, kappa, rand_number; rand_number = nrand() * mesh->points[point].emission / FOUR_PI /mesh->point_presure; cumulative_energy = 0; nu = 0; for(i_nu=0;i_nu<NB_BAND;i_nu++) { compute_index(mesh->points[point].temperature, mesh->points[point].h2o, &i_t_le, &i_t_kappa, &i_t_fQ, &i_h2o); cumulative_energy_old = cumulative_energy; kappa = mesh->points[point].h2o * mesh->ckmodel.fQH_store[i_t_fQ] * mesh->ckmodel.kappa_h2o_store[i_nu][i_t_kappa][i_h2o] + mesh->points[point].co2 * mesh->ckmodel.fQC_store[i_t_fQ] * mesh->ckmodel.kappa_co2_store[i_nu][i_t_kappa]; cumulative_energy = cumulative_energy + kappa * mesh->ckmodel.le_store[i_nu][i_t_le]; if(rand_number <= cumulative_energy && rand_number > cumulative_energy_old) { nu = i_nu; break; } } return nu; }
void gen_subscript(Node node) /*;gen_subscript*/ { Symbol comp_type; Node index_name, array_node; Node index_list_node, subscript; Tuple index_type_list, subscripts, tup; Symbol array_name, array_type; int optimized; int index, seg, offset; Fortup ft1; #ifdef TRACE if (debug_flag) gen_trace_node("GEN_SUBSCRIPT", node); #endif array_node = N_AST1(node); index_list_node = N_AST2(node); array_name = N_UNQ(array_node); array_type = get_type(array_node); tup = SIGNATURE(array_type); index_type_list = (Tuple) tup[1]; comp_type = (Symbol) tup[2]; /* need tup_copy since subscripts used in tup_fromb below */ subscripts = tup_copy(N_LIST(index_list_node)); /* * Before applying the brute force method of the 'do-it-all' instruction * "subscript", which can solve any case, some optimizations will be * attempted. * * First, we try to compute the address of the indexed element directly, * when subscripts are immediate values and the index check can be done * at compile time: */ if ((Symbol)index_type_list[1] == symbol_none) { optimized = FALSE; } else if (!(is_unconstrained(array_type))) { index = compute_index(subscripts, index_type_list); optimized = index != -1; if (optimized) { if (has_static_size(comp_type)) { index = index * size_of(comp_type); if (is_simple_name(array_node) && !is_renaming(array_name) ) { if (is_global(array_name)) { reference_of(array_name); seg = REFERENCE_SEGMENT; offset = REFERENCE_OFFSET; /*gen_todo(I_PUSH_EFFECTIVE_ADDRESS,[seg, offset+index], * array_name + '(" + str(get_ivalue(subscripts(1))) * +/ [', '+str(get_ivalue(subscripts(i))): * i in [2..#subscripts] ] * + ")' ); */ gen_rc(I_PUSH_EFFECTIVE_ADDRESS, explicit_ref_new(seg, offset+index), ""); } else { gen_s(I_PUSH_EFFECTIVE_ADDRESS, array_name); if (index != 0) gen_kic(I_ADD_IMMEDIATE, mu_word, index, "offset"); } } else { gen_address(array_node); gen_ks(I_DISCARD_ADDR, 1, array_type); if (index != 0) gen_ki(I_ADD_IMMEDIATE, mu_word, index); } } else { optimized = FALSE; } } } else { optimized = FALSE; } /* * Nothing worked, we are left with the worse case, solved by the * "subscript" instruction */ if (!optimized) { FORTUP( index_name=(Node), index_type_list, ft1); subscript = (Node) tup_fromb(subscripts); gen_value(subscript) ; ENDFORTUP(ft1); gen_address(array_node); gen(I_SUBSCRIPT); } if (is_array_type(comp_type)) { gen_s(I_PUSH_EFFECTIVE_ADDRESS, comp_type); } }
auto run_simulation(const wayverb::core::geo::box& boundary, const util::aligned::vector<glm::vec3>& receivers, const wayverb::waveguide::coefficients_canonical& coefficients) const { const auto scene_data = wayverb::core::geo::get_scene_data( boundary, wayverb::core::make_surface<wayverb::core::simulation_bands>( 0, 0)); auto mesh = wayverb::waveguide::compute_mesh( cc_, make_voxelised_scene_data( scene_data, 5, wayverb::waveguide::compute_adjusted_boundary( wayverb::core::geo::compute_aabb( scene_data.get_vertices()), source_position_, divisions_)), divisions_, speed_of_sound); mesh.set_coefficients({coefficients}); const auto source_index = compute_index(mesh.get_descriptor(), source_position_); const auto input = [&] { const util::aligned::vector<float> raw_input{1.0f}; auto ret = wayverb::waveguide::make_transparent( raw_input.data(), raw_input.data() + raw_input.size()); ret.resize(steps, 0); return ret; }(); auto prep = wayverb::waveguide::preprocessor::make_soft_source( source_index, input.begin(), input.end()); auto output_holders = util::map_to_vector( begin(receivers), end(receivers), [&](auto i) { const auto receiver_index{ compute_index(mesh.get_descriptor(), i)}; if (!wayverb::waveguide::is_inside(mesh, receiver_index)) { throw std::runtime_error{ "receiver is outside of mesh!"}; } return wayverb::core::callback_accumulator< wayverb::waveguide::postprocessor::node> { receiver_index }; }); util::progress_bar pb{}; wayverb::waveguide::run( cc_, mesh, prep, [&](auto& queue, const auto& buffer, auto step) { for (auto& i : output_holders) { i(queue, buffer, step); } set_progress(pb, step, steps); }, true); return util::map_to_vector( begin(output_holders), end(output_holders), [](const auto& i) { return i.get_output(); }); }
/// The actual test described in section V A from the sheaffer2014 paper. void test_from_paper() { // Set up all the generic features of the simulation. const wayverb::core::geo::box box{glm::vec3{-3}, glm::vec3{3}}; const auto sample_rate = 16000.0; const auto speed_of_sound = 340.0; const wayverb::core::compute_context cc{}; const glm::vec3 receiver{0}; const auto radius = 1.5; const glm::vec3 source{ std::sin(M_PI / 4) * radius, 0, std::cos(M_PI / 4) * radius}; auto voxels_and_mesh = wayverb::waveguide::compute_voxels_and_mesh( cc, wayverb::core::geo::get_scene_data( box, wayverb::core::make_surface< wayverb::core::simulation_bands>(0, 0)), receiver, sample_rate, speed_of_sound); { constexpr auto absorption = 0.005991; voxels_and_mesh.mesh.set_coefficients( wayverb::waveguide::to_flat_coefficients(absorption)); } const auto input_node = compute_index(voxels_and_mesh.mesh.get_descriptor(), source); const auto output_node = compute_index(voxels_and_mesh.mesh.get_descriptor(), receiver); // Now we get to do the interesting new bit: // Set up a physically modelled source signal. const auto length = 1 << 12; auto pulse_shaping_filter = wayverb::waveguide::maxflat(0.075, 16, 250e-6, length); wayverb::core::filter::biquad mechanical_filter{ wayverb::waveguide::mech_sphere( 0.025, 100 / sample_rate, 0.7, 1 / sample_rate)}; run_one_pass(mechanical_filter, pulse_shaping_filter.signal.begin(), pulse_shaping_filter.signal.end()); const auto one_over_two_T = sample_rate / 2; wayverb::core::filter::biquad injection_filter{ {one_over_two_T, 0, -one_over_two_T, 0, 0}}; run_one_pass(injection_filter, pulse_shaping_filter.signal.begin(), pulse_shaping_filter.signal.end()); const auto input_signal = pulse_shaping_filter; // Run the simulation. auto prep = wayverb::waveguide::preprocessor::make_soft_source( input_node, input_signal.signal.begin(), input_signal.signal.end()); wayverb::core::callback_accumulator<wayverb::waveguide::postprocessor::node> postprocessor{output_node}; util::progress_bar pb; wayverb::waveguide::run(cc, voxels_and_mesh.mesh, prep, [&](auto& a, const auto& b, auto c) { postprocessor(a, b, c); set_progress(pb, c, input_signal.signal.size()); }, true); write("test_from_paper", postprocessor.get_output(), sample_rate); }
void other_tests() { // Set up all the generic features of the simulation. const wayverb::core::geo::box box{glm::vec3{-3}, glm::vec3{3}}; const auto sample_rate = 4000.0; const auto acoustic_impedance = 400.0; const auto speed_of_sound = 340.0; const wayverb::core::compute_context cc{}; const glm::vec3 receiver{0}; const auto radius = 1.5; const glm::vec3 source{ std::sin(M_PI / 4) * radius, 0, std::cos(M_PI / 4) * radius}; auto voxels_and_mesh = wayverb::waveguide::compute_voxels_and_mesh( cc, wayverb::core::geo::get_scene_data( box, wayverb::core::make_surface< wayverb::core::simulation_bands>(0, 0)), receiver, sample_rate, speed_of_sound); voxels_and_mesh.mesh.set_coefficients( wayverb::waveguide::to_flat_coefficients(0.005991)); const auto input_node = compute_index(voxels_and_mesh.mesh.get_descriptor(), source); const auto output_node = compute_index(voxels_and_mesh.mesh.get_descriptor(), receiver); // Now we get to do the interesting new bit: // Set up a physically modelled source signal. const auto run_tests = [&](auto name, auto signals) { auto count = 0; for (const auto& input_signal : signals) { write(util::build_string(name, "_test_input_", count), input_signal.signal, sample_rate); // Run the simulation. auto prep = wayverb::waveguide::preprocessor::make_soft_source( input_node, input_signal.signal.begin(), input_signal.signal.end()); wayverb::core::callback_accumulator< wayverb::waveguide::postprocessor::node> postprocessor{output_node}; util::progress_bar pb; wayverb::waveguide::run( cc, voxels_and_mesh.mesh, prep, [&](auto& a, const auto& b, auto c) { postprocessor(a, b, c); set_progress(pb, c, input_signal.signal.size()); }, true); write(util::build_string(name, "_test_output_", count), postprocessor.get_output(), sample_rate); count += 1; } }; // run_tests("mass", get_mass_test_signals(sample_rate)); run_tests("cutoff", get_cutoff_test_signals( acoustic_impedance, speed_of_sound, sample_rate)); }
constexpr int compute_index(std::integer_sequence< int, First, Indices ... > , First_Int first_, Ints ... indices) const { return // instead of using First and first_, the index should be chosen according to the layout vector // implement something like layout::select<First>(first_, indices ...) first_ + m_dims[First] * compute_index(std::integer_sequence<int, Indices ...>(), indices ...); }
constexpr int index(Ints ... idx) const { return compute_index(std::make_integer_sequence<int, sizeof...(Ints)>(), idx ... ); }