1#ifndef TURBINE_FAST_OPS_H
2#define TURBINE_FAST_OPS_H
13template <
typename SrcTrait>
21 auto& tdata = data.
meta();
24 pp.
get(
"density", tdata.density);
27 bool override_density_check =
false;
28 pp.
query(
"override_density_check", override_density_check);
33 const auto& tinfo = data.
info();
34 auto& tf = data.
meta().fast_data;
35 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
36 tf.base_pos[i] =
static_cast<float>(tinfo.base_pos[i]);
39 tf.tlabel = tinfo.label;
40 tf.tid_global = tinfo.id;
41 tf.num_blades = tdata.num_blades;
42 tf.num_pts_blade = tdata.num_pts_blade;
43 tf.num_pts_tower = tdata.num_pts_tower;
46 pp.
get(
"openfast_start_time", tf.start_time);
47 pp.
get(
"openfast_stop_time", tf.stop_time);
49 std::string sim_mode = (tf.start_time > 0.0) ?
"restart" :
"init";
50 pp.
query(
"openfast_sim_mode", sim_mode);
52 if (sim_mode ==
"init") {
54 amrex::Print() <<
"Initializing turbine:" << tf.tlabel << std::endl;
55 }
else if (sim_mode ==
"replay") {
57 amrex::Print() <<
"Replaying turbine:" << tf.tlabel << std::endl;
58 }
else if (sim_mode ==
"restart") {
60 amrex::Print() <<
"Restarting turbine:" << tf.tlabel << std::endl;
63 "Actuator: Invalid OpenFAST simulation mode: " + sim_mode);
69 pp.
get(
"openfast_restart_file", tf.checkpoint_file);
71 pp.
get(
"openfast_input_file", tf.input_file);
74 const auto& time = data.
sim().
time();
79 perform_density_checks(
80 tdata.density, override_density_check, is_restart);
85 const auto& time = data.
sim().
time();
87 AMREX_ALWAYS_ASSERT(!time.adaptive_timestep());
92 const amrex::Real rho_tdef,
const bool no_check,
const bool is_rst)
95 amrex::ParmParse pp_incflo(
"incflo");
96 amrex::ParmParse pp_cstdns(
"ConstValue.density");
97 bool is_incflo = pp_incflo.contains(
"density");
98 bool is_cstdns = pp_cstdns.contains(
"value");
100 bool cft_incflo =
false;
101 bool cft_cstdns =
false;
104 const amrex::Real tiny = std::numeric_limits<amrex::Real>::epsilon();
106 amrex::Real rho_incflo = 1.0;
107 pp_incflo.query(
"density", rho_incflo);
108 if (std::abs(rho_incflo - rho_tdef) > tiny) {
112 "Density conflict detected between TurbineFast "
113 "density and incflo.density.\n----- Values are " +
114 std::to_string(rho_tdef) +
" and " +
115 std::to_string(rho_incflo) +
116 ", respectively. Check the problem setup and the "
117 "turbine definition.\n----- If this difference is "
118 "intended, set the override_density_check flag to "
122 <<
"WARNING: Density conflict detected between FAST "
123 "Turbine density and incflo.density.\n----- Values "
125 std::to_string(rho_tdef) +
" and " +
126 std::to_string(rho_incflo) +
127 ", respectively. Abort overridden by flag.\n";
132 amrex::Real rho_cstdns = 1.0;
133 pp_cstdns.query(
"value", rho_cstdns);
134 if (std::abs(rho_cstdns - rho_tdef) > tiny) {
138 "Density conflict detected between TurbineFast "
139 "density and ConstValue.density.value.\n----- Values "
141 std::to_string(rho_tdef) +
" and " +
142 std::to_string(rho_cstdns) +
143 ", respectively. Check the problem setup and the "
144 "turbine definition.\n----- If this difference is "
145 "intended, set the override_density_check flag to "
149 <<
"WARNING: Density conflict detected between "
152 "ConstValue.density.value.\n----- Values are " +
153 std::to_string(rho_tdef) +
" and " +
154 std::to_string(rho_cstdns) +
155 ", respectively. Abort overridden by flag.\n";
159 if (!is_incflo && !is_cstdns) {
161 <<
"TurbineFast: no density conflict detected, but no density "
162 "arguments found to check against.\n";
163 }
else if (!cft_incflo && !cft_cstdns) {
164 amrex::Print() <<
"TurbineFast: no density conflict detected.\n";
168 <<
"TurbineFast: simulation begins using a checkpoint file, "
169 "density compatibility must be manually confirmed between "
170 "the precursor simulation and the specified TurbineFast "
172 std::to_string(rho_tdef)
182 auto& info = data.
info();
186 AMREX_ALWAYS_ASSERT(info.root_proc > -1);
190 info.procs.insert(info.root_proc);
192 const int iproc = amrex::ParallelDescriptor::MyProc();
193 auto in_proc = info.procs.find(iproc);
194 info.actuator_in_proc = (in_proc != info.procs.end());
195 info.sample_vel_in_proc = info.is_root_proc;
202 namespace utils = ::amr_wind::actuator::utils;
203 auto& info = data.
info();
213 info.sample_vel_in_proc = info.is_root_proc;
217 if (info.is_root_proc) {
218 auto& tdata = data.
meta();
222 tdata.fast->register_turbine(tdata.fast_data);
226template <
typename SrcTrait>
231 BL_PROFILE(
"amr-wind::InitDataOp<TurbineFast>");
236 check_fast_sim_time(data);
238 const auto& info = data.
info();
239 auto& tdata = data.
meta();
242 amrex::ParallelDescriptor::Comm_dup(
243 amrex::ParallelDescriptor::Communicator(), tdata.tcomm);
245 amrex::Array<int, 5> sz_info = {0, 0, 0, 0, 0};
246 if (info.is_root_proc) {
247 tdata.fast->init_turbine(tdata.fast_data.tid_local);
249 const auto& tf = tdata.fast_data;
250 sz_info[0] = tf.num_blades;
251 sz_info[1] = tf.to_cfd.fx_Len;
252 sz_info[2] = tf.from_cfd.u_Len;
253 sz_info[3] = tf.num_pts_tower;
254 sz_info[4] = tf.num_blade_elem;
258 amrex::ParallelDescriptor::Bcast(
259 sz_info.begin(), sz_info.size(), info.root_proc, tdata.tcomm);
262 tdata.num_blades = sz_info[0];
265 tdata.num_vel_pts_blade = sz_info[4];
266 data.
grid().resize(sz_info[1], sz_info[2]);
267 tdata.chord.resize(sz_info[1]);
268 tdata.num_pts_tower = sz_info[3];
273 if (info.is_root_proc) {
275 int npts = sz_info[1];
276 const auto& fchord = tdata.fast_data.to_cfd.forceNodesChord;
277 for (
int i = 0; i < npts; ++i) {
278 tdata.chord[i] =
static_cast<amrex::Real
>(fchord[i]);
282 amrex::ParallelDescriptor::Bcast(
283 tdata.chord.data(), tdata.chord.size(), info.root_proc,
286 make_component_views(data);
292 auto& grid = data.
grid();
293 auto& tdata = data.
meta();
294 const int num_blades = tdata.num_blades;
295 const int num_pts_blade = tdata.num_pts_blade;
296 const int num_vel_pts_blade = tdata.num_vel_pts_blade;
298 for (
int ib = 0; ib < num_blades; ++ib) {
301 const auto start = ib * num_pts_blade + 1;
302 const auto start_vel = ib * num_vel_pts_blade;
305 grid.pos, start, num_pts_blade);
307 grid.force, start, num_pts_blade);
309 grid.epsilon, start, num_pts_blade);
311 grid.orientation, start, num_pts_blade);
313 tdata.chord, start, num_pts_blade);
315 tdata.vel_rel, start, num_pts_blade);
317 grid.vel, start_vel, num_vel_pts_blade);
319 grid.vel_pos, start_vel, num_vel_pts_blade);
322 tdata.blades.emplace_back(cv);
324 if (tdata.num_pts_tower > 0) {
325 const int num_pts_tower = tdata.num_pts_tower;
326 const int ntwr_start = num_blades * num_pts_blade + 1;
327 auto& cv = tdata.tower;
334 grid.epsilon, ntwr_start, num_pts_tower);
336 grid.orientation, ntwr_start, num_pts_tower);
338 tdata.chord, ntwr_start, num_pts_tower);
341 auto& cv = tdata.hub;
352 auto& tdata = data.
meta();
355 swap_epsilon(tdata.eps_inp);
356 swap_epsilon(tdata.eps_min);
357 swap_epsilon(tdata.eps_chord);
358 swap_epsilon(tdata.eps_tower);
361 const auto& cd = tdata.nacelle_cd;
362 const auto& area = tdata.nacelle_area;
366 auto& nac_eps = data.
grid().epsilon[0];
367 nac_eps.x() = amrex::max(eps, tdata.eps_min.x());
368 nac_eps.y() = amrex::max(eps, tdata.eps_min.y());
369 nac_eps.z() = amrex::max(eps, tdata.eps_min.z());
372 for (
int ib = 0; ib < tdata.num_blades; ++ib) {
373 auto& cv = tdata.blades[ib];
375 for (
int i = 0; i < tdata.num_pts_blade; ++i) {
376 const auto eps_crd = tdata.eps_chord * cv.chord[i];
378 for (
int n = 0; n < AMREX_SPACEDIM; ++n) {
379 cv.epsilon[i][n] = amrex::max(
380 tdata.eps_min[n], tdata.eps_inp[n], eps_crd[n]);
385 auto& cv = tdata.tower;
386 for (
int i = 0; i < tdata.num_pts_tower; ++i) {
387 for (
int n = 0; n < AMREX_SPACEDIM; ++n) {
388 cv.epsilon[i][n] = amrex::max(
389 tdata.eps_min[n], tdata.eps_inp[n], tdata.eps_tower[n]);
397 const auto x = eps.
x();
398 const auto y = eps.
y();
405 const auto& time = data.
sim().
time();
409 const amrex::Real stop1 = time.
stop_time() > 0.0
411 : std::numeric_limits<amrex::Real>::max();
412 const amrex::Real stop2 = time.stop_time_index() > -1
413 ? time.stop_time_index() * time.delta_t()
414 : std::numeric_limits<amrex::Real>::max();
415 const amrex::Real cfd_stop = amrex::min(stop1, stop2);
416 const amrex::Real cfd_start = time.current_time();
417 const amrex::Real cfd_sim = cfd_stop - cfd_start - 1.0e-6;
420 const auto& tf = data.
meta().fast_data;
421 const amrex::Real fast_sim = tf.stop_time - tf.start_time;
422 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
424 "OpenFAST simulation time is shorter than AMR-Wind duration");
428template <
typename SrcTrait>
437 if (!data.
info().is_root_proc) {
440 BL_PROFILE(
"amr-wind::actuator::UpdatePosOp<TurbineFast>");
442 const auto& tdata = data.
meta();
443 const auto& bp = data.
info().base_pos;
444 const auto& pxvel = tdata.fast_data.to_cfd.pxVel;
445 const auto& pyvel = tdata.fast_data.to_cfd.pyVel;
446 const auto& pzvel = tdata.fast_data.to_cfd.pzVel;
447 auto& vel_pos = data.
grid().vel_pos;
448 for (
int i = 0; i < vel_pos.size(); ++i) {
449 vel_pos[i].x() =
static_cast<amrex::Real
>(pxvel[i]) + bp.x();
450 vel_pos[i].y() =
static_cast<amrex::Real
>(pyvel[i]) + bp.y();
451 vel_pos[i].z() =
static_cast<amrex::Real
>(pzvel[i]) + bp.z();
456template <
typename SrcTrait>
465 if (!data.
info().is_root_proc) {
468 BL_PROFILE(
"amr-wind::actuator::UpdateVelOp<TurbineFast>");
469 auto& tdata = data.
meta();
471 auto& from_cfd = tdata.fast_data.from_cfd;
472 auto& uvel = from_cfd.u;
473 auto& vvel = from_cfd.v;
474 auto& wvel = from_cfd.w;
475 const auto& vel = data.
grid().vel;
477 if (!tdata.fllc.empty()) {
479 for (
int i = 0; i < tdata.vel_rel.size(); ++i) {
480 tdata.vel_rel[i][0] =
481 uvel[i] -
static_cast<amrex::Real
>(
482 tdata.fast_data.to_cfd.xdotForce[i]);
483 tdata.vel_rel[i][1] =
484 vvel[i] -
static_cast<amrex::Real
>(
485 tdata.fast_data.to_cfd.ydotForce[i]);
486 tdata.vel_rel[i][2] =
487 wvel[i] -
static_cast<amrex::Real
>(
488 tdata.fast_data.to_cfd.zdotForce[i]);
491 for (
int i = 0; i < tdata.num_blades; ++i) {
492 FLLCOp()(tdata.blades[i], tdata.fllc[i]);
496 for (
int i = 0; i < from_cfd.u_Len; ++i) {
497 uvel[i] =
static_cast<float>(vel[i].x());
498 vvel[i] =
static_cast<float>(vel[i].y());
499 wvel[i] =
static_cast<float>(vel[i].z());
504template <
typename SrcTrait>
509 BL_PROFILE(
"amr-wind::actuator::ComputeForceOp<TurbineFast>");
516 const auto& time = data.
sim().
time();
518 auto& tdata = data.
meta();
519 if (!tdata.fllc.empty()) {
520 for (
int i = 0; i < tdata.num_blades; ++i) {
521 if (!(tdata.fllc[i].initialized) &&
522 (time.current_time() > tdata.fllc[i].fllc_start_time)) {
524 tdata.fllc[i], tdata.blades[i], tdata.eps_chord[0]);
532 if (!data.
info().is_root_proc) {
536 auto& meta = data.
meta();
537 auto& tf = data.
meta().fast_data;
538 if (tf.is_solution0) {
539 meta.fast->init_solution(tf.tid_local);
541 meta.fast->advance_turbine(tf.tid_local);
544 meta.fast->get_hub_stats(tf.tid_local);
549 compute_nacelle_force(data);
554 if (!data.
info().is_root_proc) {
558 const auto& cd = data.
meta().nacelle_cd;
559 const auto& area = data.
meta().nacelle_area;
560 const auto& cd_area = cd * area;
561 const auto& fcfd = data.
meta().fast_data.from_cfd;
562 const auto& tcfd = data.
meta().fast_data.to_cfd;
563 const auto& rho = data.
meta().density;
565 const auto& eps = data.
grid().epsilon[0].x();
566 vs::Vector vel{fcfd.u[0], fcfd.v[0], fcfd.w[0]};
567 amrex::Real correction = 0.0;
572 correction = 1.0 / fac;
575 0.5 * rho * cd_area *
vs::mag(vel) * correction * correction;
577 tcfd.fx[0] =
static_cast<float>(coeff * fcfd.u[0]);
578 tcfd.fy[0] =
static_cast<float>(coeff * fcfd.v[0]);
579 tcfd.fz[0] =
static_cast<float>(coeff * fcfd.w[0]);
584 if (!data.
info().actuator_in_proc) {
592 const auto dsize = data.
grid().pos.size() * 15;
593 amrex::Vector<float> buf(dsize);
597 if (data.
info().is_root_proc) {
599 "amr-wind::actuator::ComputeForceOp<TurbineFast>::scatter1");
600 const auto& tocfd = data.
meta().fast_data.to_cfd;
601 auto it = buf.begin();
602 std::copy(tocfd.fx, tocfd.fx + tocfd.fx_Len, it);
603 std::advance(it, tocfd.fx_Len);
604 std::copy(tocfd.fy, tocfd.fy + tocfd.fy_Len, it);
605 std::advance(it, tocfd.fy_Len);
606 std::copy(tocfd.fz, tocfd.fz + tocfd.fz_Len, it);
607 std::advance(it, tocfd.fz_Len);
609 std::copy(tocfd.pxForce, tocfd.pxForce + tocfd.pxForce_Len, it);
610 std::advance(it, tocfd.pxForce_Len);
611 std::copy(tocfd.pyForce, tocfd.pyForce + tocfd.pyForce_Len, it);
612 std::advance(it, tocfd.pyForce_Len);
613 std::copy(tocfd.pzForce, tocfd.pzForce + tocfd.pzForce_Len, it);
614 std::advance(it, tocfd.pzForce_Len);
617 std::copy(tocfd.pOrientation,
618 tocfd.pOrientation + tocfd.pOrientation_Len, it);
623 const auto& procs = data.
info().procs;
624 const int tag = 1001;
625 if (data.
info().is_root_proc) {
627 "amr-wind::actuator::ComputeForceOp<TurbineFast>::scatter2");
628 for (
const int ip : procs) {
629 if (ip == data.
info().root_proc) {
633 amrex::ParallelDescriptor::Send(
634 buf.data(), dsize, ip, tag, data.
meta().tcomm);
638 "amr-wind::actuator::ComputeForceOp<TurbineFast>::scatter2");
639 amrex::ParallelDescriptor::Recv(
640 buf.data(), dsize, data.
info().root_proc, tag,
648 "amr-wind::actuator::ComputeForceOp<TurbineFast>::scatter3");
649 const auto& bp = data.
info().base_pos;
650 auto& grid = data.
grid();
651 const auto& npts = grid.pos.size();
652 const auto& rho = data.
meta().density;
653 const size_t ifx = 0;
654 const size_t ify = ifx + npts;
655 const size_t ifz = ify + npts;
656 const size_t ipx = ifz + npts;
657 const size_t ipy = ipx + npts;
658 const size_t ipz = ipy + npts;
659 const size_t iori = ipz + npts;
661 for (
int i = 0; i < npts; ++i) {
667 -
static_cast<amrex::Real
>(buf[ifx + i]) / rho;
669 -
static_cast<amrex::Real
>(buf[ify + i]) / rho;
671 -
static_cast<amrex::Real
>(buf[ifz + i]) / rho;
676 static_cast<amrex::Real
>(buf[ipx + i]) + bp.x();
678 static_cast<amrex::Real
>(buf[ipy + i]) + bp.y();
680 static_cast<amrex::Real
>(buf[ipz + i]) + bp.z();
688 const auto off =
static_cast<int>(iori) +
689 i * AMREX_SPACEDIM * AMREX_SPACEDIM;
690 for (
int j = 0; j < AMREX_SPACEDIM; ++j) {
691 for (
int k = 0; k < AMREX_SPACEDIM; ++k) {
692 grid.orientation[i][j * AMREX_SPACEDIM + k] =
693 static_cast<amrex::Real
>(
694 buf[off + j + k * AMREX_SPACEDIM]);
700 auto& meta = data.
meta();
701 meta.rot_center = grid.pos[0];
704 const auto xvec = grid.orientation[0].x().unit();
706 const auto zvec = xvec ^ yvec;
707 meta.rotor_frame.rows(xvec, yvec.unit(), zvec.unit());
712template <
typename SrcTrait>
734 pp.
query(
"output_frequency", m_out_freq);
739 m_nc_filename = out_dir +
"/" + m_data.
info().label +
".nc";
741 m_nc_filename, m_data.
meta(), m_data.
info(), m_data.
grid());
746 const auto& time = m_data.
sim().
time();
748 if ((m_out_freq > 0) && (tidx % m_out_freq != 0)) {
753 m_nc_filename, m_data.
meta(), m_data.
info(), m_data.
grid(),
amrex::AmrCore & mesh()
Return the AMR mesh hierarchy.
Definition CFDSim.H:54
SimTime & time()
Return simulation time control.
Definition CFDSim.H:58
ExtSolverMgr & ext_solver_manager()
Definition CFDSim.H:98
IOManager & io_manager()
Definition CFDSim.H:83
Type & create(const std::string &key, Args &&... args)
Definition CollMgr.H:38
bool is_restart() const
Definition IOManager.H:85
AMREX_FORCE_INLINE int time_index() const
Definition SimTime.H:114
AMREX_FORCE_INLINE amrex::Real stop_time() const
Definition SimTime.H:132
AMREX_FORCE_INLINE amrex::Real delta_t() const
Definition SimTime.H:84
AMREX_FORCE_INLINE int chkpt_interval() const
Definition SimTime.H:141
Definition actuator_types.H:184
CFDSim & sim()
Definition actuator_types.H:211
ActTrait::GridType & grid()
Definition actuator_types.H:217
ActTrait::InfoType & info()
Definition actuator_types.H:214
ActTrait::MetaType & meta()
Definition actuator_types.H:220
Definition MultiParser.H:18
void get(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:42
void query(const std::string &name, vs::Vector &value) const
Definition MultiParser.H:57
Definition FastIface.H:21
Definition ActSrcLineOp.H:9
void determine_influenced_procs< TurbineFast >(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:180
void determine_root_proc< TurbineFast >(typename TurbineFast::DataType &data, amrex::Vector< int > &act_proc_count)
Definition turbine_fast_ops.H:199
std::set< int > determine_influenced_procs(const amrex::AmrCore &mesh, const amrex::RealBox &rbx)
Definition actuator_utils.cpp:6
void write_netcdf(const std::string &ncfile, const TurbineBaseData &meta, const TurbineInfo &info, const ActGrid &grid, const amrex::Real time)
Definition turbine_utils.cpp:118
void read_inputs(TurbineBaseData &tdata, TurbineInfo &tinfo, const utils::ActParser &pp)
Definition turbine_utils.cpp:8
void prepare_netcdf_file(const std::string &ncfile, const TurbineBaseData &meta, const TurbineInfo &info, const ActGrid &grid)
Definition turbine_utils.cpp:52
void determine_root_proc(ActInfo &info, amrex::Vector< int > &act_proc_count)
Definition actuator_utils.cpp:34
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
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:22
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr amrex::Real pi()
Return as an amrex::Real.
Definition trig_ops.H:16
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T mag(const TensorT< T > &t)
Definition tensorI.H:182
@ restart
Restart using FAST checkpoint files.
@ replay
Replay using velocities stored in file.
Definition actuator_types.H:126
VecSlice vel
Definition actuator_types.H:133
VecSlice epsilon
Definition actuator_types.H:129
VecSlice vel_rel
Definition actuator_types.H:134
VecSlice force
Definition actuator_types.H:128
TensorSlice orientation
Definition actuator_types.H:130
RealSlice chord
Definition actuator_types.H:136
VecSlice pos
Definition actuator_types.H:127
VecSlice vel_pos
Definition actuator_types.H:132
This struct will operate on a blade/wing. The velocity from the simulation is corrected using the Fil...
Definition FLLCOp.H:17
Definition TurbineFast.H:22
void compute_nacelle_force(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:552
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:507
void fast_step(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:530
void scatter_data(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:582
Definition actuator_ops.H:61
void check_fast_sim_time(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:403
void swap_epsilon(vs::Vector &eps)
Definition turbine_fast_ops.H:395
void make_component_views(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:290
void operator()(TurbineFast::DataType &data)
Definition turbine_fast_ops.H:229
void init_epsilon(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:350
Definition actuator_ops.H:32
ProcessOutputsOp(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:728
std::string m_nc_filename
NetCDF output filename for this turbine.
Definition turbine_fast_ops.H:722
TurbineFast::DataType & m_data
Definition turbine_fast_ops.H:716
void prepare_outputs(const std::string &out_dir)
Definition turbine_fast_ops.H:737
std::string m_out_dir
Path to the output directory (specified by Actuator physics class)
Definition turbine_fast_ops.H:719
void write_outputs()
Definition turbine_fast_ops.H:744
void read_io_options(const utils::ActParser &pp)
Definition turbine_fast_ops.H:732
Definition actuator_ops.H:71
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:431
Definition actuator_ops.H:43
void operator()(typename TurbineFast::DataType &data)
Definition turbine_fast_ops.H:459
Definition actuator_ops.H:54
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & x() &noexcept
Definition vector.H:97
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & y() &noexcept
Definition vector.H:98
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr VectorT< T > zero()
Zero vector.
Definition vector.H:45
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr VectorT< T > khat(const T &z=Traits::one())
Definition vector.H:80