Skip to content
Snippets Groups Projects
Commit a96888a5 authored by ferrari's avatar ferrari
Browse files

version working for nvc++ -stdpar -fast

parent e6c503b6
No related branches found
No related tags found
No related merge requests found
#include <iostream> #include <iostream>
#include <fstream>
#include <vector> #include <vector>
#include <string>
#include <cstring> #include <cstring>
#include "sound_column.h" #include "sound_column.h"
#include <execution> #include <execution>
...@@ -11,30 +13,41 @@ ...@@ -11,30 +13,41 @@
#define DEFAULT_MAX_FREQ 12'500.0f #define DEFAULT_MAX_FREQ 12'500.0f
#define WATER_SPEED 1'500.f #define WATER_SPEED 1'500.f
std::complex<float> gaussian_init(float, float); void gaussian_init(sound_column&);
float media(float, float); bool step_r(sound_column&);
int run_simulation(float, float, float, float); void _step_r_(sound_column&, size_t);
float media(float, float, float);
std::vector<sound_column*>* run_simulation(float, float, float, float);
int save_results(std::string&, std::vector<sound_column*>&);
int main(int argc, char **argv) { int main(int argc, char **argv) {
float r_max = DEFAULT_DISTANCE, z_max = DEFAULT_DEPTH, f_min = DEFAULT_MIN_FREQ, f_max = DEFAULT_MAX_FREQ; float r_max = DEFAULT_DISTANCE, z_max = DEFAULT_DEPTH, f_min = DEFAULT_MIN_FREQ, f_max = DEFAULT_MAX_FREQ;
bool dry_run = false;
std::string save_path = "";
int i=1; int i=1;
while (i < argc){ while (i < argc){
if (strcmp(argv[i], "--d_max") != 0 || strcmp(argv[i], "-d") != 0) if (strcmp(argv[i], "--r_max") == 0 || strcmp(argv[i], "-r") == 0)
r_max = atof(argv[++i]); r_max = atof(argv[++i]);
else if (strcmp(argv[i], "--f_max") != 0 || strcmp(argv[i], "-F") != 0) else if (strcmp(argv[i], "--f_max") == 0 || strcmp(argv[i], "-F") == 0)
f_max = atof(argv[++i]); f_max = atof(argv[++i]);
else if (strcmp(argv[i], "--f_min") != 0 || strcmp(argv[i], "-f") != 0) else if (strcmp(argv[i], "--f_min") == 0 || strcmp(argv[i], "-f") == 0)
f_min = atof(argv[++i]); f_min = atof(argv[++i]);
else if (strcmp(argv[i], "--z_max") != 0 || strcmp(argv[i], "-z") != 0) else if (strcmp(argv[i], "--z_max") == 0 || strcmp(argv[i], "-z") == 0)
z_max = atof(argv[++i]); z_max = atof(argv[++i]);
else if (strcmp(argv[i], "--help") != 0 || strcmp(argv[i], "-h") != 0){ else if (strcmp(argv[i], "--save_path") == 0 || strcmp(argv[i], "-s") == 0)
save_path = argv[++i];
else if (strcmp(argv[i], "--dry_run") == 0)
dry_run = true;
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0){
std::cout << "Simulation of wave propagation using the parabolic equation." << std::endl std::cout << "Simulation of wave propagation using the parabolic equation." << std::endl
<< "--r_max, -r : Set the maximum range of the simulation. Default :" << DEFAULT_DISTANCE << std::endl << "--r_max, -r : Set the maximum range of the simulation. Default :" << DEFAULT_DISTANCE << std::endl
<< "--f_max, -F : Set the maximum frequency of the simulation. Default :" << DEFAULT_MAX_FREQ << std::endl << "--f_max, -F : Set the maximum frequency of the simulation. Default :" << DEFAULT_MAX_FREQ << std::endl
<< "--f_min, -f : Set the minimum frequency of the simulation. Default :" << DEFAULT_MIN_FREQ << std::endl << "--f_min, -f : Set the minimum frequency and the frequency step of the simulation. Default :" << DEFAULT_MIN_FREQ << std::endl
<< "--z_max, -z : Set the maximum depth of the simulation. Default :" << DEFAULT_DEPTH << std::endl; << "--z_max, -z : Set the maximum depth of the simulation. Default :" << DEFAULT_DEPTH << std::endl
<< "--save_path, -s : Set the path to the output file. Default will not save anything" << std::endl
<< "--dry_run : Run the simulation but does not save anything, even if save_path is set" << std::endl;
return 1; return 1;
} }
else { else {
...@@ -43,40 +56,109 @@ int main(int argc, char **argv) { ...@@ -43,40 +56,109 @@ int main(int argc, char **argv) {
i++; i++;
} }
std::vector<sound_column*>* results(run_simulation(r_max, z_max, f_min, f_max));
return run_simulation(r_max, z_max, f_min, f_max); if (not dry_run && save_path.length()){
std::cout << "Saving results to " << save_path << std::endl;
return save_results(save_path, *results);
}
else
return 0;
}
std::vector<sound_column*>* run_simulation(float r_max, float z_max, float f_min, float f_max){
auto nf = size_t(f_max / f_min);
float delta_r = r_max/10'000;
static std::vector<sound_column*> column(nf, nullptr);
//std::ranges::iota_view indexes((size_t) 0, nf);
std::cout << "Initializing " << nf << " pressure columns" << std::endl;
std::for_each(std::execution::par, column.begin(), column.end(), //par_unseq does not compile
[&](sound_column*& c) {int i = &c - &column[0];
c = new sound_column(delta_r, (size_t) 1.10 * z_max*(4*(i+1)*f_min)/WATER_SPEED, 7, r_max, z_max, (i+1)*f_min, WATER_SPEED);
gaussian_init(*c);});
std::cout << "Running the simulation" << std::endl;
std::for_each(std::execution::par, column.begin(), column.end(),
[&](sound_column*& c) {while (not step_r(*c));std::cout << '.' << std::flush;});
std::cout << std::endl << "Done" << std::endl;
return &column;
}
void gaussian_init(sound_column& column){
float k0 = 2*M_1_PIf32 * column.freq / column.c0;
std::for_each(std::execution::par_unseq, column.pressures.begin(), column.pressures.end(),
[&, k0](std::complex<float>& p) {int i = &p - &column.pressures[0];
p = sqrtf(k0 / 0.6f) * expf(-powf((k0 / 0.6f) * (column.z_max/column.n_z*i - 1'000.f), 2));});
} }
bool step_r(sound_column& column) {
if (column.r >= column.d_max)
return true;
//std::ranges::iota_view z_ind((size_t) 0, n_z);
column.r += column.delta_r;
std::for_each(std::execution::par_unseq, column.n_next.begin(), column.n_next.end(), //par_unseq does not compile
[&](float& n) {int i = &n - &column.n_next[0]; n = media(column.r, column.z_max/column.n_z*i, column.c0);});
for(size_t i=0; i < column.n_p;i++){
_step_r_(column, i);
}
// Hank
std::for_each(std::execution::par_unseq, column.pressures.begin(), column.pressures.end(),
[&](std::complex<float>& p) {p *= std::complex<float>(2.f / (M_1_PIf32 * M_1_PIf32 * column.freq / column.c0 * column.r), 0.0f) *
std::exp(std::complex<float>(0.0f, 2.f* M_1_PIf32 * column.freq / column.c0 * column.r - M_1_PIf32 / 4));});
return false;
}
void _step_r_(sound_column& column, size_t ip) {
// std::ranges::iota_view z_ind((size_t) 0, n_z);
//tri diag init
std::fill(std::execution::par_unseq, column._u_.begin(), column._u_.end(), column.fbmaj[ip]/column.h2);
std::fill(std::execution::par_unseq, column._l_.begin(), column._l_.end(), column.fbmaj[ip]/column.h2);
float k02 = powf(2*M_1_PIf32 * column.freq / column.c0, 2);
std::for_each(std::execution::par_unseq, column._d_.begin(), column._d_.end(),
[&, k02, ip](std::complex<float>& d) {int i = &d - &column._d_[0];
d = std::complex<float>(2 * k02, 0.0f) + column.fbmaj[ip] /
std::complex<float>(-2.f/column.h2 + k02 * (powf(column.n_next[i], 2) - 1.f), 0.0f);});
std::complex<float> gaussian_init(float depth, float k0){ // first matmul
return sqrtf(k0 / 0.6f) * expf(-powf((k0 / 0.6f) * (depth - 1'000.f), 2));
// Inv tri matmul
column._u_[0] /= column._d_[0];
column.pressures[0] /= column._d_[0];
for(size_t i=1; i < column.n_z-1; i++){
column._u_[i] /= column._d_[i] - column._l_[i-1] * column._u_[i-1];
column.pressures[i] = (column.pressures[i] - column._l_[i-1] * column.pressures[i-1]) / (column._d_[i] - column._l_[i-1] * column._u_[i-1]);
}
column.pressures[column.n_z-1] = (column.pressures[column.n_z-1] - column._l_[column.n_z-2] * column.pressures[column.n_z-2]) / (column._d_[column.n_z-1] - column._l_[column.n_z-2] * column._u_[column.n_z-2]);
for(ssize_t i=column.n_z-2; i >= 0; i--) {
column.pressures[i] -= column._u_[i]*column.pressures[i+1];
}
} }
float media(float r, float depth){ float media(float r, float depth, float speed){
static const float slope = -0.009f; const float slope = -0.009f;
if ( depth > slope * r + 2531.f) if ( depth > slope * r + 2531.f)
return WATER_SPEED / 1650.f; return speed / 1650.f;
else if ( depth > slope/2 * r + 3042.f) else if ( depth > slope/2 * r + 3042.f)
return WATER_SPEED / 1700.f; return speed / 1700.f;
else if ( depth > slope/3 * r + 4111.f) else if ( depth > slope/3 * r + 4111.f)
return WATER_SPEED / 1800.f; return speed / 1800.f;
else else
return WATER_SPEED / (1500.f*(1.f+0.00737f*(depth-1.f+expf(-depth)))); return speed / (1500.f*(1.f+0.00737f*(depth-1.f+expf(-depth))));
} }
int run_simulation(float r_max, float z_max, float f_min, float f_max){ int save_results(std::string& path, std::vector<sound_column*>& results){
auto nf = size_t(f_max / f_min); std::fstream file;
float delta_r = r_max/10'000; file.open(path, std::fstream::out | std::fstream::trunc);
for(auto c:results){
std::vector<sound_column*> column(nf, nullptr); for(auto val:c->pressures){
file << val << ',';
//std::ranges::iota_view indexes((size_t) 0, nf); }
file << std::endl;
}
std::for_each(std::execution::par_unseq, column.begin(), column.end(),
[&](sound_column*& c) {int i = &c - &column[0];
c = new sound_column(delta_r, (size_t) 1.10 * z_max*(4*(i+1)*f_min)/WATER_SPEED, 7, r_max, z_max, (i+1)*f_min, WATER_SPEED);
c->init_source(gaussian_init);});
std::for_each(std::execution::par_unseq, column.begin(), column.end(),
[&](sound_column*& c) {while (c->step_r(media));});
return 0; return 0;
} }
...@@ -21,7 +21,7 @@ sound_column::sound_column(float dr, size_t nz, size_t np, float dm, float zm, f ...@@ -21,7 +21,7 @@ sound_column::sound_column(float dr, size_t nz, size_t np, float dm, float zm, f
n_next.resize(nz); n_next.resize(nz);
fapbj.resize(np); fapbj.resize(np);
fbmaj.resize(np); fbmaj.resize(np);
for(int i=0; i < np; i++) { for(size_t i=0; i < np; i++) {
faj = std::complex<float>(0, 4* M_1_PIf32 * freq / c0) / float((2.f * n_p + 1.f) * faj = std::complex<float>(0, 4* M_1_PIf32 * freq / c0) / float((2.f * n_p + 1.f) *
powf(sinf(float(i+1) * M_1_PIf32 / (2.f * n_p + 1.f)), 2) * delta_r); powf(sinf(float(i+1) * M_1_PIf32 / (2.f * n_p + 1.f)), 2) * delta_r);
fbj = 2 * powf(cosf(float(i+1) * M_1_PIf32 / (2.f * n_p + 1.f)),2); fbj = 2 * powf(cosf(float(i+1) * M_1_PIf32 / (2.f * n_p + 1.f)),2);
...@@ -31,41 +31,28 @@ sound_column::sound_column(float dr, size_t nz, size_t np, float dm, float zm, f ...@@ -31,41 +31,28 @@ sound_column::sound_column(float dr, size_t nz, size_t np, float dm, float zm, f
} }
} }
sound_column::sound_column() = default;
sound_column::~sound_column() = default; sound_column::~sound_column() = default;
bool sound_column::step_r(float (*fun)(float, float)) {
if (r >= d_max)
return true;
//std::ranges::iota_view z_ind((size_t) 0, n_z);
r += delta_r;
std::for_each(std::execution::par_unseq, n_next.begin(), n_next.end(),
[&](float& n) {int i = &n - &n_next[0]; n = (*fun)(r, z_max/n_z*i);});
for(int i=0; i < n_p;i++){
_step_r_(i);
}
// Hank
std::for_each(std::execution::par_unseq, pressures.begin(), pressures.end(),
[&](std::complex<float>& p) {p *= static_cast<std::complex<float>>(2.f / (M_1_PIf32 * M_1_PIf32 * freq / c0 * r)) *
std::exp(std::complex<float>(0, 2.f* M_1_PIf32 * freq / c0 * r - M_1_PIf32 / 4));});
return false;
}
void sound_column::init_source(std::complex<float> (*fun)(float, float)) { //void sound_column::init_source(std::complex<float> (*fun)(float, float)) {
// std::ranges::iota_view z_ind((size_t) 0, n_z); //// std::ranges::iota_view z_ind((size_t) 0, n_z);
std::for_each(std::execution::par_unseq, pressures.begin(), pressures.end(), // std::for_each(std::execution::par_unseq, pressures.begin(), pressures.end(),
[&](std::complex<float>& p) {int i = &p - &pressures[0]; // [&](std::complex<float>& p) {int i = &p - &pressures[0];
p = (*fun)(z_max/n_z*i, 2*M_1_PIf32 * freq / c0);}); // p = (*fun)(z_max/n_z*i, 2*M_1_PIf32 * freq / c0);});
} //}
void sound_column::_step_r_(int ip) { /*void sound_column::_step_r_(size_t ip) {
// std::ranges::iota_view z_ind((size_t) 0, n_z); // std::ranges::iota_view z_ind((size_t) 0, n_z);
//tri diag init //tri diag init
std::fill(std::execution::par_unseq, _u_.begin(), _u_.end(), fbmaj[ip]/h2); std::fill(std::execution::par_unseq, _u_.begin(), _u_.end(), fbmaj[ip]/h2);
std::fill(std::execution::par_unseq, _l_.begin(), _l_.end(), fbmaj[ip]/h2); std::fill(std::execution::par_unseq, _l_.begin(), _l_.end(), fbmaj[ip]/h2);
float double_k0 = 4*M_1_PIf32 * freq / c0;
std::for_each(std::execution::par_unseq, _d_.begin(), _d_.end(), std::for_each(std::execution::par_unseq, _d_.begin(), _d_.end(),
[&](std::complex<float>& d) {int i = &d - &_d_[0];d = static_cast<std::complex<float>>(4* M_1_PIf32 * freq / c0) + fbmaj[ip] / [&, double_k0, ip](std::complex<float>& d) {int i = &d - &_d_[0];d = std::complex<float>(double_k0,0.0f) + fbmaj[ip] /
static_cast<std::complex<float>>(-2.f/h2 + powf(4* M_1_PIf32 * freq / c0, 2) * (powf(n_next[i], 2) - 1.f));}); std::complex<float>(-2.f/h2 + powf(double_k0, 2) * (powf(n_next[i], 2) - 1.f), 0.0f);});
// first matmul // first matmul
...@@ -80,4 +67,4 @@ void sound_column::_step_r_(int ip) { ...@@ -80,4 +67,4 @@ void sound_column::_step_r_(int ip) {
for(ssize_t i=n_z-2; i >= 0; i--) { for(ssize_t i=n_z-2; i >= 0; i--) {
pressures[i] -= _u_[i]*pressures[i+1]; pressures[i] -= _u_[i]*pressures[i+1];
} }
} }*/
...@@ -10,38 +10,36 @@ ...@@ -10,38 +10,36 @@
#include <execution> #include <execution>
#include <algorithm> #include <algorithm>
#ifndef M_1_PIf32
#define M_1_PIf32 (0.318309886183790671537767526745028724) #define M_1_PIf32 (0.318309886183790671537767526745028724)
#endif
class sound_column { class sound_column {
private: public:
float delta_r; float delta_r{};
size_t n_z; size_t n_z{};
size_t n_p; size_t n_p{};
float r=0; float r=0;
float d_max; float d_max{};
float z_max; float z_max{};
float h2; float h2{};
float freq; std::complex<float> faj{}, fbj{};
float c0;
std::vector<std::complex<float>> pressures;
std::complex<float> faj, fbj;
std::vector<std::complex<float>> fapbj; // faj + fbj std::vector<std::complex<float>> fapbj; // faj + fbj
std::vector<std::complex<float>> fbmaj; // fbj - faj std::vector<std::complex<float>> fbmaj; // fbj - faj
std::vector<std::complex<float>> _u_; std::vector<std::complex<float>> _u_;
std::vector<std::complex<float>> _l_; std::vector<std::complex<float>> _l_;
std::vector<std::complex<float>> _d_; std::vector<std::complex<float>> _d_;
std::vector<float> n_next; std::vector<float> n_next{};
std::complex<float> (*fun)(float, float) source_fun; // void _step_r_(size_t ip);
void _step_r_(int ip);
public:
sound_column(float dr, size_t nz, size_t np, float dm, float zm, float f, float speed); sound_column(float dr, size_t nz, size_t np, float dm, float zm, float f, float speed);
sound_column();
~sound_column(); ~sound_column();
bool step_r(float (*fun)(float, float)); // void init_source(std::complex<float> (*fun)(float, float));
void init_source(std::complex<float> (*fun)(float, float));
void init_source();
float freq{};
float c0{};
std::vector<std::complex<float>> pressures;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment