1 #include <vtestbed/base/blitz.hh> 2 #include <vtestbed/base/constants.hh> 3 #include <vtestbed/config/openmp.hh> 4 #include <vtestbed/config/real_type.hh> 5 #include <vtestbed/core/anlt_wind_solver.hh> 6 #include <vtestbed/core/policy.hh> 7 #include <vtestbed/core/ship_hull_panel.hh> 8 #include <vtestbed/geometry/tetrahedron.hh> 9 #include <vtestbed/linalg/linear_algebra.hh> 14 #if defined(VTB_DEBUG_WIND) 27 using typename base_type::array_type;
28 using typename base_type::wind_field_type;
44 const grid_type& grid,
47 using vec3 = blitz::TinyVector<T,3>;
51 auto& wind_field = this->_wind_field;
52 wind_field.resize(grid.shape());
54 auto stratification = this->stratification();
55 const auto& delta = grid.delta();
56 #if defined(VTB_DEBUG_WIND_CYLINDER) 57 constexpr T R = T{54.8858}/2;
60 if (this->near_the_boundary()) {
63 [&] (
const int3& index) {
64 const auto& r = grid(index, delta);
67 for (
const auto& panel : panels) {
68 const auto& n = panel.normal();
69 const auto& S = panel.centre();
78 T S_z = panel.centre()(2);
80 vec3 u_r = u - 2 * dot(u,n) * n;
81 vec3 u1(0, 0, (1+alpha)*
pow(S_z,alpha)*dot(u, S));
82 vec3 u2(0, 0, (1+alpha)*
pow(S_z,alpha));
83 vec3 u3(1, 1, (1+alpha)*
pow(S_z,alpha + 1));
84 vec3 u4(0, 0, (1+alpha)*
pow(z,alpha));
85 T S_r =
sqrt(dot(S-r,S-r));
86 vec3 delta_phi(0, 0, 0);
87 T z_a =
pow(z0, -alpha)/(alpha + 1);
90 T C2 = dot(vec3(u*
pow(S_z,alpha+1)+ u1), n)/
91 dot(vec3(u2*dot(u_r,S) + u3*u_r), n);
94 delta_phi += z_a*C2*u_r*
exp(-S_r/coef)*
pow(z,1+alpha);
102 vec3 u_r = u - T{2}*dot(u,n)*n;
103 T weight = T{1} / (T{1}+sum_of_squares(vec3(r-S)));
105 total_weight += weight;
111 if (total_weight != 0) { sum /= total_weight; }
112 if (stratification) {
114 T z_a =
pow(10.0, -alpha)/(alpha + 1);
116 sum += u * z_a *
pow(r(2), alpha);
121 #if defined(VTB_DEBUG_WIND_CYLINDER) 123 auto x = r(0), y = r(1);
124 auto pow2 = [] (T x) {
return x*x; };
125 sum = vec3{U*(R*R*(y*y-x*x)+pow2(x*x+y*y)), -2*R*R*U*x*y, 0}/pow2(x*x+y*y);
127 wind_field(index) = sum;
131 #if defined(VTB_DEBUG_WIND) 133 #if defined(VTB_DEBUG_WIND_CYLINDER) 140 [&] (
const int3& index) {
141 if (index(2) != grid.extent(2)/2) {
return; }
142 const auto& v = wind_field(index);
143 const auto& r = grid(index, delta);
144 #if defined(VTB_DEBUG_WIND_CYLINDER) 145 if (r(0)*r(0)+r(1)*r(1) < R*R) {
return; }
147 out << r(0) <<
' ' << r(1) <<
' ';
148 out << v(0) <<
' ' << v(1) <<
' ';
153 auto m =
minmax(wind_field);
154 std::clog <<
"phi_min=" << m.min << std::endl;
155 std::clog <<
"phi_max=" << m.max << std::endl;
157 auto& wind_field_boundary = this->_wind_field_boundary;
158 if (this->on_the_boundary()) {
159 const int npanels = panels.size();
160 wind_field_boundary.resize(npanels);
161 constexpr
auto rho = constants<T>::air_density();
162 constexpr
auto g = constants<T>::g();
163 constexpr
auto p0 = constants<T>::atmospheric_pressure();
164 #if defined(VTB_WITH_OPENMP) 165 #pragma omp parallel for 167 for (
int i=0; i<npanels; ++i) {
168 auto& panel = panels[i];
169 const auto& r = panel.centre();
170 const auto& n = panel.normal();
171 vec3 u_r = u - 2*dot(u,n)*n;
172 vec3 velocity = u + u_r;
174 auto pressure = p0-rho*(T{0.5}*sum_of_squares(velocity) + g*z);
175 panel.force() = pressure * (-n) * panel.area();
176 wind_field_boundary[i] = ray_type(r, velocity);
179 wind_field_boundary.clear();
185 vtb::core::make_anlt_wind_solver<VTB_REAL_TYPE,vtb::core::Policy::OpenMP>() ->
186 std::unique_ptr<ANLT_wind_solver<VTB_REAL_TYPE>> {
188 new ANLT_wind_solver_openmp<VTB_REAL_TYPE>
Triangular ship hull panel (face).