source: palm/trunk/SOURCE/ls_forcing.f90 @ 1239

Last change on this file since 1239 was 1239, checked in by heinze, 8 years ago

routines for nudging and large scale forcing from external file added

  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1 MODULE ls_forcing_mod
2
3!--------------------------------------------------------------------------------!
4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2012  Leibniz University Hannover
18!--------------------------------------------------------------------------------!
19!
20! Current revisions:
21! ------------------
22!
23!
24! Former revisions:
25! -----------------
26! $Id: ls_forcing.f90 1239 2013-10-29 10:11:53Z heinze $
27!
28!
29! Description:
30! ------------
31! Calculates large scale forcings (geostrophic wind and subsidence velocity) as
32! well as surfaces fluxes dependend on time given in an external file (LSF_DATA).
33! Code is based in parts on DALES and UCLA-LES.
34!--------------------------------------------------------------------------------!
35
36    PRIVATE
37    PUBLIC init_ls_forcing, ls_forcing_surf, ls_forcing_vert
38    SAVE
39
40
41 CONTAINS
42
43    SUBROUTINE init_ls_forcing
44
45       USE arrays_3d
46       USE control_parameters
47       USE cpulog
48       USE indices
49       USE interfaces
50       USE pegrid
51       USE user
52
53       IMPLICIT NONE
54
55       INTEGER :: finput = 90, ierrn, k, t
56       CHARACTER (100):: chmess
57       CHARACTER(1) :: hash
58       REAL :: r_dummy, fac
59       REAL :: highheight, highug_vert, highvg_vert, highwsubs_vert
60       REAL :: lowheight, lowug_vert, lowvg_vert, lowwsubs_vert
61
62       ALLOCATE( p_surf(0:nlsf), pt_surf(0:nlsf), q_surf(0:nlsf),         &
63                 qsws_surf(0:nlsf), shf_surf(0:nlsf), time_vert(0:nlsf),  &
64                 time_surf(0:nlsf), ug_vert(nzb:nzt+1,0:nlsf),            &
65                 vg_vert(nzb:nzt+1,0:nlsf), wsubs_vert(nzb:nzt+1,0:nlsf) )
66
67       p_surf = 0.0; pt_surf = 0.0; q_surf = 0.0; qsws_surf = 0.0
68       shf_surf = 0.0; time_vert = 0.0; time_surf = 0.0; ug_vert = 0.0
69       vg_vert = 0.0; wsubs_vert = 0.0
70
71
72       OPEN (finput, FILE='LSF_DATA', STATUS='OLD', &
73              FORM='FORMATTED', IOSTAT=ierrn)
74
75       IF (ierrn /= 0 ) THEN
76          message_string = 'file LSF_DATA does not exist'
77          CALL message( 'ls_forcing', 'PA0368', 1, 2, 0, 6, 0 )
78       ENDIF
79
80       ierrn = 0
81!
82!--    First three lines of LSF_DATA contain header
83       READ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess
84       READ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess
85       READ( finput, FMT='(a100)', IOSTAT=ierrn ) chmess
86
87       IF (ierrn /= 0 ) THEN
88          message_string = 'errors in file LSF_DATA'
89          CALL message( 'ls_forcing', 'PA0369', 1, 2, 0, 6, 0 )
90       ENDIF
91
92!
93!--    Surface values are read in
94       t     = 0
95       ierrn = 0
96
97       DO WHILE ( time_surf(t) < end_time )
98          t = t + 1
99          READ( finput, *, IOSTAT = ierrn ) time_surf(t), shf_surf(t), &
100                                             qsws_surf(t), pt_surf(t),  &
101                                             q_surf(t), p_surf(t)
102
103          IF ( ierrn < 0 ) THEN
104            WRITE( message_string, * ) 'No time dependend surface variables ',&
105                              'in&LSF_DATA for end of run found'
106
107             CALL message( 'ls_forcing', 'PA0370', 1, 2, 0, 6, 0 )
108          ENDIF
109       ENDDO
110
111
112       IF ( time_surf(1) > end_time ) THEN
113          WRITE( message_string, * ) 'No time dependend surface variables in ',  &
114                                     '&LSF_DATA for end of run found - ',  &
115                                     'lsf_surf is set to FALSE'
116          CALL message( 'ls_forcing', 'PA0371', 0, 0, 0, 6, 0 )
117          lsf_surf = .FALSE.
118       ENDIF
119
120!
121!--    Go to the end of the list with surface variables
122       DO WHILE ( ierrn == 0 )
123          READ (finput, *, IOSTAT = ierrn) r_dummy
124       ENDDO
125
126!
127!--    Profiles of ug, vg and w_subs are read in (large scale forcing)
128
129       t = 0
130       DO WHILE (time_vert(t) < end_time)
131          t = t + 1
132          hash = "#"
133          ierrn = 1 ! not zero
134!
135!--       Search for the next line consisting of "# time",
136!--       from there onwards the profiles will be read
137          DO WHILE ( .NOT. ( hash == "#" .AND. ierrn == 0 ) ) 
138             READ( finput, *, IOSTAT=ierrn ) hash, time_vert(t)
139             IF ( ierrn < 0 ) THEN
140                WRITE( message_string, * ) 'No time dependend vertical profiles',&
141                                 ' in&LSF_DATA for end of run found'
142                CALL message( 'ls_forcing', 'PA0372', 1, 2, 0, 6, 0 )
143             ENDIF
144          ENDDO
145
146          IF ( t == 1 .AND. time_vert(t) > end_time ) EXIT
147
148          READ( finput, *, IOSTAT=ierrn ) lowheight, lowug_vert, lowvg_vert, &
149                                          lowwsubs_vert
150          IF (ierrn /= 0 ) THEN
151             message_string = 'errors in file LSF_DATA'
152             CALL message( 'nudging', 'PA0369', 1, 2, 0, 6, 0 )
153          ENDIF
154
155          READ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, highvg_vert, &
156                                          highwsubs_vert
157     
158          IF (ierrn /= 0 ) THEN
159             message_string = 'errors in file LSF_DATA'
160             CALL message( 'nudging', 'PA0369', 1, 2, 0, 6, 0 )
161          ENDIF
162
163          DO  k = nzb, nzt+1
164             IF ( highheight < zu(k) ) THEN
165                lowheight     = highheight
166                lowug_vert    = highug_vert
167                lowvg_vert    = highvg_vert
168                lowwsubs_vert = highwsubs_vert
169
170                ierrn = 0
171                READ( finput, *, IOSTAT=ierrn ) highheight, highug_vert, &
172                                                highvg_vert, highwsubs_vert
173
174                IF (ierrn /= 0 ) THEN
175                   message_string = 'errors in file LSF_DATA'
176                   CALL message( 'nudging', 'PA0369', 1, 2, 0, 6, 0 )
177                ENDIF
178
179             ENDIF
180
181!
182!--          Interpolation of prescribed profiles in space
183             fac = (highheight-zu(k))/(highheight - lowheight)
184
185             ug_vert(k,t)    = fac*lowug_vert    + (1-fac)*highug_vert
186             vg_vert(k,t)    = fac*lowvg_vert    + (1-fac)*highvg_vert
187             wsubs_vert(k,t) = fac*lowwsubs_vert + (1-fac)*highwsubs_vert
188
189          ENDDO
190
191       ENDDO
192
193       IF ( time_vert(1) > end_time ) THEN
194          WRITE( message_string, * ) 'Time dependent large scale profile ',&
195                            'forcing from&LSF_DATA sets in after end of ' ,&
196                            'simulation - lsf_vert is set to FALSE'
197          CALL message( 'ls_forcing', 'PA0373', 0, 0, 0, 6, 0 )
198          lsf_vert = .FALSE.
199       ENDIF
200
201       CLOSE( finput )
202
203
204    END SUBROUTINE init_ls_forcing
205
206
207    SUBROUTINE ls_forcing_surf ( time )
208
209       USE arrays_3d
210       USE control_parameters
211       USE cpulog
212       USE indices
213       USE interfaces
214       USE pegrid
215       USE user
216
217       IMPLICIT NONE
218
219       REAL, INTENT(in)  :: time
220       REAL :: fac
221       INTEGER :: t
222
223!
224!--    Interpolation in time of LSF_DATA at the surface
225       t = 1
226       DO WHILE ( time > time_surf(t) )
227          t = t + 1
228       ENDDO
229       IF ( time /= time_surf(t) ) THEN
230         t = t - 1
231       ENDIF
232
233       fac = ( time -time_surf(t) ) / ( time_surf(t+1) - time_surf(t) )
234
235       shf              = shf_surf(t) + fac * ( shf_surf(t+1) - shf_surf(t) )
236       qsws             = qsws_surf(t) + fac * ( qsws_surf(t+1) - qsws_surf(t) )
237       pt_surface       = pt_surf(t) + fac * ( pt_surf(t+1) - pt_surf(t) )
238       surface_pressure = p_surf(t) + fac * ( p_surf(t+1) - p_surf(t) )
239
240    END SUBROUTINE ls_forcing_surf
241
242
243    SUBROUTINE ls_forcing_vert ( time )
244
245       USE arrays_3d
246       USE control_parameters
247       USE cpulog
248       USE indices
249       USE interfaces
250       USE pegrid
251       USE user
252
253       IMPLICIT NONE
254
255       REAL, INTENT(in)  :: time
256       REAL :: fac
257       INTEGER :: t
258
259!
260!--    Interpolation in time of LSF_DATA for ug, vg and w_subs
261       t = 1
262       DO WHILE ( time > time_vert(t) )
263          t = t + 1
264       ENDDO
265       IF ( time /= time_vert(t) ) THEN
266         t = t - 1
267       ENDIF
268
269       fac = (time-time_vert(t)) / (time_vert(t+1)-time_vert(t))
270
271       ug     = ug_vert(:,t) + fac * ( ug_vert(:,t+1) - ug_vert(:,t) )
272       vg     = vg_vert(:,t) + fac * ( vg_vert(:,t+1) - vg_vert(:,t) )
273
274       IF ( large_scale_subsidence ) THEN
275          w_subs = wsubs_vert(:,t) + fac * ( wsubs_vert(:,t+1) - wsubs_vert(:,t) )
276       ENDIF
277
278    END SUBROUTINE ls_forcing_vert
279
280
281 END MODULE ls_forcing_mod
Note: See TracBrowser for help on using the repository browser.