source: palm/trunk/SOURCE/chemistry_model_mod.f90 @ 3449

Last change on this file since 3449 was 3449, checked in by suehring, 5 years ago

Branch resler -r 3439 re-integrated into current trunk: RTM 3.0, transpiration of plant canopy, output fixes in USM

  • Property svn:keywords set to Id
File size: 101.1 KB
RevLine 
[2425]1!> @file chemistry_model_mod.f90
2!------------------------------------------------------------------------------!
[2828]3! This file is part of the PALM model system.
[2425]4!
5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! 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!
[3298]17! Copyright 2017-2018 Leibniz Universitaet Hannover
[2828]18! Copyright 2017-2018 Karlsruhe Institute of Technology
19! Copyright 2017-2018 Freie Universitaet Berlin
[2425]20!------------------------------------------------------------------------------!
21!
22! Current revisions:
23! -----------------
[3298]24!
25!
26! Former revisions:
27! -----------------
28! $Id: chemistry_model_mod.f90 3449 2018-10-29 19:36:56Z suehring $
[3449]29! additional output - merged from branch resler
30!
31! 3438 2018-10-28 19:31:42Z pavelkrc
[3435]32! Add terrain-following masked output
33!
34! 3373 2018-10-18 15:25:56Z kanani
[3373]35! Remove MPI_Abort, replace by message
36!
37! 3318 2018-10-08 11:43:01Z sward
[3318]38! Fixed faulty syntax of message string
39!
40! 3298 2018-10-02 12:21:11Z kanani
[3298]41! Add remarks (kanani)
[3292]42! Merge with trunk, replaced cloud_physics by bulk_cloud_model         28.09.2018 forkel
[3281]43! Subroutines header and chem_check_parameters added                   25.09.2018 basit
[3190]44! Removed chem_emission routine now declared in chem_emissions.f90     30.07.2018 ERUSSO
45! Introduced emissions namelist parameters                             30.07.2018 ERUSSO
[3188]46!
47! Timestep steering added in subroutine chem_integrate_ij and
48! output of chosen solver in chem_parin added                          30.07.2018 ketelsen
49!
50! chem_check_data_output_pr: added unit for PM compounds               20.07.2018 forkel
51! replaced : by nzb+1:nzt for pt,q,ql (found by kk)                    18.07.2018 forkel
[3140]52! debugged restart run for chem species               06.07.2018 basit
53! reorganized subroutines in alphabetical order.      27.06.2018 basit
54! subroutine chem_parin updated for profile output    27.06.2018 basit
[3114]55! Added humidity arrays to USE section and tmp_qvap in chem_integrate  26.6.2018 forkel
56! Merged chemistry with with trunk (nzb_do and nzt_do in 3d output)    26.6.2018 forkel
57!
[3140]58! reorganized subroutines in alphabetical order.      basit 22.06.2018
59! subroutine chem_parin updated for profile output    basit 22.06.2018
60! subroutine chem_statistics added                 
61! subroutine chem_check_data_output_pr add            21.06.2018 basit
62! subroutine chem_data_output_mask added              20.05.2018 basit
63! subroutine chem_data_output_2d added                20.05.2018 basit
64! subroutine chem_statistics added                    04.06.2018 basit
[2914]65! subroutine chem_emissions: Set cssws to zero before setting values 20.03.2018 forkel
[2900]66! subroutine chem_emissions: Introduced different conversion factors
67! for PM and gaseous compounds                                    15.03.2018 forkel
[2888]68! subroutine chem_emissions updated to take variable number of chem_spcs and
[3140]69! emission factors.                                               13.03.2018 basit
70! chem_boundary_conds_decycle improved.                           05.03.2018 basit
71! chem_boundary_conds_decycle subroutine added                    21.02.2018 basit
[3188]72! chem_init_profiles subroutines re-activated after correction    21.02.2018 basit
[2616]73!
[2828]74!
[3298]75! 3293 2018-09-28 12:45:20Z forkel
[3287]76! Modularization of all bulk cloud physics code components
77!
78! 3248 2018-09-14 09:42:06Z sward
79! Minor formating changes
80!
81! 3246 2018-09-13 15:14:50Z sward
82! Added error handling for input namelist via parin_fail_message
83!
84! 3241 2018-09-12 15:02:00Z raasch
[3228]85! +nest_chemistry
86!
87! 3209 2018-08-27 16:58:37Z suehring
88! Rename flags indicating outflow boundary conditions
89!
90! 3182 2018-07-27 13:36:03Z suehring
91! Revise output of surface quantities in case of overhanging structures
92!
93! 3045 2018-05-28 07:55:41Z Giersch
[3114]94! error messages revised
95!
96! 3014 2018-05-09 08:42:38Z maronga
97! Bugfix: nzb_do and nzt_do were not used for 3d data output
98!
99! 3004 2018-04-27 12:33:25Z Giersch
100! Comment concerning averaged data output added
101!
102! 2932 2018-03-26 09:39:22Z maronga
[2981]103! renamed chemistry_par to chemistry_parameters
104!
105! 2894 2018-03-15 09:17:58Z Giersch
[2914]106! Calculations of the index range of the subdomain on file which overlaps with
107! the current subdomain are already done in read_restart_data_mod,
108! chem_last_actions was renamed to chem_wrd_local, chem_read_restart_data was
109! renamed to chem_rrd_local, chem_write_var_list was renamed to
110! chem_wrd_global, chem_read_var_list was renamed to chem_rrd_global,
111! chem_skip_var_list has been removed, variable named found has been
112! introduced for checking if restart data was found, reading of restart strings
113! has been moved completely to read_restart_data_mod, chem_rrd_local is already
114! inside the overlap loop programmed in read_restart_data_mod, todo list has
115! bees extended, redundant characters in chem_wrd_local have been removed,
116! the marker *** end chemistry *** is not necessary anymore, strings and their
117! respective lengths are written out and read now in case of restart runs to
118! get rid of prescribed character lengths
119!
120! 2815 2018-02-19 11:29:57Z suehring
[2828]121! Bugfix in restart mechanism,
122! rename chem_tendency to chem_prognostic_equations,
123! implement vector-optimized version of chem_prognostic_equations,
124! some clean up (incl. todo list)
[2656]125!
[2828]126! 2773 2018-01-30 14:12:54Z suehring
127! Declare variables required for nesting as public
[2656]128!
[2828]129! 2772 2018-01-29 13:10:35Z suehring
130! Bugfix in string handling
[2635]131!
[2828]132! 2768 2018-01-24 15:38:29Z kanani
133! Shorten lines to maximum length of 132 characters
[2633]134!
[2828]135! 2766 2018-01-22 17:17:47Z kanani
136! Removed preprocessor directive __chem
[2633]137!
[2828]138! 2756 2018-01-16 18:11:14Z suehring
139! Fill values in 3D output introduced.
[2627]140!
[2828]141! 2718 2018-01-02 08:49:38Z maronga
142! Initial revision
143!
[2452]144!
[2828]145!
146!
147! Authors:
148! --------
149! @author Renate Forkel
150! @author Farah Kanani-Suehring
151! @author Klaus Ketelsen
152! @author Basit Khan
153!
154!
[2426]155!------------------------------------------------------------------------------!
[2425]156! Description:
157! ------------
[2592]158!> Chemistry model for PALM-4U
[2914]159!> @todo Adjust chem_rrd_local to CASE structure of others modules. It is not
160!>       allowed to use the chemistry model in a precursor run and additionally
161!>       not using it in a main run
[2828]162!> @todo Update/clean-up todo list! (FK)
163!> @todo Set proper fill values (/= 0) for chem output arrays! (FK)
164!> @todo Add routine chem_check_parameters, add checks for inconsistent or
165!>       unallowed parameter settings.
166!>       CALL of chem_check_parameters from check_parameters. (FK)
167!> @todo Make routine chem_header available, CALL from header.f90
168!>       (see e.g. how it is done in routine lsm_header in
169!>        land_surface_model_mod.f90). chem_header should include all setup
170!>        info about chemistry parameter settings. (FK)
[2592]171!> @todo Implement turbulent inflow of chem spcs in inflow_turbulence.
172!> @todo Separate boundary conditions for each chem spcs to be implemented
173!> @todo Currently only total concentration are calculated. Resolved, parameterized
174!>       and chemistry fluxes although partially and some completely coded but
175!>       are not operational/activated in this version. bK.
176!> @todo slight differences in passive scalar and chem spcs when chem reactions
177!>       turned off. Need to be fixed. bK
[2828]178!> @todo test nesting for chem spcs, was implemented by suehring (kanani)
[2592]179!> @todo chemistry error messages
[2425]180!> @todo Format this module according to PALM coding standard (see e.g. module
181!>       template under http://palm.muk.uni-hannover.de/mosaik/downloads/8 or
182!>       D3_coding_standard.pdf under https://palm.muk.uni-hannover.de/trac/downloads/16)
[2482]183!
[2425]184!------------------------------------------------------------------------------!
185
[3281]186 MODULE chemistry_model_mod
[2828]187
[3281]188    USE kinds,              ONLY: wp, iwp
[3282]189    USE indices,            ONLY: nz, nzb,nzt,nysg,nyng,nxlg,nxrg,                                 &
[3114]190                                 nys,nyn,nx,nxl,nxr,ny,wall_flags_0
[3281]191    USE pegrid,             ONLY: myid, threads_per_task
[3293]192
193   USE bulk_cloud_model_mod,                                               &
194        ONLY:  bulk_cloud_model
195
196    USE control_parameters, ONLY: bc_lr_cyc, bc_ns_cyc, dt_3d, humidity,                           &
[3282]197                                 initializing_actions, message_string,                             &
198                                 omega, tsc, intermediate_timestep_count,                          &
199                                 intermediate_timestep_count_max,                                  &
[3287]200                                 timestep_scheme, use_prescribed_profile_data, ws_scheme_sca 
201   USE arrays_3d,          ONLY: exner, hyp, pt, q, ql, rdf_sc, tend, zu
[3282]202    USE chem_gasphase_mod,  ONLY: nspec, spc_names, nkppctrl, nmaxfixsteps,                        &
203                                 t_steps, chem_gasphase_integrate, vl_dim,                         &
204                                 nvar, nreact,  atol, rtol, nphot, phot_names
[3281]205    USE cpulog,             ONLY: cpu_log, log_point
[2425]206
[3281]207    USE chem_modules
[2615]208 
[3281]209    USE statistics
[2615]210
[3281]211    IMPLICIT   NONE
212    PRIVATE
213    SAVE
[2425]214
[3281]215    LOGICAL ::  nest_chemistry = .TRUE. !< flag for nesting mode of chemical species, independent on parent or not
[3228]216!
[2425]217!- Define chemical variables
[3281]218    TYPE   species_def
219       CHARACTER(LEN=8)                                   :: name
220       CHARACTER(LEN=16)                                  :: unit
221       REAL(kind=wp),POINTER,DIMENSION(:,:,:)             :: conc
222       REAL(kind=wp),POINTER,DIMENSION(:,:,:)             :: conc_av
223       REAL(kind=wp),POINTER,DIMENSION(:,:,:)             :: conc_p
224       REAL(kind=wp),POINTER,DIMENSION(:,:,:)             :: tconc_m
225       REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:)           :: cssws_av           
226       REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:)           :: flux_s_cs
227       REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:)           :: diss_s_cs
228       REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:)         :: flux_l_cs
229       REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:)         :: diss_l_cs
230       REAL(kind=wp),ALLOCATABLE,DIMENSION(:)             :: conc_pr_init
231    END TYPE species_def
[2425]232
[2592]233
[3281]234    TYPE   photols_def                                                           
235       CHARACTER(LEN=8)                                   :: name
236       CHARACTER(LEN=16)                                  :: unit
237       REAL(kind=wp),POINTER,DIMENSION(:,:,:)             :: freq
238    END TYPE photols_def
[2425]239
240
[3281]241    PUBLIC  species_def
242    PUBLIC  photols_def
[2425]243
[3228]244
[3281]245    TYPE(species_def),ALLOCATABLE,DIMENSION(:),TARGET, PUBLIC     :: chem_species
246    TYPE(photols_def),ALLOCATABLE,DIMENSION(:),TARGET, PUBLIC     :: phot_frequen 
[2425]247
[3281]248    REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:,:),TARGET   :: spec_conc_1
249    REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:,:),TARGET   :: spec_conc_2
250    REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:,:),TARGET   :: spec_conc_3
251    REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:,:),TARGET   :: spec_conc_av       
252    REAL(kind=wp),ALLOCATABLE,DIMENSION(:,:,:,:),TARGET   :: freq_1
[2425]253
[3281]254    INTEGER,DIMENSION(nkppctrl)                           :: icntrl                            ! Fine tuning kpp
255    REAL(kind=wp),DIMENSION(nkppctrl)                     :: rcntrl                            ! Fine tuning kpp
256    LOGICAL :: decycle_chem_lr    = .FALSE.
257    LOGICAL :: decycle_chem_ns    = .FALSE.
258    CHARACTER (LEN=20), DIMENSION(4) ::  decycle_method = &
[2854]259                  (/'dirichlet','dirichlet','dirichlet','dirichlet'/)
260                                 !< Decycling method at horizontal boundaries,
261                                 !< 1=left, 2=right, 3=south, 4=north
262                                 !< dirichlet = initial size distribution and
263                                 !< chemical composition set for the ghost and
264                                 !< first three layers
265                                 !< neumann = zero gradient
[2425]266
[3449]267    REAL(kind=wp), PUBLIC :: cs_time_step = 0._wp
[3281]268    CHARACTER(10), PUBLIC :: photolysis_scheme
[3114]269                                         ! 'constant',
[2592]270                                         ! 'simple' (Simple parameterisation from MCM, Saunders et al., 2003, Atmos. Chem. Phys., 3, 161-180
271                                         ! 'fastj'  (Wild et al., 2000, J. Atmos. Chem., 37, 245-282) STILL NOT IMPLEMENTED
[2535]272
[3281]273    PUBLIC nest_chemistry
274    PUBLIC nspec
[3282]275    PUBLIC nreact
[3281]276    PUBLIC nvar     
277    PUBLIC spc_names
278    PUBLIC spec_conc_2 
[2425]279
[3281]280!-  Interface section
281    INTERFACE chem_3d_data_averaging
282       MODULE PROCEDURE chem_3d_data_averaging 
283    END INTERFACE chem_3d_data_averaging
[3228]284
[3281]285    INTERFACE chem_boundary_conds
286       MODULE PROCEDURE chem_boundary_conds
287       MODULE PROCEDURE chem_boundary_conds_decycle
288    END INTERFACE chem_boundary_conds
[2425]289
[3281]290    INTERFACE chem_check_data_output
291       MODULE PROCEDURE chem_check_data_output
292    END INTERFACE chem_check_data_output
[2425]293
[3281]294    INTERFACE chem_data_output_2d
295       MODULE PROCEDURE chem_data_output_2d
296    END INTERFACE chem_data_output_2d
[2425]297
[3281]298    INTERFACE chem_data_output_3d
299       MODULE PROCEDURE chem_data_output_3d
300    END INTERFACE chem_data_output_3d
[2425]301
[3281]302    INTERFACE chem_data_output_mask
303       MODULE PROCEDURE chem_data_output_mask
304    END INTERFACE chem_data_output_mask
[3085]305
[3281]306    INTERFACE chem_check_data_output_pr
307       MODULE PROCEDURE chem_check_data_output_pr
308    END INTERFACE chem_check_data_output_pr
[3085]309
[3281]310    INTERFACE chem_check_parameters
311       MODULE PROCEDURE chem_check_parameters
312    END INTERFACE chem_check_parameters
[2425]313
[3281]314    INTERFACE chem_define_netcdf_grid
315       MODULE PROCEDURE chem_define_netcdf_grid
316    END INTERFACE chem_define_netcdf_grid
[2425]317
[3281]318    INTERFACE chem_header
319       MODULE PROCEDURE chem_header
320    END INTERFACE chem_header
[2425]321
[3281]322    INTERFACE chem_init
323       MODULE PROCEDURE chem_init
324    END INTERFACE chem_init
[2425]325
[3281]326    INTERFACE chem_init_profiles
327       MODULE PROCEDURE chem_init_profiles
328    END INTERFACE chem_init_profiles
[2425]329
[3281]330    INTERFACE chem_integrate
331       MODULE PROCEDURE chem_integrate_ij
332    END INTERFACE chem_integrate
[2425]333
[3281]334    INTERFACE chem_parin
335       MODULE PROCEDURE chem_parin
336    END INTERFACE chem_parin
[2425]337
[3281]338    INTERFACE chem_prognostic_equations
339       MODULE PROCEDURE chem_prognostic_equations
340       MODULE PROCEDURE chem_prognostic_equations_ij
341    END INTERFACE chem_prognostic_equations
[3228]342
[3281]343    INTERFACE chem_rrd_local
344       MODULE PROCEDURE chem_rrd_local
345    END INTERFACE chem_rrd_local
[2467]346
[3281]347    INTERFACE chem_statistics
348       MODULE PROCEDURE chem_statistics
349    END INTERFACE chem_statistics
[3085]350
[3281]351    INTERFACE chem_swap_timelevel
352       MODULE PROCEDURE chem_swap_timelevel
353    END INTERFACE chem_swap_timelevel
354
355    INTERFACE chem_wrd_local
356       MODULE PROCEDURE chem_wrd_local 
357    END INTERFACE chem_wrd_local
[2482]358
[2615]359
[3281]360    PUBLIC chem_3d_data_averaging, chem_boundary_conds, chem_check_data_output, &
361           chem_check_data_output_pr, chem_check_parameters,                    &
362           chem_data_output_2d, chem_data_output_3d, chem_data_output_mask,     &
363           chem_define_netcdf_grid, chem_header, chem_init,                     &
364           chem_init_profiles, chem_integrate, chem_parin,                      &
365           chem_prognostic_equations, chem_rrd_local,                           &
366           chem_statistics, chem_swap_timelevel, chem_wrd_local 
[2425]367
[3281]368
369
[2425]370 CONTAINS
371
[3228]372!
[2425]373!------------------------------------------------------------------------------!
[2535]374!
[2425]375! Description:
376! ------------
[3228]377!> Subroutine for averaging 3D data of chemical species. Due to the fact that
378!> the averaged chem arrays are allocated in chem_init, no if-query concerning
379!> the allocation is required (in any mode). Attention: If you just specify an
380!> averaged output quantity in the _p3dr file during restarts the first output
381!> includes the time between the beginning of the restart run and the first
382!> output time (not necessarily the whole averaging_interval you have
383!> specified in your _p3d/_p3dr file )
384!------------------------------------------------------------------------------!
385
[3281]386    SUBROUTINE chem_3d_data_averaging ( mode, variable )
[3228]387
[3281]388       USE control_parameters
[3228]389
[3281]390       USE indices
[3228]391
[3281]392       USE kinds
[3228]393
[3281]394       USE surface_mod,                                                         &
395          ONLY: surf_def_h, surf_lsm_h, surf_usm_h   
[3228]396 
[3281]397       IMPLICIT NONE
[3228]398 
[3281]399       CHARACTER (LEN=*) ::  mode    !<
400       CHARACTER (LEN=*) :: variable !<
[3228]401 
[3281]402       LOGICAL      ::  match_def !< flag indicating natural-type surface
403       LOGICAL      ::  match_lsm !< flag indicating natural-type surface
404       LOGICAL      ::  match_usm !< flag indicating urban-type surface
[3228]405
[3281]406       INTEGER(iwp) ::  i                  !< grid index x direction
407       INTEGER(iwp) ::  j                  !< grid index y direction
408       INTEGER(iwp) ::  k                  !< grid index z direction
409       INTEGER(iwp) ::  m                  !< running index surface type
410       INTEGER(iwp) :: lsp                 !< running index for chem spcs
[3228]411
[3281]412
413       IF ( mode == 'allocate' )  THEN
414          DO lsp = 1, nspec
[3449]415             IF ( TRIM(variable(1:3)) == 'kc_' .AND. &
416                  TRIM(variable(4:)) == TRIM(chem_species(lsp)%name)) THEN
[3281]417                chem_species(lsp)%conc_av = 0.0_wp
418             ENDIF
419          ENDDO
420
421       ELSEIF ( mode == 'sum' )  THEN
422
423          DO lsp = 1, nspec
[3449]424             IF ( TRIM(variable(1:3)) == 'kc_' .AND. &
425                  TRIM(variable(4:)) == TRIM(chem_species(lsp)%name)) THEN
[3281]426                DO  i = nxlg, nxrg
427                   DO  j = nysg, nyng
428                      DO  k = nzb, nzt+1
429                          chem_species(lsp)%conc_av(k,j,i) = chem_species(lsp)%conc_av(k,j,i) + &
430                                                             chem_species(lsp)%conc(k,j,i)
431                      ENDDO
[3228]432                   ENDDO
433                ENDDO
[3281]434             ELSEIF ( TRIM(variable(4:)) == TRIM('cssws*') )        THEN
435                DO  i = nxl, nxr
436                   DO  j = nys, nyn
437                      match_def = surf_def_h(0)%start_index(j,i) <=               &
438                                  surf_def_h(0)%end_index(j,i)
439                      match_lsm = surf_lsm_h%start_index(j,i) <=                  &
440                                  surf_lsm_h%end_index(j,i)
441                      match_usm = surf_usm_h%start_index(j,i) <=                  &
442                                  surf_usm_h%end_index(j,i)
[3228]443
[3281]444                      IF ( match_def )  THEN
445                         m = surf_def_h(0)%end_index(j,i)
446                         chem_species(lsp)%cssws_av(j,i) =                        &
447                                                chem_species(lsp)%cssws_av(j,i) + &
448                                                surf_def_h(0)%cssws(lsp,m)
449                      ELSEIF ( match_lsm  .AND.  .NOT. match_usm )  THEN
450                         m = surf_lsm_h%end_index(j,i)
451                         chem_species(lsp)%cssws_av(j,i) =                        &
452                                                chem_species(lsp)%cssws_av(j,i) + &
453                                                surf_lsm_h%cssws(lsp,m)
454                      ELSEIF ( match_usm )  THEN
455                         m = surf_usm_h%end_index(j,i)
456                         chem_species(lsp)%cssws_av(j,i) =                        &
457                                                chem_species(lsp)%cssws_av(j,i) + &
458                                                surf_usm_h%cssws(lsp,m)
459                      ENDIF
460                   ENDDO
[3228]461                ENDDO
[3281]462             ENDIF
463          ENDDO
[3228]464 
[3281]465       ELSEIF ( mode == 'average' )  THEN
466          DO lsp = 1, nspec
[3449]467             IF ( TRIM(variable(1:3)) == 'kc_' .AND. &
468                  TRIM(variable(4:)) == TRIM(chem_species(lsp)%name)) THEN
[3281]469                DO  i = nxlg, nxrg
470                   DO  j = nysg, nyng
471                      DO  k = nzb, nzt+1
472                          chem_species(lsp)%conc_av(k,j,i) = chem_species(lsp)%conc_av(k,j,i) / REAL( average_count_3d, KIND=wp )
473                      ENDDO
[3228]474                   ENDDO
475                ENDDO
476
[3281]477             ELSEIF (TRIM(variable(4:)) == TRIM('cssws*') )            THEN
478                DO i = nxlg, nxrg
479                   DO  j = nysg, nyng
480                        chem_species(lsp)%cssws_av(j,i) = chem_species(lsp)%cssws_av(j,i) / REAL( average_count_3d, KIND=wp )
481                   ENDDO
[3228]482                ENDDO
[3281]483                   CALL exchange_horiz_2d( chem_species(lsp)%cssws_av, nbgp )                 
484             ENDIF
485          ENDDO
486         
487       ENDIF     
[3228]488
[3281]489    END SUBROUTINE chem_3d_data_averaging
490
491!   
[3228]492!------------------------------------------------------------------------------!
493!
494! Description:
495! ------------
[2535]496!> Subroutine to initialize and set all boundary conditions for chemical species
[2425]497!------------------------------------------------------------------------------!
498
[3281]499    SUBROUTINE chem_boundary_conds( mode )                                           
500                                                                                     
501       USE control_parameters,                                                    & 
502          ONLY:  air_chemistry, bc_radiation_l, bc_radiation_n, bc_radiation_r,  &
503                 bc_radiation_s               
504       USE indices,                                                               & 
505          ONLY:  nxl, nxr,  nxlg, nxrg, nyng, nysg, nzt                             
506                                                                                     
[2425]507
[3281]508       USE arrays_3d,                                                             &     
509          ONLY:  dzu                                               
510       USE surface_mod,                                                           &
511          ONLY:  bc_h                                                           
[2425]512
[3281]513       CHARACTER (len=*), INTENT(IN) :: mode
514       INTEGER(iwp) ::  i                                                            !< grid index x direction.
515       INTEGER(iwp) ::  j                                                            !< grid index y direction.
516       INTEGER(iwp) ::  k                                                            !< grid index z direction.
517       INTEGER(iwp) ::  kb                                                           !< variable to set respective boundary value, depends on facing.
518       INTEGER(iwp) ::  l                                                            !< running index boundary type, for up- and downward-facing walls.
519       INTEGER(iwp) ::  m                                                            !< running index surface elements.
520       INTEGER(iwp) ::  lsp                                                          !< running index for chem spcs.
521       INTEGER(iwp) ::  lph                                                          !< running index for photolysis frequencies
[2425]522
[2615]523
[3281]524       SELECT CASE ( TRIM( mode ) )       
525          CASE ( 'init' )
[2626]526
[3281]527             IF ( bc_cs_b == 'dirichlet' )    THEN
528                ibc_cs_b = 0 
529             ELSEIF ( bc_cs_b == 'neumann' )  THEN
530                ibc_cs_b = 1 
531             ELSE
532                message_string = 'unknown boundary condition: bc_cs_b ="' // TRIM( bc_cs_b ) // '"' 
533                CALL message( 'chem_boundary_conds', 'CM0429', 1, 2, 0, 6, 0 )     !<
534             ENDIF                                                                 
[2425]535!
[3281]536!--          Set Integer flags and check for possible erroneous settings for top
537!--          boundary condition.
538             IF ( bc_cs_t == 'dirichlet' )             THEN
539                ibc_cs_t = 0 
540             ELSEIF ( bc_cs_t == 'neumann' )           THEN
541                ibc_cs_t = 1
542             ELSEIF ( bc_cs_t == 'initial_gradient' )  THEN
543                ibc_cs_t = 2
544             ELSEIF ( bc_cs_t == 'nested' )            THEN         
545                ibc_cs_t = 3
546             ELSE
547                message_string = 'unknown boundary condition: bc_c_t ="' // TRIM( bc_cs_t ) // '"'     
548                CALL message( 'check_parameters', 'CM0430', 1, 2, 0, 6, 0 )
549             ENDIF
[2425]550
[3281]551         
552          CASE ( 'set_bc_bottomtop' )                   
553!--          Bottom boundary condtions for chemical species     
554             DO lsp = 1, nspec                                                     
555                IF ( ibc_cs_b == 0 ) THEN                   
556                   DO l = 0, 1 
557!--                Set index kb: For upward-facing surfaces (l=0), kb=-1, i.e.
[3282]558!--                the chem_species(nspec)%conc_p value at the topography top (k-1)
[3281]559!--                is set; for downward-facing surfaces (l=1), kb=1, i.e. the
560!--                value at the topography bottom (k+1) is set.
[2425]561
[3281]562                      kb = MERGE( -1, 1, l == 0 )
563                      !$OMP PARALLEL DO PRIVATE( i, j, k )
564                      DO m = 1, bc_h(l)%ns
565                         i = bc_h(l)%i(m)           
566                         j = bc_h(l)%j(m)
567                         k = bc_h(l)%k(m)
568                         chem_species(lsp)%conc_p(k+kb,j,i) = chem_species(lsp)%conc(k+kb,j,i) 
569                      ENDDO                                       
570                   ENDDO                                       
571             
572                ELSEIF ( ibc_cs_b == 1 ) THEN
573!--             in boundary_conds there is som extra loop over m here for passive tracer
574                   DO l = 0, 1
575                      kb = MERGE( -1, 1, l == 0 )
576                      !$OMP PARALLEL DO PRIVATE( i, j, k )                                           
577                      DO m = 1, bc_h(l)%ns
578                         i = bc_h(l)%i(m)           
579                         j = bc_h(l)%j(m)
580                         k = bc_h(l)%k(m)
581                         chem_species(lsp)%conc_p(k+kb,j,i) = chem_species(lsp)%conc_p(k,j,i)
[2535]582
[3281]583                      ENDDO
[2615]584                   ENDDO
[3281]585                ENDIF
[3287]586          ENDDO    ! end lsp loop 
[3281]587
[3287]588!--    Top boundary conditions for chemical species - Should this not be done for all species?
[3281]589             IF ( ibc_cs_t == 0 )  THEN                   
590                DO lsp = 1, nspec
591                   chem_species(lsp)%conc_p(nzt+1,:,:) = chem_species(lsp)%conc(nzt+1,:,:)       
[2615]592                ENDDO
[3281]593             ELSEIF ( ibc_cs_t == 1 )  THEN
594                DO lsp = 1, nspec
595                   chem_species(lsp)%conc_p(nzt+1,:,:) = chem_species(lsp)%conc_p(nzt,:,:)
596                ENDDO
597             ELSEIF ( ibc_cs_t == 2 )  THEN
598                DO lsp = 1, nspec
599                   chem_species(lsp)%conc_p(nzt+1,:,:) = chem_species(lsp)%conc_p(nzt,:,:) + bc_cs_t_val(lsp) * dzu(nzt+1)
600                ENDDO
[2615]601             ENDIF
[2425]602!
[3281]603          CASE ( 'set_bc_lateral' )                       
604!--             Lateral boundary conditions for chem species at inflow boundary
605!--             are automatically set when chem_species concentration is
606!--             initialized. The initially set value at the inflow boundary is not
607!--             touched during time integration, hence, this boundary value remains
608!--             at a constant value, which is the concentration that flows into the
609!--             domain.                                                           
610!--             Lateral boundary conditions for chem species at outflow boundary
[2535]611
[3281]612             IF ( bc_radiation_s )  THEN
613                DO lsp = 1, nspec
614                   chem_species(lsp)%conc_p(:,nys-1,:) = chem_species(lsp)%conc_p(:,nys,:)
615                ENDDO
616             ELSEIF ( bc_radiation_n )  THEN
617                DO lsp = 1, nspec
618                   chem_species(lsp)%conc_p(:,nyn+1,:) = chem_species(lsp)%conc_p(:,nyn,:)
619                ENDDO
620             ELSEIF ( bc_radiation_l )  THEN
621                DO lsp = 1, nspec
622                   chem_species(lsp)%conc_p(:,:,nxl-1) = chem_species(lsp)%conc_p(:,:,nxl)
623                ENDDO
624             ELSEIF ( bc_radiation_r )  THEN
625                DO lsp = 1, nspec
626                   chem_species(lsp)%conc_p(:,:,nxr+1) = chem_species(lsp)%conc_p(:,:,nxr)
627                ENDDO
628             ENDIF
629           
630       END SELECT
[2535]631
[3281]632    END SUBROUTINE chem_boundary_conds
[2831]633
[2425]634!
[2535]635!------------------------------------------------------------------------------!
[2831]636! Description:
637! ------------
638!> Boundary conditions for prognostic variables in chemistry: decycling in the
639!> x-direction
640!-----------------------------------------------------------------------------
[3281]641    SUBROUTINE chem_boundary_conds_decycle (cs_3d, cs_pr_init )
642       USE pegrid,                                                             &
643                 ONLY: myid
[2831]644
[3281]645       IMPLICIT NONE
646       INTEGER(iwp) ::  boundary !<
647       INTEGER(iwp) ::  ee !<
648       INTEGER(iwp) ::  copied !<
649       INTEGER(iwp) ::  i !<
650       INTEGER(iwp) ::  j !<
651       INTEGER(iwp) ::  k !<
652       INTEGER(iwp) ::  ss !<
653       REAL(wp), DIMENSION(nzb:nzt+1) ::  cs_pr_init
654       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  cs_3d
655       REAL(wp) ::  flag !< flag to mask topography grid points
[2831]656
[3281]657       flag = 0.0_wp
[2854]658
[3281]659       
660!--    Left and right boundaries
661       IF ( decycle_chem_lr  .AND.  bc_lr_cyc )  THEN
[2854]662
[3281]663          DO  boundary = 1, 2
[2854]664
[3281]665             IF ( decycle_method(boundary) == 'dirichlet' )  THEN
[2854]666!   
[3281]667!--             Initial profile is copied to ghost and first three layers         
668                ss = 1
669                ee = 0
670                IF ( boundary == 1  .AND.  nxl == 0 )  THEN
671                   ss = nxlg
672                   ee = nxl+2
673                ELSEIF ( boundary == 2  .AND.  nxr == nx )  THEN
674                   ss = nxr-2
675                   ee = nxrg
676                ENDIF
[2854]677
[3281]678                DO  i = ss, ee
679                   DO  j = nysg, nyng
680                      DO  k = nzb+1, nzt
681                         flag = MERGE( 1.0_wp, 0.0_wp,                            &
682                                       BTEST( wall_flags_0(k,j,i), 0 ) )
683                         cs_3d(k,j,i) = cs_pr_init(k) * flag
684                      ENDDO
[2854]685                   ENDDO
[2831]686                ENDDO
687
[3281]688           ELSEIF ( decycle_method(boundary) == 'neumann' )  THEN
[2854]689!
[3281]690!--             The value at the boundary is copied to the ghost layers to simulate
691!--             an outlet with zero gradient
692                ss = 1
693                ee = 0
694                IF ( boundary == 1  .AND.  nxl == 0 )  THEN
695                   ss = nxlg
696                   ee = nxl-1
697                   copied = nxl
698                ELSEIF ( boundary == 2  .AND.  nxr == nx )  THEN
699                   ss = nxr+1
700                   ee = nxrg
701                   copied = nxr
702                ENDIF
[2854]703
[3281]704                 DO  i = ss, ee
705                   DO  j = nysg, nyng
706                      DO  k = nzb+1, nzt
707                         flag = MERGE( 1.0_wp, 0.0_wp,                            &
708                                       BTEST( wall_flags_0(k,j,i), 0 ) )
709                        cs_3d(k,j,i) = cs_3d(k,j,copied) * flag
710                      ENDDO
[2854]711                   ENDDO
[2831]712                ENDDO
[2854]713
[3281]714             ELSE
715                WRITE(message_string,*)                                           &
716                                    'unknown decycling method: decycle_method (', &
717                        boundary, ') ="' // TRIM( decycle_method(boundary) ) // '"'
718                CALL message( 'chem_boundary_conds_decycle', 'CM0431',           &
719                              1, 2, 0, 6, 0 )
720             ENDIF
721          ENDDO
722       ENDIF
[2831]723
[3281]724       
725!--    South and north boundaries
726       IF ( decycle_chem_ns  .AND.  bc_ns_cyc )  THEN
[2854]727
[3281]728          DO  boundary = 3, 4
[2854]729
[3281]730             IF ( decycle_method(boundary) == 'dirichlet' )  THEN
[2854]731!   
[3281]732!--             Initial profile is copied to ghost and first three layers         
733                ss = 1
734                ee = 0
735                IF ( boundary == 3  .AND.  nys == 0 )  THEN
736                   ss = nysg
737                   ee = nys+2
738                ELSEIF ( boundary == 4  .AND.  nyn == ny )  THEN
739                   ss = nyn-2
740                   ee = nyng
741                ENDIF
[2854]742
[3281]743                DO  i = nxlg, nxrg
744                   DO  j = ss, ee
745                      DO  k = nzb+1, nzt
746                         flag = MERGE( 1.0_wp, 0.0_wp,                            &
747                                       BTEST( wall_flags_0(k,j,i), 0 ) )
748                         cs_3d(k,j,i) = cs_pr_init(k) * flag
749                      ENDDO
[2854]750                   ENDDO
[2831]751                ENDDO
[3281]752       
753       
754           ELSEIF ( decycle_method(boundary) == 'neumann' )  THEN
[2854]755!
[3281]756!--             The value at the boundary is copied to the ghost layers to simulate
757!--             an outlet with zero gradient
758                ss = 1
759                ee = 0
760                IF ( boundary == 3  .AND.  nys == 0 )  THEN
761                   ss = nysg
762                   ee = nys-1
763                   copied = nys
764                ELSEIF ( boundary == 4  .AND.  nyn == ny )  THEN
765                   ss = nyn+1
766                   ee = nyng
767                   copied = nyn
768                ENDIF
[2831]769
[3281]770                 DO  i = nxlg, nxrg
771                   DO  j = ss, ee
772                      DO  k = nzb+1, nzt
773                         flag = MERGE( 1.0_wp, 0.0_wp,                            &
774                                       BTEST( wall_flags_0(k,j,i), 0 ) )
775                         cs_3d(k,j,i) = cs_3d(k,copied,i) * flag
776                      ENDDO
[2854]777                   ENDDO
[2831]778                ENDDO
[2854]779
[3281]780             ELSE
781                WRITE(message_string,*)                                           &
782                                    'unknown decycling method: decycle_method (', &
783                        boundary, ') ="' // TRIM( decycle_method(boundary) ) // '"'
784                CALL message( 'chem_boundary_conds_decycle', 'CM0432',           &
785                              1, 2, 0, 6, 0 )
786             ENDIF
787          ENDDO
788       ENDIF
789    END SUBROUTINE chem_boundary_conds_decycle
790   !
[3085]791!------------------------------------------------------------------------------!
[2831]792!
[3085]793! Description:
794! ------------
795!> Subroutine for checking data output for chemical species
[2831]796!------------------------------------------------------------------------------!
[3085]797
[3281]798    SUBROUTINE chem_check_data_output( var, unit, i, ilen, k )
[3085]799
800
[3281]801       USE control_parameters,                                                 &
802          ONLY: data_output, message_string
[3085]803
[3281]804       IMPLICIT NONE
[3085]805
[3281]806       CHARACTER (LEN=*) ::  unit     !<
807       CHARACTER (LEN=*) ::  var      !<
[3085]808
[3281]809       INTEGER(iwp) :: i, lsp
810       INTEGER(iwp) :: ilen
811       INTEGER(iwp) :: k
[3085]812
[3281]813       CHARACTER(len=16)    ::  spec_name
[3085]814
[3281]815       unit = 'illegal'
[3085]816
[3449]817       spec_name = TRIM(var(4:))             !< var 1:3 is 'kc_' or 'em_'.
[3085]818
[3449]819       IF ( TRIM(var(1:3)) == 'em_' )  THEN
[3281]820          DO lsp=1,nspec
821             IF (TRIM(spec_name) == TRIM(chem_species(lsp)%name))   THEN
[3449]822                unit = 'mol m-2 s-1'
823             ENDIF
824             !-- It is possible to plant PM10 and PM25 into the gasphase chemistry code
825             !-- as passive species (e.g. 'passive' in GASPHASE_PREPROC/mechanisms):
826             !-- set unit to micrograms per m**3 for PM10 and PM25 (PM2.5)
827             IF (spec_name(1:2) == 'PM')   THEN
828                unit = 'kg m-2 s-1'
829             ENDIF
830          ENDDO
831
832       ELSE
833
834          DO lsp=1,nspec
835             IF (TRIM(spec_name) == TRIM(chem_species(lsp)%name))   THEN
[3281]836                unit = 'ppm'
837             ENDIF
838!            It is possible  to plant PM10 and PM25 into the gasphase chemistry code
839!            as passive species (e.g. 'passive' in GASPHASE_PREPROC/mechanisms):
840!            set unit to micrograms per m**3 for PM10 and PM25 (PM2.5)
841             IF (spec_name(1:2) == 'PM')   THEN 
[3449]842               unit = 'kg m-3'
[3281]843             ENDIF
844          ENDDO
[3085]845
[3449]846          DO lsp=1,nphot
[3281]847             IF (TRIM(spec_name) == TRIM(phot_frequen(lsp)%name))   THEN
848                unit = 'sec-1'
849             ENDIF
850          ENDDO
[3449]851       ENDIF
[3085]852
853
[3449]854      RETURN
[3281]855    END SUBROUTINE chem_check_data_output
[2831]856!
[3085]857!------------------------------------------------------------------------------!
858!
[2535]859! Description:
860! ------------
[3085]861!> Subroutine for checking data output of profiles for chemistry model
[2535]862!------------------------------------------------------------------------------!
[2615]863
[3281]864    SUBROUTINE chem_check_data_output_pr( variable, var_count, unit, dopr_unit )
[3085]865
[3281]866       USE arrays_3d
867       USE control_parameters,                                                    &
868           ONLY: data_output_pr, message_string, air_chemistry
869       USE indices
870       USE profil_parameter
871       USE statistics
[3085]872
873
[3281]874       IMPLICIT NONE
[3085]875
[3281]876       CHARACTER (LEN=*) ::  unit     !<
877       CHARACTER (LEN=*) ::  variable !<
878       CHARACTER (LEN=*) ::  dopr_unit
879       CHARACTER(len=16) ::  spec_name
[3228]880   
[3281]881       INTEGER(iwp) ::  var_count, lsp  !<
882       
[3085]883
[3281]884       spec_name = TRIM(variable(4:))   
[3085]885
886          IF (  .NOT.  air_chemistry )  THEN
[3281]887             message_string = 'data_output_pr = ' //                        &
888             TRIM( data_output_pr(var_count) ) // ' is not imp' // &
889                         'lemented for air_chemistry = .FALSE.'
890             CALL message( 'chem_check_parameters', 'CM0433', 1, 2, 0, 6, 0 )             
[3085]891
892          ELSE
893             DO lsp = 1, nspec
894                IF (TRIM( spec_name ) == TRIM( chem_species(lsp)%name ) ) THEN
[3281]895                   cs_pr_count = cs_pr_count+1
896                   cs_pr_index(cs_pr_count) = lsp
897                   dopr_index(var_count) = pr_palm+cs_pr_count 
898                   dopr_unit  = 'ppm'
899                   IF (spec_name(1:2) == 'PM')   THEN
[3276]900                        dopr_unit = 'kg m-3'
[3281]901                   ENDIF
[3085]902                      hom(:,2, dopr_index(var_count),:) = SPREAD( zu, 2, statistic_regions+1 )
903                      unit = dopr_unit 
904                ENDIF
905             ENDDO
906          ENDIF
907
[3281]908    END SUBROUTINE chem_check_data_output_pr
[3085]909
[3281]910!
911!------------------------------------------------------------------------------!
912! Description:
913! ------------
914!> Check parameters routine for chemistry_model_mod
915!------------------------------------------------------------------------------!
916    SUBROUTINE chem_check_parameters
[3085]917
[3281]918       IMPLICIT NONE
919
920       LOGICAL                        ::  found
921       INTEGER (iwp)                  ::  lsp_usr      !< running index for user defined chem spcs
922       INTEGER (iwp)                  ::  lsp          !< running index for chem spcs.
923
924
925!!--   check for chemical reactions status
926       IF ( chem_gasphase_on )  THEN
927          message_string = 'Chemical reactions: ON'
928          CALL message( 'chem_check_parameters', 'CM0421', 0, 0, 0, 6, 0 )
929       ELSEIF ( .not. (chem_gasphase_on) ) THEN
930          message_string = 'Chemical reactions: OFF'
931          CALL message( 'chem_check_parameters', 'CM0422', 0, 0, 0, 6, 0 )
932       ENDIF
933
934!--    check for chemistry time-step
935       IF ( call_chem_at_all_substeps )  THEN
936          message_string = 'Chemistry is calculated at all meteorology time-step'
937          CALL message( 'chem_check_parameters', 'CM0423', 0, 0, 0, 6, 0 )
938       ELSEIF ( .not. (call_chem_at_all_substeps) ) THEN
939          message_string = 'Sub-time-steps are skipped for chemistry time-steps'
940          CALL message( 'chem_check_parameters', 'CM0424', 0, 0, 0, 6, 0 )
941       ENDIF
942
943!--    check for photolysis scheme
944       IF ( (photolysis_scheme /= 'simple') .AND. (photolysis_scheme /= 'constant')  )  THEN
945          message_string = 'Incorrect photolysis scheme selected, please check spelling'
946          CALL message( 'chem_check_parameters', 'CM0425', 1, 2, 0, 6, 0 )
947       ENDIF
948
949!--    check for  decycling of chem species
950       IF ( (.not. any(decycle_method == 'neumann') ) .AND. (.not. any(decycle_method == 'dirichlet') ) )   THEN
[3318]951          message_string = 'Incorrect boundary conditions. Only neumann or '   &
952                   // 'dirichlet &available for decycling chemical species '
[3281]953          CALL message( 'chem_check_parameters', 'CM0426', 1, 2, 0, 6, 0 )
954       ENDIF
955
[3449]956!---------------------
957!--    chem_check_parameters is called before the array chem_species is allocated!
958!--    temporary switch of this part of the check
959       RETURN
960!---------------------
961
[3281]962!--    check for initial chem species input
963       lsp_usr = 1
964       lsp     = 1
965       DO WHILE ( cs_name (lsp_usr) /= 'novalue')
966          found = .FALSE.
967          DO lsp = 1, nvar
968             IF ( TRIM(cs_name (lsp_usr)) == TRIM(chem_species(lsp)%name) ) THEN
969                found = .TRUE.
970                EXIT
971             ENDIF
972          ENDDO
973          IF ( .not. found ) THEN
974             message_string = 'Incorrect input for initial surface vaue: ' // TRIM(cs_name(lsp_usr))
975             CALL message( 'chem_check_parameters', 'CM0427', 0, 1, 0, 6, 0 )
976          ENDIF
977          lsp_usr = lsp_usr + 1
978       ENDDO
979
980!--    check for surface  emission flux chem species
981
982       lsp_usr = 1
983       lsp     = 1
984       DO WHILE ( surface_csflux_name (lsp_usr) /= 'novalue')
985          found = .FALSE.
986          DO lsp = 1, nvar
987             IF ( TRIM(surface_csflux_name (lsp_usr)) == TRIM(chem_species(lsp)%name) ) THEN
988                found = .TRUE.
989                EXIT
990             ENDIF
991          ENDDO
992          IF ( .not. found ) THEN
993             message_string = 'Incorrect input of chemical species for surface emission fluxes: '  &
994                               // TRIM(surface_csflux_name(lsp_usr))
995             CALL message( 'chem_check_parameters', 'CM0428', 0, 1, 0, 6, 0 )
996          ENDIF
997          lsp_usr = lsp_usr + 1
998       ENDDO
999
1000    END SUBROUTINE chem_check_parameters
1001
[3085]1002!
1003!------------------------------------------------------------------------------!
1004!
1005! Description:
1006! ------------
1007!> Subroutine defining 2D output variables for chemical species
[3298]1008!> @todo: Remove "mode" from argument list, not used.
[3085]1009!------------------------------------------------------------------------------!
1010   
[3281]1011    SUBROUTINE chem_data_output_2d( av, variable, found, grid, mode, local_pf,   &
1012                                     two_d, nzb_do, nzt_do, fill_value )
1013   
1014       USE indices
[3085]1015
[3281]1016       USE kinds
[3085]1017
[3281]1018       USE pegrid,             ONLY: myid, threads_per_task
[3085]1019
[3281]1020       IMPLICIT NONE
[3085]1021
[3281]1022       CHARACTER (LEN=*) ::  grid       !<
1023       CHARACTER (LEN=*) ::  mode       !<
1024       CHARACTER (LEN=*) ::  variable   !<
[3282]1025       INTEGER(iwp) ::  av              !< flag to control data output of instantaneous or time-averaged data
[3281]1026       INTEGER(iwp) ::  nzb_do          !< lower limit of the domain (usually nzb)
1027       INTEGER(iwp) ::  nzt_do          !< upper limit of the domain (usually nzt+1)
1028       LOGICAL      ::  found           !<
1029       LOGICAL      ::  two_d           !< flag parameter that indicates 2D variables (horizontal cross sections)
1030       REAL(wp)     ::  fill_value 
1031       REAL(wp), DIMENSION(nxl:nxr,nys:nyn,nzb:nzt+1) ::  local_pf !<
[3085]1032
[3281]1033       !-- local variables.
1034       CHARACTER(len=16)    ::  spec_name
1035       INTEGER(iwp) ::  lsp
[3282]1036       INTEGER(iwp) ::  i               !< grid index along x-direction
1037       INTEGER(iwp) ::  j               !< grid index along y-direction
1038       INTEGER(iwp) ::  k               !< grid index along z-direction
1039       INTEGER(iwp) ::  m               !< running index surface elements
1040       INTEGER(iwp) ::  char_len        !< length of a character string
[3281]1041       found = .TRUE.
1042       char_len  = LEN_TRIM(variable)
[3085]1043
[3281]1044       spec_name = TRIM( variable(4:char_len-3) )
[3085]1045
[3281]1046          DO lsp=1,nspec
1047             IF (TRIM(spec_name) == TRIM(chem_species(lsp)%name)    .AND.                             &
1048                   ( (variable(char_len-2:) == '_xy')               .OR.                              &
1049                     (variable(char_len-2:) == '_xz')               .OR.                              &
1050                     (variable(char_len-2:) == '_yz') ) )               THEN             
[3373]1051!
1052!--   todo: remove or replace by "CALL message" mechanism (kanani)
1053!                    IF(myid == 0)  WRITE(6,*) 'Output of species ' // TRIM(variable)  //               &
1054!                                                             TRIM(chem_species(lsp)%name)       
[3281]1055                IF (av == 0) THEN
1056                   DO  i = nxl, nxr
1057                      DO  j = nys, nyn
1058                         DO  k = nzb_do, nzt_do
1059                              local_pf(i,j,k) = MERGE(                                                &
1060                                                 chem_species(lsp)%conc(k,j,i),                       &
1061                                                 REAL( fill_value, KIND = wp ),                       &
1062                                                 BTEST( wall_flags_0(k,j,i), 0 ) )
[3085]1063
1064
[3281]1065                         ENDDO
[3085]1066                      ENDDO
1067                   ENDDO
[3281]1068             
1069                ELSE
1070                   DO  i = nxl, nxr
1071                      DO  j = nys, nyn
1072                         DO  k = nzb_do, nzt_do
1073                              local_pf(i,j,k) = MERGE(                                                &
1074                                                 chem_species(lsp)%conc(k,j,i),                       &
1075                                                 REAL( fill_value, KIND = wp ),                       &
1076                                                 BTEST( wall_flags_0(k,j,i), 0 ) )
1077                         ENDDO
[3085]1078                      ENDDO
1079                   ENDDO
[3281]1080                ENDIF
1081                 grid = 'zu'           
[2535]1082             ENDIF
[3281]1083          ENDDO
[3085]1084
[3281]1085          RETURN
1086     
1087    END SUBROUTINE chem_data_output_2d     
[3085]1088
1089!
1090!------------------------------------------------------------------------------!
1091!
1092! Description:
1093! ------------
1094!> Subroutine defining 3D output variables for chemical species
1095!------------------------------------------------------------------------------!
1096
[3281]1097    SUBROUTINE chem_data_output_3d( av, variable, found, local_pf, fill_value, nzb_do, nzt_do )
[3085]1098
1099
[3281]1100       USE indices
[3228]1101
[3281]1102       USE kinds
[3085]1103
[3449]1104       USE surface_mod
[3085]1105
[3449]1106       !USE chem_modules, ONLY: nvar
1107
[3281]1108       IMPLICIT NONE
[3085]1109
[3282]1110       CHARACTER (LEN=*)    ::  variable     !<
1111       INTEGER(iwp)         ::  av           !<
1112       INTEGER(iwp) ::  nzb_do               !< lower limit of the data output (usually 0)
1113       INTEGER(iwp) ::  nzt_do               !< vertical upper limit of the data output (usually nz_do3d)
[3085]1114
[3282]1115       LOGICAL      ::  found                !<
[3085]1116
[3281]1117       REAL(wp)             ::  fill_value !<
1118       REAL(sp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf 
[3228]1119
[3085]1120
[3281]1121       !-- local variables
1122       CHARACTER(len=16)    ::  spec_name
[3449]1123       INTEGER(iwp)         ::  i, j, k
1124       INTEGER(iwp)         ::  m, l    !< running indices for surfaces
1125       INTEGER(iwp)         ::  lsp  !< running index for chem spcs
[3085]1126
1127
[3281]1128       found = .FALSE.
[3449]1129       IF ( .NOT. (variable(1:3) == 'kc_' .OR. variable(1:3) == 'em_' ) ) THEN
1130          RETURN
1131       ENDIF
[3085]1132
[3281]1133       spec_name = TRIM(variable(4:))
[3085]1134
[3449]1135       IF ( variable(1:3) == 'em_' ) THEN
1136
1137         local_pf = 0.0_wp
1138
1139         DO lsp = 1, nvar  !!! cssws - nvar species, chem_species - nspec species !!!
1140            IF ( TRIM(spec_name) == TRIM(chem_species(lsp)%name) )   THEN
1141               ! no average for now
1142               DO m = 1, surf_usm_h%ns
1143                  local_pf(surf_usm_h%i(m),surf_usm_h%j(m),surf_usm_h%k(m)) = &
1144                     local_pf(surf_usm_h%i(m),surf_usm_h%j(m),surf_usm_h%k(m)) + surf_usm_h%cssws(lsp,m)
1145               ENDDO
1146               DO m = 1, surf_lsm_h%ns
1147                  local_pf(surf_lsm_h%i(m),surf_lsm_h%j(m),surf_lsm_h%k(m)) = &
1148                     local_pf(surf_lsm_h%i(m),surf_lsm_h%j(m),surf_lsm_h%k(m)) + surf_lsm_h%cssws(lsp,m)
1149               ENDDO
1150               DO l = 0, 3
1151                  DO m = 1, surf_usm_v(l)%ns
1152                     local_pf(surf_usm_v(l)%i(m),surf_usm_v(l)%j(m),surf_usm_v(l)%k(m)) = &
1153                        local_pf(surf_usm_v(l)%i(m),surf_usm_v(l)%j(m),surf_usm_v(l)%k(m)) + surf_usm_v(l)%cssws(lsp,m)
1154                  ENDDO
1155                  DO m = 1, surf_lsm_v(l)%ns
1156                     local_pf(surf_lsm_v(l)%i(m),surf_lsm_v(l)%j(m),surf_lsm_v(l)%k(m)) = &
1157                        local_pf(surf_lsm_v(l)%i(m),surf_lsm_v(l)%j(m),surf_lsm_v(l)%k(m)) + surf_lsm_v(l)%cssws(lsp,m)
1158                  ENDDO
1159               ENDDO
1160               found = .TRUE.
1161            ENDIF
1162         ENDDO
1163       ELSE
1164         DO lsp=1,nspec
1165            IF (TRIM(spec_name) == TRIM(chem_species(lsp)%name))   THEN
[3373]1166!
1167!--   todo: remove or replace by "CALL message" mechanism (kanani)
1168!              IF(myid == 0 .AND. chem_debug0 )  WRITE(6,*) 'Output of species ' // TRIM(variable)  //  &
1169!                                                           TRIM(chem_species(lsp)%name)       
[3449]1170               IF (av == 0) THEN
1171                  DO  i = nxl, nxr
1172                     DO  j = nys, nyn
1173                        DO  k = nzb_do, nzt_do
1174                            local_pf(i,j,k) = MERGE(                             &
1175                                                chem_species(lsp)%conc(k,j,i),   &
1176                                                REAL( fill_value, KIND = wp ),   &
1177                                                BTEST( wall_flags_0(k,j,i), 0 ) )
1178                        ENDDO
1179                     ENDDO
1180                  ENDDO
[3085]1181
[3449]1182               ELSE
1183                  DO  i = nxl, nxr
1184                     DO  j = nys, nyn
1185                        DO  k = nzb_do, nzt_do
1186                            local_pf(i,j,k) = MERGE(                             &
1187                                                chem_species(lsp)%conc_av(k,j,i),&
1188                                                REAL( fill_value, KIND = wp ),   &
1189                                                BTEST( wall_flags_0(k,j,i), 0 ) )
1190                        ENDDO
1191                     ENDDO
1192                  ENDDO
1193               ENDIF
1194               found = .TRUE.
1195            ENDIF
1196         ENDDO
1197       ENDIF
[3085]1198
1199       RETURN
[3449]1200
[3281]1201    END SUBROUTINE chem_data_output_3d
[3085]1202!
1203!------------------------------------------------------------------------------!
1204!
1205! Description:
1206! ------------
1207!> Subroutine defining mask output variables for chemical species
1208!------------------------------------------------------------------------------!
1209   
[3281]1210    SUBROUTINE chem_data_output_mask( av, variable, found, local_pf )
1211   
1212       USE control_parameters
1213       USE indices
1214       USE kinds
1215       USE pegrid,             ONLY: myid, threads_per_task
[3435]1216       USE surface_mod,        ONLY: get_topography_top_index_ji
[3085]1217
[3281]1218       IMPLICIT NONE
[3085]1219
[3435]1220       CHARACTER(LEN=5) ::  grid        !< flag to distinquish between staggered grids
1221
[3282]1222       CHARACTER (LEN=*)::  variable    !<
1223       INTEGER(iwp)     ::  av          !< flag to control data output of instantaneous or time-averaged data
1224       LOGICAL          ::  found       !<
[3281]1225       REAL(wp), DIMENSION(mask_size_l(mid,1),mask_size_l(mid,2),mask_size_l(mid,3)) ::  &
1226                 local_pf   !<
[3085]1227
1228
[3281]1229       !-- local variables.
1230       CHARACTER(len=16)    ::  spec_name
1231       INTEGER(iwp) ::  lsp
[3282]1232       INTEGER(iwp) ::  i               !< grid index along x-direction
1233       INTEGER(iwp) ::  j               !< grid index along y-direction
1234       INTEGER(iwp) ::  k               !< grid index along z-direction
[3435]1235       INTEGER(iwp) ::  topo_top_ind    !< k index of highest horizontal surface
1236
[3281]1237       found = .TRUE.
[3435]1238       grid  = 's'
[3085]1239
[3281]1240       spec_name = TRIM( variable(4:) )
[3449]1241       !av == 0
[3085]1242
1243       DO lsp=1,nspec
1244          IF (TRIM(spec_name) == TRIM(chem_species(lsp)%name) )               THEN             
[3373]1245!
1246!--   todo: remove or replace by "CALL message" mechanism (kanani)
1247!                 IF(myid == 0 .AND. chem_debug0 )  WRITE(6,*) 'Output of species ' // TRIM(variable)  // &
1248!                                                           TRIM(chem_species(lsp)%name)       
[3085]1249             IF (av == 0) THEN
[3435]1250                IF ( .NOT. mask_surface(mid) )  THEN
1251
1252                   DO  i = 1, mask_size_l(mid,1)
1253                      DO  j = 1, mask_size_l(mid,2) 
1254                         DO  k = 1, mask_size(mid,3) 
1255                             local_pf(i,j,k) = chem_species(lsp)%conc(  &
1256                                                  mask_k(mid,k),        &
1257                                                  mask_j(mid,j),        &
1258                                                  mask_i(mid,i)      )
1259                         ENDDO
[3085]1260                      ENDDO
1261                   ENDDO
[3435]1262
1263                ELSE
1264!             
1265!--                Terrain-following masked output
1266                   DO  i = 1, mask_size_l(mid,1)
1267                      DO  j = 1, mask_size_l(mid,2)
1268!             
1269!--                      Get k index of highest horizontal surface
1270                         topo_top_ind = get_topography_top_index_ji( &
1271                                           mask_j(mid,j),  &
1272                                           mask_i(mid,i),  &
1273                                           grid                    )
1274!             
1275!--                      Save output array
1276                         DO  k = 1, mask_size_l(mid,3)
1277                            local_pf(i,j,k) = chem_species(lsp)%conc( &
1278                                                 MIN( topo_top_ind+mask_k(mid,k), &
1279                                                      nzt+1 ),        &
1280                                                 mask_j(mid,j),       &
1281                                                 mask_i(mid,i)      )
1282                         ENDDO
1283                      ENDDO
1284                   ENDDO
1285
1286                ENDIF
[3085]1287             ELSE
[3435]1288                IF ( .NOT. mask_surface(mid) )  THEN
1289
1290                   DO  i = 1, mask_size_l(mid,1)
1291                      DO  j = 1, mask_size_l(mid,2)
1292                         DO  k =  1, mask_size_l(mid,3)
1293                             local_pf(i,j,k) = chem_species(lsp)%conc_av(  &
1294                                                  mask_k(mid,k),           &
1295                                                  mask_j(mid,j),           &
1296                                                  mask_i(mid,i)         )
1297                         ENDDO
[3085]1298                      ENDDO
1299                   ENDDO
[3435]1300
1301                ELSE
1302!             
1303!--                Terrain-following masked output
1304                   DO  i = 1, mask_size_l(mid,1)
1305                      DO  j = 1, mask_size_l(mid,2)
1306!             
1307!--                      Get k index of highest horizontal surface
1308                         topo_top_ind = get_topography_top_index_ji( &
1309                                           mask_j(mid,j),  &
1310                                           mask_i(mid,i),  &
1311                                           grid                    )
1312!             
1313!--                      Save output array
1314                         DO  k = 1, mask_size_l(mid,3)
1315                            local_pf(i,j,k) = chem_species(lsp)%conc_av(  &
1316                                                 MIN( topo_top_ind+mask_k(mid,k), &
1317                                                      nzt+1 ),            &
1318                                                 mask_j(mid,j),           &
1319                                                 mask_i(mid,i)         )
1320                         ENDDO
1321                      ENDDO
1322                   ENDDO
1323
1324                ENDIF
1325
1326
[3085]1327             ENDIF
1328             found = .FALSE.
1329          ENDIF
1330       ENDDO
1331
1332       RETURN
[3281]1333     
1334    END SUBROUTINE chem_data_output_mask     
[3085]1335
1336!
1337!------------------------------------------------------------------------------!
1338!
1339! Description:
1340! ------------
1341!> Subroutine defining appropriate grid for netcdf variables.
1342!> It is called out from subroutine netcdf.
1343!------------------------------------------------------------------------------!
[3281]1344    SUBROUTINE chem_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
[3085]1345
[3281]1346       IMPLICIT NONE
[3085]1347
[3282]1348       CHARACTER (LEN=*), INTENT(IN)  ::  var          !<
1349       LOGICAL, INTENT(OUT)           ::  found        !<
1350       CHARACTER (LEN=*), INTENT(OUT) ::  grid_x       !<
1351       CHARACTER (LEN=*), INTENT(OUT) ::  grid_y       !<
1352       CHARACTER (LEN=*), INTENT(OUT) ::  grid_z       !<
[3085]1353
[3281]1354       found  = .TRUE.
[3085]1355
[3449]1356       IF ( var(1:3) == 'kc_' .OR. var(1:3) == 'em_' )   THEN                   !< always the same grid for chemistry variables
[3281]1357          grid_x = 'x'
1358          grid_y = 'y'
1359          grid_z = 'zu'                             
1360       ELSE
1361          found  = .FALSE.
1362          grid_x = 'none'
1363          grid_y = 'none'
1364          grid_z = 'none'
1365       ENDIF
[3085]1366
1367
[3281]1368    END SUBROUTINE chem_define_netcdf_grid
[3085]1369!
1370!------------------------------------------------------------------------------!
1371!
1372! Description:
1373! ------------
1374!> Subroutine defining header output for chemistry model
1375!------------------------------------------------------------------------------!
[3281]1376    SUBROUTINE chem_header ( io )
[3085]1377       
[3281]1378       IMPLICIT NONE
[3085]1379 
1380       INTEGER(iwp), INTENT(IN) ::  io            !< Unit of the output file
[3281]1381       INTEGER(iwp)             :: lsp            !< running index for chem spcs
[3282]1382       INTEGER(iwp)             :: cs_fixed 
1383       CHARACTER (LEN=80)       :: docsflux_chr
1384       CHARACTER (LEN=80)       :: docsinit_chr
1385
[3281]1386!
1387!--    Write chemistry model  header
1388       WRITE( io, 1 )
[3085]1389
[3281]1390!--    Gasphase reaction status
1391       IF ( chem_gasphase_on )  THEN
1392          WRITE( io, 2 )
1393       ELSE
1394          WRITE( io, 3 )
1395       ENDIF
1396
1397!      Chemistry time-step
1398       WRITE ( io, 4 ) cs_time_step
1399
1400!--    Emission mode info
1401       IF ( mode_emis == "DEFAULT" )  THEN
1402          WRITE( io, 5 ) 
1403       ELSEIF ( mode_emis == "PARAMETERIZED" )  THEN
1404          WRITE( io, 6 )
1405       ELSEIF ( mode_emis == "PRE-PROCESSED" )  THEN
1406          WRITE( io, 7 )
1407       ENDIF 
1408
1409!--    Photolysis scheme info
1410       IF ( photolysis_scheme == "simple" )      THEN
1411          WRITE( io, 8 ) 
1412       ELSEIF (photolysis_scheme == "conastant" ) THEN
1413          WRITE( io, 9 )
1414       ENDIF
1415 
1416 !--   Emission flux info
1417       lsp = 1
1418       docsflux_chr ='Chemical species for surface emission flux: ' 
1419       DO WHILE ( surface_csflux_name(lsp) /= 'novalue' )
1420          docsflux_chr = TRIM( docsflux_chr ) // ' ' // TRIM( surface_csflux_name(lsp) ) // ',' 
1421          IF ( LEN_TRIM( docsflux_chr ) >= 75 )  THEN
1422           WRITE ( io, 10 )  docsflux_chr
1423           docsflux_chr = '       '
1424          ENDIF
1425          lsp = lsp + 1
1426       ENDDO
1427 
1428       IF ( docsflux_chr /= '' )  THEN
1429          WRITE ( io, 10 )  docsflux_chr
1430       ENDIF
1431
1432
1433!--    initializatoin of Surface and profile chemical species
1434
1435       lsp = 1
1436       docsinit_chr ='Chemical species for initial surface and profile emissions: ' 
1437       DO WHILE ( cs_name(lsp) /= 'novalue' )
1438          docsinit_chr = TRIM( docsinit_chr ) // ' ' // TRIM( cs_name(lsp) ) // ',' 
1439          IF ( LEN_TRIM( docsinit_chr ) >= 75 )  THEN
1440           WRITE ( io, 11 )  docsinit_chr
1441           docsinit_chr = '       '
1442          ENDIF
1443          lsp = lsp + 1
1444       ENDDO
1445 
1446       IF ( docsinit_chr /= '' )  THEN
1447          WRITE ( io, 11 )  docsinit_chr
1448       ENDIF
1449
1450!--    number of variable and fix chemical species and number of reactions
[3282]1451       cs_fixed = nspec - nvar
1452       WRITE ( io, * ) '   --> Chemical species, variable: ', nvar
1453       WRITE ( io, * ) '   --> Chemical species, fixed   : ', cs_fixed
1454       WRITE ( io, * ) '   --> Total number of reactions : ', nreact
[3281]1455
1456
14571   FORMAT (//' Chemistry model information:'/                                  &
1458              ' ----------------------------'/)
14592   FORMAT ('    --> Chemical reactions are turned on')
14603   FORMAT ('    --> Chemical reactions are turned off')
14614   FORMAT ('    --> Time-step for chemical species: ',F6.2, ' s')
14625   FORMAT ('    --> Emission mode = DEFAULT ')
14636   FORMAT ('    --> Emission mode = PARAMETERIZED ')
14647   FORMAT ('    --> Emission mode = PRE-PROCESSED ')
14658   FORMAT ('    --> Photolysis scheme used =  simple ')
14669   FORMAT ('    --> Photolysis scheme used =  constant ')
[3282]146710  FORMAT (/'    ',A) 
146811  FORMAT (/'    ',A) 
[3085]1469!
1470!
[3281]1471    END SUBROUTINE chem_header
[3085]1472
1473!
1474!------------------------------------------------------------------------------!
1475!
1476! Description:
1477! ------------
[2535]1478!> Subroutine initializating chemistry_model_mod
[2425]1479!------------------------------------------------------------------------------!
[3281]1480    SUBROUTINE chem_init
[2535]1481
[3281]1482       USE control_parameters,                                                  &
1483          ONLY: message_string, io_blocks, io_group, turbulent_inflow
1484       USE arrays_3d,                                                           &
1485           ONLY: mean_inflow_profiles
1486       USE pegrid
[3085]1487
[3281]1488       IMPLICIT   none
1489   !-- local variables
1490       INTEGER                 :: i,j               !< running index for for horiz numerical grid points
1491       INTEGER                 :: lsp               !< running index for chem spcs
1492       INTEGER                 :: lpr_lev           !< running index for chem spcs profile level
[2535]1493!
1494!-- NOPOINTER version not implemented yet
[2828]1495! #if defined( __nopointer )
1496!     message_string = 'The chemistry module only runs with POINTER version'
1497!     CALL message( 'chemistry_model_mod', 'CM0001', 1, 2, 0, 6, 0 )     
1498! #endif
1499!
1500!-- Allocate memory for chemical species
[3281]1501       ALLOCATE( chem_species(nspec) )
1502       ALLOCATE( spec_conc_1 (nzb:nzt+1,nysg:nyng,nxlg:nxrg,nspec) )
1503       ALLOCATE( spec_conc_2 (nzb:nzt+1,nysg:nyng,nxlg:nxrg,nspec) )
1504       ALLOCATE( spec_conc_3 (nzb:nzt+1,nysg:nyng,nxlg:nxrg,nspec) )
1505       ALLOCATE( spec_conc_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nspec) ) 
1506       ALLOCATE( phot_frequen(nphot) ) 
1507       ALLOCATE( freq_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nphot) )
1508       ALLOCATE( bc_cs_t_val(nspec) )
[2828]1509!
1510!-- Initialize arrays
[3281]1511       spec_conc_1 (:,:,:,:) = 0.0_wp
1512       spec_conc_2 (:,:,:,:) = 0.0_wp
1513       spec_conc_3 (:,:,:,:) = 0.0_wp
1514       spec_conc_av(:,:,:,:) = 0.0_wp
[2535]1515
[2828]1516
[3281]1517       DO lsp = 1, nspec
1518          chem_species(lsp)%name    = spc_names(lsp)
[2535]1519
[3281]1520          chem_species(lsp)%conc   (nzb:nzt+1,nysg:nyng,nxlg:nxrg)       => spec_conc_1 (:,:,:,lsp)
1521          chem_species(lsp)%conc_p (nzb:nzt+1,nysg:nyng,nxlg:nxrg)       => spec_conc_2 (:,:,:,lsp)
1522          chem_species(lsp)%tconc_m(nzb:nzt+1,nysg:nyng,nxlg:nxrg)       => spec_conc_3 (:,:,:,lsp)
1523          chem_species(lsp)%conc_av(nzb:nzt+1,nysg:nyng,nxlg:nxrg)       => spec_conc_av(:,:,:,lsp)     
[2425]1524
[3281]1525          ALLOCATE (chem_species(lsp)%cssws_av(nysg:nyng,nxlg:nxrg))                   
1526          chem_species(lsp)%cssws_av    = 0.0_wp
[2828]1527!
[3282]1528!--       The following block can be useful when emission module is not applied. &
1529!--       if emission module is applied the following block will be overwritten.
1530          ALLOCATE (chem_species(lsp)%flux_s_cs(nzb+1:nzt,0:threads_per_task-1))   
1531          ALLOCATE (chem_species(lsp)%diss_s_cs(nzb+1:nzt,0:threads_per_task-1))   
1532          ALLOCATE (chem_species(lsp)%flux_l_cs(nzb+1:nzt,nys:nyn,0:threads_per_task-1)) 
1533          ALLOCATE (chem_species(lsp)%diss_l_cs(nzb+1:nzt,nys:nyn,0:threads_per_task-1))   
1534          chem_species(lsp)%flux_s_cs = 0.0_wp                                     
1535          chem_species(lsp)%flux_l_cs = 0.0_wp                                     
1536          chem_species(lsp)%diss_s_cs = 0.0_wp                                     
1537          chem_species(lsp)%diss_l_cs = 0.0_wp                                     
[2828]1538!
1539!--   Allocate memory for initial concentration profiles
1540!--   (concentration values come from namelist)
[3282]1541!--   (@todo (FK): Because of this, chem_init is called in palm before
[2828]1542!--               check_parameters, since conc_pr_init is used there.
1543!--               We have to find another solution since chem_init should
1544!--               eventually be called from init_3d_model!!)
[3281]1545          ALLOCATE ( chem_species(lsp)%conc_pr_init(0:nz+1) )
1546          chem_species(lsp)%conc_pr_init(:) = 0.0_wp
[2425]1547
[3281]1548       ENDDO
[2425]1549
[2615]1550!
[3281]1551!--    Initial concentration of profiles is prescribed by parameters cs_profile
1552!--    and cs_heights in the namelist &chemistry_parameters
1553       CALL chem_init_profiles     
1554           
1555           
[2615]1556!
1557!-- Initialize model variables
[2425]1558
[3114]1559
[3281]1560       IF ( TRIM( initializing_actions ) /= 'read_restart_data'  .AND.            &
1561            TRIM( initializing_actions ) /= 'cyclic_fill' )  THEN
[2425]1562
[3228]1563
[2615]1564!--    First model run of a possible job queue.
[3282]1565!--    Initial profiles of the variables must be computed.
[3281]1566          IF ( INDEX( initializing_actions, 'set_1d-model_profiles' ) /= 0 )  THEN
[3282]1567            CALL location_message( 'initializing with 1D chemistry model profiles', .FALSE. )
[2615]1568!
1569!--        Transfer initial profiles to the arrays of the 3D model
[3281]1570             DO lsp = 1, nspec
1571                DO  i = nxlg, nxrg
1572                   DO  j = nysg, nyng
1573                      DO lpr_lev = 1, nz + 1
1574                         chem_species(lsp)%conc(lpr_lev,j,i) = chem_species(lsp)%conc_pr_init(lpr_lev)
1575                      ENDDO
[2615]1576                   ENDDO
[3281]1577                ENDDO   
1578             ENDDO
1579         
1580          ELSEIF ( INDEX(initializing_actions, 'set_constant_profiles') /= 0 )    &
1581          THEN
[3282]1582             CALL location_message( 'initializing with constant chemistry profiles', .FALSE. )
[2425]1583
[3281]1584             DO lsp = 1, nspec 
1585                DO  i = nxlg, nxrg
1586                   DO  j = nysg, nyng
1587                      chem_species(lsp)%conc(:,j,i) = chem_species(lsp)%conc_pr_init   
1588                   ENDDO
[2615]1589                ENDDO
1590             ENDDO
1591
[3281]1592          ENDIF
[2615]1593
[2535]1594!
[3281]1595!--       If required, change the surface chem spcs at the start of the 3D run
1596          IF ( cs_surface_initial_change(1) /= 0.0_wp ) THEN           
1597             DO lsp = 1, nspec 
1598                chem_species(lsp)%conc(nzb,:,:) = chem_species(lsp)%conc(nzb,:,:) +  &
1599                                                  cs_surface_initial_change(lsp)
1600             ENDDO
1601          ENDIF 
1602!
1603!--      Initiale old and new time levels.
1604          DO lsp = 1, nvar
1605             chem_species(lsp)%tconc_m = 0.0_wp                     
1606             chem_species(lsp)%conc_p  = chem_species(lsp)%conc     
[2615]1607          ENDDO
[2592]1608
[3281]1609       ENDIF
[2535]1610
[3114]1611
1612
[3281]1613!---   new code add above this line
1614       DO lsp = 1, nphot
1615          phot_frequen(lsp)%name = phot_names(lsp)
[3373]1616!
1617!--   todo: remove or replace by "CALL message" mechanism (kanani)
[3281]1618!         IF( myid == 0 )  THEN
1619!            WRITE(6,'(a,i4,3x,a)')  'Photolysis: ',lsp,trim(phot_names(lsp))
1620!         ENDIF
1621             phot_frequen(lsp)%freq(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => freq_1(:,:,:,lsp)
1622       ENDDO
[2425]1623
[3281]1624       RETURN
[2425]1625
[3085]1626 END SUBROUTINE chem_init
[2425]1627
[2535]1628!
1629!------------------------------------------------------------------------------!
1630!
1631! Description:
1632! ------------
[3085]1633!> Subroutine defining initial vertical profiles of chemical species (given by
1634!> namelist parameters chem_profiles and chem_heights)  --> which should work
1635!> analogue to parameters u_profile, v_profile and uv_heights)
[2535]1636!------------------------------------------------------------------------------!
[3281]1637    SUBROUTINE chem_init_profiles              !< SUBROUTINE is called from chem_init in case of
1638                                               !< TRIM( initializing_actions ) /= 'read_restart_data'
1639                                               !< We still need to see what has to be done in case of restart run
1640       USE chem_modules
[2615]1641
[3281]1642       IMPLICIT NONE
[2425]1643
[3281]1644   !-- Local variables
1645       INTEGER ::  lsp        !< running index for number of species in derived data type species_def
1646       INTEGER ::  lsp_usr     !< running index for number of species (user defined)  in cs_names, cs_profiles etc
1647       INTEGER ::  lpr_lev    !< running index for profile level for each chem spcs.
1648       INTEGER ::  npr_lev    !< the next available profile lev
[2425]1649
[3085]1650!-----------------
1651!-- Parameter "cs_profile" and "cs_heights" are used to prescribe user defined initial profiles
1652!-- and heights. If parameter "cs_profile" is not prescribed then initial surface values
1653!-- "cs_surface" are used as constant initial profiles for each species. If "cs_profile" and
1654!-- "cs_heights" are prescribed, their values will!override the constant profile given by
1655!-- "cs_surface".
[3114]1656!
[3281]1657       IF ( TRIM( initializing_actions ) /= 'read_restart_data' )  THEN
1658          lsp_usr = 1
1659          DO  WHILE ( TRIM( cs_name( lsp_usr ) ) /= 'novalue' )   !'novalue' is the default
1660             DO  lsp = 1, nspec                                !
[3282]1661!--             create initial profile (conc_pr_init) for each chemical species
[3281]1662                IF ( TRIM( chem_species(lsp)%name ) == TRIM( cs_name(lsp_usr) ) )  THEN   !
1663                   IF ( cs_profile(lsp_usr,1) == 9999999.9_wp ) THEN
[3282]1664!--                set a vertically constant profile based on the surface conc (cs_surface(lsp_usr)) of each species
1665                      DO lpr_lev = 0, nzt+1
1666                         chem_species(lsp)%conc_pr_init(lpr_lev) = cs_surface(lsp_usr)
1667                      ENDDO
[3281]1668                   ELSE
1669                      IF ( cs_heights(1,1) /= 0.0_wp )  THEN
1670                         message_string = 'The surface value of cs_heights must be 0.0'
1671                         CALL message( 'chem_check_parameters', 'CM0434', 1, 2, 0, 6, 0 )
1672                      ENDIF
1673     
1674                      use_prescribed_profile_data = .TRUE.
1675   
1676                      npr_lev = 1
1677!                     chem_species(lsp)%conc_pr_init(0) = 0.0_wp
1678                      DO  lpr_lev = 1, nz+1
1679                         IF ( npr_lev < 100 )  THEN
1680                            DO  WHILE ( cs_heights(lsp_usr, npr_lev+1) <= zu(lpr_lev) )
1681                               npr_lev = npr_lev + 1
1682                               IF ( npr_lev == 100 )  THEN
1683                                   message_string = 'number of chem spcs exceeding the limit'
1684                                   CALL message( 'chem_check_parameters', 'CM0435', 1, 2, 0, 6, 0 )               
1685                                   EXIT
1686                               ENDIF
1687                            ENDDO
1688                         ENDIF
1689                         IF ( npr_lev < 100  .AND.  cs_heights(lsp_usr, npr_lev + 1) /= 9999999.9_wp )  THEN
1690                            chem_species(lsp)%conc_pr_init(lpr_lev) = cs_profile(lsp_usr, npr_lev) +                          &
1691                                                    ( zu(lpr_lev) - cs_heights(lsp_usr, npr_lev) ) /                          &
1692                                                    ( cs_heights(lsp_usr, (npr_lev + 1)) - cs_heights(lsp_usr, npr_lev ) ) *  &
1693                                                    ( cs_profile(lsp_usr, (npr_lev + 1)) - cs_profile(lsp_usr, npr_lev ) )
1694                         ELSE
1695                               chem_species(lsp)%conc_pr_init(lpr_lev) = cs_profile(lsp_usr, npr_lev)
1696                         ENDIF
1697                      ENDDO
[3085]1698                   ENDIF
[3282]1699!-- If a profile is prescribed explicity using cs_profiles and cs_heights, then 
1700!-- chem_species(lsp)%conc_pr_init is populated with the specific "lsp" based
1701!-- on the cs_profiles(lsp_usr,:)  and cs_heights(lsp_usr,:).
[3281]1702                ENDIF
1703             ENDDO
1704             lsp_usr = lsp_usr + 1
[3085]1705          ENDDO
[3281]1706       ENDIF
[2425]1707
[3281]1708    END SUBROUTINE chem_init_profiles
[2828]1709!
[2535]1710!------------------------------------------------------------------------------!
1711!
1712! Description:
1713! ------------
1714!> Subroutine to integrate chemical species in the given chemical mechanism
1715!------------------------------------------------------------------------------!
1716
[3281]1717    SUBROUTINE chem_integrate_ij (i, j)
[2425]1718
[3281]1719       USE cpulog,                                                              &
1720          ONLY: cpu_log, log_point
[3287]1721       USE statistics,                                                          &
[3281]1722          ONLY:  weight_pres
[3287]1723        USE control_parameters,                                                 &
[3281]1724          ONLY:  dt_3d, intermediate_timestep_count,simulated_time
[2425]1725
[3281]1726       IMPLICIT   none
1727       INTEGER,INTENT(IN)       :: i,j
[2425]1728
[3281]1729 !--   local variables
[3282]1730       INTEGER(iwp) ::  lsp                                                     !< running index for chem spcs.
1731       INTEGER(iwp) ::  lph                                                     !< running index for photolysis frequencies
[3281]1732       INTEGER                  :: k,m,istatf
1733       INTEGER,DIMENSION(20)    :: istatus
1734       REAL(kind=wp),DIMENSION(nzb+1:nzt,nspec)                :: tmp_conc
1735       REAL(kind=wp),DIMENSION(nzb+1:nzt)                      :: tmp_temp
1736       REAL(kind=wp),DIMENSION(nzb+1:nzt)                      :: tmp_qvap
1737       REAL(kind=wp),DIMENSION(nzb+1:nzt,nphot)                :: tmp_phot
1738       REAL(kind=wp),DIMENSION(nzb+1:nzt)                      :: tmp_fact
1739       REAL(kind=wp),DIMENSION(nzb+1:nzt)                      :: tmp_fact_i    !< conversion factor between
1740                                                                                !<    molecules cm^{-3} and ppm
[3185]1741
[3281]1742       INTEGER,DIMENSION(nzb+1:nzt)                            :: nacc          !< Number of accepted steps
1743       INTEGER,DIMENSION(nzb+1:nzt)                            :: nrej          !< Number of rejected steps
[3185]1744
[3281]1745       REAL(wp)                         ::  conv                                !< conversion factor
1746       REAL(wp), PARAMETER              ::  ppm2fr  = 1.0e-6_wp                 !< Conversion factor ppm to fraction
1747       REAL(wp), PARAMETER              ::  xm_air  = 28.96_wp                  !< Mole mass of dry air
1748       REAL(wp), PARAMETER              ::  xm_h2o  = 18.01528_wp               !< Mole mass of water vapor
1749       REAL(wp), PARAMETER              ::  pref_i  = 1._wp / 100000.0_wp       !< inverse reference pressure (1/Pa)
1750       REAL(wp), PARAMETER              ::  t_std   = 273.15_wp                 !< standard pressure (Pa)
1751       REAL(wp), PARAMETER              ::  p_std   = 101325.0_wp               !< standard pressure (Pa)
1752       REAL(wp), PARAMETER              ::  vmolcm  = 22.414e3_wp               !< Mole volume (22.414 l) in cm^{-3}
1753       REAL(wp), PARAMETER              ::  xna     = 6.022e23_wp               !< Avogadro number (molecules/mol)
[2425]1754
[3281]1755       REAL(wp),DIMENSION(size(rcntrl)) :: rcntrl_local
[2615]1756
[3185]1757
[3281]1758       REAL(kind=wp)  :: dt_chem                                             
[2425]1759
[2535]1760       CALL cpu_log( log_point(80), '[chem_integrate_ij]', 'start' )
[3282]1761!<     set chem_gasphase_on to .FALSE. if you want to skip computation of gas phase chemistry
[3281]1762       IF (chem_gasphase_on) THEN
1763          nacc = 0
1764          nrej = 0
[2635]1765
[3287]1766       tmp_temp(:) = pt(nzb+1:nzt,j,i) * exner(nzb+1:nzt)
[3282]1767!         ppm to molecules/cm**3
[3287]1768!         tmp_fact = 1.e-6_wp*6.022e23_wp/(22.414_wp*1000._wp) * 273.15_wp * hyp(nzb+1:nzt)/( 101300.0_wp * tmp_temp ) 
[3281]1769          conv = ppm2fr * xna / vmolcm
1770          tmp_fact(:) = conv * t_std * hyp(nzb+1:nzt) / (tmp_temp(:) * p_std)
1771          tmp_fact_i = 1.0_wp/tmp_fact
[2615]1772
[3281]1773          IF ( humidity ) THEN
[3292]1774             IF ( bulk_cloud_model )  THEN
[3281]1775                tmp_qvap(:) = ( q(nzb+1:nzt,j,i) - ql(nzb+1:nzt,j,i) ) * xm_air/xm_h2o * tmp_fact(:)
1776             ELSE
1777                tmp_qvap(:) = q(nzb+1:nzt,j,i) * xm_air/xm_h2o * tmp_fact(:)
1778             ENDIF
[3114]1779          ELSE
[3281]1780             tmp_qvap(:) = 0.01 * tmp_fact(:)                          !< Constant value for q if water vapor is not computed
[3114]1781          ENDIF
1782
[3281]1783          DO lsp = 1,nspec
1784             tmp_conc(:,lsp) = chem_species(lsp)%conc(nzb+1:nzt,j,i) * tmp_fact(:) 
1785          ENDDO
[2425]1786
[3281]1787          DO lph = 1,nphot
1788             tmp_phot(:,lph) = phot_frequen(lph)%freq(nzb+1:nzt,j,i)               
1789          ENDDO
[3373]1790!
1791!--   todo: remove (kanani)
1792!           IF(myid == 0 .AND. chem_debug0 ) THEN
1793!              IF (i == 10 .and. j == 10) WRITE(0,*) 'begin chemics step ',dt_3d
1794!           ENDIF
[2425]1795
[3281]1796!--       Compute length of time step
1797          IF ( call_chem_at_all_substeps )  THEN
1798             dt_chem = dt_3d * weight_pres(intermediate_timestep_count)
1799          ELSE
1800             dt_chem = dt_3d
1801          ENDIF
[2425]1802
[3281]1803          cs_time_step = dt_chem
[2425]1804
[3281]1805          CALL cpu_log( log_point(81), '{chem_gasphase_integrate}', 'start' )
[2425]1806
[3281]1807          IF(maxval(rcntrl) > 0.0)   THEN    ! Only if rcntrl is set
1808             IF( simulated_time <= 2*dt_3d)  THEN
1809                 rcntrl_local = 0
[3373]1810!
1811!--   todo: remove (kanani)
1812!                  WRITE(9,'(a,2f10.3)') 'USE Default rcntrl in the first steps ',simulated_time,dt_3d
[3281]1813             ELSE
1814                 rcntrl_local = rcntrl
1815             ENDIF
1816          ELSE
1817             rcntrl_local = 0
1818          END IF
[2425]1819
[3281]1820          CALL chem_gasphase_integrate (dt_chem, tmp_conc, tmp_temp, tmp_qvap, tmp_fact, tmp_phot, &
1821                             icntrl_i = icntrl, rcntrl_i = rcntrl_local, xnacc = nacc, xnrej = nrej, istatus=istatus)
[2425]1822
[3281]1823          CALL cpu_log( log_point(81), '{chem_gasphase_integrate}', 'stop' )
[2425]1824
[3281]1825          DO lsp = 1,nspec
1826             chem_species(lsp)%conc (nzb+1:nzt,j,i) = tmp_conc(:,lsp) * tmp_fact_i(:)
1827          ENDDO
[3185]1828
[2535]1829
[3281]1830       ENDIF
1831          CALL cpu_log( log_point(80), '[chem_integrate_ij]', 'stop' )
1832
[2615]1833       RETURN
[3281]1834    END SUBROUTINE chem_integrate_ij
[2535]1835!
1836!------------------------------------------------------------------------------!
1837!
1838! Description:
1839! ------------
[3085]1840!> Subroutine defining parin for &chemistry_parameters for chemistry model
[2535]1841!------------------------------------------------------------------------------!
[3281]1842    SUBROUTINE chem_parin
[3085]1843   
[3281]1844       USE chem_modules
1845       USE control_parameters
[3287]1846     
[3281]1847       USE kinds
1848       USE pegrid
1849       USE statistics
1850           
1851       IMPLICIT   NONE
[2425]1852
[3282]1853       CHARACTER (LEN=80) ::  line                        !< dummy string that contains the current line of the parameter file
[3281]1854       CHARACTER (LEN=3)  ::  cs_prefix 
[2425]1855
[3282]1856       REAL(wp), DIMENSION(nmaxfixsteps) ::   my_steps    !< List of fixed timesteps   my_step(1) = 0.0 automatic stepping
1857       INTEGER(iwp) ::  i                                 !<
1858       INTEGER(iwp) ::  j                                 !<
1859       INTEGER(iwp) ::  max_pr_cs_tmp                     !<
[2425]1860
1861
[3281]1862       NAMELIST /chemistry_parameters/  bc_cs_b,                          &
[3085]1863                                        bc_cs_t,                          &
1864                                        call_chem_at_all_substeps,        &
1865                                        chem_debug0,                      &
1866                                        chem_debug1,                      &
1867                                        chem_debug2,                      &
1868                                        chem_gasphase_on,                 &
1869                                        cs_heights,                       &
1870                                        cs_name,                          &
1871                                        cs_profile,                       &
1872                                        cs_profile_name,                  & 
1873                                        cs_surface,                       &
1874                                        decycle_chem_lr,                  &
1875                                        decycle_chem_ns,                  &           
1876                                        decycle_method,                   & 
1877                                        emiss_factor_main,                &
1878                                        emiss_factor_side,                &                     
1879                                        icntrl,                           &
1880                                        main_street_id,                   &
1881                                        max_street_id,                    &
1882                                        my_steps,                         &
[3228]1883                                        nest_chemistry,                   &
[3085]1884                                        rcntrl,                           &
1885                                        side_street_id,                   &
1886                                        photolysis_scheme,                &
1887                                        wall_csflux,                      &
1888                                        cs_vertical_gradient,             &
1889                                        top_csflux,                       & 
1890                                        surface_csflux,                   &
1891                                        surface_csflux_name,              &
1892                                        cs_surface_initial_change,        &
[3190]1893                                        cs_vertical_gradient_level,       &
[3282]1894!                                       namelist parameters for emissions
[3190]1895                                        mode_emis,                        &
1896                                        time_fac_type,                    &
1897                                        daytype_mdh,                      &
1898                                        do_emis                             
[3085]1899                             
1900!-- analogue to chem_names(nspj) we could invent chem_surfaceflux(nspj) and chem_topflux(nspj)
1901!-- so this way we could prescribe a specific flux value for each species
1902!>  chemistry_parameters for initial profiles
1903!>  cs_names = 'O3', 'NO2', 'NO', ...   to set initial profiles)
1904!>  cs_heights(1,:) = 0.0, 100.0, 500.0, 2000.0, .... (height levels where concs will be prescribed for O3)
1905!>  cs_heights(2,:) = 0.0, 200.0, 400.0, 1000.0, .... (same for NO2 etc.)
1906!>  cs_profiles(1,:) = 10.0, 20.0, 20.0, 30.0, .....  (chem spcs conc at height lvls chem_heights(1,:)) etc.
1907!>  If the respective concentration profile should be constant with height, then use "cs_surface( number of spcs)"
1908!>  then write these cs_surface values to chem_species(lsp)%conc_pr_init(:)
[2425]1909
1910!
[3085]1911!--   Read chem namelist   
[3185]1912
[3281]1913       INTEGER             :: ier
1914       CHARACTER(LEN=64)   :: text
1915       CHARACTER(LEN=8)    :: solver_type
[3185]1916
[3281]1917       icntrl    = 0
1918       rcntrl    = 0.0_wp
1919       my_steps  = 0.0_wp
1920       photolysis_scheme = 'simple'
1921       atol = 1.0_wp
1922       rtol = 0.01_wp
1923 !
1924 !--   Try to find chemistry package
1925       REWIND ( 11 )
1926       line = ' '
1927       DO   WHILE ( INDEX( line, '&chemistry_parameters' ) == 0 )
[3287]1928          READ ( 11, '(A)', END=20 )  line
[3281]1929       ENDDO
1930       BACKSPACE ( 11 )
1931 !
1932 !--   Read chemistry namelist
[3287]1933       READ ( 11, chemistry_parameters, ERR = 10, END = 20 )     
[3281]1934 !
1935 !--   Enable chemistry model
1936       air_chemistry = .TRUE.                   
[3449]1937       GOTO 20
[3287]1938
[3449]1939 10    BACKSPACE( 11 )
1940       READ( 11 , '(A)') line
1941       CALL parin_fail_message( 'chemistry_parameters', line )
[3287]1942
[3449]1943 20    CONTINUE
[3287]1944
1945!
1946!--    check for  emission mode for chem species
[3281]1947       IF ( (mode_emis /= 'PARAMETERIZED')  .AND. ( mode_emis /= 'DEFAULT') .AND. (mode_emis /= 'PRE-PROCESSED'  ) )   THEN
1948            message_string = 'Incorrect mode_emiss  option select. Please check spelling'
1949            CALL message( 'chem_check_parameters', 'CM0436', 1, 2, 0, 6, 0 )
1950       ENDIF
[2425]1951
[3282]1952       t_steps = my_steps         
1953                                   
1954!--    Determine the number of user-defined profiles and append them to the
1955!--    standard data output (data_output_pr)
[3085]1956       max_pr_cs_tmp = 0 
1957       i = 1
[2425]1958
[3085]1959       DO  WHILE ( data_output_pr(i)  /= ' '  .AND.  i <= 100 )
1960          IF ( TRIM( data_output_pr(i)(1:3)) == 'kc_' ) THEN
1961             max_pr_cs_tmp = max_pr_cs_tmp+1
[2615]1962          ENDIF
[3085]1963          i = i +1
[2615]1964       ENDDO
[2425]1965
[3085]1966       IF ( max_pr_cs_tmp > 0 ) THEN
1967          cs_pr_namelist_found = .TRUE.
1968          max_pr_cs = max_pr_cs_tmp
[2914]1969       ENDIF
[3185]1970
1971!      Set Solver Type
[3260]1972       IF(icntrl(3) == 0)   THEN
[3185]1973          solver_type = 'rodas3'           !Default
[3260]1974       ELSE IF(icntrl(3) == 1)   THEN
[3185]1975          solver_type = 'ros2'
[3260]1976       ELSE IF(icntrl(3) == 2)   THEN
[3185]1977          solver_type = 'ros3'
[3260]1978       ELSE IF(icntrl(3) == 3)   THEN
[3185]1979          solver_type = 'ro4'
[3260]1980       ELSE IF(icntrl(3) == 4)   THEN
[3185]1981          solver_type = 'rodas3'
[3260]1982       ELSE IF(icntrl(3) == 5)   THEN
[3185]1983          solver_type = 'rodas4'
[3260]1984       ELSE IF(icntrl(3) == 6)   THEN
[3185]1985          solver_type = 'Rang3'
[3260]1986       ELSE
[3373]1987           message_string = 'illegal solver type'
1988           CALL message( 'chem_parin', 'PA0506', 1, 2, 0, 6, 0 )
[3260]1989       END IF
[3185]1990
[3373]1991!
1992!--   todo: remove or replace by "CALL message" mechanism (kanani)
1993!       write(text,*) 'gas_phase chemistry: solver_type = ',trim(solver_type)
[3185]1994!kk    Has to be changed to right calling sequence
1995!kk       CALL location_message( trim(text), .FALSE. )
[3373]1996!        IF(myid == 0)   THEN
1997!           write(9,*) ' '
1998!           write(9,*) 'kpp setup '
1999!           write(9,*) ' '
2000!           write(9,*) '    gas_phase chemistry: solver_type = ',trim(solver_type)
2001!           write(9,*) ' '
2002!           write(9,*) '    Hstart  = ',rcntrl(3)
2003!           write(9,*) '    FacMin  = ',rcntrl(4)
2004!           write(9,*) '    FacMax  = ',rcntrl(5)
2005!           write(9,*) ' '
2006!           IF(vl_dim > 1)    THEN
2007!              write(9,*) '    Vector mode                   vektor length = ',vl_dim
2008!           ELSE
2009!              write(9,*) '    Scalar mode'
2010!           ENDIF
2011!           write(9,*) ' '
2012!        END IF
[3185]2013
[3281]2014       RETURN
[2491]2015
[3281]2016    END SUBROUTINE chem_parin
[2467]2017
2018!
[2828]2019!------------------------------------------------------------------------------!
[2467]2020!
[2828]2021! Description:
2022! ------------
2023!> Subroutine calculating prognostic equations for chemical species
2024!> (vector-optimized).
2025!> Routine is called separately for each chemical species over a loop from
2026!> prognostic_equations.
2027!------------------------------------------------------------------------------!
[3281]2028    SUBROUTINE chem_prognostic_equations ( cs_scalar_p, cs_scalar, tcs_scalar_m,  &
2029                                           pr_init_cs, ilsp )
[2467]2030
[3281]2031       USE advec_s_pw_mod,                                                        &
2032           ONLY:  advec_s_pw
2033       USE advec_s_up_mod,                                                        &
2034           ONLY:  advec_s_up
2035       USE advec_ws,                                                              &
2036           ONLY:  advec_s_ws 
2037       USE diffusion_s_mod,                                                       &
2038           ONLY:  diffusion_s
2039       USE indices,                                                               &
2040           ONLY:  nxl, nxr, nyn, nys, wall_flags_0
2041       USE pegrid
2042       USE surface_mod,                                                           &
2043           ONLY:  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h,     &
2044                  surf_usm_v
[2828]2045
[3281]2046       IMPLICIT NONE
[2828]2047
[3281]2048       INTEGER ::  i   !< running index
2049       INTEGER ::  j   !< running index
2050       INTEGER ::  k   !< running index
[2828]2051
[3281]2052       INTEGER(iwp),INTENT(IN) ::  ilsp          !<
[2828]2053
[3281]2054       REAL(wp), DIMENSION(0:nz+1) ::  pr_init_cs   !<
[2828]2055
[3281]2056       REAL(wp), DIMENSION(:,:,:), POINTER ::  cs_scalar      !<
2057       REAL(wp), DIMENSION(:,:,:), POINTER ::  cs_scalar_p    !<
2058       REAL(wp), DIMENSION(:,:,:), POINTER ::  tcs_scalar_m   !<
[2828]2059
2060
[3281]2061   !
2062   !-- Tendency terms for chemical species
2063       tend = 0.0_wp
2064   !   
2065   !-- Advection terms
2066       IF ( timestep_scheme(1:5) == 'runge' )  THEN
2067          IF ( ws_scheme_sca )  THEN
2068             CALL advec_s_ws( cs_scalar, 'kc' )
2069          ELSE
2070             CALL advec_s_pw( cs_scalar )
2071          ENDIF
[2828]2072       ELSE
[3281]2073            CALL advec_s_up( cs_scalar )
[2828]2074       ENDIF
[3281]2075   !
2076   !-- Diffusion terms  (the last three arguments are zero)
2077       CALL diffusion_s( cs_scalar,                                               &
2078                         surf_def_h(0)%cssws(ilsp,:),                             &
2079                         surf_def_h(1)%cssws(ilsp,:),                             &
2080                         surf_def_h(2)%cssws(ilsp,:),                             &
2081                         surf_lsm_h%cssws(ilsp,:),                                &
2082                         surf_usm_h%cssws(ilsp,:),                                &
2083                         surf_def_v(0)%cssws(ilsp,:),                             &
2084                         surf_def_v(1)%cssws(ilsp,:),                             &
2085                         surf_def_v(2)%cssws(ilsp,:),                             &
2086                         surf_def_v(3)%cssws(ilsp,:),                             &
2087                         surf_lsm_v(0)%cssws(ilsp,:),                             &
2088                         surf_lsm_v(1)%cssws(ilsp,:),                             &
2089                         surf_lsm_v(2)%cssws(ilsp,:),                             &
2090                         surf_lsm_v(3)%cssws(ilsp,:),                             &
2091                         surf_usm_v(0)%cssws(ilsp,:),                             &
2092                         surf_usm_v(1)%cssws(ilsp,:),                             &
2093                         surf_usm_v(2)%cssws(ilsp,:),                             &
2094                         surf_usm_v(3)%cssws(ilsp,:) )
2095   !   
2096   !-- Prognostic equation for chemical species
2097       DO  i = nxl, nxr
2098          DO  j = nys, nyn   
2099             DO  k = nzb+1, nzt
2100                cs_scalar_p(k,j,i) =   cs_scalar(k,j,i)                           &
2101                                     + ( dt_3d  *                                 &
2102                                         (   tsc(2) * tend(k,j,i)                 &
2103                                           + tsc(3) * tcs_scalar_m(k,j,i)         &
2104                                         )                                        & 
2105                                       - tsc(5) * rdf_sc(k)                       &
2106                                                * ( cs_scalar(k,j,i) - pr_init_cs(k) )    &   
2107                                       )                                          &
2108                                       * MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )       
[2828]2109
[3281]2110                IF ( cs_scalar_p(k,j,i) < 0.0_wp )  cs_scalar_p(k,j,i) = 0.1_wp * cs_scalar(k,j,i)
2111             ENDDO
[2828]2112          ENDDO
2113       ENDDO
[3281]2114   !
2115   !-- Calculate tendencies for the next Runge-Kutta step
2116       IF ( timestep_scheme(1:5) == 'runge' )  THEN
2117          IF ( intermediate_timestep_count == 1 )  THEN
2118             DO  i = nxl, nxr
2119                DO  j = nys, nyn   
2120                   DO  k = nzb+1, nzt
2121                      tcs_scalar_m(k,j,i) = tend(k,j,i)
2122                   ENDDO
[2828]2123                ENDDO
2124             ENDDO
[3281]2125          ELSEIF ( intermediate_timestep_count < &
2126             intermediate_timestep_count_max )  THEN
2127             DO  i = nxl, nxr
2128                DO  j = nys, nyn
2129                   DO  k = nzb+1, nzt
2130                      tcs_scalar_m(k,j,i) = - 9.5625_wp * tend(k,j,i)             &
2131                                            + 5.3125_wp * tcs_scalar_m(k,j,i)
2132                   ENDDO
[2828]2133                ENDDO
2134             ENDDO
[3281]2135          ENDIF
[2828]2136       ENDIF
2137
[3281]2138    END SUBROUTINE chem_prognostic_equations
[3228]2139
[2482]2140!------------------------------------------------------------------------------!
[2535]2141!
[2482]2142! Description:
2143! ------------
[3085]2144!> Subroutine calculating prognostic equations for chemical species
2145!> (cache-optimized).
2146!> Routine is called separately for each chemical species over a loop from
2147!> prognostic_equations.
[2482]2148!------------------------------------------------------------------------------!
[3281]2149    SUBROUTINE chem_prognostic_equations_ij ( cs_scalar_p, cs_scalar, tcs_scalar_m, pr_init_cs,    &
2150                               i, j, i_omp_start, tn, ilsp, flux_s_cs, diss_s_cs,                  &
2151                               flux_l_cs, diss_l_cs )
2152       USE pegrid         
2153       USE advec_ws,        ONLY:  advec_s_ws 
2154       USE advec_s_pw_mod,  ONLY:  advec_s_pw
2155       USE advec_s_up_mod,  ONLY:  advec_s_up
2156       USE diffusion_s_mod, ONLY:  diffusion_s
2157       USE indices,         ONLY:  wall_flags_0
2158       USE surface_mod,     ONLY:  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h,     &
2159                                   surf_usm_v
[3085]2160
2161
[3281]2162       IMPLICIT NONE
[3085]2163
[3281]2164       REAL(wp), DIMENSION(:,:,:), POINTER   :: cs_scalar_p, cs_scalar, tcs_scalar_m
[3085]2165
[3281]2166       INTEGER(iwp),INTENT(IN) :: i, j, i_omp_start, tn, ilsp
2167       REAL(wp), DIMENSION(nzb+1:nzt,0:threads_per_task-1)         :: flux_s_cs   !<
2168       REAL(wp), DIMENSION(nzb+1:nzt,0:threads_per_task-1)         :: diss_s_cs   !<
2169       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn,0:threads_per_task-1) :: flux_l_cs   !<
2170       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn,0:threads_per_task-1) :: diss_l_cs   !<
2171       REAL(wp), DIMENSION(0:nz+1)                                 :: pr_init_cs  !<
[3085]2172
2173!-- local variables
2174
[3281]2175       INTEGER :: k
2176!
2177!--    Tendency-terms for chem spcs.
2178       tend(:,j,i) = 0.0_wp
[3085]2179!   
2180!-- Advection terms
[3281]2181       IF ( timestep_scheme(1:5) == 'runge' )  THEN
2182          IF ( ws_scheme_sca )  THEN
2183             CALL advec_s_ws( i, j, cs_scalar, 'kc', flux_s_cs, diss_s_cs,                &
2184                flux_l_cs, diss_l_cs, i_omp_start, tn )
2185          ELSE
2186             CALL advec_s_pw( i, j, cs_scalar )
2187          ENDIF
[3085]2188       ELSE
[3281]2189            CALL advec_s_up( i, j, cs_scalar )
[3085]2190       ENDIF
2191
2192!
2193
2194!-- Diffusion terms (the last three arguments are zero)
2195
[3281]2196         CALL diffusion_s( i, j, cs_scalar,                                                 &
2197                           surf_def_h(0)%cssws(ilsp,:), surf_def_h(1)%cssws(ilsp,:),        &
2198                           surf_def_h(2)%cssws(ilsp,:),                                     &
2199                           surf_lsm_h%cssws(ilsp,:), surf_usm_h%cssws(ilsp,:),              &
2200                           surf_def_v(0)%cssws(ilsp,:), surf_def_v(1)%cssws(ilsp,:),        &
2201                           surf_def_v(2)%cssws(ilsp,:), surf_def_v(3)%cssws(ilsp,:),        &
2202                           surf_lsm_v(0)%cssws(ilsp,:), surf_lsm_v(1)%cssws(ilsp,:),        &
2203                           surf_lsm_v(2)%cssws(ilsp,:), surf_lsm_v(3)%cssws(ilsp,:),        &
2204                           surf_usm_v(0)%cssws(ilsp,:), surf_usm_v(1)%cssws(ilsp,:),        &
2205                           surf_usm_v(2)%cssws(ilsp,:), surf_usm_v(3)%cssws(ilsp,:) )
2206   
[3085]2207!   
2208!-- Prognostic equation for chem spcs
[3281]2209       DO k = nzb+1, nzt
2210          cs_scalar_p(k,j,i) = cs_scalar(k,j,i) + ( dt_3d  *                       &
2211                                                  ( tsc(2) * tend(k,j,i) +         &
2212                                                    tsc(3) * tcs_scalar_m(k,j,i) ) & 
2213                                                  - tsc(5) * rdf_sc(k)             &
2214                                                           * ( cs_scalar(k,j,i) - pr_init_cs(k) )    &   
2215                                                  )                                                  &
2216                                                           * MERGE( 1.0_wp, 0.0_wp,                  &     
2217                                                                   BTEST( wall_flags_0(k,j,i), 0 )   &             
2218                                                                    )       
[2467]2219
[3281]2220          IF ( cs_scalar_p(k,j,i) < 0.0_wp )  cs_scalar_p(k,j,i) = 0.1_wp * cs_scalar(k,j,i)    !FKS6
2221       ENDDO
[3085]2222
[2482]2223!
[3085]2224!-- Calculate tendencies for the next Runge-Kutta step
[3281]2225       IF ( timestep_scheme(1:5) == 'runge' )  THEN
2226          IF ( intermediate_timestep_count == 1 )  THEN
2227             DO  k = nzb+1, nzt
2228                tcs_scalar_m(k,j,i) = tend(k,j,i)
2229             ENDDO
2230          ELSEIF ( intermediate_timestep_count < &
2231             intermediate_timestep_count_max )  THEN
2232             DO  k = nzb+1, nzt
2233                tcs_scalar_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
2234                   5.3125_wp * tcs_scalar_m(k,j,i)
2235             ENDDO
2236          ENDIF
[3085]2237       ENDIF
2238
[3281]2239    END SUBROUTINE chem_prognostic_equations_ij
[3085]2240
[2482]2241!
[3085]2242!------------------------------------------------------------------------------!
2243!
2244! Description:
2245! ------------
2246!> Subroutine to read restart data of chemical species
2247!------------------------------------------------------------------------------!
[2828]2248
[3281]2249    SUBROUTINE chem_rrd_local( i, k, nxlf, nxlc, nxl_on_file, nxrf, nxrc,         &
2250                               nxr_on_file, nynf, nync, nyn_on_file, nysf, nysc,  &
2251                               nys_on_file, tmp_3d, found )   
2252                                       
2253       USE control_parameters
2254               
2255       USE indices
2256       
2257       USE pegrid
[3085]2258
[3281]2259       IMPLICIT NONE
[3085]2260
[3281]2261       CHARACTER (LEN=20) :: spc_name_av !<   
2262         
2263       INTEGER(iwp) ::  i, lsp          !<
2264       INTEGER(iwp) ::  k               !<
2265       INTEGER(iwp) ::  nxlc            !<
2266       INTEGER(iwp) ::  nxlf            !<
2267       INTEGER(iwp) ::  nxl_on_file     !<   
2268       INTEGER(iwp) ::  nxrc            !<
2269       INTEGER(iwp) ::  nxrf            !<
2270       INTEGER(iwp) ::  nxr_on_file     !<   
2271       INTEGER(iwp) ::  nync            !<
2272       INTEGER(iwp) ::  nynf            !<
2273       INTEGER(iwp) ::  nyn_on_file     !<   
2274       INTEGER(iwp) ::  nysc            !<
2275       INTEGER(iwp) ::  nysf            !<
2276       INTEGER(iwp) ::  nys_on_file     !<   
[3085]2277       
[3281]2278       LOGICAL, INTENT(OUT)  :: found 
[3085]2279
[3281]2280       REAL(wp), DIMENSION(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d   !< 3D array to temp store data
[3085]2281
2282
[3281]2283       found = .FALSE. 
[3085]2284
2285
[3281]2286          IF ( ALLOCATED(chem_species) )  THEN
[3085]2287
[3281]2288             DO  lsp = 1, nspec
[3085]2289
[3281]2290                 !< for time-averaged chemical conc.
2291                spc_name_av  =  TRIM(chem_species(lsp)%name)//'_av'
[3085]2292
[3281]2293                IF (restart_string(1:length) == TRIM(chem_species(lsp)%name) )    &
2294                THEN
2295                   !< read data into tmp_3d
2296                   IF ( k == 1 )  READ ( 13 )  tmp_3d 
2297                   !< fill ..%conc in the restart run   
2298                   chem_species(lsp)%conc(:,nysc-nbgp:nync+nbgp,                  &
2299                                          nxlc-nbgp:nxrc+nbgp) =                  & 
2300                   tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
2301                   found = .TRUE.
2302                ELSEIF (restart_string(1:length) == spc_name_av )  THEN
2303                   IF ( k == 1 )  READ ( 13 )  tmp_3d
2304                   chem_species(lsp)%conc_av(:,nysc-nbgp:nync+nbgp,               &
2305                                             nxlc-nbgp:nxrc+nbgp) =               &
2306                   tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
2307                   found = .TRUE.
2308                ENDIF
[3085]2309
[3281]2310             ENDDO
[3085]2311
[3281]2312          ENDIF
[3085]2313
2314
[3281]2315    END SUBROUTINE chem_rrd_local
[3085]2316!
2317!-------------------------------------------------------------------------------!
2318!> Description:
2319!> Calculation of horizontally averaged profiles
2320!> This routine is called for every statistic region (sr) defined by the user,
2321!> but at least for the region "total domain" (sr=0).
2322!> quantities.
[2828]2323!------------------------------------------------------------------------------!
[3281]2324    SUBROUTINE chem_statistics( mode, sr, tn )
[3085]2325
2326
[3281]2327       USE arrays_3d
2328       USE indices
2329       USE kinds
2330       USE pegrid
2331       USE statistics
[3085]2332
2333    USE user
2334
2335    IMPLICIT NONE
2336
2337    CHARACTER (LEN=*) ::  mode   !<
2338
2339    INTEGER(iwp) :: i    !< running index on x-axis
2340    INTEGER(iwp) :: j    !< running index on y-axis
2341    INTEGER(iwp) :: k    !< vertical index counter
2342    INTEGER(iwp) :: sr   !< statistical region
2343    INTEGER(iwp) :: tn   !< thread number
2344    INTEGER(iwp) :: n    !<
2345    INTEGER(iwp) :: m    !<
2346    INTEGER(iwp) :: lpr  !< running index chem spcs
2347!    REAL(wp),                                                                                      &
2348!    DIMENSION(dots_num_palm+1:dots_max) ::                                                         &
2349!          ts_value_l   !<
2350
2351    IF ( mode == 'profiles' )  THEN
[2615]2352!
[3085]2353!--    Sample on how to calculate horizontally averaged profiles of user-
2354!--    defined quantities. Each quantity is identified by the index
2355!--    "pr_palm+#" where "#" is an integer starting from 1. These
2356!--    user-profile-numbers must also be assigned to the respective strings
2357!--    given by data_output_pr_cs in routine user_check_data_output_pr.
2358!--    hom(:,:,:,:) =  dim-1 = vertical level, dim-2= 1: met-species,2:zu/zw, dim-3 = quantity( e.g.
2359!                       w*pt*), dim-4 = statistical region.
2360
2361       !$OMP DO
2362       DO  i = nxl, nxr
2363          DO  j = nys, nyn
2364              DO  k = nzb, nzt+1
2365                DO lpr = 1, cs_pr_count
2366
2367                   sums_l(k,pr_palm+lpr,tn) = sums_l(k,pr_palm+lpr,tn) +    &
2368                                                 chem_species(cs_pr_index(lpr))%conc(k,j,i) *       &
2369                                                 rmask(j,i,sr)  *                                   &
2370                                                 MERGE( 1.0_wp, 0.0_wp,                             &
2371                                                 BTEST( wall_flags_0(k,j,i), 22 ) )
2372                ENDDO                                                                         
2373             ENDDO
2374          ENDDO
2375       ENDDO
2376    ELSEIF ( mode == 'time_series' )  THEN
[3282]2377       CALL location_message( 'Time series not calculated for chemistry', .TRUE. )
2378    ENDIF
[3085]2379
[3281]2380    END SUBROUTINE chem_statistics
[3085]2381!
2382!------------------------------------------------------------------------------!
2383!
[2828]2384! Description:
2385! ------------
[3085]2386!> Subroutine for swapping of timelevels for chemical species
2387!> called out from subroutine swap_timelevel
2388!------------------------------------------------------------------------------!
2389
[3281]2390    SUBROUTINE chem_swap_timelevel (level)
[3085]2391
[3281]2392          IMPLICIT   none
[3085]2393
[3281]2394          INTEGER,INTENT(IN)        :: level
2395!--       local variables
2396          INTEGER                   :: lsp
[3085]2397
[3298]2398
[3281]2399          IF ( level == 0 ) THEN
2400             DO lsp=1, nvar                                       
2401                chem_species(lsp)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => spec_conc_1(:,:,:,lsp)
2402                chem_species(lsp)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg)  => spec_conc_2(:,:,:,lsp)
2403             ENDDO
2404          ELSE
2405             DO lsp=1, nvar                                       
2406                chem_species(lsp)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => spec_conc_2(:,:,:,lsp)
2407                chem_species(lsp)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg)  => spec_conc_1(:,:,:,lsp)
2408             ENDDO
2409          ENDIF
[3085]2410
[3281]2411       RETURN
2412    END SUBROUTINE chem_swap_timelevel
[3085]2413!
[2615]2414!------------------------------------------------------------------------------!
[3085]2415!
[2615]2416! Description:
2417! ------------
[3085]2418!> Subroutine to write restart data for chemistry model
[2615]2419!------------------------------------------------------------------------------!
[3281]2420    SUBROUTINE chem_wrd_local
[2482]2421
[3281]2422       IMPLICIT NONE
[2615]2423
[3281]2424       INTEGER(iwp) ::  lsp !<
[2615]2425
[3281]2426       DO  lsp = 1, nspec
2427          CALL wrd_write_string( TRIM( chem_species(lsp)%name ))
2428          WRITE ( 14 )  chem_species(lsp)%conc
2429          CALL wrd_write_string( TRIM( chem_species(lsp)%name )//'_av' )
2430          WRITE ( 14 )  chem_species(lsp)%conc_av
2431       ENDDO
[2615]2432
[3281]2433    END SUBROUTINE chem_wrd_local
[2615]2434 END MODULE chemistry_model_mod
2435
Note: See TracBrowser for help on using the repository browser.