ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
GeneralAD Class Reference

#include <ERF_GeneralAD.H>

Inheritance diagram for GeneralAD:
Collaboration diagram for GeneralAD:

Public Member Functions

 GeneralAD ()
 
virtual ~GeneralAD ()=default
 
void advance (const amrex::Geometry &geom, const amrex::Real &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &mf_vars_windfarm, amrex::MultiFab &U_old, amrex::MultiFab &V_old, amrex::MultiFab &W_old, const amrex::MultiFab &mf_Nturb, const amrex::MultiFab &mf_SMark, const amrex::Real &time) override
 
void compute_freestream_velocity (const amrex::MultiFab &cons_in, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &mf_SMark)
 
void source_terms_cellcentered (const amrex::Geometry &geom, const amrex::MultiFab &cons_in, const amrex::MultiFab &mf_Smark, amrex::MultiFab &mf_vars_generalAD)
 
void update (const amrex::Real &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &U_old, amrex::MultiFab &V_old, amrex::MultiFab &W_old, const amrex::MultiFab &mf_vars)
 
void compute_power_output (const amrex::Real &time)
 
- Public Member Functions inherited from NullWindFarm
 NullWindFarm ()
 
virtual ~NullWindFarm ()=default
 
virtual void set_turb_spec (const amrex::Real &rotor_rad, const amrex::Real &hub_height, const amrex::Real &thrust_coeff_standing, const amrex::Vector< amrex::Real > &wind_speed, const amrex::Vector< amrex::Real > &thrust_coeff, const amrex::Vector< amrex::Real > &power)
 
virtual void set_turb_loc (const amrex::Vector< amrex::Real > &xloc, const amrex::Vector< amrex::Real > &yloc)
 
virtual void set_turb_disk_angle (const amrex::Real &turb_disk_angle)
 
virtual void set_blade_spec (const amrex::Vector< amrex::Real > &bld_rad_loc, const amrex::Vector< amrex::Real > &bld_twist, const amrex::Vector< amrex::Real > &bld_chord)
 
virtual void set_blade_airfoil_spec (const amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_aoa, const amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cl, const amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cd)
 
virtual void set_turb_spec_extra (const amrex::Vector< amrex::Real > &velocity, const amrex::Vector< amrex::Real > &C_P, const amrex::Vector< amrex::Real > &C_T, const amrex::Vector< amrex::Real > &rotor_RPM, const amrex::Vector< amrex::Real > &blade_pitch)
 
void get_turb_spec (amrex::Real &rotor_rad, amrex::Real &hub_height, amrex::Real &thrust_coeff_standing, amrex::Vector< amrex::Real > &wind_speed, amrex::Vector< amrex::Real > &thrust_coeff, amrex::Vector< amrex::Real > &power)
 
void get_turb_loc (amrex::Vector< amrex::Real > &xloc, amrex::Vector< amrex::Real > &yloc)
 
void get_turb_disk_angle (amrex::Real &turb_disk_angle)
 
void get_blade_spec (amrex::Vector< amrex::Real > &bld_rad_loc, amrex::Vector< amrex::Real > &bld_twist, amrex::Vector< amrex::Real > &bld_chord)
 
void get_blade_airfoil_spec (amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_aoa, amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cl, amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cd)
 
void get_turb_spec_extra (amrex::Vector< amrex::Real > &velocity, amrex::Vector< amrex::Real > &C_P, amrex::Vector< amrex::Real > &C_T, amrex::Vector< amrex::Real > &rotor_RPM, amrex::Vector< amrex::Real > &blade_pitch)
 

Protected Attributes

amrex::Vector< amrex::Real > xloc
 
amrex::Vector< amrex::Real > yloc
 
amrex::Real turb_disk_angle
 
amrex::Real hub_height
 
amrex::Real rotor_rad
 
amrex::Real thrust_coeff_standing
 
amrex::Real nominal_power
 
amrex::Vector< amrex::Real > wind_speed
 
amrex::Vector< amrex::Real > thrust_coeff
 
amrex::Vector< amrex::Real > power
 
amrex::Vector< amrex::Real > freestream_velocity
 
amrex::Vector< amrex::Real > freestream_phi
 
amrex::Vector< amrex::Real > disk_cell_count
 
amrex::Vector< amrex::Real > bld_rad_loc
 
amrex::Vector< amrex::Real > bld_twist
 
amrex::Vector< amrex::Real > bld_chord
 
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_aoa
 
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_Cl
 
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_Cd
 
amrex::Vector< amrex::Real > velocity
 
amrex::Vector< amrex::Real > C_P
 
amrex::Vector< amrex::Real > C_T
 
amrex::Vector< amrex::Real > rotor_RPM
 
amrex::Vector< amrex::Real > blade_pitch
 
- Protected Attributes inherited from NullWindFarm
amrex::Vector< amrex::Real > m_xloc
 
amrex::Vector< amrex::Real > m_yloc
 
amrex::Real m_turb_disk_angle
 
amrex::Real m_hub_height
 
amrex::Real m_rotor_rad
 
amrex::Real m_thrust_coeff_standing
 
amrex::Real m_nominal_power
 
amrex::Vector< amrex::Real > m_wind_speed
 
amrex::Vector< amrex::Real > m_thrust_coeff
 
amrex::Vector< amrex::Real > m_power
 
amrex::Vector< amrex::Real > m_bld_rad_loc
 
amrex::Vector< amrex::Real > m_bld_twist
 
amrex::Vector< amrex::Real > m_bld_chord
 
amrex::Vector< amrex::Vector< amrex::Real > > m_bld_airfoil_aoa
 
amrex::Vector< amrex::Vector< amrex::Real > > m_bld_airfoil_Cl
 
amrex::Vector< amrex::Vector< amrex::Real > > m_bld_airfoil_Cd
 
amrex::Vector< amrex::Real > m_velocity
 
amrex::Vector< amrex::Real > m_C_P
 
amrex::Vector< amrex::Real > m_C_T
 
amrex::Vector< amrex::Real > m_rotor_RPM
 
amrex::Vector< amrex::Real > m_blade_pitch
 

Additional Inherited Members

- Static Public Member Functions inherited from NullWindFarm
static AMREX_GPU_DEVICE bool find_if_marked (amrex::Real x1, amrex::Real x2, amrex::Real y1, amrex::Real y2, amrex::Real x0, amrex::Real y0, amrex::Real nx, amrex::Real ny, amrex::Real d_hub_height, amrex::Real d_rotor_rad, amrex::Real z)
 

Constructor & Destructor Documentation

◆ GeneralAD()

GeneralAD::GeneralAD ( )
inline
12 {}

◆ ~GeneralAD()

virtual GeneralAD::~GeneralAD ( )
virtualdefault

Member Function Documentation

◆ advance()

void GeneralAD::advance ( const amrex::Geometry &  geom,
const amrex::Real &  dt_advance,
amrex::MultiFab &  cons_in,
amrex::MultiFab &  mf_vars_windfarm,
amrex::MultiFab &  U_old,
amrex::MultiFab &  V_old,
amrex::MultiFab &  W_old,
const amrex::MultiFab &  mf_Nturb,
const amrex::MultiFab &  mf_SMark,
const amrex::Real &  time 
)
overridevirtual

Implements NullWindFarm.

19 {
20  AMREX_ALWAYS_ASSERT(W_old.nComp() > 0);
21  AMREX_ALWAYS_ASSERT(mf_Nturb.nComp() > 0);
22  AMREX_ALWAYS_ASSERT(mf_vars_generalAD.nComp() > 0);
23  AMREX_ALWAYS_ASSERT(time > -1.0);
24  compute_freestream_velocity(cons_in, U_old, V_old, mf_SMark);
25  source_terms_cellcentered(geom, cons_in, mf_SMark, mf_vars_generalAD);
26  update(dt_advance, cons_in, U_old, V_old, W_old, mf_vars_generalAD);
28 }
void update(const amrex::Real &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &U_old, amrex::MultiFab &V_old, amrex::MultiFab &W_old, const amrex::MultiFab &mf_vars)
Definition: ERF_AdvanceGeneralAD.cpp:60
void source_terms_cellcentered(const amrex::Geometry &geom, const amrex::MultiFab &cons_in, const amrex::MultiFab &mf_Smark, amrex::MultiFab &mf_vars_generalAD)
Definition: ERF_AdvanceGeneralAD.cpp:317
void compute_freestream_velocity(const amrex::MultiFab &cons_in, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &mf_SMark)
Definition: ERF_AdvanceGeneralAD.cpp:96
void compute_power_output(const amrex::Real &time)
Definition: ERF_AdvanceGeneralAD.cpp:31

◆ compute_freestream_velocity()

void GeneralAD::compute_freestream_velocity ( const amrex::MultiFab &  cons_in,
const amrex::MultiFab &  U_old,
const amrex::MultiFab &  V_old,
const amrex::MultiFab &  mf_SMark 
)
100 {
102  freestream_velocity.clear();
103  freestream_phi.clear();
104  disk_cell_count.clear();
105  freestream_velocity.resize(xloc.size(),0.0);
106  freestream_phi.resize(xloc.size(),0.0);
107  disk_cell_count.resize(xloc.size(),0.0);
108 
109  Gpu::DeviceVector<Real> d_freestream_velocity(xloc.size());
110  Gpu::DeviceVector<Real> d_freestream_phi(yloc.size());
111  Gpu::DeviceVector<Real> d_disk_cell_count(yloc.size());
112  Gpu::copy(Gpu::hostToDevice, freestream_velocity.begin(), freestream_velocity.end(), d_freestream_velocity.begin());
113  Gpu::copy(Gpu::hostToDevice, freestream_phi.begin(), freestream_phi.end(), d_freestream_phi.begin());
114  Gpu::copy(Gpu::hostToDevice, disk_cell_count.begin(), disk_cell_count.end(), d_disk_cell_count.begin());
115 
116  Real* d_freestream_velocity_ptr = d_freestream_velocity.data();
117  Real* d_freestream_phi_ptr = d_freestream_phi.data();
118  Real* d_disk_cell_count_ptr = d_disk_cell_count.data();
119 
120 
121  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
122 
123  auto SMark_array = mf_SMark.array(mfi);
124  auto u_vel = U_old.array(mfi);
125  auto v_vel = V_old.array(mfi);
126  Box tbx = mfi.nodaltilebox(0);
127 
128  ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
129 
130  if(SMark_array(i,j,k,0) != -1.0) {
131  int turb_index = static_cast<int>(SMark_array(i,j,k,0));
132  Real phi = std::atan2(v_vel(i,j,k),u_vel(i,j,k)); // Wind direction w.r.t the x-dreiction
133  Gpu::Atomic::Add(&d_freestream_velocity_ptr[turb_index],std::pow(u_vel(i,j,k)*u_vel(i,j,k) + v_vel(i,j,k)*v_vel(i,j,k),0.5));
134  Gpu::Atomic::Add(&d_disk_cell_count_ptr[turb_index],1.0);
135  Gpu::Atomic::Add(&d_freestream_phi_ptr[turb_index],phi);
136  }
137  });
138  }
139 
140  // Copy back to host
141  Gpu::copy(Gpu::deviceToHost, d_freestream_velocity.begin(), d_freestream_velocity.end(), freestream_velocity.begin());
142  Gpu::copy(Gpu::deviceToHost, d_freestream_phi.begin(), d_freestream_phi.end(), freestream_phi.begin());
143  Gpu::copy(Gpu::deviceToHost, d_disk_cell_count.begin(), d_disk_cell_count.end(), disk_cell_count.begin());
144 
145  // Reduce the data on every processor
146  amrex::ParallelAllReduce::Sum(freestream_velocity.data(),
147  freestream_velocity.size(),
148  amrex::ParallelContext::CommunicatorAll());
149 
150  amrex::ParallelAllReduce::Sum(freestream_phi.data(),
151  freestream_phi.size(),
152  amrex::ParallelContext::CommunicatorAll());
153 
154 
155  amrex::ParallelAllReduce::Sum(disk_cell_count.data(),
156  disk_cell_count.size(),
157  amrex::ParallelContext::CommunicatorAll());
158 
160 
161 
162  /*if (ParallelDescriptor::IOProcessor()){
163  for(int it=0; it<xloc.size(); it++){
164  std::cout << "turbine index, freestream velocity is " << it << " " << freestream_velocity[it] << " " <<
165  disk_cell_count[it] << " " <<
166  freestream_velocity[it]/(disk_cell_count[it] + 1e-10) << " " <<
167  freestream_phi[it]/(disk_cell_count[it] + 1e-10) << "\n";
168  }
169  }*/
170 }
amrex::Vector< amrex::Real > freestream_velocity
Definition: ERF_GeneralAD.H:51
amrex::Vector< amrex::Real > xloc
Definition: ERF_GeneralAD.H:47
amrex::Vector< amrex::Real > disk_cell_count
Definition: ERF_GeneralAD.H:51
amrex::Vector< amrex::Real > freestream_phi
Definition: ERF_GeneralAD.H:51
amrex::Vector< amrex::Real > yloc
Definition: ERF_GeneralAD.H:47
void get_turb_loc(amrex::Vector< amrex::Real > &xloc, amrex::Vector< amrex::Real > &yloc)
Definition: ERF_NullWindFarm.H:96

◆ compute_power_output()

void GeneralAD::compute_power_output ( const amrex::Real &  time)
32 {
36 
37  const int n_spec_table = wind_speed.size();
38  // Compute power based on the look-up table
39 
40  if (ParallelDescriptor::IOProcessor()){
41  static std::ofstream file("power_output_GeneralAD.txt", std::ios::app);
42  // Check if the file opened successfully
43  if (!file.is_open()) {
44  std::cerr << "Error opening file!" << std::endl;
45  Abort("Could not open file to write power output in ERF_AdvanceSimpleAD.cpp");
46  }
47  Real total_power = 0.0;
48  for(int it=0; it<xloc.size(); it++){
49  Real avg_vel = freestream_velocity[it]/(disk_cell_count[it] + 1e-10);
50  Real turb_power = interpolate_1d(wind_speed.data(), power.data(), avg_vel, n_spec_table);
51  total_power = total_power + turb_power;
52  }
53  file << time << " " << total_power << "\n";
54  file.flush();
55  }
56 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real interpolate_1d(const amrex::Real *alpha, const amrex::Real *beta, const amrex::Real alpha_interp, const int alpha_size)
Definition: ERF_Interpolation_1D.H:12
amrex::Vector< amrex::Real > wind_speed
Definition: ERF_GeneralAD.H:50
amrex::Vector< amrex::Real > power
Definition: ERF_GeneralAD.H:50
amrex::Vector< amrex::Real > thrust_coeff
Definition: ERF_GeneralAD.H:50
amrex::Real rotor_rad
Definition: ERF_GeneralAD.H:49
amrex::Real hub_height
Definition: ERF_GeneralAD.H:49
amrex::Real thrust_coeff_standing
Definition: ERF_GeneralAD.H:49
void get_turb_spec(amrex::Real &rotor_rad, amrex::Real &hub_height, amrex::Real &thrust_coeff_standing, amrex::Vector< amrex::Real > &wind_speed, amrex::Vector< amrex::Real > &thrust_coeff, amrex::Vector< amrex::Real > &power)
Definition: ERF_NullWindFarm.H:84
Here is the call graph for this function:

◆ source_terms_cellcentered()

void GeneralAD::source_terms_cellcentered ( const amrex::Geometry &  geom,
const amrex::MultiFab &  cons_in,
const amrex::MultiFab &  mf_Smark,
amrex::MultiFab &  mf_vars_generalAD 
)
321 {
322 
324 
327 
329 
331 
333 
334  Real d_hub_height = hub_height;
335  Real d_rotor_rad = rotor_rad;
336 
337  Gpu::DeviceVector<Real> d_xloc(xloc.size());
338  Gpu::DeviceVector<Real> d_yloc(yloc.size());
339  Gpu::copy(Gpu::hostToDevice, xloc.begin(), xloc.end(), d_xloc.begin());
340  Gpu::copy(Gpu::hostToDevice, yloc.begin(), yloc.end(), d_yloc.begin());
341 
342  auto dx = geom.CellSizeArray();
343 
344  // Domain valid box
345  const amrex::Box& domain = geom.Domain();
346  auto ProbLoArr = geom.ProbLoArray();
347  int domlo_x = domain.smallEnd(0);
348  int domhi_x = domain.bigEnd(0) + 1;
349  int domlo_y = domain.smallEnd(1);
350  int domhi_y = domain.bigEnd(1) + 1;
351  int domlo_z = domain.smallEnd(2);
352  int domhi_z = domain.bigEnd(2) + 1;
353 
354  // The order of variables are - Vabs dVabsdt, dudt, dvdt, dTKEdt
355  mf_vars_generalAD.setVal(0.0);
356 
357  long unsigned int nturbs = xloc.size();
358 
359  // This is the angle phi in Fig. 10 in Mirocha et. al. 2014
360  // set_turb_disk angle in ERF_InitWindFarm.cpp sets this phi as
361  // the turb_disk_angle
363  Real d_turb_disk_angle = turb_disk_angle;
364 
365  Gpu::DeviceVector<Real> d_freestream_velocity(nturbs);
366  Gpu::DeviceVector<Real> d_disk_cell_count(nturbs);
367  Gpu::copy(Gpu::hostToDevice, freestream_velocity.begin(), freestream_velocity.end(), d_freestream_velocity.begin());
368  Gpu::copy(Gpu::hostToDevice, disk_cell_count.begin(), disk_cell_count.end(), d_disk_cell_count.begin());
369 
370  Real* d_xloc_ptr = d_xloc.data();
371  Real* d_yloc_ptr = d_yloc.data();
372  Real* d_freestream_velocity_ptr = d_freestream_velocity.data();
373  Real* d_disk_cell_count_ptr = d_disk_cell_count.data();
374 
375  int n_bld_sections = bld_rad_loc.size();
376 
377  Gpu::DeviceVector<Real> d_bld_rad_loc(n_bld_sections);
378  Gpu::DeviceVector<Real> d_bld_twist(n_bld_sections);
379  Gpu::DeviceVector<Real> d_bld_chord(n_bld_sections);
380 
381  Gpu::copy(Gpu::hostToDevice, bld_rad_loc.begin(), bld_rad_loc.end(), d_bld_rad_loc.begin());
382  Gpu::copy(Gpu::hostToDevice, bld_twist.begin(), bld_twist.end(), d_bld_twist.begin());
383  Gpu::copy(Gpu::hostToDevice, bld_chord.begin(), bld_chord.end(), d_bld_chord.begin());
384 
385  Real* bld_rad_loc_ptr = d_bld_rad_loc.data();
386  Real* bld_twist_ptr = d_bld_twist.data();
387  Real* bld_chord_ptr = d_bld_chord.data();
388 
389  Vector<Gpu::DeviceVector<Real>> d_bld_airfoil_aoa(n_bld_sections);
390  Vector<Gpu::DeviceVector<Real>> d_bld_airfoil_Cl(n_bld_sections);
391  Vector<Gpu::DeviceVector<Real>> d_bld_airfoil_Cd(n_bld_sections);
392 
393  int n_pts_airfoil = bld_airfoil_aoa[0].size();
394 
395  for(int i=0;i<n_bld_sections;i++){
396  d_bld_airfoil_aoa[i].resize(n_pts_airfoil);
397  d_bld_airfoil_Cl[i].resize(n_pts_airfoil);
398  d_bld_airfoil_Cd[i].resize(n_pts_airfoil);
399  Gpu::copy(Gpu::hostToDevice, bld_airfoil_aoa[i].begin(), bld_airfoil_aoa[i].end(), d_bld_airfoil_aoa[i].begin());
400  Gpu::copy(Gpu::hostToDevice, bld_airfoil_Cl[i].begin(), bld_airfoil_Cl[i].end(), d_bld_airfoil_Cl[i].begin());
401  Gpu::copy(Gpu::hostToDevice, bld_airfoil_Cd[i].begin(), bld_airfoil_Cd[i].end(), d_bld_airfoil_Cd[i].begin());
402  }
403 
404  Vector<Real*> hp_bld_airfoil_aoa, hp_bld_airfoil_Cl, hp_bld_airfoil_Cd;
405  for (auto & v :d_bld_airfoil_aoa) {
406  hp_bld_airfoil_aoa.push_back(v.data());
407  }
408  for (auto & v :d_bld_airfoil_Cl) {
409  hp_bld_airfoil_Cl.push_back(v.data());
410  }
411  for (auto & v :d_bld_airfoil_Cd) {
412  hp_bld_airfoil_Cd.push_back(v.data());
413  }
414 
415  Gpu::AsyncArray<Real*> aoa(hp_bld_airfoil_aoa.data(), n_bld_sections);
416  Gpu::AsyncArray<Real*> Cl(hp_bld_airfoil_Cl.data(), n_bld_sections);
417  Gpu::AsyncArray<Real*> Cd(hp_bld_airfoil_Cd.data(), n_bld_sections);
418 
419  auto d_bld_airfoil_aoa_ptr = aoa.data();
420  auto d_bld_airfoil_Cl_ptr = Cl.data();
421  auto d_bld_airfoil_Cd_ptr = Cd.data();
422 
423  int n_spec_extra = velocity.size();
424 
425  Gpu::DeviceVector<Real> d_velocity(n_spec_extra);
426  Gpu::DeviceVector<Real> d_rotor_RPM(n_spec_extra);
427  Gpu::DeviceVector<Real> d_blade_pitch(n_spec_extra);
428 
429  Gpu::copy(Gpu::hostToDevice, velocity.begin(), velocity.end(), d_velocity.begin());
430  Gpu::copy(Gpu::hostToDevice, rotor_RPM.begin(), rotor_RPM.end(), d_rotor_RPM.begin());
431  Gpu::copy(Gpu::hostToDevice, blade_pitch.begin(), blade_pitch.end(), d_blade_pitch.begin());
432 
433  auto d_velocity_ptr = d_velocity.data();
434  auto d_rotor_RPM_ptr = d_rotor_RPM.data();
435  auto d_blade_pitch_ptr = d_blade_pitch.data();
436 
437  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
438 
439  const Box& gbx = mfi.growntilebox(1);
440  auto SMark_array = mf_SMark.array(mfi);
441  auto generalAD_array = mf_vars_generalAD.array(mfi);
442 
443  ParallelFor(gbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
444  int ii = amrex::min(amrex::max(i, domlo_x), domhi_x);
445  int jj = amrex::min(amrex::max(j, domlo_y), domhi_y);
446  int kk = amrex::min(amrex::max(k, domlo_z), domhi_z);
447 
448  Real x = ProbLoArr[0] + (ii+0.5)*dx[0];
449  Real y = ProbLoArr[1] + (jj+0.5)*dx[1];
450  Real z = ProbLoArr[2] + (kk+0.5)*dx[2];
451  // ?? Density needed here
452 
453  int check_int = 0;
454 
455  Real source_x = 0.0, source_y = 0.0, source_z = 0.0;
456  std::array<Real,2> Fn_and_Ft;
457 
458  for(long unsigned int it=0;it<nturbs;it++) {
459  Real avg_vel = d_freestream_velocity_ptr[it]/(d_disk_cell_count_ptr[it] + 1e-10);
460  Real phi = d_turb_disk_angle;
461 
462  // This if check makes sure it is a point on the actuator disk
463  if(SMark_array(ii,jj,kk,1) == static_cast<double>(it)) {
464  check_int++;
465 
466  // Find radial distance of the point and the zeta angle
467  Real rad = std::pow( (x-d_xloc_ptr[it])*(x-d_xloc_ptr[it]) +
468  (y-d_yloc_ptr[it])*(y-d_yloc_ptr[it]) +
469  (z-d_hub_height)*(z-d_hub_height), 0.5 );
470 
471  int index = find_rad_loc_index(rad, bld_rad_loc_ptr, n_bld_sections);
472 
473  // This if check makes sure it is a point with radial distance
474  // between the hub radius and the rotor radius.
475  // ?? hub radius needed here
476  if(rad >= 2.0 and rad <= d_rotor_rad) {
477  //AMREX_ASSERT( (z-d_hub_height) <= rad );
478  // Consider the vector that joines the point and the turbine center.
479  // Dot it on to the vector that joins the turbine center and along
480  // the plane of the disk. See fig. 10 in Mirocha et. al. 2014.
481 
482  Real vec_proj = (x-d_xloc_ptr[it])*(std::sin(phi)) +
483  (y-d_yloc_ptr[it])*(-std::cos(phi));
484 
485 
486  Real zeta = std::atan2(z-d_hub_height, vec_proj);
487  //printf("zeta val is %0.15g\n", zeta*180.0/PI);
488  Fn_and_Ft = compute_source_terms_Fn_Ft(rad, avg_vel,
489  bld_rad_loc_ptr,
490  bld_twist_ptr,
491  bld_chord_ptr,
492  n_bld_sections,
493  d_bld_airfoil_aoa_ptr[index],
494  d_bld_airfoil_Cl_ptr[index],
495  d_bld_airfoil_Cd_ptr[index],
496  n_pts_airfoil,
497  d_velocity_ptr,
498  d_rotor_RPM_ptr,
499  d_blade_pitch_ptr,
500  n_spec_extra);
501 
502  Real Fn = 3.0*Fn_and_Ft[0];
503  Real Ft = 3.0*Fn_and_Ft[1];
504  // Compute the source terms - pass in radial distance, free stream velocity
505 
506  Real Fx = Fn*std::cos(phi) + Ft*std::sin(zeta)*std::sin(phi);
507  Real Fy = Fn*std::sin(phi) - Ft*std::sin(zeta)*std::cos(phi);
508  Real Fz = -Ft*std::cos(zeta);
509 
510  //Real dn = (
511 
512  source_x = -Fx/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5);
513  source_y = -Fy/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5);
514  source_z = -Fz/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5);
515 
516 
517  //printf("Val source_x, is %0.15g, %0.15g, %0.15g %0.15g %0.15g %0.15g\n", rad, Fn, Ft, source_x, source_y, source_z);
518  }
519  }
520  }
521 
522  if(check_int > 1){
523  amrex::Error("Actuator disks are overlapping. Visualize actuator_disks.vtk "
524  "and check the windturbine locations input file. Exiting..");
525  }
526 
527  generalAD_array(i,j,k,0) = source_x;
528  generalAD_array(i,j,k,1) = source_y;
529  generalAD_array(i,j,k,2) = source_z;
530  });
531  }
532 }
AMREX_FORCE_INLINE AMREX_GPU_DEVICE int find_rad_loc_index(const Real rad, const Real *bld_rad_loc, const int n_bld_sections)
Definition: ERF_AdvanceGeneralAD.cpp:174
AMREX_FORCE_INLINE AMREX_GPU_DEVICE std::array< Real, 2 > compute_source_terms_Fn_Ft(const Real rad, const Real avg_vel, const Real *bld_rad_loc, const Real *bld_twist, const Real *bld_chord, int n_bld_sections, const Real *bld_airfoil_aoa, const Real *bld_airfoil_Cl, const Real *bld_airfoil_Cd, const int n_pts_airfoil, const Real *velocity, const Real *rotor_RPM, const Real *blade_pitch, const int n_spec_extra)
Definition: ERF_AdvanceGeneralAD.cpp:207
constexpr amrex::Real PI
Definition: ERF_Constants.H:6
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_Cl
Definition: ERF_GeneralAD.H:53
amrex::Vector< amrex::Real > velocity
Definition: ERF_GeneralAD.H:54
amrex::Vector< amrex::Real > blade_pitch
Definition: ERF_GeneralAD.H:54
amrex::Vector< amrex::Real > C_P
Definition: ERF_GeneralAD.H:54
amrex::Vector< amrex::Real > bld_twist
Definition: ERF_GeneralAD.H:52
amrex::Vector< amrex::Real > bld_chord
Definition: ERF_GeneralAD.H:52
amrex::Vector< amrex::Real > bld_rad_loc
Definition: ERF_GeneralAD.H:52
amrex::Real turb_disk_angle
Definition: ERF_GeneralAD.H:48
amrex::Vector< amrex::Real > C_T
Definition: ERF_GeneralAD.H:54
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_aoa
Definition: ERF_GeneralAD.H:53
amrex::Vector< amrex::Real > rotor_RPM
Definition: ERF_GeneralAD.H:54
amrex::Vector< amrex::Vector< amrex::Real > > bld_airfoil_Cd
Definition: ERF_GeneralAD.H:53
void get_turb_spec_extra(amrex::Vector< amrex::Real > &velocity, amrex::Vector< amrex::Real > &C_P, amrex::Vector< amrex::Real > &C_T, amrex::Vector< amrex::Real > &rotor_RPM, amrex::Vector< amrex::Real > &blade_pitch)
Definition: ERF_NullWindFarm.H:126
void get_blade_airfoil_spec(amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_aoa, amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cl, amrex::Vector< amrex::Vector< amrex::Real >> &bld_airfoil_Cd)
Definition: ERF_NullWindFarm.H:117
void get_turb_disk_angle(amrex::Real &turb_disk_angle)
Definition: ERF_NullWindFarm.H:103
void get_blade_spec(amrex::Vector< amrex::Real > &bld_rad_loc, amrex::Vector< amrex::Real > &bld_twist, amrex::Vector< amrex::Real > &bld_chord)
Definition: ERF_NullWindFarm.H:108
Here is the call graph for this function:

◆ update()

void GeneralAD::update ( const amrex::Real &  dt_advance,
amrex::MultiFab &  cons_in,
amrex::MultiFab &  U_old,
amrex::MultiFab &  V_old,
amrex::MultiFab &  W_old,
const amrex::MultiFab &  mf_vars 
)
66 {
67 
68  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
69 
70  Box tbx = mfi.nodaltilebox(0);
71  Box tby = mfi.nodaltilebox(1);
72  Box tbz = mfi.nodaltilebox(2);
73 
74  auto generalAD_array = mf_vars_generalAD.array(mfi);
75  auto u_vel = U_old.array(mfi);
76  auto v_vel = V_old.array(mfi);
77  auto w_vel = W_old.array(mfi);
78 
79  ParallelFor(tbx, tby, tbz,
80  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
81  {
82  u_vel(i,j,k) = u_vel(i,j,k) + (generalAD_array(i-1,j,k,0) + generalAD_array(i,j,k,0))/2.0*dt_advance;
83  },
84  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
85  {
86  v_vel(i,j,k) = v_vel(i,j,k) + (generalAD_array(i,j-1,k,1) + generalAD_array(i,j,k,1))/2.0*dt_advance;
87  },
88  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
89  {
90  w_vel(i,j,k) = w_vel(i,j,k) + (generalAD_array(i,j,k-1,2) + generalAD_array(i,j,k,2))/2.0*dt_advance;
91  });
92 
93  }
94 }

Member Data Documentation

◆ blade_pitch

amrex::Vector<amrex::Real> GeneralAD::blade_pitch
protected

◆ bld_airfoil_aoa

amrex::Vector<amrex::Vector<amrex::Real> > GeneralAD::bld_airfoil_aoa
protected

◆ bld_airfoil_Cd

amrex::Vector<amrex::Vector<amrex::Real> > GeneralAD::bld_airfoil_Cd
protected

◆ bld_airfoil_Cl

amrex::Vector<amrex::Vector<amrex::Real> > GeneralAD::bld_airfoil_Cl
protected

◆ bld_chord

amrex::Vector<amrex::Real> GeneralAD::bld_chord
protected

◆ bld_rad_loc

amrex::Vector<amrex::Real> GeneralAD::bld_rad_loc
protected

◆ bld_twist

amrex::Vector<amrex::Real> GeneralAD::bld_twist
protected

◆ C_P

amrex::Vector<amrex::Real> GeneralAD::C_P
protected

◆ C_T

amrex::Vector<amrex::Real> GeneralAD::C_T
protected

◆ disk_cell_count

amrex::Vector<amrex::Real> GeneralAD::disk_cell_count
protected

◆ freestream_phi

amrex::Vector<amrex::Real> GeneralAD::freestream_phi
protected

◆ freestream_velocity

amrex::Vector<amrex::Real> GeneralAD::freestream_velocity
protected

◆ hub_height

amrex::Real GeneralAD::hub_height
protected

◆ nominal_power

amrex::Real GeneralAD::nominal_power
protected

◆ power

amrex::Vector<amrex::Real> GeneralAD::power
protected

◆ rotor_rad

amrex::Real GeneralAD::rotor_rad
protected

◆ rotor_RPM

amrex::Vector<amrex::Real> GeneralAD::rotor_RPM
protected

◆ thrust_coeff

amrex::Vector<amrex::Real> GeneralAD::thrust_coeff
protected

◆ thrust_coeff_standing

amrex::Real GeneralAD::thrust_coeff_standing
protected

◆ turb_disk_angle

amrex::Real GeneralAD::turb_disk_angle
protected

◆ velocity

amrex::Vector<amrex::Real> GeneralAD::velocity
protected

◆ wind_speed

amrex::Vector<amrex::Real> GeneralAD::wind_speed
protected

◆ xloc

amrex::Vector<amrex::Real> GeneralAD::xloc
protected

◆ yloc

amrex::Vector<amrex::Real> GeneralAD::yloc
protected

The documentation for this class was generated from the following files: