1#ifndef Joukowsky_OPS_H_
2#define Joukowsky_OPS_H_
10using namespace amrex::literals;
19 const amrex::Real uInfMag = std::sqrt(uInfSqr);
24 const std::string& name,
30 const std::string& name,
34 const amrex::Real time);
45 auto& meta = data.
meta();
61#ifdef AMR_WIND_USE_HELICS
63 auto& meta = data.
meta();
65 const amrex::Real turbine_direction =
68 const amrex::Real turbine_direction_radian =
71 meta.normal_vec[0] = std::cos(turbine_direction_radian);
72 meta.normal_vec[1] = std::sin(turbine_direction_radian);
73 meta.normal_vec[2] = 0.0_rt;
75 meta.sample_vec[0] = meta.normal_vec[0];
76 meta.sample_vec[1] = meta.normal_vec[1];
77 meta.sample_vec[2] = meta.normal_vec[2];
91 auto& meta = data.
meta();
93 meta.root_correction.resize(meta.num_vel_pts_r);
94 meta.f_normal.resize(meta.num_vel_pts_r);
95 meta.f_theta.resize(meta.num_force_pts);
98 meta.tip_correction.begin(), meta.tip_correction.end(), 1.0_rt);
100 if (meta.use_root_correction) {
101 const amrex::Real dx = 1.0_rt / meta.num_vel_pts_r;
103 const auto a = meta.root_correction_coefficient;
104 const auto b = meta.root_correction_exponent;
106 const auto delta = amrex::max<amrex::Real>(
107 meta.vortex_core_size / meta.radius(),
110 const auto factor = dx / delta;
112 for (
int i = 0; i < meta.root_correction.size(); ++i) {
113 meta.root_correction[i] =
114 1.0_rt - std::exp(-a * std::pow((i + 0.5_rt) * factor, b));
118 meta.root_correction.begin(), meta.root_correction.end(),
147 auto& grid = data.
grid();
148 auto& ddata = data.
meta();
150 ddata.disk_force *= 0.0_rt;
153 const amrex::Real U_ref =
154 amrex::max<amrex::Real>(std::sqrt(uInfSqr), machine_eps);
158 const amrex::Real Ct = ddata.current_ct;
159 const amrex::Real dx = ddata.dr / ddata.radius();
162 ddata.radius(), ddata.num_vel_pts_r, ddata.num_vel_pts_t);
164 const amrex::Real lambda =
165 ddata.radius() * ddata.current_angular_velocity / U_ref;
167 ddata.current_tip_speed_ratio = lambda;
169 const amrex::Real lambda_2 = lambda * lambda;
172 if (ddata.use_tip_correction) {
173 auto& f = ddata.tip_correction;
174 for (
int i = 0; i < f.size(); ++i) {
175 const auto x = (i + 0.5_rt) * dx;
176 f[i] = 2.0_rt /
static_cast<amrex::Real
>(M_PI) *
179 -0.5_rt * ddata.num_blades *
180 std::sqrt(1.0_rt + lambda_2) * (1.0_rt - x)));
185 amrex::Real S0 = 0.0_rt;
186 const amrex::Real alpha1 = ddata.S0_alpha1;
187 const amrex::Real alpha2 = ddata.S0_alpha2;
189 if (ddata.Ct_rated > 0.0_rt) {
190 if (Ct < ddata.Ct_rated) {
192 std::pow((ddata.Ct_rated - Ct) / ddata.Ct_rated, 3.0_rt);
194 S0 = alpha2 * (ddata.Ct_rated - Ct) / ddata.Ct_rated;
200 amrex::Real a1 = 0.0_rt;
201 amrex::Real a2 = 0.0_rt;
202 amrex::Real a3 = 0.0_rt;
203 amrex::Real a4 = 0.0_rt;
204 amrex::Real a5 = 0.0_rt;
206 for (
int ip = 0; ip < ddata.num_vel_pts_r; ip++) {
207 const amrex::Real x =
208 amrex::max<amrex::Real>((ip + 0.5_rt) * dx, machine_eps);
210 a1 += std::pow(ddata.tip_correction[ip], 2.0_rt) *
211 std::pow(ddata.root_correction[ip], 2.0_rt) / x * dx;
213 a2 += ddata.tip_correction[ip] * ddata.root_correction[ip] * x * dx;
215 a3 += std::pow(ddata.tip_correction[ip], 2.0_rt) *
216 std::pow(ddata.root_correction[ip], 2.0_rt) * x * dx;
218 a4 += ddata.tip_correction[ip] * ddata.root_correction[ip] *
219 std::pow(x, 3.0_rt) * dx;
221 a5 += std::pow(ddata.tip_correction[ip], 2.0_rt) *
222 std::pow(ddata.root_correction[ip], 2.0_rt) *
223 std::pow(x, 3.0_rt) * dx;
233 const amrex::Real term1 = std::pow(a2 * lambda + a3 * S0, 2.0_rt);
234 const amrex::Real term2 =
235 a1 * (0.5_rt * Ct - 2.0_rt * a4 * lambda * S0 - a5 * S0 * S0);
236 const amrex::Real term3 = a2 * lambda + a3 * S0;
238 const amrex::Real numerator = std::sqrt(term1 + term2) - term3;
240 const amrex::Real denominator =
241 amrex::max<amrex::Real>(a1, machine_eps);
243 const amrex::Real q0 = numerator / denominator;
249 grid.vel, ddata.num_force_pts, ddata.num_force_pts);
251 amrex::Real moment = 0.0_rt;
258 for (
int i = 0; i < ddata.num_vel_pts_r; i++) {
259 const amrex::Real& F = ddata.tip_correction[i];
260 const amrex::Real& g = ddata.root_correction[i];
262 const amrex::Real x =
263 amrex::max<amrex::Real>((i + 0.5_rt) * dx, machine_eps);
265 const amrex::Real f_z =
266 (q0 / x + S0 * x) * g * F *
267 (lambda * x + 0.5_rt * (q0 / x + S0 * x) * g * F);
269 ddata.f_normal[i] = f_z;
273 for (
int j = 0; j < ddata.num_vel_pts_t; j++, ip++) {
274 const auto point_current = grid.pos[ip];
275 const auto theta_angle = j * dTheta;
281 ddata.center, ddata.normal_vec, point_current);
285 const amrex::Real u_disk_ij =
286 -ddata.normal_vec & disk_velocity[ip];
288 const amrex::Real f_theta =
289 u_disk_ij / U_ref * (q0 / x + S0 * x) * g * F;
290 ddata.f_theta[ip] = f_theta;
293 moment += x * ddata.radius() * f_theta * dArea;
295 const amrex::Real f_awc =
296 ddata.awc_amplitude *
298 ddata.awc_angular_frequency * current_time -
299 ddata.awc_azimuthal_mode * theta_angle +
300 ddata.awc_clocking_angle);
302 grid.force[ip] = ((1 + f_awc) * f_z * ddata.normal_vec +
303 f_theta * theta_vec) *
304 ddata.density * uInfSqr * dArea;
306 ddata.disk_force = ddata.disk_force + grid.force[ip];
311 const amrex::Real eq_20_denominator = amrex::max<amrex::Real>(
312 0.5_rt *
static_cast<amrex::Real
>(M_PI) * ddata.density *
313 std::pow(ddata.radius(), 2.0_rt) * std::pow(U_ref, 3.0_rt),
316 ddata.current_power =
317 ddata.density * uInfSqr * moment * ddata.current_angular_velocity;
319 ddata.current_cp = ddata.density * uInfSqr * moment *
320 ddata.current_angular_velocity / eq_20_denominator;
321#ifdef AMR_WIND_USE_HELICS
324 std::cout <<
"turbine: " << data.
info().
id
325 <<
" jouk power: " << ddata.current_power
326 <<
" uinfsqr: " << uInfSqr <<
" moment: " << moment
327 <<
" ang vel: " << ddata.current_angular_velocity
328 <<
" normal vec: " << ddata.normal_vec[0] <<
' '
329 << ddata.normal_vec[1] << std::endl;
333 const amrex::Real turbine_angle = std::atan2(
334 ddata.reference_velocity[1], ddata.reference_velocity[0]);
378 const auto& time =
m_data.sim().time();
379 const int tidx = time.time_index();
HelicsStorage & helics()
Definition CFDSim.H:120
SimTime & time()
Return simulation time control.
Definition CFDSim.H:65
amrex::Vector< amrex::Real > m_turbine_wind_direction_to_controller
Definition helics.H:39
amrex::Vector< amrex::Real > m_turbine_yaw_to_amrwind
Definition helics.H:40
amrex::Vector< amrex::Real > m_turbine_power_to_controller
Definition helics.H:38
bool is_activated() const
Definition helics.H:26
AMREX_FORCE_INLINE amrex::Real current_time() const
Definition SimTime.H:110
CFDSim & sim()
Definition actuator_types.H:214
ActTrait::GridType & grid()
Definition actuator_types.H:220
ActTrait::InfoType & info()
Definition actuator_types.H:217
ActTrait::MetaType & meta()
Definition actuator_types.H:223
amrex::Real area_section(const int iRadius) const
Definition disk_ops.cpp:113
void query(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:56
void set_thrust_coefficient(DiskBaseData &data, const amrex::Real &uInfSqr)
Definition disk_ops.H:130
void allocate_basic_grid_quantities(typename T::DataType &data)
Definition disk_ops.H:80
amrex::Real compute_reference_velocity_sqr(DiskBaseData &data)
Definition disk_ops.H:117
void do_parse_based_computations(ActDataHolder< T > &data)
Definition disk_ops.H:93
Definition Joukowsky_ops.cpp:9
void write_netcdf(const std::string &name, const JoukowskyData &data, const ActInfo &info, const ActGrid &, const amrex::Real time)
Definition Joukowsky_ops.cpp:159
void update_disk_points(Joukowsky::DataType &data)
Definition Joukowsky_ops.cpp:65
void prepare_netcdf_file(const std::string &name, const JoukowskyData &data, const ActInfo &info, const ActGrid &grid)
Definition Joukowsky_ops.cpp:86
void set_current_angular_velocity(JoukowskyData &data, const amrex::Real uInfSqr)
Definition Joukowsky_ops.H:17
void parse_and_gather_params(const utils::ActParser &pp, JoukowskyData &data)
Definition Joukowsky_ops.cpp:54
Definition ActSrcLineOp.H:12
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE vs::Vector compute_tangential_vector(const vs::Vector ¢er, const vs::Vector &normal, const vs::Vector &point)
Definition actuator_utils.H:133
::amr_wind::utils::MultiParser ActParser
Definition ActParser.H:8
::amr_wind::utils::Slice< amr_wind::vs::Vector > VecSlice
Definition actuator_types.H:66
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type linear(const C1 xbegin, const C1 xend, const C2 yinp, const typename std::iterator_traits< C1 >::value_type &xout, const int ncomp=1, const int comp=0)
Definition linear_interpolation.H:129
Slice< T > slice(std::vector< T > &vec, const size_t start, const size_t count)
Definition Slice.H:66
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr amrex::Real two_pi()
Return .
Definition trig_ops.H:24
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real degrees(const amrex::Real rad_val)
Convert from radians to degrees.
Definition trig_ops.H:44
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real radians(const amrex::Real deg_val)
Convert from degrees to radians.
Definition trig_ops.H:37
Definition actuator_types.H:77
Definition actuator_types.H:147
int id
Unique integer identifier for the turbine.
Definition actuator_types.H:159
bool is_root_proc
Flag indicating whether this is root proc.
Definition actuator_types.H:165
Definition actuator_types.H:56
RealList table_velocity
Definition ActuatorDisk.H:32
Definition Joukowsky.H:14
RealList angular_velocity
Definition Joukowsky.H:15
amrex::Real current_angular_velocity
Definition Joukowsky.H:20
RealList tip_correction
Definition Joukowsky.H:16
Definition Joukowsky.H:50
ActDataHolder< Joukowsky > DataType
Definition Joukowsky.H:54
void operator()(Joukowsky::DataType &data)
Definition Joukowsky_ops.H:144
Definition actuator_ops.H:61
void operator()(typename Joukowsky::DataType &data)
Definition Joukowsky_ops.H:87
Definition actuator_ops.H:32
int m_out_freq
Output frequency (specified in input file)
Definition Joukowsky_ops.H:357
void operator()(Joukowsky::DataType &)
Definition Joukowsky_ops.H:365
void read_io_options(const utils::ActParser &pp)
Definition Joukowsky_ops.H:366
ProcessOutputsOp(const Joukowsky::DataType &data)
Definition Joukowsky_ops.H:361
void write_outputs()
Definition Joukowsky_ops.H:376
const Joukowsky::DataType & m_data
Definition Joukowsky_ops.H:349
void prepare_outputs(const std::string &out_dir)
Definition Joukowsky_ops.H:370
std::string m_out_dir
Path to the output directory (specified by Actuator physics class)
Definition Joukowsky_ops.H:351
std::string m_nc_filename
NetCDF output filename for this turbine.
Definition Joukowsky_ops.H:354
Definition actuator_ops.H:71
void operator()(typename Joukowsky::DataType &data)
Definition Joukowsky_ops.H:54
Definition actuator_ops.H:43