/home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/disk/disk_spreading.H Source File

AMR-Wind API: /home/runner/work/amr-wind/amr-wind/amr-wind/wind_energy/actuator/disk/disk_spreading.H Source File
AMR-Wind API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
disk_spreading.H
Go to the documentation of this file.
1#ifndef DISK_SPREADING_H_
2#define DISK_SPREADING_H_
3
7
9
18template <typename T>
20{
21public:
22 using OwnerType = T;
23
25 const T& actObj,
26 const int lev,
27 const amrex::MFIter& mfi,
28 const amrex::Geometry& geom)
29 {
30 (this->*m_function)(actObj, lev, mfi, geom);
31 }
32
34 void operator=(const SpreadingFunction&) = delete;
35
37 const T& actObj,
38 const int,
39 const amrex::MFIter&,
40 const amrex::Geometry&);
41
43 const T& actObj,
44 const int lev,
45 const amrex::MFIter& mfi,
46 const amrex::Geometry& geom)
47 {
48 const auto& bx = mfi.tilebox();
49
50 const auto bxa = amr_wind::utils::realbox_to_box(
51 actObj.m_data.info().bound_box, geom);
52 const auto& bxi = bx & bxa;
53 if (bxi.isEmpty()) {
54 return;
55 }
56
57 const auto& sarr = actObj.m_act_src(lev).array(mfi);
58 const auto& problo = geom.ProbLoArray();
59 const auto& dx = geom.CellSizeArray();
60
61 const auto& data = actObj.m_data.meta();
62
63 const vs::Vector epsilon = vs::Vector::one() * data.epsilon;
64 const vs::Vector m_normal(data.normal_vec);
65 const auto* pos = actObj.m_pos.data();
66 const auto* force = actObj.m_force.data();
67 const int npts = data.num_force_pts;
68 const int nForceTheta = data.num_force_theta_pts;
69 const auto dTheta = ::amr_wind::utils::two_pi() / nForceTheta;
70
71 amrex::ParallelFor(
72 bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
73 const vs::Vector cc{
74 problo[0] + (i + 0.5) * dx[0],
75 problo[1] + (j + 0.5) * dx[1],
76 problo[2] + (k + 0.5) * dx[2],
77 };
78
79 amrex::RealArray src_force = {0.0};
80 for (int ip = 0; ip < npts; ++ip) {
81 const auto& pforce = force[ip] / nForceTheta;
82 const auto pLoc = pos[ip];
83
84 for (int it = 0; it < nForceTheta; ++it) {
85 const amrex::Real angle =
86 ::amr_wind::utils::degrees(it * dTheta);
87 const auto rotMatrix = vs::quaternion(m_normal, angle);
88 const auto diskPoint = pLoc & rotMatrix;
89 const auto distance = diskPoint - cc;
90 const auto projection_weight =
91 utils::gaussian3d(distance, epsilon);
92
93 src_force[0] += projection_weight * pforce.x();
94 src_force[1] += projection_weight * pforce.y();
95 src_force[2] += projection_weight * pforce.z();
96 }
97 }
98
99 sarr(i, j, k, 0) += src_force[0];
100 sarr(i, j, k, 1) += src_force[1];
101 sarr(i, j, k, 2) += src_force[2];
102 });
103 }
104
106 const T& actObj,
107 const int lev,
108 const amrex::MFIter& mfi,
109 const amrex::Geometry& geom)
110 {
111 const auto& bx = mfi.tilebox();
112
113 const auto bxa = amr_wind::utils::realbox_to_box(
114 actObj.m_data.info().bound_box, geom);
115 const auto& bxi = bx & bxa;
116 if (bxi.isEmpty()) {
117 return;
118 }
119
120 const auto& sarr = actObj.m_act_src(lev).array(mfi);
121 const auto& problo = geom.ProbLoArray();
122 const auto& dx = geom.CellSizeArray();
123
124 const auto& data = actObj.m_data.meta();
125
126 const amrex::Real dR = data.dr;
127 const amrex::Real epsilon = data.epsilon;
128 const vs::Vector m_normal(data.normal_vec);
129 const vs::Vector m_origin(data.center);
130 const auto* pos = actObj.m_pos.data();
131 const auto* force = actObj.m_force.data();
132 const int npts = data.num_force_pts;
133
134 amrex::ParallelFor(
135 bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
136 const vs::Vector cc{
137 problo[0] + (i + 0.5) * dx[0],
138 problo[1] + (j + 0.5) * dx[1],
139 problo[2] + (k + 0.5) * dx[2],
140 };
141
142 amrex::RealArray src_force = {0.0};
143 for (int ip = 0; ip < npts; ++ip) {
144 const auto R = utils::delta_pnts_cyl(
145 m_origin, m_normal, m_origin, pos[ip])
146 .x();
147 const auto dist_on_disk =
148 utils::delta_pnts_cyl(m_origin, m_normal, cc, pos[ip]);
149 const auto& pforce = force[ip];
150
151 const amrex::Real weight_R =
152 utils::linear_basis_1d(dist_on_disk.x(), dR);
153 const amrex::Real weight_T =
154 1.0 / (::amr_wind::utils::two_pi() * R);
155 const amrex::Real weight_N =
156 utils::gaussian1d(dist_on_disk.z(), epsilon);
157 const auto projection_weight =
158 weight_R * weight_T * weight_N;
159
160 src_force[0] += projection_weight * pforce.x();
161 src_force[1] += projection_weight * pforce.y();
162 src_force[2] += projection_weight * pforce.z();
163 }
164
165 sarr(i, j, k, 0) += src_force[0];
166 sarr(i, j, k, 1) += src_force[1];
167 sarr(i, j, k, 2) += src_force[2];
168 });
169 }
171 const T& actObj,
172 const int lev,
173 const amrex::MFIter& mfi,
174 const amrex::Geometry& geom)
175 {
176 const auto& bx = mfi.tilebox();
177
178 const auto bxa = amr_wind::utils::realbox_to_box(
179 actObj.m_data.info().bound_box, geom);
180 const auto& bxi = bx & bxa;
181 if (bxi.isEmpty()) {
182 return;
183 }
184
185 const auto& sarr = actObj.m_act_src(lev).array(mfi);
186 const auto& problo = geom.ProbLoArray();
187 const auto& dx = geom.CellSizeArray();
188
189 const auto& data = actObj.m_data.meta();
190
191 const amrex::Real dR = data.dr;
192 const amrex::Real dTheta =
193 ::amr_wind::utils::two_pi() / data.num_vel_pts_t;
194 const amrex::Real epsilon = data.epsilon;
195 const vs::Vector m_normal(data.normal_vec);
196 const vs::Vector m_origin(data.center);
197 const auto* pos = actObj.m_pos.data();
198 const auto* force = actObj.m_force.data();
199 const int npts = data.num_force_pts;
200
201 amrex::ParallelFor(
202 bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
203 const vs::Vector cc{
204 problo[0] + (i + 0.5) * dx[0],
205 problo[1] + (j + 0.5) * dx[1],
206 problo[2] + (k + 0.5) * dx[2],
207 };
208
209 amrex::RealArray src_force = {0.0};
210 for (int ip = 0; ip < npts; ++ip) {
211 const auto radius =
213 m_origin, m_normal, m_origin, pos[ip])
214 .x();
215 const auto dArc = radius * dTheta;
216 const auto dist_on_disk =
217 utils::delta_pnts_cyl(m_origin, m_normal, cc, pos[ip]);
218 const amrex::Real arclength = dist_on_disk.y() * radius;
219 const auto& pforce = force[ip];
220
221 const amrex::Real weight_R =
222 utils::linear_basis_1d(dist_on_disk.x(), dR);
223 const amrex::Real weight_T =
224 utils::linear_basis_1d(arclength, dArc);
225 const amrex::Real weight_N =
226 utils::gaussian1d(dist_on_disk.z(), epsilon);
227 const auto projection_weight =
228 weight_R * weight_T * weight_N;
229
230 src_force[0] += projection_weight * pforce.x();
231 src_force[1] += projection_weight * pforce.y();
232 src_force[2] += projection_weight * pforce.z();
233 }
234
235 sarr(i, j, k, 0) += src_force[0];
236 sarr(i, j, k, 1) += src_force[1];
237 sarr(i, j, k, 2) += src_force[2];
238 });
239 }
240
243 void initialize(const std::string& key)
244 {
245 if (std::is_same<UniformCt, typename OwnerType::TraitType>::value) {
246 if (key == "UniformGaussian") {
248 } else if (key == "LinearBasis") {
250 } else {
251 amrex::Abort("Invalid spreading type");
252 }
253 } else {
255 }
256 }
257};
258} // namespace amr_wind::actuator::ops
259#endif /* DISK_SPREADING_H_ */
A collection of spreading functions This class allows for polymorphic spreading functions....
Definition disk_spreading.H:20
void linear_basis_spreading(const T &actObj, const int lev, const amrex::MFIter &mfi, const amrex::Geometry &geom)
Definition disk_spreading.H:105
SpreadingFunction()
Definition disk_spreading.H:241
void linear_basis_in_theta(const T &actObj, const int lev, const amrex::MFIter &mfi, const amrex::Geometry &geom)
Definition disk_spreading.H:170
void uniform_gaussian_spreading(const T &actObj, const int lev, const amrex::MFIter &mfi, const amrex::Geometry &geom)
Definition disk_spreading.H:42
T OwnerType
Definition disk_spreading.H:22
void initialize(const std::string &key)
Definition disk_spreading.H:243
SpreadingFunction(const SpreadingFunction &)=delete
void operator()(const T &actObj, const int lev, const amrex::MFIter &mfi, const amrex::Geometry &geom)
Definition disk_spreading.H:24
void(SpreadingFunction::* m_function)(const T &actObj, const int, const amrex::MFIter &, const amrex::Geometry &)
Definition disk_spreading.H:36
void operator=(const SpreadingFunction &)=delete
Definition ActSrcLineOp.H:9
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE vs::Vector delta_pnts_cyl(const vs::Vector &origin, const vs::Vector &normal, const vs::Vector &point1, const vs::Vector &point2)
Definition actuator_utils.H:86
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real gaussian3d(const vs::Vector &dist, const vs::Vector &eps)
Definition actuator_utils.H:43
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real gaussian1d(const amrex::Real &dist, const amrex::Real &eps)
Definition actuator_utils.H:68
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real linear_basis_1d(const amrex::Real distance, const amrex::Real dX)
Definition actuator_utils.H:126
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 amrex::Real degrees(const amrex::Real rad_val)
Convert from radians to degrees.
Definition trig_ops.H:42
amrex::Box realbox_to_box(const amrex::RealBox &rbx, const amrex::Geometry &geom)
Definition index_operations.cpp:5
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Tensor quaternion(const Vector &axis, const amrex::Real angle)
Definition tensorI.H:215
Definition vector.H:13
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr VectorT< T > one()
Definition vector.H:50
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T & x() &noexcept
Definition vector.H:97