Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
!MNH_LIC Copyright 1994-2021 CNRS, Meteo-France and Universite Paul Sabatier
!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
!MNH_LIC for details. version 1.
! #######################
MODULE MODI_EOL_MAIN
! #######################
!
INTERFACE
!
SUBROUTINE EOL_MAIN(KTCOUNT, PTSTEP, &
PDXX, PDYY, PDZZ, &
PRHODJ, PUT, PVT, PWT, &
PRUS, PRVS, PRWS )
!
INTEGER, INTENT(IN) :: KTCOUNT ! iteration count
REAL, INTENT(IN) :: PTSTEP ! timestep except
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ ! mesh size
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! dry Density * Jacobian
REAL, DIMENSION(:,:,:), INTENT(IN) :: PUT, PVT, PWT ! wind speed variables
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PRUS, PRVS, PRWS ! Sources of Momentum
!
END SUBROUTINE EOL_MAIN
!
END INTERFACE
!
END MODULE MODI_EOL_MAIN
!
! ###################################################################
SUBROUTINE EOL_MAIN(KTCOUNT, PTSTEP, &
PDXX, PDYY, PDZZ, &
PRHODJ, PUT, PVT, PWT, &
PRUS, PRVS, PRWS )
! ###################################################################
!
!!**** *EOL_MAIN * -
!!
!! PURPOSE
!! -------
!! It is possible to include wind turbines parameterization in Meso-NH,
!! and several models are available. EOL_MAIN is the main subroutine
!! to compute the aerodynamics of the wind turbine, according to the
!! model chosen.
!!
!!** METHOD
!! ------
!!
!! REFERENCE
!! ---------
!!
!!
!! AUTHOR
!! ------
!! PA. Joulin *CNRM & IFPEN*
!!
!! MODIFICATIONS
!! -------------
!! 21/10/20 Original
!!
!!---------------------------------------------------------------
!
!
!* 0. DECLARATIONS
! ------------
!
! To work with wind turbines
USE MODD_EOL_MAIN
USE MODI_EOL_ADNR
USE MODI_EOL_ALM
USE MODI_EOL_SMEAR
! To play with MPI
USE MODD_ARGSLIST_ll, ONLY: LIST_ll
USE MODE_ll , ONLY: ADD3DFIELD_ll
USE MODE_ll , ONLY: UPDATE_HALO_ll
USE MODE_ll , ONLY: CLEANLIST_ll
! To use some toolkit
USE MODI_SHUMAN , ONLY: MXF, MYF, MZF
USE MODI_SHUMAN , ONLY: MXM, MYM, MZM
!
use modd_budget, only: lbudget_u, lbudget_v, lbudget_w, NBUDGET_U, NBUDGET_V, NBUDGET_W, tbudgets
use mode_budget, only: budget_store_init, budget_store_end
!
!
IMPLICIT NONE
!
!* 0.1 Declarations of dummy arguments :
!
INTEGER, INTENT(IN) :: KTCOUNT ! iteration count
REAL, INTENT(IN) :: PTSTEP ! timestep except
REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ ! mesh size
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! dry Density * Jacobian
REAL, DIMENSION(:,:,:), INTENT(IN) :: PUT, PVT, PWT ! Wind speed
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PRUS, PRVS, PRWS ! Sources of Momentum
!
!
!* 0.2 Declarations of local variables :
!
! Pointeurs and exchanges
TYPE(LIST_ll), POINTER :: TZFIELDS_W_ll ! Field list of Wind for exchange
TYPE(LIST_ll), POINTER :: TZFIELDS_F_ll ! Field list of aero Forces for exchange
TYPE(LIST_ll), POINTER :: TZFIELDS_S_ll ! Field list of Smeared aero forces for exchange
TYPE(LIST_ll), POINTER :: TZFIELDS_R_ll ! Field list of mnh foRces for exchange
INTEGER :: IINFO ! Info integer
INTEGER :: IKU ! Vertical size of the domain
!
! ABL
REAL, DIMENSION(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)) :: ZUT_M, ZVT_M, ZWT_M ! Wind speed at mass point
REAL, DIMENSION(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)) :: ZRHO_M ! Air density at mass point
!
!
!* 0.3 Implicit arguments
!* From MODD_EOL_MAIN
! Aerodynamic forces in cartesian mesh
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFX_RG ! Along X in RG frame [F]
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFY_RG ! Along Y in RG frame [F]
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFZ_RG ! Along Z in RG frame [F]
! Smeared forces
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFX_SMR_RG ! Along X in RG frame [F]
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFY_SMR_RG ! Along Y in RG frame [F]
!REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFZ_SMR_RG ! ALong Z in RG frame [F]
!
!* From NAM_EOL namelist
!CHARACTER(LEN=4) :: CMETH_EOL ! Aerodynamic method
!CHARACTER(LEN=4) :: CSMEAR ! Type of smearing
!
!
!--------------------------------------------------------
!
!* 1. INITIALIZATIONS
! ---------------
!
!* 1.1 Indices
!
IKU = SIZE(PUT,3)
!
!* 1.2 Pointers
!
NULLIFY(TZFIELDS_W_ll)
NULLIFY(TZFIELDS_F_ll)
NULLIFY(TZFIELDS_S_ll)
NULLIFY(TZFIELDS_R_ll)
!
!* 1.3 Forces
!
XFX_RG(:,:,:) = 0.
XFY_RG(:,:,:) = 0.
XFZ_RG(:,:,:) = 0.
XFX_SMR_RG(:,:,:) = 0.
XFY_SMR_RG(:,:,:) = 0.
XFZ_SMR_RG(:,:,:) = 0.
!
!
!-----------------------------------------------------------------------
!
!* 2. COMPUTES VELOCITY COMPONENTS AND DENSITY AT MASS POINT
! ------------------------------------------------------
!
!* 2.1 Sharing the input
!
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PUT, 'EOL_MAIN::PUT')
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PWT, 'EOL_MAIN::PWT')
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PVT, 'EOL_MAIN::PVT')
CALL UPDATE_HALO_ll(TZFIELDS_W_ll,IINFO)
CALL CLEANLIST_ll( TZFIELDS_W_ll)
!
!* 2.2 Masss point evaluation
!
ZUT_M(:,:,:) = MXF( PUT(:,:,:) )
ZVT_M(:,:,:) = MYF( PVT(:,:,:) )
ZWT_M(:,:,:) = MZF( PWT(:,:,:) )
ZRHO_M(:,:,:) = PRHODJ(:,:,:)/(PDXX(:,:,:)*PDYY(:,:,:)*PDZZ(:,:,:))
!
!* 2.3 Sharing the new wind
!
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZUT_M, 'EOL_MAIN::ZUT_M')
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZWT_M, 'EOL_MAIN::ZWT_M')
CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZVT_M, 'EOL_MAIN::ZVT_M')
CALL UPDATE_HALO_ll(TZFIELDS_W_ll,IINFO)
CALL CLEANLIST_ll( TZFIELDS_W_ll)
!
!
!--------------------------------------------------------
!
!* 3. COMPUTES AERODYNAMICS FORCES
! ----------------------------
!
!* 3.1 Model selection
!
!
SELECT CASE(CMETH_EOL)
!
CASE('ADNR') ! Actuator Disc Non-Rotating
CALL EOL_ADNR(PDXX, PDYY, PDZZ, &
ZRHO_M, &
ZUT_M, &
XFX_RG )
!
CASE('ALM') ! Actuator Line Method
CALL EOL_ALM(KTCOUNT, PTSTEP, &
PDXX, PDYY, PDZZ, &
ZRHO_M, &
ZUT_M, ZVT_M, ZWT_M, &
XFX_RG, XFY_RG, XFZ_RG )
!
END SELECT
!
!* 3.2 Sharing 3D field
!
CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFX_RG, 'EOL_MAIN::XFX_RG' )
CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFY_RG, 'EOL_MAIN::XFY_RG' )
CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFZ_RG, 'EOL_MAIN::XFZ_RG' )
CALL UPDATE_HALO_ll(TZFIELDS_F_ll,IINFO)
CALL CLEANLIST_ll( TZFIELDS_F_ll)
!
!
!--------------------------------------------------------
!
!* 4. SMEARING THE FORCES
! -------------------
!
!* 4.1 Smearing technique selection
!
SELECT CASE (CSMEAR)
!
CASE( 'NULL' ) ! No smearing
XFX_SMR_RG(:,:,:) = XFX_RG(:,:,:)
XFY_SMR_RG(:,:,:) = XFY_RG(:,:,:)
XFZ_SMR_RG(:,:,:) = XFZ_RG(:,:,:)
!
CASE( '1LIN' ) ! Linear smearing
CALL SMEAR_1LIN(XFX_RG, &
XFX_SMR_RG)
!
CASE( '3LIN' ) ! Linear smearing
CALL SMEAR_3LIN(XFX_RG, &
XFY_RG, &
XFZ_RG, &
XFX_SMR_RG,&
XFY_SMR_RG,&
XFZ_SMR_RG)
!
END SELECT
!
!* 4.2 Sharing 3D field
!
CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFX_SMR_RG, 'EOL_MAIN::XFX_SMR_RG' )
CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFY_SMR_RG, 'EOL_MAIN::XFY_SMR_RG' )
CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFZ_SMR_RG, 'EOL_MAIN::XFZ_SMR_RG' )
CALL UPDATE_HALO_ll(TZFIELDS_S_ll,IINFO)
CALL CLEANLIST_ll( TZFIELDS_S_ll)
!
!
!-------------------------------------------------------------------------------
!
!* 5. ADDING THE FORCES TO THE FIELD
! ------------------------------
!
!* 5.1 Adding them to flux points, rotor->wind
!
if (lbudget_u) call Budget_store_init( tbudgets(NBUDGET_U), 'EOL', prus(:,:,:) )
if (lbudget_v) call Budget_store_init( tbudgets(NBUDGET_V), 'EOL', prvs(:,:,:) )
if (lbudget_w) call Budget_store_init( tbudgets(NBUDGET_W), 'EOL', prws(:,:,:) )
!
PRUS(:,:,:)=PRUS(:,:,:)-MXM(XFX_SMR_RG(:,:,:))
PRVS(:,:,:)=PRVS(:,:,:)-MYM(XFY_SMR_RG(:,:,:))
PRWS(:,:,:)=PRWS(:,:,:)-MZM(XFZ_SMR_RG(:,:,:))
!
if (lbudget_u) call Budget_store_end( tbudgets(NBUDGET_U), 'EOL', prus(:,:,:) )
if (lbudget_v) call Budget_store_end( tbudgets(NBUDGET_V), 'EOL', prvs(:,:,:) )
if (lbudget_w) call Budget_store_end( tbudgets(NBUDGET_W), 'EOL', prws(:,:,:) )
!
!
!* 5.2 Sharing the field
!
CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRUS,'EOL_MAIN::PRUS' )
CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRVS,'EOL_MAIN::PRVS' )
CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRWS,'EOL_MAIN::PRWS' )
CALL UPDATE_HALO_ll(TZFIELDS_R_ll,IINFO)
CALL CLEANLIST_ll( TZFIELDS_R_ll)
!
END SUBROUTINE EOL_MAIN