From 84c0bfa85374e45f06c1b6d7311b80f78670fb7c Mon Sep 17 00:00:00 2001 From: jjesswan Date: Tue, 23 Apr 2024 17:48:02 -0400 Subject: saving --- src/ocean/ocean_alt.cpp | 306 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ocean/ocean_alt.h | 95 +++++++++++++++ 2 files changed, 401 insertions(+) create mode 100644 src/ocean/ocean_alt.cpp create mode 100644 src/ocean/ocean_alt.h (limited to 'src/ocean') diff --git a/src/ocean/ocean_alt.cpp b/src/ocean/ocean_alt.cpp new file mode 100644 index 0000000..4dbf767 --- /dev/null +++ b/src/ocean/ocean_alt.cpp @@ -0,0 +1,306 @@ +#include "ocean_alt.h" +#include + + +ocean_alt::ocean_alt() +{ + // to be used for efficiency during fft + std::cout << "hello" << std::endl; + init_wave_index_constants(); + +} + +// initializes static constants (aka they are not time dependent) +void ocean_alt::init_wave_index_constants(){ + + for (int i=0; i h_tildas = std::vector(); + + // find each h_tilda at each index, to be used for next for loop + for (int i=0; i randoms = sample_complex_gaussian(); + double random_r = randoms.first; + double random_i = randoms.second; + + // seperate real and imag products + double coeff = 0.707106781187 * sqrt(Ph_prime); + double real_comp = coeff*random_r; + double imag_comp = coeff*random_i; + + return Eigen::Vector2d(real_comp, imag_comp); +} + + +double ocean_alt::phillips_prime(Eigen::Vector2d k){ + double k_mag = k.norm(); + + k.normalize(); + double dot_prod = k.dot(omega_wind); + + double output = 0.0; + // l = 1 + if (k_mag < .0001) return 0.0; + + if (k_mag > 1.0){ + + output = A*exp(-(k_mag*k_mag))*dot_prod*dot_prod/(k_mag*k_mag*k_mag*k_mag); + } else { + output = A*exp(-1.0/(k_mag*L*k_mag*L))*dot_prod*dot_prod/(k_mag*k_mag*k_mag*k_mag); + + } + + + + return output; +} + +Eigen::Vector2d ocean_alt::get_k_vector(int n_prime, int m_prime){ + double n_ = (double)n_prime; + double m_ = (double)m_prime; + double N_ = (double)num_rows; + double M_ = (double)num_cols; + + double k_x = (2.0*M_PI*n_ - M_PI*N_)/Lx; + double k_z = (2.0*M_PI*m_ - M_PI*M_)/Lz; + + return Eigen::Vector2d(k_x, k_z); +} + +Eigen::Vector2d ocean_alt::get_horiz_pos(int i){ + Eigen::Vector2i m_n = index_1d_to_2d(i); + double n_prime = (double)m_n[0]; + double m_prime = (double)m_n[1]; + double N_ = (double)num_rows; + double M_ = (double)num_cols; + + + double x = (n_prime-.5*N_)*Lx / N_; + double z = (m_prime-.5*M_)*Lz / M_; + + + + return Eigen::Vector2d(x, z); +} + + +Eigen::Vector2i ocean_alt::index_1d_to_2d(int i){ + int row = i/num_rows; // n' + int col = i%num_rows; // m' + + return Eigen::Vector2i(row, col); + +} + +std::pair ocean_alt::sample_complex_gaussian(){ + double uniform_1 = (double)rand() / (RAND_MAX); + double uniform_2 = (double)rand() / (RAND_MAX); + + // set a lower bound on zero to avoid undefined log(0) + if (uniform_1 == 0) + { + uniform_1 = 1e-10; + } + if (uniform_2 == 0) + { + uniform_2 = 1e-10; + } + + // real and imaginary parts of the complex number + double real = sqrt(-2 * log(uniform_1)) * cos(2 * M_PI * uniform_2); + double imag = sqrt(-2 * log(uniform_1)) * sin(2 * M_PI * uniform_2); + + return std::make_pair(real, imag); +} + +Eigen::Vector2d ocean_alt::complex_exp(double exponent){ + double real = cos(exponent); + double imag = sin(exponent); + + return Eigen::Vector2d(real, imag); +} + +std::vector ocean_alt::get_vertices() +{ + std::vector vertices = std::vector(); + for (int i = 0; i < N; i++){ + Eigen::Vector2d horiz_pos = spacing*m_waveIndexConstants[i].base_horiz_pos; + Eigen::Vector2d amplitude = m_current_h[i]; + float height = amplitude[0]; + + Eigen::Vector2d slope = m_slopes[i] * .3f; + Eigen::Vector3f s = Eigen::Vector3f(-slope[0], 0.0, -slope[1]); + Eigen::Vector3f y = Eigen::Vector3f(0.0, 1.0, 0.0); + + float xs = 1.f + s[0]*s[0]; + float ys = 1.f + s[1]*s[1]; + float zs = 1.f + s[2]*s[2]; + + Eigen::Vector3f diff = y - s; + Eigen::Vector3f norm = Eigen::Vector3f(diff[0]/ sqrt(xs), diff[1]/ sqrt(ys), diff[2]/sqrt(zs)); + + + + + + //if (i==6) std::cout << amplitude[0] << std::endl; + + // calculate displacement + Eigen::Vector2d disp = lambda*m_displacements[i]; + + // + + + // for final vertex position, use the real number component of amplitude vector + vertices.push_back(Eigen::Vector3f(horiz_pos[0] + disp[0], height, horiz_pos[1] + disp[1])); + m_normals[i] = norm.normalized();//Eigen::Vector3f(-slope[0], 1.0, -slope[1]).normalized(); + //std::cout << "normal: " << m_normals[i] << std::endl; + + } + return vertices; +} + +std::vector ocean_alt::getNormals(){ + return m_normals; +} + +std::vector ocean_alt::get_faces() +{ + // connect the vertices into faces + std::vector faces = std::vector(); + for (int i = 0; i < N; i++) + { + int x = i / num_rows; + int z = i % num_rows; + + // connect the vertices into faces + if (x < num_rows - 1 && z < num_cols - 1) + { + int i1 = i; + int i2 = i + 1; + int i3 = i + num_rows; + int i4 = i + num_rows + 1; + + faces.emplace_back(i2, i1, i3); + faces.emplace_back(i2, i3, i4); + faces.emplace_back(i1, i2, i3); + faces.emplace_back(i3, i2, i4); + } + } + return faces; +} diff --git a/src/ocean/ocean_alt.h b/src/ocean/ocean_alt.h new file mode 100644 index 0000000..76a298e --- /dev/null +++ b/src/ocean/ocean_alt.h @@ -0,0 +1,95 @@ +#ifndef OCEAN_ALT_H +#define OCEAN_ALT_H +#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT +#define EIGEN_DONT_VECTORIZE + +#include +#include +#include +#include + +// for every 1d index up to length*width +struct WaveIndexConstant{ + Eigen::Vector2d h0_prime = Eigen::Vector2d(0.f, 0.f); + Eigen::Vector2d h0_prime_conj = Eigen::Vector2d(0.f, 0.f); + + double w_prime = 0.0; + + + Eigen::Vector2d base_horiz_pos = Eigen::Vector2d(0.f, 0.f); // static horiz pos with no displacement + Eigen::Vector2d k_vector = Eigen::Vector2d(0.f, 0.f); // static horiz pos with no displacement +}; + +class ocean_alt +{ +public: + ocean_alt(); + void updateVertexAmplitudes(double t); + std::vector get_vertices(); + std::vector get_faces(); + void fft_prime(double t); + std::vector getNormals(); + + + + + + +private: + + Eigen::Vector2i index_1d_to_2d(int i); + Eigen::Vector2d get_k_vector(int n_prime, int m_prime); + double phillips_prime(Eigen::Vector2d k); + Eigen::Vector2d h_0_prime(Eigen::Vector2d k); + double omega_prime(Eigen::Vector2d k); + void init_wave_index_constants(); + Eigen::Vector2d complex_exp(double exponent); + Eigen::Vector2d h_prime_t(int i, double t); + Eigen::Vector2d get_horiz_pos(int i); + std::pair sample_complex_gaussian(); + + + + + + + + + + std::map m_waveIndexConstants; // stores constants that only need to be calculate once for each grid constant + + + + const double Lx = 100.0; + const double Lz = 100.0; + + const int num_rows = 32; + const int num_cols = 32; + + const int N = num_rows*num_cols; // total number of grid points + const double lambda = .40; // how much displacement matters + const double spacing = 35.0; // spacing between grid points + + const double A = 1.0; // numeric constant for the Phillips spectrum + const double V = 5.5; // wind speed + const double gravity = 9.81; + const double L = V*V/gravity; + const Eigen::Vector2d omega_wind = Eigen::Vector2d(1.0, 0.0); // wind direction, used in Phillips equation + + std::vector m_current_h; // current height fields for each K + std::vector m_displacements; // current displacement vector for each K + std::vector m_slopes; // current displacement vector for each K + //std::vector m_slope_vectors; // current displacement vector for each K + + std::vector m_normals; // current displacement vector for each K + + + + + + const double D = 1.0; // Depth below mean water level (for dispersion relation) + + +}; + +#endif // OCEAN_ALT_H -- cgit v1.2.3-70-g09d2