/home/runner/work/kynema-sgf/kynema-sgf/src/wind_energy/actuator/disk/uniform_ct_ops.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/wind_energy/actuator/disk/uniform_ct_ops.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
uniform_ct_ops.H
Go to the documentation of this file.
1#ifndef UNIFORM_CT_OPS_H
2#define UNIFORM_CT_OPS_H
3
4#include <numbers>
9#include "AMReX_REAL.H"
10
11using namespace amrex::literals;
13namespace uniformct {
14
15void parse_and_gather_params(const utils::ActParser& pp, UniformCtData& data);
17} // namespace uniformct
18
19template <>
29
30template <>
32{
33 void operator()(typename UniformCt::DataType& data)
34 {
35 if (!data.sim().helics().is_activated()) {
36 return;
37 }
38
39#ifdef KYNEMA_SGF_USE_HELICS
40
41 const amrex::Real wind_direction =
42 -data.sim().helics().m_turbine_yaw_to_kynema_sgf[data.info().id] +
43 90.0_rt;
44 const amrex::Real wind_direction_radian =
45 kynema_sgf::utils::radians(wind_direction);
46
47 auto& meta = data.meta();
48
49 meta.normal_vec[0] = std::cos(wind_direction_radian);
50 meta.normal_vec[1] = std::sin(wind_direction_radian);
51 meta.normal_vec[2] = 0.0_rt;
52
53 meta.sample_vec[0] = meta.normal_vec[0];
54 meta.sample_vec[1] = meta.normal_vec[1];
55 meta.sample_vec[2] = meta.normal_vec[2];
56
57 if (data.info().is_root_proc) {
58 std::cout << "turbine " << data.info().id
59 << " normal: " << meta.normal_vec[0] << ' '
60 << meta.normal_vec[1] << std::endl;
61 }
62
64#endif
65 }
66};
67// compute the total force over a given radial section
68// this will then be spread uniformly over that area in the
69// projection step
70template <>
72{
74 {
75 auto& grid = data.grid();
76 auto& ddata = data.meta();
77 const auto& normal = ddata.normal_vec;
78 const amrex::Real uInfSqr = base::compute_reference_velocity_sqr(ddata);
79 base::set_thrust_coefficient(ddata, uInfSqr);
80
81 const int npts = ddata.num_force_pts;
82 // Kinematic aero pressure [m^2/s^2]. grid.force is stored in
83 // kinematic units (force / density): ActuatorForcing adds it into
84 // the ICNS src_term in the same [m/s^2] convention as every other
85 // momentum source, ahead of the shared multiply_rho step.
86 const amrex::Real aeroPressure = 0.5_rt * uInfSqr * ddata.current_ct;
87 const amrex::Real dr = ddata.dr;
88
89 for (int ip = 0; ip < npts; ++ip) {
90 const amrex::Real r = (ip + 0.5_rt) * dr;
91 const amrex::Real rp = r + (dr * 0.5_rt);
92 const amrex::Real rm = r - (dr * 0.5_rt);
93 const amrex::Real a =
94 std::numbers::pi_v<amrex::Real> * (rp * rp - rm * rm);
95 // disk force should always point in direction of the normal
96 grid.force[ip] = (aeroPressure * a) * normal;
97 }
98#ifdef KYNEMA_SGF_USE_HELICS
99
100 if (data.info().is_root_proc && data.sim().helics().is_activated()) {
101
102 const amrex::Real rho = ddata.density;
103 const amrex::Real ct = ddata.current_ct;
104 std::cout << "turbine" << data.info().id << " thrust: " << ct
105 << std::endl;
106 const amrex::Real cp = 0.5_rt * (ct + ct * std::sqrt(1.0_rt - ct));
107 const amrex::Real area = std::numbers::pi_v<amrex::Real> * 0.25_rt *
108 ddata.diameter * ddata.diameter;
109 const amrex::Real power =
110 cp * 0.5_rt * rho * std::pow(uInfSqr, 1.5_rt) * area;
111
113 power;
114 const amrex::Real turbine_angle = std::atan2(
115 ddata.reference_velocity[1], ddata.reference_velocity[0]);
116 data.sim()
117 .helics()
119 -kynema_sgf::utils::degrees(turbine_angle) + 270.0_rt;
120 }
121#endif
122 }
123};
124
125template <>
134template <>
136{
137private:
138 // cppcheck-suppress uninitMemberVarPrivate
141 std::string m_out_dir;
142
144 std::string m_nc_filename;
145
147 int m_out_freq{10};
148
149public:
151 const UniformCt::DataType& data)
152 : m_data(data)
153 {}
154 void operator()(UniformCt::DataType& /*unused*/) {}
156 {
157 pp.query("output_frequency", m_out_freq);
158 }
159 void prepare_outputs(const std::string& out_dir)
160 {
161 m_nc_filename = out_dir + "/" + m_data.info().label + ".nc";
163 m_nc_filename, m_data.meta(), m_data.info(), m_data.grid());
164 }
166 {
167 const auto& time = m_data.sim().time();
168 const int tidx = time.time_index();
169 if (tidx % m_out_freq != 0) {
170 return;
171 }
172
174 m_nc_filename, m_data.meta(), m_data.info(), m_data.grid(),
175 time.new_time());
176 }
177};
178} // namespace kynema_sgf::actuator::ops
179
180#endif /* UNIFORM_CT_OPS_H */
HelicsStorage & helics()
Definition CFDSim.H:136
bool is_activated() const
Definition helics.H:26
amrex::Vector< amrex::Real > m_turbine_wind_direction_to_controller
Definition helics.H:39
amrex::Vector< amrex::Real > m_turbine_power_to_controller
Definition helics.H:38
amrex::Vector< amrex::Real > m_turbine_yaw_to_kynema_sgf
Definition helics.H:40
CFDSim & sim()
Definition actuator_types.H:214
ActTrait::MetaType & meta()
Definition actuator_types.H:229
ActTrait::GridType & grid()
Definition actuator_types.H:223
ActTrait::InfoType & info()
Definition actuator_types.H:217
void query(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:59
void write_netcdf(const std::string &name, const DiskBaseData &data, const ActInfo &info, const ActGrid &, const amrex::Real time)
Definition disk_ops.cpp:74
void prepare_netcdf_file(const std::string &name, const DiskBaseData &data, const ActInfo &info, const ActGrid &grid)
Definition disk_ops.cpp:10
void do_parse_based_computations(ActDataHolder< T > &data)
Definition disk_ops.H:92
AMREX_INLINE amrex::Real compute_reference_velocity_sqr(DiskBaseData &data)
Definition disk_ops.H:116
void allocate_basic_grid_quantities(typename T::DataType &data)
Definition disk_ops.H:79
AMREX_INLINE void set_thrust_coefficient(DiskBaseData &data, const amrex::Real &uInfSqr)
Definition disk_ops.H:129
Definition uniform_ct_ops.cpp:8
void parse_and_gather_params(const utils::ActParser &pp, UniformCtData &data)
Definition uniform_ct_ops.cpp:53
void update_disk_points(UniformCt::DataType &data)
Definition uniform_ct_ops.cpp:65
Definition ActSrcLineOp.H:12
::kynema_sgf::utils::MultiParser ActParser
Definition ActParser.H:8
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real degrees(const amrex::Real rad_val)
Convert from radians to degrees.
Definition trig_ops.H:39
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real radians(const amrex::Real deg_val)
Convert from degrees to radians.
Definition trig_ops.H:32
bool is_root_proc
Flag indicating whether this is root proc.
Definition actuator_types.H:165
int id
Unique integer identifier for the turbine.
Definition actuator_types.H:159
Definition actuator_types.H:56
vs::Vector normal_vec
Definition ActuatorDisk.H:20
Definition UniformCt.H:12
ActDataHolder< UniformCt > DataType
Definition UniformCt.H:16
void operator()(UniformCt::DataType &data)
Definition uniform_ct_ops.H:73
Definition actuator_ops.H:61
void operator()(typename UniformCt::DataType &data)
Definition uniform_ct_ops.H:128
Definition actuator_ops.H:32
ProcessOutputsOp(const UniformCt::DataType &data)
Definition uniform_ct_ops.H:150
void operator()(UniformCt::DataType &)
Definition uniform_ct_ops.H:154
std::string m_out_dir
Path to the output directory (specified by Actuator physics class)
Definition uniform_ct_ops.H:141
std::string m_nc_filename
NetCDF output filename for this turbine.
Definition uniform_ct_ops.H:144
int m_out_freq
Output frequency (specified in input file)
Definition uniform_ct_ops.H:147
void read_io_options(const utils::ActParser &pp)
Definition uniform_ct_ops.H:155
void prepare_outputs(const std::string &out_dir)
Definition uniform_ct_ops.H:159
const UniformCt::DataType & m_data
Definition uniform_ct_ops.H:139
void operator()(UniformCt::DataType &data, const utils::ActParser &pp)
Definition uniform_ct_ops.H:22
Definition actuator_ops.H:19
void operator()(typename UniformCt::DataType &data)
Definition uniform_ct_ops.H:33
Definition actuator_ops.H:43