1#ifndef TURBINE_EXTERNAL_OPS_H
2#define TURBINE_EXTERNAL_OPS_H
15template <
typename datatype>
19 data.meta().solver_name = data.meta().ext_ptr->identifier();
23 auto& tdata = data.meta();
26 pp.
get(
"density", tdata.density);
29 const auto& tinfo = data.info();
30 auto& tf = data.meta().ext_data;
31 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
32 tf.base_pos[i] =
static_cast<float>(tinfo.base_pos[i]);
35 tf.tlabel = tinfo.label;
36 tf.tid_global = tinfo.id;
37 tf.num_blades = tdata.num_blades;
38 tf.num_pts_blade = tdata.num_pts_blade;
39 tf.num_pts_tower = tdata.num_pts_tower;
40 tf.dt_cfd = data.sim().time().delta_t();
42 const auto& time = data.sim().time();
43 tf.chkpt_interval = time.chkpt_interval();
46template <
typename datatype>
49 auto& info = data.info();
53 AMREX_ALWAYS_ASSERT(info.root_proc > -1);
57 info.procs.insert(info.root_proc);
59 const int iproc = amrex::ParallelDescriptor::MyProc();
60 auto in_proc = info.procs.find(iproc);
61 info.actuator_in_proc = (in_proc != info.procs.end());
62 info.sample_vel_in_proc = info.is_root_proc;
65template <
typename datatype,
typename SolverTurbine,
typename SolverData>
70 auto& info = data.info();
80 info.sample_vel_in_proc = info.is_root_proc;
84 if (info.is_root_proc) {
85 auto& tdata = data.meta();
86 auto& ext_mgr = data.sim().ext_solver_manager();
89 &(ext_mgr.template get<
91 tdata.ext_ptr->register_turbine(tdata.ext_data);
95template <
typename datatype>
99 const auto& info = data.info();
100 auto& tdata = data.meta();
103 amrex::ParallelDescriptor::Comm_dup(
104 amrex::ParallelDescriptor::Communicator(), tdata.tcomm);
106 amrex::Array<int, 5> sz_info = {0, 0, 0, 0, 0};
107 if (info.is_root_proc) {
108 tdata.ext_ptr->init_turbine(tdata.ext_data.tid_local);
110 const auto& tf = tdata.ext_data;
111 sz_info[0] = tf.num_blades;
112 sz_info[1] = tf.length_force(0);
113 sz_info[2] = tf.length_fluid_velocity(0);
114 sz_info[3] = tf.num_pts_tower;
115 sz_info[4] = tf.num_vel_pts_blade();
119 amrex::ParallelDescriptor::Bcast(
120 sz_info.begin(), sz_info.size(), info.root_proc, tdata.tcomm);
123 tdata.num_blades = sz_info[0];
126 tdata.num_vel_pts_blade = sz_info[4];
127 data.grid().resize(sz_info[1], sz_info[2]);
128 tdata.chord.resize(sz_info[1]);
129 tdata.num_pts_tower = sz_info[3];
134 if (info.is_root_proc) {
136 int npts = sz_info[1];
137 for (
int i = 0; i < npts; ++i) {
139 static_cast<amrex::Real
>(tdata.ext_data.chord_at_force()[i]);
143 amrex::ParallelDescriptor::Bcast(
144 tdata.chord.data(), tdata.chord.size(), info.root_proc, tdata.tcomm);
150template <
typename datatype>
157 if (!data.info().is_root_proc) {
161 const auto& tdata = data.meta();
162 const auto& bp = data.info().base_pos;
163 const auto& pxvel = tdata.ext_data.position_at_vel(0);
164 const auto& pyvel = tdata.ext_data.position_at_vel(1);
165 const auto& pzvel = tdata.ext_data.position_at_vel(2);
166 auto& vel_pos = data.grid().vel_pos;
167 for (
int i = 0; i < vel_pos.size(); ++i) {
168 vel_pos[i].x() =
static_cast<amrex::Real
>(pxvel[i]) + bp.x();
169 vel_pos[i].y() =
static_cast<amrex::Real
>(pyvel[i]) + bp.y();
170 vel_pos[i].z() =
static_cast<amrex::Real
>(pzvel[i]) + bp.z();
174template <
typename datatype>
181 if (!data.info().is_root_proc) {
184 auto& tdata = data.meta();
186 const auto& uvel = tdata.ext_data.fluid_velocity(0);
187 const auto& vvel = tdata.ext_data.fluid_velocity(1);
188 const auto& wvel = tdata.ext_data.fluid_velocity(2);
189 const auto& vel = data.grid().vel;
191 if (!tdata.fllc.empty()) {
193 const auto& xdot = tdata.ext_data.solid_velocity(0);
194 const auto& ydot = tdata.ext_data.solid_velocity(1);
195 const auto& zdot = tdata.ext_data.solid_velocity(2);
196 for (
int i = 0; i < tdata.vel_rel.size(); ++i) {
197 tdata.vel_rel[i][0] = uvel[i] -
static_cast<amrex::Real
>(xdot[i]);
198 tdata.vel_rel[i][1] = vvel[i] -
static_cast<amrex::Real
>(ydot[i]);
199 tdata.vel_rel[i][2] = wvel[i] -
static_cast<amrex::Real
>(zdot[i]);
202 for (
int i = 0; i < tdata.num_blades; ++i) {
203 FLLCOp()(tdata.blades[i], tdata.fllc[i]);
207 for (
int i = 0; i < tdata.ext_data.length_fluid_velocity(0); ++i) {
208 uvel[i] =
static_cast<float>(vel[i].x());
209 vvel[i] =
static_cast<float>(vel[i].y());
210 wvel[i] =
static_cast<float>(vel[i].z());
214template <
typename datatype>
223 const auto& time = data.sim().time();
225 auto& tdata = data.meta();
226 if (!tdata.fllc.empty()) {
227 for (
int i = 0; i < tdata.num_blades; ++i) {
228 if (!(tdata.fllc[i].initialized) &&
229 (time.current_time() > tdata.fllc[i].fllc_start_time)) {
230 fllc_init(tdata.fllc[i], tdata.blades[i], tdata.eps_chord[0]);
void get(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:41
Definition ExtTurbIface.H:23
Definition turbine_external_utils.H:11
void scatter_data(datatype &data)
Definition turbine_external_utils.H:189
void ext_step(datatype &data)
Definition turbine_external_utils.H:166
void make_component_views(datatype &data)
Definition turbine_external_utils.H:22
void init_epsilon(datatype &data)
Definition turbine_external_utils.H:84
Definition ActSrcLineOp.H:9
void update_pos_op(datatype &data)
Definition turbine_external_ops.H:151
void compute_force_op(datatype &data)
Definition turbine_external_ops.H:215
void external_determine_influenced_procs(datatype &data)
Definition turbine_external_ops.H:47
void read_ops(datatype &data, const utils::ActParser &pp)
Definition turbine_external_ops.H:16
void update_vel_op(datatype &data)
Definition turbine_external_ops.H:175
void init_data_op(datatype &data)
Definition turbine_external_ops.H:96
void external_determine_root_proc(datatype &data, amrex::Vector< int > &act_proc_count)
Definition turbine_external_ops.H:67
std::set< int > determine_influenced_procs(const amrex::AmrCore &mesh, const amrex::RealBox &rbx)
Definition actuator_utils.cpp:6
void read_inputs(TurbineBaseData &tdata, TurbineInfo &tinfo, const utils::ActParser &pp)
Definition turbine_utils.cpp:8
void determine_root_proc(ActInfo &info, amrex::Vector< int > &act_proc_count)
Definition actuator_utils.cpp:34
::amr_wind::utils::MultiParser ActParser
Definition ActParser.H:8
void fllc_init(FLLCData &data, const ComponentView &view, const amrex::Real eps_chord)
Initialize FLLC data structure. This should be called at the end of the first ComputeForceOp to ensur...
Definition FLLC.cpp:6
This struct will operate on a blade/wing. The velocity from the simulation is corrected using the Fil...
Definition FLLCOp.H:17
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr VectorT< amrex::Real > zero()
Definition vector.H:45