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

#include <ERF_EWP.H>

Inheritance diagram for EWP:
Collaboration diagram for EWP:

Public Member Functions

 EWP ()
 
virtual ~EWP ()=default
 
void advance (const amrex::Geometry &geom, const double &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &mf_vars_ewp, amrex::MultiFab &U_old, amrex::MultiFab &V_old, amrex::MultiFab &W_old, const amrex::MultiFab &mf_Nturb, const amrex::MultiFab &mf_SMark, const double &time) override
 
void source_terms_cellcentered (const amrex::Geometry &geom, const amrex::MultiFab &cons_in, amrex::MultiFab &mf_vars, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &W_old, const amrex::MultiFab &mf_Nturb)
 
void update (const double &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &U_old, amrex::MultiFab &V_old, const amrex::MultiFab &mf_vars_ewp)
 
void compute_power_output (const amrex::MultiFab &cons_in, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &W_old, const amrex::MultiFab &mf_SMark, const amrex::MultiFab &mf_Nturb, const double &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::Realxloc
 
amrex::Vector< amrex::Realyloc
 
amrex::Real hub_height
 
amrex::Real rotor_rad
 
amrex::Real thrust_coeff_standing
 
amrex::Real nominal_power
 
amrex::Vector< amrex::Realwind_speed
 
amrex::Vector< amrex::Realthrust_coeff
 
amrex::Vector< amrex::Realpower
 
- Protected Attributes inherited from NullWindFarm
amrex::Vector< amrex::Realm_xloc
 
amrex::Vector< amrex::Realm_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::Realm_wind_speed
 
amrex::Vector< amrex::Realm_thrust_coeff
 
amrex::Vector< amrex::Realm_power
 
amrex::Vector< amrex::Realm_bld_rad_loc
 
amrex::Vector< amrex::Realm_bld_twist
 
amrex::Vector< amrex::Realm_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::Realm_velocity
 
amrex::Vector< amrex::Realm_C_P
 
amrex::Vector< amrex::Realm_C_T
 
amrex::Vector< amrex::Realm_rotor_RPM
 
amrex::Vector< amrex::Realm_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

◆ EWP()

EWP::EWP ( )
inline
13 {}

◆ ~EWP()

virtual EWP::~EWP ( )
virtualdefault

Member Function Documentation

◆ advance()

void EWP::advance ( const amrex::Geometry &  geom,
const double &  dt_advance,
amrex::MultiFab &  cons_in,
amrex::MultiFab &  mf_vars_ewp,
amrex::MultiFab &  U_old,
amrex::MultiFab &  V_old,
amrex::MultiFab &  W_old,
const amrex::MultiFab &  mf_Nturb,
const amrex::MultiFab &  mf_SMark,
const double &  time 
)
overridevirtual

Implements NullWindFarm.

20  {
21  AMREX_ALWAYS_ASSERT(mf_SMark.nComp() > 0);
22  AMREX_ALWAYS_ASSERT(time > -one);
23  source_terms_cellcentered(geom, cons_in, mf_vars_ewp, U_old, V_old, W_old, mf_Nturb);
24  update(dt_advance, cons_in, U_old, V_old, mf_vars_ewp);
25  compute_power_output(cons_in, U_old, V_old, W_old, mf_SMark, mf_Nturb, time);
26 }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
void source_terms_cellcentered(const amrex::Geometry &geom, const amrex::MultiFab &cons_in, amrex::MultiFab &mf_vars, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &W_old, const amrex::MultiFab &mf_Nturb)
Definition: ERF_AdvanceEWP.cpp:134
void compute_power_output(const amrex::MultiFab &cons_in, const amrex::MultiFab &U_old, const amrex::MultiFab &V_old, const amrex::MultiFab &W_old, const amrex::MultiFab &mf_SMark, const amrex::MultiFab &mf_Nturb, const double &time)
Definition: ERF_AdvanceEWP.cpp:30
void update(const double &dt_advance, amrex::MultiFab &cons_in, amrex::MultiFab &U_old, amrex::MultiFab &V_old, const amrex::MultiFab &mf_vars_ewp)
Definition: ERF_AdvanceEWP.cpp:100
Here is the call graph for this function:

◆ compute_power_output()

void EWP::compute_power_output ( const amrex::MultiFab &  cons_in,
const amrex::MultiFab &  U_old,
const amrex::MultiFab &  V_old,
const amrex::MultiFab &  W_old,
const amrex::MultiFab &  mf_SMark,
const amrex::MultiFab &  mf_Nturb,
const double &  time 
)
37 {
41 
42  const int n_spec_table = static_cast<int>(wind_speed.size());
43 
44  Gpu::DeviceVector<Real> d_wind_speed(wind_speed.size());
45  Gpu::DeviceVector<Real> d_power(wind_speed.size());
46  Gpu::copy(Gpu::hostToDevice, wind_speed.begin(), wind_speed.end(), d_wind_speed.begin());
47  Gpu::copy(Gpu::hostToDevice, power.begin(), power.end(), d_power.begin());
48 
49  Gpu::DeviceScalar<Real> d_total_power(zero);
50  Real* d_total_power_ptr = d_total_power.dataPtr();
51 
52  const Real* d_wind_speed_ptr = d_wind_speed.dataPtr();
53  const Real* d_power_ptr = d_power.dataPtr();
54 
55  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
56 
57  auto SMark_array = mf_SMark.array(mfi);
58  auto Nturb_array = mf_Nturb.array(mfi);
59  auto u_vel = U_old.array(mfi);
60  auto v_vel = V_old.array(mfi);
61  auto w_vel = W_old.array(mfi);
62  // NOTE: this reduction is driven by the cell-centered SMark/Nturb, so it
63  // must run over the cell-centered tilebox. Using nodaltilebox(0)
64  // here would include the plane at bigEnd(0)+1, which is a ghost
65  // cell of this box and a valid cell of its x-neighbor, and so
66  // would count that plane twice in the power sum below.
67  Box tbx = mfi.tilebox();
68 
69  ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
70 
71  if(SMark_array(i,j,k,0) == one) {
72  Real avg_vel = std::pow(u_vel(i,j,k)*u_vel(i,j,k) +
73  v_vel(i,j,k)*v_vel(i,j,k) +
74  w_vel(i,j,k)*w_vel(i,j,k),myhalf);
75  Real turb_power = interpolate_1d(d_wind_speed_ptr, d_power_ptr, avg_vel, n_spec_table);
76  turb_power = turb_power*Nturb_array(i,j,k,0);
77  Gpu::Atomic::Add(d_total_power_ptr,turb_power);
78  }
79  });
80  }
81 
82  Real h_total_power = zero;
83  Gpu::copy(Gpu::deviceToHost, d_total_power.dataPtr(), d_total_power.dataPtr()+1, &h_total_power);
84 
85  amrex::ParallelAllReduce::Sum(&h_total_power, 1, amrex::ParallelContext::CommunicatorAll());
86 
87  if (ParallelDescriptor::IOProcessor()){
88  static std::ofstream file("power_output_EWP.txt", std::ios::app);
89  // Check if the file opened successfully
90  if (!file.is_open()) {
91  std::cerr << "Error opening file!" << std::endl;
92  Abort("Could not open file to write power output in ERF_AdvanceSimpleAD.cpp");
93  }
94  file << time << " " << h_total_power << "\n";
95  file.flush();
96  }
97 }
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:14
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
amrex::Real Real
Definition: ERF_ShocInterface.H:19
amrex::Real thrust_coeff_standing
Definition: ERF_EWP.H:52
amrex::Real hub_height
Definition: ERF_EWP.H:52
amrex::Vector< amrex::Real > wind_speed
Definition: ERF_EWP.H:53
amrex::Vector< amrex::Real > xloc
Definition: ERF_EWP.H:51
amrex::Vector< amrex::Real > thrust_coeff
Definition: ERF_EWP.H:53
amrex::Vector< amrex::Real > power
Definition: ERF_EWP.H:53
amrex::Real rotor_rad
Definition: ERF_EWP.H:52
amrex::Vector< amrex::Real > yloc
Definition: ERF_EWP.H:51
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
void get_turb_loc(amrex::Vector< amrex::Real > &xloc, amrex::Vector< amrex::Real > &yloc)
Definition: ERF_NullWindFarm.H:96
Here is the call graph for this function:

◆ source_terms_cellcentered()

void EWP::source_terms_cellcentered ( const amrex::Geometry &  geom,
const amrex::MultiFab &  cons_in,
amrex::MultiFab &  mf_vars,
const amrex::MultiFab &  U_old,
const amrex::MultiFab &  V_old,
const amrex::MultiFab &  W_old,
const amrex::MultiFab &  mf_Nturb 
)
141 {
142 
145 
146  auto dx = geom.CellSizeArray();
147  auto ProbLoArr = geom.ProbLoArray();
148  Real sigma_0 = Real(1.7)*rotor_rad;
149 
150  Real d_rotor_rad = rotor_rad;
151  Real d_hub_height = hub_height;
152 
153  Gpu::DeviceVector<Real> d_wind_speed(wind_speed.size());
154  Gpu::DeviceVector<Real> d_thrust_coeff(thrust_coeff.size());
155 
156  // Copy data from host vectors to device vectors
157  Gpu::copy(Gpu::hostToDevice, wind_speed.begin(), wind_speed.end(), d_wind_speed.begin());
158  Gpu::copy(Gpu::hostToDevice, thrust_coeff.begin(), thrust_coeff.end(), d_thrust_coeff.begin());
159 
160 
161  // Domain valid box
162  const amrex::Box& domain = geom.Domain();
163  int domlo_z = domain.smallEnd(2);
164  int domhi_z = domain.bigEnd(2) + 1;
165 
166  // The order of variables are - Vabs dVabsdt, dudt, dvdt, dTKEdt
167  mf_vars_ewp.setVal(0.0);
168 
169  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
170 
171  const Box& gbx = mfi.growntilebox(1);
172  auto ewp_array = mf_vars_ewp.array(mfi);
173  auto Nturb_array = mf_Nturb.array(mfi);
174  auto u_vel = U_old.array(mfi);
175  auto v_vel = V_old.array(mfi);
176  auto w_vel = W_old.array(mfi);
177 
178  const Real* wind_speed_d = d_wind_speed.dataPtr();
179  const Real* thrust_coeff_d = d_thrust_coeff.dataPtr();
180  const int n_spec_table = static_cast<int>(d_wind_speed.size());
181 
182  ParallelFor(gbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
183 
184  int kk = amrex::min(amrex::max(k, domlo_z), domhi_z);
185  Real z = ProbLoArr[2] + (kk+myhalf) * dx[2];
186 
187  // Compute Fitch source terms
188 
189  Real Vabs = std::pow(u_vel(i,j,k)*u_vel(i,j,k) +
190  v_vel(i,j,k)*v_vel(i,j,k) +
191  w_vel(i,j,kk)*w_vel(i,j,kk), myhalf);
192 
193  Real C_T = interpolate_1d(wind_speed_d, thrust_coeff_d, Vabs, n_spec_table);
194 
195  Real C_TKE = zero;
196  Real K_turb = Real(6.0);
197 
198  Real L_wake = std::pow(dx[0]*dx[1],myhalf)/two;
199  Real sigma_e = Vabs/(three*K_turb*L_wake)*
200  (std::pow(two*K_turb*L_wake/Vabs + std::pow(sigma_0,2),three/two) - amrex::Math::powi<3>(sigma_0));
201 
202  Real phi = std::atan2(v_vel(i,j,k),u_vel(i,j,k)); // Wind direction w.r.t the x-dreiction
203  Real fac = -std::pow(PI/Real(8.0),myhalf)*C_T*amrex::Math::powi<2>(d_rotor_rad)*
204  amrex::Math::powi<2>(Vabs)/(dx[0]*dx[1]*sigma_e)*
205  std::exp(-myhalf*amrex::Math::powi<2>((z - d_hub_height)/sigma_e));
206  ewp_array(i,j,k,0) = fac*std::cos(phi)*Nturb_array(i,j,k);
207  ewp_array(i,j,k,1) = fac*std::sin(phi)*Nturb_array(i,j,k);
208  ewp_array(i,j,k,2) = C_TKE*zero;
209  });
210  }
211 }
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
constexpr amrex::Real three
Definition: ERF_NumericalConstants.H:32
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
Here is the call graph for this function:

◆ update()

void EWP::update ( const double &  dt_advance,
amrex::MultiFab &  cons_in,
amrex::MultiFab &  U_old,
amrex::MultiFab &  V_old,
const amrex::MultiFab &  mf_vars_ewp 
)
104 {
105 
106  for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
107 
108  Box bx = mfi.tilebox();
109  Box tbx = mfi.nodaltilebox(0);
110  Box tby = mfi.nodaltilebox(1);
111 
112  auto cons_array = cons_in.array(mfi);
113  auto ewp_array = mf_vars_ewp.array(mfi);
114  auto u_vel = U_old.array(mfi);
115  auto v_vel = V_old.array(mfi);
116 
117  ParallelFor(tbx, tby, bx,
118  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
119  {
120  u_vel(i,j,k) = u_vel(i,j,k) + (ewp_array(i-1,j,k,0) + ewp_array(i,j,k,0))/two*dt_advance;
121  },
122  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
123  {
124  v_vel(i,j,k) = v_vel(i,j,k) + (ewp_array(i,j-1,k,1) + ewp_array(i,j,k,1))/two*dt_advance;
125  },
126  [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
127  {
128  cons_array(i,j,k,RhoKE_comp) = cons_array(i,j,k,RhoKE_comp) + ewp_array(i,j,k,2)*dt_advance;
129  });
130  }
131 }
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
Here is the call graph for this function:

Member Data Documentation

◆ hub_height

amrex::Real EWP::hub_height
protected

◆ nominal_power

amrex::Real EWP::nominal_power
protected

◆ power

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

◆ rotor_rad

amrex::Real EWP::rotor_rad
protected

◆ thrust_coeff

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

◆ thrust_coeff_standing

amrex::Real EWP::thrust_coeff_standing
protected

◆ wind_speed

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

◆ xloc

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

◆ yloc

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

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