/home/runner/work/kynema-sgf/kynema-sgf/src/wind_energy/actuator/turbine/fast/turbine_fast_ops.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/wind_energy/actuator/turbine/fast/turbine_fast_ops.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
turbine_fast_ops.H
Go to the documentation of this file.
1#ifndef TURBINE_FAST_OPS_H
2#define TURBINE_FAST_OPS_H
3
6#include "AMReX_REAL.H"
7
8using namespace amrex::literals;
9
11
12template <typename SrcTrait>
13struct ReadInputsOp<TurbineFast, SrcTrait>
14{
16 {
18
19 auto& tf = data.meta().ext_data;
20
21 pp.get("openfast_start_time", tf.start_time);
22 pp.get("openfast_stop_time", tf.stop_time);
23
24 std::string sim_mode = (tf.start_time > 0.0_rt) ? "restart" : "init";
25 pp.query("openfast_sim_mode", sim_mode);
26
27 if (sim_mode == "init") {
28 tf.sim_mode = ::ext_turb::SimMode::init;
29 amrex::Print() << "Initializing turbine:" << tf.tlabel << std::endl;
30 } else if (sim_mode == "replay") {
31 tf.sim_mode = ::ext_turb::SimMode::replay;
32 amrex::Print() << "Replaying turbine:" << tf.tlabel << std::endl;
33 } else if (sim_mode == "restart") {
34 tf.sim_mode = ::ext_turb::SimMode::restart;
35 amrex::Print() << "Restarting turbine:" << tf.tlabel << std::endl;
36 } else {
37 amrex::Abort(
38 "Actuator: Invalid OpenFAST simulation mode: " + sim_mode);
39 }
40
41 // If we are using OpenFAST restart file, require that the user provide
42 // the path to the checkpoint file.
43 if (tf.sim_mode == ::ext_turb::SimMode::restart) {
44 pp.get("openfast_restart_file", tf.checkpoint_file);
45 } else {
46 pp.get("openfast_input_file", tf.input_file);
47 }
48
49 // Check if user wants to override density checks
50 bool override_density_check = false;
51 pp.query("override_density_check", override_density_check);
52 // Check if simulation is a restart
53 bool is_restart = data.sim().io_manager().is_restart();
54
55 perform_checks(data);
56
58 data.meta().density, override_density_check, is_restart);
59 }
60
62 {
63 const auto& time = data.sim().time();
64 // Ensure that we are using fixed timestepping scheme
65 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
66 !time.adaptive_timestep(),
67 "time.adaptive_timestep() = " +
68 std::to_string(time.adaptive_timestep()));
69 }
70
71 // Check other density parsing arguments against turbine air density
73 const amrex::Real rho_tdef, const bool no_check, const bool is_rst)
74 {
75 // Check if other arguments are in input file
76 amrex::ParmParse pp_incflo("incflo");
77 amrex::ParmParse pp_cstdns("ConstValue.density");
78 bool is_incflo = pp_incflo.contains("density");
79 bool is_cstdns = pp_cstdns.contains("value");
80 // Flags for detecting conflicts
81 bool cft_incflo = false;
82 bool cft_cstdns = false;
83
84 // Do warnings or aborts depending on values
85 const amrex::Real tiny = std::numeric_limits<amrex::Real>::epsilon();
86 if (is_incflo) {
87 amrex::Real rho_incflo = 1.0_rt;
88 pp_incflo.query("density", rho_incflo);
89 if (std::abs(rho_incflo - rho_tdef) > tiny) {
90 cft_incflo = true;
91 if (!no_check) {
92 amrex::Abort(
93 "Density conflict detected between TurbineFast "
94 "density and incflo.density.\n----- Values are " +
95 std::to_string(rho_tdef) + " and " +
96 std::to_string(rho_incflo) +
97 ", respectively. Check the problem setup and the "
98 "turbine definition.\n----- If this difference is "
99 "intended, set the override_density_check flag to "
100 "true.\n");
101 } else {
102 amrex::Print()
103 << "WARNING: Density conflict detected between FAST "
104 "Turbine density and incflo.density.\n----- Values "
105 "are " +
106 std::to_string(rho_tdef) + " and " +
107 std::to_string(rho_incflo) +
108 ", respectively. Abort overridden by flag.\n";
109 }
110 }
111 }
112 if (is_cstdns) {
113 amrex::Real rho_cstdns = 1.0_rt;
114 pp_cstdns.query("value", rho_cstdns);
115 if (std::abs(rho_cstdns - rho_tdef) > tiny) {
116 cft_cstdns = true;
117 if (!no_check) {
118 amrex::Abort(
119 "Density conflict detected between TurbineFast "
120 "density and ConstValue.density.value.\n----- Values "
121 "are " +
122 std::to_string(rho_tdef) + " and " +
123 std::to_string(rho_cstdns) +
124 ", respectively. Check the problem setup and the "
125 "turbine definition.\n----- If this difference is "
126 "intended, set the override_density_check flag to "
127 "true.\n");
128 } else {
129 amrex::Print()
130 << "WARNING: Density conflict detected between "
131 "TurbineFast "
132 "density and "
133 "ConstValue.density.value.\n----- Values are " +
134 std::to_string(rho_tdef) + " and " +
135 std::to_string(rho_cstdns) +
136 ", respectively. Abort overridden by flag.\n";
137 }
138 }
139 }
140 if (!is_incflo && !is_cstdns) {
141 amrex::Print()
142 << "TurbineFast: no density conflict detected, but no density "
143 "arguments found to check against.\n";
144 } else if (!cft_incflo && !cft_cstdns) {
145 amrex::Print() << "TurbineFast: no density conflict detected.\n";
146 }
147 if (is_rst) {
148 amrex::Print()
149 << "TurbineFast: simulation begins using a checkpoint file, "
150 "density compatibility must be manually confirmed between "
151 "the precursor simulation and the specified TurbineFast "
152 "density, " +
153 std::to_string(rho_tdef)
154 << ".\n";
155 }
156 }
157};
158
159// Note: inline is necessary here to avoid duplicate symbol errors
160template <>
166
167// Note: inline is necessary here to avoid duplicate symbol errors
168template <>
170 typename TurbineFast::DataType& data, amrex::Vector<int>& act_proc_count)
171{
174 ::ext_turb::FastSolverData>(data, act_proc_count);
175}
176
177template <typename SrcTrait>
178struct InitDataOp<TurbineFast, SrcTrait>
179{
181 {
182 BL_PROFILE("kynema-sgf::InitDataOp<TurbineFast>");
183 // Ensure that FAST simulation time is set properly before doing any
184 // initialization tasks. We perform this check here to account for
185 // restart which is only known after reading the checkpoint file.
187
189 }
190
192 {
193 const auto& time = data.sim().time();
194
195 // Set OpenFAST solver end time to be at least as long as the CFD time.
196 // User can choose a longer duration in input file.
197 const amrex::Real stop1 = time.stop_time() > 0.0_rt
198 ? time.stop_time()
199 : std::numeric_limits<amrex::Real>::max();
200 const amrex::Real stop2 = time.stop_time_index() > -1
201 ? time.stop_time_index() * time.delta_t()
202 : std::numeric_limits<amrex::Real>::max();
203 const amrex::Real cfd_stop = amrex::min(stop1, stop2);
204 const amrex::Real cfd_start = time.current_time();
205 const amrex::Real cfd_sim = cfd_stop - cfd_start - 1.0e-6_rt;
206
207 // Ensure that the user specified stop_time is not shorter than CFD sim
208 const auto& tf = data.meta().ext_data;
209 const amrex::Real fast_sim = tf.stop_time - tf.start_time;
210 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
211 fast_sim > cfd_sim,
212 "OpenFAST simulation time is shorter than Kynema-SGF duration");
213 }
214};
215
216template <typename SrcTrait>
217struct UpdatePosOp<TurbineFast, SrcTrait>
218{
220 {
221 BL_PROFILE("kynema-sgf::actuator::UpdatePosOp<TurbineFast>");
223 }
224};
225
226template <typename SrcTrait>
227struct UpdateVelOp<TurbineFast, SrcTrait>
228{
230 {
231 BL_PROFILE("kynema-sgf::actuator::UpdateVelOp<TurbineFast>");
233 }
234};
235
236template <typename SrcTrait>
238{
240 {
241 BL_PROFILE("kynema-sgf::actuator::ComputeForceOp<TurbineFast>");
243 }
244};
245
246template <typename SrcTrait>
248{
249private:
251
253 std::string m_out_dir;
254
256 std::string m_nc_filename;
257
259 int m_out_freq{10};
260
261public:
263 : m_data(data)
264 {}
265
267 {
268 pp.query("output_frequency", m_out_freq);
269 }
270
271 void prepare_outputs(const std::string& out_dir)
272 {
273 m_nc_filename = out_dir + "/" + m_data.info().label + ".nc";
275 m_nc_filename, m_data.meta(), m_data.info(), m_data.grid());
276 }
277
279 {
280 const auto& time = m_data.sim().time();
281 const int tidx = time.time_index();
282 if ((m_out_freq > 0) && (tidx % m_out_freq != 0)) {
283 return;
284 }
285
287 m_nc_filename, m_data.meta(), m_data.info(), m_data.grid(),
288 time.new_time());
289 }
290};
291
292} // namespace kynema_sgf::actuator::ops
293
294#endif /* TURBINE_FAST_OPS_H */
SimTime & time()
Return simulation time control.
Definition CFDSim.H:66
IOManager & io_manager()
Definition CFDSim.H:118
bool is_restart() const
Definition IOManager.H:84
AMREX_FORCE_INLINE amrex::Real stop_time() const
Definition SimTime.H:145
CFDSim & sim()
Definition actuator_types.H:252
ActTrait::MetaType & meta()
Definition actuator_types.H:267
void get(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:44
void query(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:62
@ restart
Restart using external checkpoint files.
Definition external_base_types.H:16
@ replay
Replay using velocities stored in file.
Definition external_base_types.H:15
@ init
Clean start.
Definition external_base_types.H:14
Definition ActSrcLineOp.H:12
void determine_root_proc< TurbineFast >(typename TurbineFast::DataType &data, amrex::Vector< int > &act_proc_count)
Definition turbine_fast_ops.H:169
void external_determine_root_proc(datatype &data, amrex::Vector< int > &act_proc_count)
Definition turbine_external_ops.H:67
void read_ops(datatype &data, const utils::ActParser &pp)
Definition turbine_external_ops.H:16
void determine_influenced_procs< TurbineFast >(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:162
void update_pos_op(datatype &data)
Definition turbine_external_ops.H:154
void update_vel_op(datatype &data)
Definition turbine_external_ops.H:178
void external_determine_influenced_procs(datatype &data)
Definition turbine_external_ops.H:46
void init_data_op(datatype &data)
Definition turbine_external_ops.H:97
void compute_force_op(datatype &data)
Definition turbine_external_ops.H:218
::kynema_sgf::utils::MultiParser ActParser
Definition ActParser.H:8
void prepare_netcdf_file(const std::string &ncfile, const TurbineBaseData &meta, const TurbineInfo &info, const ActGrid &grid)
Definition turbine_utils.cpp:63
void write_netcdf(const std::string &ncfile, const TurbineBaseData &meta, const TurbineInfo &info, const ActGrid &grid, const amrex::Real time)
Definition turbine_utils.cpp:130
TurbineFromExtSolver<::ext_turb::FastTurbine, ::ext_turb::FastSolverData > TurbineFast
Definition TurbineFast.H:9
Definition fast_types.H:93
Definition fast_types.H:17
ActDataHolder< TurbineFromExtSolver< ::ext_turb::FastTurbine, ::ext_turb::FastSolverData > > DataType
Definition TurbineExternal.H:31
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:239
Definition actuator_ops.H:64
void operator()(TurbineFast::DataType &data)
Definition turbine_fast_ops.H:180
void check_fast_sim_time(TurbineFast::DataType &data)
Definition turbine_fast_ops.H:191
Definition actuator_ops.H:35
std::string m_nc_filename
NetCDF output filename for this turbine.
Definition turbine_fast_ops.H:256
ProcessOutputsOp(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:262
void prepare_outputs(const std::string &out_dir)
Definition turbine_fast_ops.H:271
void read_io_options(const utils::ActParser &pp)
Definition turbine_fast_ops.H:266
TurbineFast::DataType & m_data
Definition turbine_fast_ops.H:250
int m_out_freq
Output frequency (specified in input file)
Definition turbine_fast_ops.H:259
std::string m_out_dir
Path to the output directory (specified by Actuator physics class)
Definition turbine_fast_ops.H:253
void perform_density_checks(const amrex::Real rho_tdef, const bool no_check, const bool is_rst)
Definition turbine_fast_ops.H:72
void operator()(TurbineFast::DataType &data, const utils::ActParser &pp)
Definition turbine_fast_ops.H:15
void perform_checks(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:61
Definition actuator_ops.H:22
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:219
Definition actuator_ops.H:46
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:229
Definition actuator_ops.H:57