source: palm/trunk/SOURCE/salsa_mod.f90 @ 3885

Last change on this file since 3885 was 3885, checked in by kanani, 2 years ago

restructure/add location/debug messages

  • Property svn:keywords set to Id
File size: 476.4 KB
Line 
1!> @file salsa_mod.f90
2!--------------------------------------------------------------------------------!
3! This file is part of PALM-4U.
4!
5! PALM-4U 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-4U is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 2018-2019 University of Helsinki
18! Copyright 1997-2019 Leibniz Universitaet Hannover
19!--------------------------------------------------------------------------------!
20!
21! Current revisions:
22! -----------------
23!
24!
25! Former revisions:
26! -----------------
27! $Id: salsa_mod.f90 3885 2019-04-11 11:29:34Z kanani $
28! Changes related to global restructuring of location messages and introduction
29! of additional debug messages
30!
31! 3876 2019-04-08 18:41:49Z knoop
32! Introduced salsa_actions module interface
33!
34! 3871 2019-04-08 14:38:39Z knoop
35! Major changes in formatting, performance and data input structure (see branch
36! the history for details)
37! - Time-dependent emissions enabled: lod=1 for yearly PM emissions that are
38!   normalised depending on the time, and lod=2 for preprocessed emissions
39!   (similar to the chemistry module).
40! - Additionally, 'uniform' emissions allowed. This emission is set constant on
41!   all horisontal upward facing surfaces and it is created based on parameters
42!   surface_aerosol_flux, aerosol_flux_dpg/sigmag/mass_fracs_a/mass_fracs_b.
43! - All emissions are now implemented as surface fluxes! No 3D sources anymore.
44! - Update the emission information by calling salsa_emission_update if
45!   skip_time_do_salsa >= time_since_reference_point and
46!   next_aero_emission_update <= time_since_reference_point
47! - Aerosol background concentrations read from PIDS_DYNAMIC. The vertical grid
48!   must match the one applied in the model.
49! - Gas emissions and background concentrations can be also read in in salsa_mod
50!   if the chemistry module is not applied.
51! - In deposition, information on the land use type can be now imported from
52!   the land use model
53! - Use SI units in PARIN, i.e. n_lognorm given in #/m3 and dpg in metres.
54! - Apply 100 character line limit
55! - Change all variable names from capital to lowercase letter
56! - Change real exponents to integer if possible. If not, precalculate the value
57!   value of exponent
58! - Rename in1a to start_subrange_1a, fn2a to end_subrange_1a etc.
59! - Rename nbins --> nbins_aerosol, ncc_tot --> ncomponents_mass and ngast -->
60!   ngases_salsa
61! - Rename ibc to index_bc, idu to index_du etc.
62! - Renamed loop indices b, c and sg to ib, ic and ig
63! - run_salsa subroutine removed
64! - Corrected a bud in salsa_driver: falsely applied ino instead of inh
65! - Call salsa_tendency within salsa_prognostic_equations which is called in
66!   module_interface_mod instead of prognostic_equations_mod
67! - Removed tailing white spaces and unused variables
68! - Change error message to start by PA instead of SA
69!
70! 3833 2019-03-28 15:04:04Z forkel
71! added USE chem_gasphase_mod for nvar, nspec and spc_names
72!
73! 3787 2019-03-07 08:43:54Z raasch
74! unused variables removed
75!
76! 3780 2019-03-05 11:19:45Z forkel
77! unused variable for file index removed from rrd-subroutines parameter list
78!
79! 3685 2019-01-21 01:02:11Z knoop
80! Some interface calls moved to module_interface + cleanup
81!
82! 3655 2019-01-07 16:51:22Z knoop
83! Implementation of the PALM module interface
84!
85! 3636 2018-12-19 13:48:34Z raasch
86! nopointer option removed
87!
88! 3630 2018-12-17 11:04:17Z knoop
89! - Moved the control parameter "salsa" from salsa_mod.f90 to control_parameters
90! - Updated salsa_rrd_local and salsa_wrd_local
91! - Add target attribute
92! - Revise initialization in case of restarts
93! - Revise masked data output
94!
95! 3582 2018-11-29 19:16:36Z suehring
96! missing comma separator inserted
97!
98! 3483 2018-11-02 14:19:26Z raasch
99! bugfix: directives added to allow compilation without netCDF
100!
101! 3481 2018-11-02 09:14:13Z raasch
102! temporary variable cc introduced to circumvent a possible Intel18 compiler bug
103! related to contiguous/non-contguous pointer/target attributes
104!
105! 3473 2018-10-30 20:50:15Z suehring
106! NetCDF input routine renamed
107!
108! 3467 2018-10-30 19:05:21Z suehring
109! Initial revision
110!
111! 3412 2018-10-24 07:25:57Z monakurppa
112!
113! Authors:
114! --------
115! @author Mona Kurppa (University of Helsinki)
116!
117!
118! Description:
119! ------------
120!> Sectional aerosol module for large scale applications SALSA
121!> (Kokkola et al., 2008, ACP 8, 2469-2483). Solves the aerosol number and mass
122!> concentration as well as chemical composition. Includes aerosol dynamic
123!> processes: nucleation, condensation/evaporation of vapours, coagulation and
124!> deposition on tree leaves, ground and roofs.
125!> Implementation is based on formulations implemented in UCLALES-SALSA except
126!> for deposition which is based on parametrisations by Zhang et al. (2001,
127!> Atmos. Environ. 35, 549-560) or Petroff&Zhang (2010, Geosci. Model Dev. 3,
128!> 753-769)
129!>
130!> @todo Apply information from emission_stack_height to lift emission sources
131!> @todo emission mode "parameterized", i.e. based on street type
132!------------------------------------------------------------------------------!
133 MODULE salsa_mod
134
135    USE basic_constants_and_equations_mod,                                     &
136        ONLY:  c_p, g, p_0, pi, r_d
137
138    USE chem_gasphase_mod,                                                     &
139        ONLY:  nspec, nvar, spc_names
140
141    USE chem_modules,                                                          &
142        ONLY:  call_chem_at_all_substeps, chem_gasphase_on, chem_species
143
144    USE control_parameters
145
146    USE indices,                                                               &
147        ONLY:  nbgp, nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg, nzb,  &
148               nzb_s_inner, nz, nzt, wall_flags_0
149
150    USE kinds
151
152    USE pegrid
153
154    USE salsa_util_mod
155
156    USE statistics,                                                            &
157        ONLY:  sums_salsa_ws_l
158
159    IMPLICIT NONE
160!
161!-- SALSA constants:
162!
163!-- Local constants:
164    INTEGER(iwp), PARAMETER ::  luc_urban = 8      !< default landuse type for urban: use desert!
165    INTEGER(iwp), PARAMETER ::  ngases_salsa   = 5 !< total number of gaseous tracers:
166                                                   !< 1 = H2SO4, 2 = HNO3, 3 = NH3, 4 = OCNV
167                                                   !< (non-volatile OC), 5 = OCSV (semi-volatile)
168    INTEGER(iwp), PARAMETER ::  nmod    = 7  !< number of modes for initialising the aerosol size
169                                             !< distribution
170    INTEGER(iwp), PARAMETER ::  nreg    = 2  !< Number of main size subranges
171    INTEGER(iwp), PARAMETER ::  maxspec = 7  !< Max. number of aerosol species
172    INTEGER(iwp), PARAMETER ::  season = 1   !< For dry depostion by Zhang et al.: 1 = summer,
173                                             !< 2 = autumn (no harvest yet), 3 = late autumn
174                                             !< (already frost), 4 = winter, 5 = transitional spring
175!
176!-- Universal constants
177    REAL(wp), PARAMETER ::  abo    = 1.380662E-23_wp   !< Boltzmann constant (J/K)
178    REAL(wp), PARAMETER ::  alv    = 2.260E+6_wp       !< latent heat for H2O
179                                                       !< vaporisation (J/kg)
180    REAL(wp), PARAMETER ::  alv_d_rv  = 4896.96865_wp  !< alv / rv
181    REAL(wp), PARAMETER ::  am_airmol = 4.8096E-26_wp  !< Average mass of one air
182                                                       !< molecule (Jacobson,
183                                                       !< 2005, Eq. 2.3)
184    REAL(wp), PARAMETER ::  api6   = 0.5235988_wp      !< pi / 6
185    REAL(wp), PARAMETER ::  argas  = 8.314409_wp       !< Gas constant (J/(mol K))
186    REAL(wp), PARAMETER ::  argas_d_cpd = 8.281283865E-3_wp  !< argas per cpd
187    REAL(wp), PARAMETER ::  avo    = 6.02214E+23_wp    !< Avogadro constant (1/mol)
188    REAL(wp), PARAMETER ::  d_sa   = 5.539376964394570E-10_wp  !< diameter of condensing sulphuric
189                                                               !< acid molecule (m)
190    REAL(wp), PARAMETER ::  for_ppm_to_nconc =  7.243016311E+16_wp !< ppm * avo / R (K/(Pa*m3))
191    REAL(wp), PARAMETER ::  epsoc  = 0.15_wp          !< water uptake of organic
192                                                      !< material
193    REAL(wp), PARAMETER ::  mclim  = 1.0E-23_wp       !< mass concentration min limit (kg/m3)
194    REAL(wp), PARAMETER ::  n3     = 158.79_wp        !< Number of H2SO4 molecules in 3 nm cluster
195                                                      !< if d_sa=5.54e-10m
196    REAL(wp), PARAMETER ::  nclim  = 1.0_wp           !< number concentration min limit (#/m3)
197    REAL(wp), PARAMETER ::  surfw0 = 0.073_wp         !< surface tension of water at 293 K (J/m2)
198!
199!-- Molar masses in kg/mol
200    REAL(wp), PARAMETER ::  ambc   = 12.0E-3_wp     !< black carbon (BC)
201    REAL(wp), PARAMETER ::  amdair = 28.970E-3_wp   !< dry air
202    REAL(wp), PARAMETER ::  amdu   = 100.E-3_wp     !< mineral dust
203    REAL(wp), PARAMETER ::  amh2o  = 18.0154E-3_wp  !< H2O
204    REAL(wp), PARAMETER ::  amh2so4  = 98.06E-3_wp  !< H2SO4
205    REAL(wp), PARAMETER ::  amhno3 = 63.01E-3_wp    !< HNO3
206    REAL(wp), PARAMETER ::  amn2o  = 44.013E-3_wp   !< N2O
207    REAL(wp), PARAMETER ::  amnh3  = 17.031E-3_wp   !< NH3
208    REAL(wp), PARAMETER ::  amo2   = 31.9988E-3_wp  !< O2
209    REAL(wp), PARAMETER ::  amo3   = 47.998E-3_wp   !< O3
210    REAL(wp), PARAMETER ::  amoc   = 150.E-3_wp     !< organic carbon (OC)
211    REAL(wp), PARAMETER ::  amss   = 58.44E-3_wp    !< sea salt (NaCl)
212!
213!-- Densities in kg/m3
214    REAL(wp), PARAMETER ::  arhobc     = 2000.0_wp  !< black carbon
215    REAL(wp), PARAMETER ::  arhodu     = 2650.0_wp  !< mineral dust
216    REAL(wp), PARAMETER ::  arhoh2o    = 1000.0_wp  !< H2O
217    REAL(wp), PARAMETER ::  arhoh2so4  = 1830.0_wp  !< SO4
218    REAL(wp), PARAMETER ::  arhohno3   = 1479.0_wp  !< HNO3
219    REAL(wp), PARAMETER ::  arhonh3    = 1530.0_wp  !< NH3
220    REAL(wp), PARAMETER ::  arhooc     = 2000.0_wp  !< organic carbon
221    REAL(wp), PARAMETER ::  arhoss     = 2165.0_wp  !< sea salt (NaCl)
222!
223!-- Volume of molecule in m3/#
224    REAL(wp), PARAMETER ::  amvh2o   = amh2o /avo / arhoh2o      !< H2O
225    REAL(wp), PARAMETER ::  amvh2so4 = amh2so4 / avo / arhoh2so4 !< SO4
226    REAL(wp), PARAMETER ::  amvhno3  = amhno3 / avo / arhohno3   !< HNO3
227    REAL(wp), PARAMETER ::  amvnh3   = amnh3 / avo / arhonh3     !< NH3
228    REAL(wp), PARAMETER ::  amvoc    = amoc / avo / arhooc       !< OC
229    REAL(wp), PARAMETER ::  amvss    = amss / avo / arhoss       !< sea salt
230!
231!-- Constants for the dry deposition model by Petroff and Zhang (2010):
232!-- obstacle characteristic dimension "L" (cm) (plane obstacle by default) and empirical constants
233!-- C_B, C_IN, C_IM, beta_IM and C_IT for each land use category (15, as in Zhang et al. (2001))
234    REAL(wp), DIMENSION(1:15), PARAMETER :: l_p10 = &
235        (/0.15, 4.0, 0.15, 3.0, 3.0, 0.5, 3.0, -99., 0.5, 2.0, 1.0, -99., -99., -99., 3.0/)
236    REAL(wp), DIMENSION(1:15), PARAMETER :: c_b_p10 = &
237        (/0.887, 1.262, 0.887, 1.262, 1.262, 0.996, 0.996, -99., 0.7, 0.93, 0.996, -99., -99., -99., 1.262/)
238    REAL(wp), DIMENSION(1:15), PARAMETER :: c_in_p10 = &
239        (/0.81, 0.216, 0.81, 0.216, 0.216, 0.191, 0.162, -99., 0.7, 0.14, 0.162, -99., -99., -99., 0.216/)
240    REAL(wp), DIMENSION(1:15), PARAMETER :: c_im_p10 = &
241        (/0.162, 0.13, 0.162, 0.13, 0.13, 0.191, 0.081, -99., 0.191, 0.086, 0.081, -99., -99., -99., 0.13/)
242    REAL(wp), DIMENSION(1:15), PARAMETER :: beta_im_p10 = &
243        (/0.6, 0.47, 0.6, 0.47, 0.47, 0.47, 0.47, -99., 0.6, 0.47, 0.47, -99., -99., -99., 0.47/)
244    REAL(wp), DIMENSION(1:15), PARAMETER :: c_it_p10 = &
245        (/0.0, 0.056, 0.0, 0.056, 0.056, 0.042, 0.056, -99., 0.042, 0.014, 0.056, -99., -99., -99., 0.056/)
246!
247!-- Constants for the dry deposition model by Zhang et al. (2001):
248!-- empirical constants "alpha" and "gamma" and characteristic radius "A" for
249!-- each land use category (15) and season (5)
250    REAL(wp), DIMENSION(1:15), PARAMETER :: alpha_z01 = &
251        (/1.0, 0.6, 1.1, 0.8, 0.8, 1.2, 1.2, 50.0, 50.0, 1.3, 2.0, 50.0, 100.0, 100.0, 1.5/)
252    REAL(wp), DIMENSION(1:15), PARAMETER :: gamma_z01 = &
253        (/0.56, 0.58, 0.56, 0.56, 0.56, 0.54, 0.54, 0.54, 0.54, 0.54, 0.54, 0.54, 0.50, 0.50, 0.56/)
254    REAL(wp), DIMENSION(1:15,1:5), PARAMETER :: A_z01 =  RESHAPE( (/& 
255         2.0, 5.0, 2.0,  5.0, 5.0, 2.0, 2.0, -99., -99., 10.0, 10.0, -99., -99., -99., 10.0,&  ! SC1
256         2.0, 5.0, 2.0,  5.0, 5.0, 2.0, 2.0, -99., -99., 10.0, 10.0, -99., -99., -99., 10.0,&  ! SC2
257         2.0, 5.0, 5.0, 10.0, 5.0, 5.0, 5.0, -99., -99., 10.0, 10.0, -99., -99., -99., 10.0,&  ! SC3
258         2.0, 5.0, 5.0, 10.0, 5.0, 5.0, 5.0, -99., -99., 10.0, 10.0, -99., -99., -99., 10.0,&  ! SC4
259         2.0, 5.0, 2.0,  5.0, 5.0, 2.0, 2.0, -99., -99., 10.0, 10.0, -99., -99., -99., 10.0 &  ! SC5
260                                                           /), (/ 15, 5 /) )
261!-- Land use categories (based on Z01 but the same applies here also for P10):
262!-- 1 = evergreen needleleaf trees,
263!-- 2 = evergreen broadleaf trees,
264!-- 3 = deciduous needleleaf trees,
265!-- 4 = deciduous broadleaf trees,
266!-- 5 = mixed broadleaf and needleleaf trees (deciduous broadleaf trees for P10),
267!-- 6 = grass (short grass for P10),
268!-- 7 = crops, mixed farming,
269!-- 8 = desert,
270!-- 9 = tundra,
271!-- 10 = shrubs and interrupted woodlands (thorn shrubs for P10),
272!-- 11 = wetland with plants (long grass for P10)
273!-- 12 = ice cap and glacier,
274!-- 13 = inland water (inland lake for P10)
275!-- 14 = ocean (water for P10),
276!-- 15 = urban
277!
278!-- SALSA variables:
279    CHARACTER(LEN=20)  ::  bc_salsa_b = 'neumann'                 !< bottom boundary condition
280    CHARACTER(LEN=20)  ::  bc_salsa_t = 'neumann'                 !< top boundary condition
281    CHARACTER(LEN=20)  ::  depo_pcm_par = 'zhang2001'             !< or 'petroff2010'
282    CHARACTER(LEN=20)  ::  depo_pcm_type = 'deciduous_broadleaf'  !< leaf type
283    CHARACTER(LEN=20)  ::  depo_surf_par = 'zhang2001'            !< or 'petroff2010'
284    CHARACTER(LEN=100) ::  input_file_dynamic = 'PIDS_DYNAMIC'    !< file name for dynamic input
285    CHARACTER(LEN=100) ::  input_file_salsa   = 'PIDS_SALSA'      !< file name for emission data
286    CHARACTER(LEN=20)  ::  salsa_emission_mode = 'no_emission'    !< 'no_emission', 'uniform',
287                                                                  !< 'parameterized', 'read_from_file'
288
289    CHARACTER(LEN=20), DIMENSION(4) ::  decycle_method =                                           &
290                                                 (/'dirichlet','dirichlet','dirichlet','dirichlet'/)
291                                     !< Decycling method at horizontal boundaries
292                                     !< 1=left, 2=right, 3=south, 4=north
293                                     !< dirichlet = initial profiles for the ghost and first 3 layers
294                                     !< neumann = zero gradient
295
296    CHARACTER(LEN=3), DIMENSION(maxspec) ::  listspec = &  !< Active aerosols
297                                   (/'SO4','   ','   ','   ','   ','   ','   '/)
298
299    INTEGER(iwp) ::  depo_pcm_type_num = 0  !< index for the dry deposition type on the plant canopy
300    INTEGER(iwp) ::  dots_salsa = 0         !< starting index for salsa-timeseries
301    INTEGER(iwp) ::  end_subrange_1a = 1    !< last index for bin subrange 1a
302    INTEGER(iwp) ::  end_subrange_2a = 1    !< last index for bin subrange 2a
303    INTEGER(iwp) ::  end_subrange_2b = 1    !< last index for bin subrange 2b
304    INTEGER(iwp) ::  ibc_salsa_b            !< index for the bottom boundary condition
305    INTEGER(iwp) ::  ibc_salsa_t            !< index for the top boundary condition
306    INTEGER(iwp) ::  index_bc  = -1         !< index for black carbon (BC)
307    INTEGER(iwp) ::  index_du  = -1         !< index for dust
308    INTEGER(iwp) ::  igctyp = 0             !< Initial gas concentration type
309                                            !< 0 = uniform (read from PARIN)
310                                            !< 1 = read vertical profile from an input file
311    INTEGER(iwp) ::  index_nh  = -1         !< index for NH3
312    INTEGER(iwp) ::  index_no  = -1         !< index for HNO3
313    INTEGER(iwp) ::  index_oc  = -1         !< index for organic carbon (OC)
314    INTEGER(iwp) ::  isdtyp = 0             !< Initial size distribution type
315                                            !< 0 = uniform (read from PARIN)
316                                            !< 1 = read vertical profile of the mode number
317                                            !<     concentration from an input file
318    INTEGER(iwp) ::  index_so4 = -1         !< index for SO4 or H2SO4
319    INTEGER(iwp) ::  index_ss  = -1         !< index for sea salt
320    INTEGER(iwp) ::  lod_gas_emissions = 0  !< level of detail of the gaseous emission data
321    INTEGER(iwp) ::  nbins_aerosol = 1      !< total number of size bins
322    INTEGER(iwp) ::  ncc   = 1              !< number of chemical components used
323    INTEGER(iwp) ::  ncomponents_mass = 1   !< total number of chemical compounds (ncc+1)
324                                            !< if particle water is advected)
325    INTEGER(iwp) ::  nj3 = 1                !< J3 parametrization (nucleation)
326                                            !< 1 = condensational sink (Kerminen&Kulmala, 2002)
327                                            !< 2 = coagulational sink (Lehtinen et al. 2007)
328                                            !< 3 = coagS+self-coagulation (Anttila et al. 2010)
329    INTEGER(iwp) ::  nsnucl = 0             !< Choice of the nucleation scheme:
330                                            !< 0 = off
331                                            !< 1 = binary nucleation
332                                            !< 2 = activation type nucleation
333                                            !< 3 = kinetic nucleation
334                                            !< 4 = ternary nucleation
335                                            !< 5 = nucleation with ORGANICs
336                                            !< 6 = activation type of nucleation with H2SO4+ORG
337                                            !< 7 = heteromolecular nucleation with H2SO4*ORG
338                                            !< 8 = homomolecular nucleation of H2SO4
339                                            !<     + heteromolecular nucleation with H2SO4*ORG
340                                            !< 9 = homomolecular nucleation of H2SO4 and ORG
341                                            !<     + heteromolecular nucleation with H2SO4*ORG
342    INTEGER(iwp) ::  start_subrange_1a = 1  !< start index for bin subranges: subrange 1a
343    INTEGER(iwp) ::  start_subrange_2a = 1  !<                                subrange 2a
344    INTEGER(iwp) ::  start_subrange_2b = 1  !<                                subrange 2b
345
346    INTEGER(iwp), DIMENSION(nreg) ::  nbin = (/ 3, 7/)  !< Number of size bins per subrange: 1 & 2
347
348    INTEGER(iwp), DIMENSION(ngases_salsa) ::  gas_index_chem = &
349                                                 (/ 1, 1, 1, 1, 1/)  !< gas indices in chemistry_model_mod
350                                                 !< 1 = H2SO4, 2 = HNO3, 3 = NH3, 4 = OCNV, 5 = OCSV
351    INTEGER(iwp), DIMENSION(ngases_salsa) ::  emission_index_chem  !< gas indices in the gas emission file
352
353    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  k_topo_top  !< vertical index of the topography top
354!
355!-- SALSA switches:
356    LOGICAL ::  advect_particle_water = .TRUE.     !< advect water concentration of particles
357    LOGICAL ::  decycle_lr            = .FALSE.    !< Undo cyclic boundary conditions: left and right
358    LOGICAL ::  decycle_ns            = .FALSE.    !< north and south boundaries
359    LOGICAL ::  feedback_to_palm      = .FALSE.    !< allow feedback due to condensation of H2O
360    LOGICAL ::  nest_salsa            = .FALSE.    !< apply nesting for salsa
361    LOGICAL ::  no_insoluble          = .FALSE.    !< Switch to exclude insoluble chemical components
362    LOGICAL ::  read_restart_data_salsa = .FALSE.  !< read restart data for salsa
363    LOGICAL ::  salsa_gases_from_chem = .FALSE.    !< Transfer the gaseous components to SALSA from
364                                                   !< from chemistry model
365    LOGICAL ::  van_der_waals_coagc   = .FALSE.    !< Enhancement of coagulation kernel by van der
366                                                   !< Waals and viscous forces
367    LOGICAL ::  write_binary_salsa    = .FALSE.    !< read binary for salsa
368!
369!-- Process switches: nl* is read from the NAMELIST and is NOT changed.
370!--                   ls* is the switch used and will get the value of nl*
371!--                       except for special circumstances (spinup period etc.)
372    LOGICAL ::  nlcoag       = .FALSE.  !< Coagulation master switch
373    LOGICAL ::  lscoag       = .FALSE.  !<
374    LOGICAL ::  nlcnd        = .FALSE.  !< Condensation master switch
375    LOGICAL ::  lscnd        = .FALSE.  !<
376    LOGICAL ::  nlcndgas     = .FALSE.  !< Condensation of precursor gases
377    LOGICAL ::  lscndgas     = .FALSE.  !<
378    LOGICAL ::  nlcndh2oae   = .FALSE.  !< Condensation of H2O on aerosol
379    LOGICAL ::  lscndh2oae   = .FALSE.  !< particles (FALSE -> equilibrium calc.)
380    LOGICAL ::  nldepo       = .FALSE.  !< Deposition master switch
381    LOGICAL ::  lsdepo       = .FALSE.  !<
382    LOGICAL ::  nldepo_surf  = .FALSE.  !< Deposition on vegetation master switch
383    LOGICAL ::  lsdepo_surf  = .FALSE.  !<
384    LOGICAL ::  nldepo_pcm   = .FALSE.  !< Deposition on walls master switch
385    LOGICAL ::  lsdepo_pcm   = .FALSE.  !<
386    LOGICAL ::  nldistupdate = .TRUE.   !< Size distribution update master switch
387    LOGICAL ::  lsdistupdate = .FALSE.  !<
388    LOGICAL ::  lspartition  = .FALSE.  !< Partition of HNO3 and NH3
389
390    REAL(wp) ::  act_coeff = 1.0E-7_wp               !< Activation coefficient
391    REAL(wp) ::  dt_salsa  = 0.00001_wp              !< Time step of SALSA
392    REAL(wp) ::  h2so4_init = nclim                  !< Init value for sulphuric acid gas
393    REAL(wp) ::  hno3_init  = nclim                  !< Init value for nitric acid gas
394    REAL(wp) ::  last_salsa_time = 0.0_wp            !< previous salsa call
395    REAL(wp) ::  next_aero_emission_update = 0.0_wp  !< previous emission update
396    REAL(wp) ::  next_gas_emission_update = 0.0_wp   !< previous emission update
397    REAL(wp) ::  nf2a = 1.0_wp                       !< Number fraction allocated to 2a-bins
398    REAL(wp) ::  nh3_init  = nclim                   !< Init value for ammonia gas
399    REAL(wp) ::  ocnv_init = nclim                   !< Init value for non-volatile organic gases
400    REAL(wp) ::  ocsv_init = nclim                   !< Init value for semi-volatile organic gases
401    REAL(wp) ::  rhlim = 1.20_wp                     !< RH limit in %/100. Prevents unrealistical RH
402    REAL(wp) ::  skip_time_do_salsa = 0.0_wp         !< Starting time of SALSA (s)
403!
404!-- Initial log-normal size distribution: mode diameter (dpg, metres),
405!-- standard deviation (sigmag) and concentration (n_lognorm, #/m3)
406    REAL(wp), DIMENSION(nmod) ::  dpg   = &
407                                     (/0.013_wp, 0.054_wp, 0.86_wp, 0.2_wp, 0.2_wp, 0.2_wp, 0.2_wp/)
408    REAL(wp), DIMENSION(nmod) ::  sigmag  = &
409                                        (/1.8_wp, 2.16_wp, 2.21_wp, 2.0_wp, 2.0_wp, 2.0_wp, 2.0_wp/)
410    REAL(wp), DIMENSION(nmod) ::  n_lognorm = &
411                             (/1.04e+11_wp, 3.23E+10_wp, 5.4E+6_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp/)
412!
413!-- Initial mass fractions / chemical composition of the size distribution
414    REAL(wp), DIMENSION(maxspec) ::  mass_fracs_a = & !< mass fractions between
415             (/1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0/) !< aerosol species for A bins
416    REAL(wp), DIMENSION(maxspec) ::  mass_fracs_b = & !< mass fractions between
417             (/0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0/) !< aerosol species for B bins
418    REAL(wp), DIMENSION(nreg+1) ::  reglim = & !< Min&max diameters of size subranges
419                                 (/ 3.0E-9_wp, 5.0E-8_wp, 1.0E-5_wp/)
420!
421!-- Initial log-normal size distribution: mode diameter (dpg, metres), standard deviation (sigmag)
422!-- concentration (n_lognorm, #/m3) and mass fractions of all chemical components (listed in
423!-- listspec) for both a (soluble) and b (insoluble) bins.
424    REAL(wp), DIMENSION(nmod) ::  aerosol_flux_dpg   = &
425                                     (/0.013_wp, 0.054_wp, 0.86_wp, 0.2_wp, 0.2_wp, 0.2_wp, 0.2_wp/)
426    REAL(wp), DIMENSION(nmod) ::  aerosol_flux_sigmag  = &
427                                        (/1.8_wp, 2.16_wp, 2.21_wp, 2.0_wp, 2.0_wp, 2.0_wp, 2.0_wp/)
428    REAL(wp), DIMENSION(nmod) ::  surface_aerosol_flux = &
429                             (/1.04e+11_wp, 3.23E+10_wp, 5.4E+6_wp, 0.0_wp, 0.0_wp, 0.0_wp, 0.0_wp/)
430    REAL(wp), DIMENSION(maxspec) ::  aerosol_flux_mass_fracs_a = &
431                                                               (/1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0/)
432    REAL(wp), DIMENSION(maxspec) ::  aerosol_flux_mass_fracs_b = &
433                                                               (/0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0/)
434
435    REAL(wp), DIMENSION(:), ALLOCATABLE ::  bin_low_limits     !< to deliver information about
436                                                               !< the lower diameters per bin
437    REAL(wp), DIMENSION(:), ALLOCATABLE ::  bc_am_t_val        !< vertical gradient of: aerosol mass
438    REAL(wp), DIMENSION(:), ALLOCATABLE ::  bc_an_t_val        !< of: aerosol number
439    REAL(wp), DIMENSION(:), ALLOCATABLE ::  bc_gt_t_val        !< salsa gases near domain top
440    REAL(wp), DIMENSION(:), ALLOCATABLE ::  gas_emission_time  !< Time array in gas emission data (s)
441    REAL(wp), DIMENSION(:), ALLOCATABLE ::  nsect              !< Background number concentrations
442    REAL(wp), DIMENSION(:), ALLOCATABLE ::  massacc            !< Mass accomodation coefficients
443!
444!-- SALSA derived datatypes:
445!
446!-- For matching LSM and the deposition module surface types
447    TYPE match_lsm_depo
448       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  match
449    END TYPE match_lsm_depo
450!
451!-- Aerosol emission data attributes
452    TYPE salsa_emission_attribute_type
453
454       CHARACTER(LEN=25) ::   units
455
456       CHARACTER(LEN=25), DIMENSION(:), ALLOCATABLE ::   cat_name    !<
457       CHARACTER(LEN=25), DIMENSION(:), ALLOCATABLE ::   cc_name     !<
458       CHARACTER(LEN=25), DIMENSION(:), ALLOCATABLE ::   unit_time   !<
459       CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE ::  var_names   !<
460
461       INTEGER(iwp) ::  lod = 0            !< level of detail
462       INTEGER(iwp) ::  nbins = 10         !< number of aerosol size bins
463       INTEGER(iwp) ::  ncat  = 0          !< number of emission categories
464       INTEGER(iwp) ::  ncc   = 7          !< number of aerosol chemical components
465       INTEGER(iwp) ::  nhoursyear = 0     !< number of hours: HOURLY mode
466       INTEGER(iwp) ::  nmonthdayhour = 0  !< number of month days and hours: MDH mode
467       INTEGER(iwp) ::  num_vars           !< number of variables
468       INTEGER(iwp) ::  nt  = 0            !< number of time steps
469       INTEGER(iwp) ::  nz  = 0            !< number of vertical levels
470       INTEGER(iwp) ::  tind               !< time index for reference time in salsa emission data
471
472       INTEGER(iwp), DIMENSION(maxspec) ::  cc_input_to_model   !<
473
474       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  cat_index  !< Index of emission categories
475       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  cc_index   !< Index of chemical components
476
477       REAL(wp) ::  conversion_factor  !< unit conversion factor for aerosol emissions
478
479       REAL(wp), DIMENSION(:), ALLOCATABLE ::  dmid         !< mean diameters of size bins (m)
480       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rho          !< average density (kg/m3)
481       REAL(wp), DIMENSION(:), ALLOCATABLE ::  time         !< time (s)
482       REAL(wp), DIMENSION(:), ALLOCATABLE ::  time_factor  !< emission time factor
483       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z            !< height (m)
484
485       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  etf  !< emission time factor
486       REAL(wp), DIMENSION(:,:), ALLOCATABLE :: stack_height
487
488    END TYPE salsa_emission_attribute_type
489!
490!-- The default size distribution and mass composition per emission category:
491!-- 1 = traffic, 2 = road dust, 3 = wood combustion, 4 = other
492!-- Mass fractions: H2SO4, OC, BC, DU, SS, HNO3, NH3
493    TYPE salsa_emission_mode_type
494
495       INTEGER(iwp) ::  ndm = 3  !< number of default modes
496       INTEGER(iwp) ::  ndc = 4  !< number of default categories
497
498       CHARACTER(LEN=25), DIMENSION(1:4) ::  cat_name_table = (/'traffic exhaust', &
499                                                                'road dust      ', &
500                                                                'wood combustion', &
501                                                                'other          '/)
502
503       INTEGER(iwp), DIMENSION(1:4) ::  cat_input_to_model   !<
504
505       REAL(wp), DIMENSION(1:3) ::  dpg_table = (/ 13.5E-9_wp, 1.4E-6_wp, 5.4E-8_wp/)  !<
506       REAL(wp), DIMENSION(1:3) ::  ntot_table  !<
507       REAL(wp), DIMENSION(1:3) ::  sigmag_table = (/ 1.6_wp, 1.4_wp, 1.7_wp /)  !<
508
509       REAL(wp), DIMENSION(1:maxspec,1:4) ::  mass_frac_table = &  !<
510          RESHAPE( (/ 0.04_wp, 0.48_wp, 0.48_wp, 0.0_wp,  0.0_wp, 0.0_wp, 0.0_wp, &
511                      0.0_wp,  0.05_wp, 0.0_wp,  0.95_wp, 0.0_wp, 0.0_wp, 0.0_wp, &
512                      0.0_wp,  0.5_wp,  0.5_wp,  0.0_wp,  0.0_wp, 0.0_wp, 0.0_wp, &
513                      0.0_wp,  0.5_wp,  0.5_wp,  0.0_wp,  0.0_wp, 0.0_wp, 0.0_wp  &
514                   /), (/maxspec,4/) )
515
516       REAL(wp), DIMENSION(1:3,1:4) ::  pm_frac_table = & !< rel. mass
517                                     RESHAPE( (/ 0.016_wp, 0.000_wp, 0.984_wp, &
518                                                 0.000_wp, 1.000_wp, 0.000_wp, &
519                                                 0.000_wp, 0.000_wp, 1.000_wp, &
520                                                 1.000_wp, 0.000_wp, 1.000_wp  &
521                                              /), (/3,4/) )
522
523    END TYPE salsa_emission_mode_type
524!
525!-- Aerosol emission data values
526    TYPE salsa_emission_value_type
527
528       REAL(wp) ::  fill  !< fill value
529
530       REAL(wp), DIMENSION(:), ALLOCATABLE :: preproc_mass_fracs  !< mass fractions
531
532       REAL(wp), DIMENSION(:,:), ALLOCATABLE :: def_mass_fracs  !< mass fractions per emis. category
533
534       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: def_data      !< surface emission values in PM
535       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: preproc_data  !< surface emission values per bin
536
537    END TYPE salsa_emission_value_type
538!
539!-- Prognostic variable: Aerosol size bin information (number (#/m3) and mass (kg/m3) concentration)
540!-- and the concentration of gaseous tracers (#/m3). Gas tracers are contained sequentially in
541!-- dimension 4 as:
542!-- 1. H2SO4, 2. HNO3, 3. NH3, 4. OCNV (non-volatile organics), 5. OCSV (semi-volatile)
543    TYPE salsa_variable
544
545       REAL(wp), ALLOCATABLE, DIMENSION(:)     ::  init  !<
546
547       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::  diss_s     !<
548       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::  flux_s     !<
549       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::  source     !<
550       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::  sums_ws_l  !<
551
552       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::  diss_l  !<
553       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::  flux_l  !<
554
555       REAL(wp), POINTER, DIMENSION(:,:,:), CONTIGUOUS ::  conc     !<
556       REAL(wp), POINTER, DIMENSION(:,:,:), CONTIGUOUS ::  conc_p   !<
557       REAL(wp), POINTER, DIMENSION(:,:,:), CONTIGUOUS ::  tconc_m  !<
558
559    END TYPE salsa_variable
560!
561!-- Datatype used to store information about the binned size distributions of aerosols
562    TYPE t_section
563
564       REAL(wp) ::  dmid     !< bin middle diameter (m)
565       REAL(wp) ::  vhilim   !< bin volume at the high limit
566       REAL(wp) ::  vlolim   !< bin volume at the low limit
567       REAL(wp) ::  vratiohi !< volume ratio between the center and high limit
568       REAL(wp) ::  vratiolo !< volume ratio between the center and low limit
569       !******************************************************
570       ! ^ Do NOT change the stuff above after initialization !
571       !******************************************************
572       REAL(wp) ::  core    !< Volume of dry particle
573       REAL(wp) ::  dwet    !< Wet diameter or mean droplet diameter (m)
574       REAL(wp) ::  numc    !< Number concentration of particles/droplets (#/m3)
575       REAL(wp) ::  veqh2o  !< Equilibrium H2O concentration for each particle
576
577       REAL(wp), DIMENSION(maxspec+1) ::  volc !< Volume concentrations (m^3/m^3) of aerosols +
578                                               !< water. Since most of the stuff in SALSA is hard
579                                               !< coded, these *have to be* in the order
580                                               !< 1:SO4, 2:OC, 3:BC, 4:DU, 5:SS, 6:NO, 7:NH, 8:H2O
581    END TYPE t_section
582
583    TYPE(salsa_emission_attribute_type) ::  aero_emission_att  !< emission attributes
584    TYPE(salsa_emission_value_type)     ::  aero_emission      !< emission values
585    TYPE(salsa_emission_mode_type)      ::  def_modes          !< default emission modes
586
587    TYPE(t_section), DIMENSION(:), ALLOCATABLE ::  aero  !< local aerosol properties
588
589    TYPE(match_lsm_depo) ::  lsm_to_depo_h
590
591    TYPE(match_lsm_depo), DIMENSION(0:3) ::  lsm_to_depo_v
592!
593!-- SALSA variables: as x = x(k,j,i,bin).
594!-- The 4th dimension contains all the size bins sequentially for each aerosol species  + water.
595!
596!-- Prognostic variables:
597!
598!-- Number concentration (#/m3)
599    TYPE(salsa_variable), ALLOCATABLE, DIMENSION(:), TARGET ::  aerosol_number  !<
600    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  nconc_1  !<
601    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  nconc_2  !<
602    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  nconc_3  !<
603!
604!-- Mass concentration (kg/m3)
605    TYPE(salsa_variable), ALLOCATABLE, DIMENSION(:), TARGET ::  aerosol_mass  !<
606    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  mconc_1  !<
607    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  mconc_2  !<
608    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  mconc_3  !<
609!
610!-- Gaseous concentrations (#/m3)
611    TYPE(salsa_variable), ALLOCATABLE, DIMENSION(:), TARGET ::  salsa_gas  !<
612    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  gconc_1  !<
613    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  gconc_2  !<
614    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  gconc_3  !<
615!
616!-- Diagnostic tracers
617    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) ::  sedim_vd  !< sedimentation velocity per bin (m/s)
618    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) ::  ra_dry    !< aerosol dry radius (m)
619
620!-- Particle component index tables
621    TYPE(component_index) :: prtcl  !< Contains "getIndex" which gives the index for a given aerosol
622                                    !< component name: 1:SO4, 2:OC, 3:BC, 4:DU, 5:SS, 6:NO, 7:NH, 8:H2O
623!
624!-- Data output arrays:
625!
626!-- Gases:
627    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  g_h2so4_av  !< H2SO4
628    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  g_hno3_av   !< HNO3
629    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  g_nh3_av    !< NH3
630    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  g_ocnv_av   !< non-volatile OC
631    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  g_ocsv_av   !< semi-volatile OC
632!
633!-- Integrated:
634    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  ldsa_av  !< lung-deposited surface area
635    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  ntot_av  !< total number concentration
636    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  pm25_av  !< PM2.5
637    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  pm10_av  !< PM10
638!
639!-- In the particle phase:
640    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_bc_av   !< black carbon
641    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_du_av   !< dust
642    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_h2o_av  !< liquid water
643    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_nh_av   !< ammonia
644    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_no_av   !< nitrates
645    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_oc_av   !< org. carbon
646    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_so4_av  !< sulphates
647    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), TARGET ::  s_ss_av   !< sea salt
648!
649!-- Bin specific mass and number concentrations:
650    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  mbins_av  !< bin mas
651    REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:), TARGET ::  nbins_av  !< bin number
652
653!
654!-- PALM interfaces:
655!
656!-- Boundary conditions:
657    INTERFACE salsa_boundary_conds
658       MODULE PROCEDURE salsa_boundary_conds
659       MODULE PROCEDURE salsa_boundary_conds_decycle
660    END INTERFACE salsa_boundary_conds
661!
662!-- Data output checks for 2D/3D data to be done in check_parameters
663    INTERFACE salsa_check_data_output
664       MODULE PROCEDURE salsa_check_data_output
665    END INTERFACE salsa_check_data_output
666!
667!-- Input parameter checks to be done in check_parameters
668    INTERFACE salsa_check_parameters
669       MODULE PROCEDURE salsa_check_parameters
670    END INTERFACE salsa_check_parameters
671!
672!-- Averaging of 3D data for output
673    INTERFACE salsa_3d_data_averaging
674       MODULE PROCEDURE salsa_3d_data_averaging
675    END INTERFACE salsa_3d_data_averaging
676!
677!-- Data output of 2D quantities
678    INTERFACE salsa_data_output_2d
679       MODULE PROCEDURE salsa_data_output_2d
680    END INTERFACE salsa_data_output_2d
681!
682!-- Data output of 3D data
683    INTERFACE salsa_data_output_3d
684       MODULE PROCEDURE salsa_data_output_3d
685    END INTERFACE salsa_data_output_3d
686!
687!-- Data output of 3D data
688    INTERFACE salsa_data_output_mask
689       MODULE PROCEDURE salsa_data_output_mask
690    END INTERFACE salsa_data_output_mask
691!
692!-- Definition of data output quantities
693    INTERFACE salsa_define_netcdf_grid
694       MODULE PROCEDURE salsa_define_netcdf_grid
695    END INTERFACE salsa_define_netcdf_grid
696!
697!-- Output of information to the header file
698    INTERFACE salsa_header
699       MODULE PROCEDURE salsa_header
700    END INTERFACE salsa_header
701!
702!-- Initialization actions
703    INTERFACE salsa_init
704       MODULE PROCEDURE salsa_init
705    END INTERFACE salsa_init
706!
707!-- Initialization of arrays
708    INTERFACE salsa_init_arrays
709       MODULE PROCEDURE salsa_init_arrays
710    END INTERFACE salsa_init_arrays
711!
712!-- Writing of binary output for restart runs  !!! renaming?!
713    INTERFACE salsa_wrd_local
714       MODULE PROCEDURE salsa_wrd_local
715    END INTERFACE salsa_wrd_local
716!
717!-- Reading of NAMELIST parameters
718    INTERFACE salsa_parin
719       MODULE PROCEDURE salsa_parin
720    END INTERFACE salsa_parin
721!
722!-- Reading of parameters for restart runs
723    INTERFACE salsa_rrd_local
724       MODULE PROCEDURE salsa_rrd_local
725    END INTERFACE salsa_rrd_local
726!
727!-- Swapping of time levels (required for prognostic variables)
728    INTERFACE salsa_swap_timelevel
729       MODULE PROCEDURE salsa_swap_timelevel
730    END INTERFACE salsa_swap_timelevel
731!
732!-- Interface between PALM and salsa
733    INTERFACE salsa_driver
734       MODULE PROCEDURE salsa_driver
735    END INTERFACE salsa_driver
736
737!-- Actions salsa variables
738    INTERFACE salsa_actions
739       MODULE PROCEDURE salsa_actions
740       MODULE PROCEDURE salsa_actions_ij
741    END INTERFACE salsa_actions
742!
743!-- Prognostics equations for salsa variables
744    INTERFACE salsa_prognostic_equations
745       MODULE PROCEDURE salsa_prognostic_equations
746       MODULE PROCEDURE salsa_prognostic_equations_ij
747    END INTERFACE salsa_prognostic_equations
748!
749!-- Tendency salsa variables
750    INTERFACE salsa_tendency
751       MODULE PROCEDURE salsa_tendency
752       MODULE PROCEDURE salsa_tendency_ij
753    END INTERFACE salsa_tendency
754
755
756    SAVE
757
758    PRIVATE
759!
760!-- Public functions:
761    PUBLIC salsa_boundary_conds, salsa_check_data_output, salsa_check_parameters,                  &
762           salsa_3d_data_averaging, salsa_data_output_2d, salsa_data_output_3d,                    &
763           salsa_data_output_mask, salsa_define_netcdf_grid, salsa_diagnostics, salsa_driver,      &
764           salsa_emission_update, salsa_header, salsa_init, salsa_init_arrays, salsa_parin,        &
765           salsa_rrd_local, salsa_swap_timelevel, salsa_prognostic_equations, salsa_wrd_local,     &
766           salsa_actions
767!
768!-- Public parameters, constants and initial values
769    PUBLIC bc_am_t_val, bc_an_t_val, bc_gt_t_val, dots_salsa, dt_salsa,                            &
770           ibc_salsa_b, last_salsa_time, lsdepo, nest_salsa, salsa, salsa_gases_from_chem,         &
771           skip_time_do_salsa
772!
773!-- Public prognostic variables
774    PUBLIC aerosol_mass, aerosol_number, gconc_2, mconc_2, nbins_aerosol, ncc, ncomponents_mass,   &
775           nclim, nconc_2, ngases_salsa, prtcl, ra_dry, salsa_gas, sedim_vd
776
777
778 CONTAINS
779
780!------------------------------------------------------------------------------!
781! Description:
782! ------------
783!> Parin for &salsa_par for new modules
784!------------------------------------------------------------------------------!
785 SUBROUTINE salsa_parin
786
787    IMPLICIT NONE
788
789    CHARACTER(LEN=80) ::  line   !< dummy string that contains the current line
790                                  !< of the parameter file
791
792    NAMELIST /salsa_parameters/      aerosol_flux_dpg, aerosol_flux_mass_fracs_a,                  &
793                                     aerosol_flux_mass_fracs_b, aerosol_flux_sigmag,               &
794                                     advect_particle_water, bc_salsa_b, bc_salsa_t, decycle_lr,    &
795                                     decycle_method, decycle_ns, depo_pcm_par, depo_pcm_type,      &
796                                     depo_surf_par, dpg, dt_salsa, feedback_to_palm, h2so4_init,   &
797                                     hno3_init, igctyp, isdtyp, listspec, mass_fracs_a,            &
798                                     mass_fracs_b, n_lognorm, nbin, nest_salsa, nf2a, nh3_init,    &
799                                     nj3, nlcnd, nlcndgas, nlcndh2oae, nlcoag, nldepo, nldepo_pcm, &
800                                     nldepo_surf, nldistupdate, nsnucl, ocnv_init, ocsv_init,      &
801                                     read_restart_data_salsa, reglim, salsa, salsa_emission_mode,  &
802                                     sigmag, skip_time_do_salsa, surface_aerosol_flux,             &
803                                     van_der_waals_coagc, write_binary_salsa
804
805    line = ' '
806!
807!-- Try to find salsa package
808    REWIND ( 11 )
809    line = ' '
810    DO WHILE ( INDEX( line, '&salsa_parameters' ) == 0 )
811       READ ( 11, '(A)', END=10 )  line
812    ENDDO
813    BACKSPACE ( 11 )
814!
815!-- Read user-defined namelist
816    READ ( 11, salsa_parameters )
817!
818!-- Enable salsa (salsa switch in modules.f90)
819    salsa = .TRUE.
820
821 10 CONTINUE
822
823 END SUBROUTINE salsa_parin
824
825!------------------------------------------------------------------------------!
826! Description:
827! ------------
828!> Check parameters routine for salsa.
829!------------------------------------------------------------------------------!
830 SUBROUTINE salsa_check_parameters
831
832    USE control_parameters,                                                                        &
833        ONLY:  message_string
834
835    IMPLICIT NONE
836
837!
838!-- Checks go here (cf. check_parameters.f90).
839    IF ( salsa  .AND.  .NOT.  humidity )  THEN
840       WRITE( message_string, * ) 'salsa = ', salsa, ' is not allowed with humidity = ', humidity
841       CALL message( 'salsa_check_parameters', 'PA0594', 1, 2, 0, 6, 0 )
842    ENDIF
843
844    IF ( bc_salsa_b == 'dirichlet' )  THEN
845       ibc_salsa_b = 0
846    ELSEIF ( bc_salsa_b == 'neumann' )  THEN
847       ibc_salsa_b = 1
848    ELSE
849       message_string = 'unknown boundary condition: bc_salsa_b = "' // TRIM( bc_salsa_t ) // '"'
850       CALL message( 'salsa_check_parameters', 'PA0595', 1, 2, 0, 6, 0 )
851    ENDIF
852
853    IF ( bc_salsa_t == 'dirichlet' )  THEN
854       ibc_salsa_t = 0
855    ELSEIF ( bc_salsa_t == 'neumann' )  THEN
856       ibc_salsa_t = 1
857    ELSEIF ( bc_salsa_t == 'nested' )  THEN
858       ibc_salsa_t = 2
859    ELSE
860       message_string = 'unknown boundary condition: bc_salsa_t = "' // TRIM( bc_salsa_t ) // '"'
861       CALL message( 'salsa_check_parameters', 'PA0596', 1, 2, 0, 6, 0 )
862    ENDIF
863
864    IF ( nj3 < 1  .OR.  nj3 > 3 )  THEN
865       message_string = 'unknown nj3 (must be 1-3)'
866       CALL message( 'salsa_check_parameters', 'PA0597', 1, 2, 0, 6, 0 )
867    ENDIF
868
869    IF ( salsa_emission_mode == 'read_from_file'  .AND.  ibc_salsa_b  == 0 ) THEN
870       message_string = 'salsa_emission_mode == read_from_file requires bc_salsa_b = "Neumann"'
871       CALL message( 'salsa_check_parameters','PA0598', 1, 2, 0, 6, 0 )
872    ENDIF
873
874 END SUBROUTINE salsa_check_parameters
875
876!------------------------------------------------------------------------------!
877!
878! Description:
879! ------------
880!> Subroutine defining appropriate grid for netcdf variables.
881!> It is called out from subroutine netcdf.
882!> Same grid as for other scalars (see netcdf_interface_mod.f90)
883!------------------------------------------------------------------------------!
884 SUBROUTINE salsa_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
885
886    IMPLICIT NONE
887
888    CHARACTER(LEN=*), INTENT(OUT) ::  grid_x   !<
889    CHARACTER(LEN=*), INTENT(OUT) ::  grid_y   !<
890    CHARACTER(LEN=*), INTENT(OUT) ::  grid_z   !<
891    CHARACTER(LEN=*), INTENT(IN)  ::  var      !<
892
893    LOGICAL, INTENT(OUT) ::  found   !<
894
895    found  = .TRUE.
896!
897!-- Check for the grid
898
899    IF ( var(1:2) == 'g_' )  THEN
900       grid_x = 'x'
901       grid_y = 'y'
902       grid_z = 'zu'
903    ELSEIF ( var(1:4) == 'LDSA' )  THEN
904       grid_x = 'x'
905       grid_y = 'y'
906       grid_z = 'zu'
907    ELSEIF ( var(1:5) == 'm_bin' )  THEN
908       grid_x = 'x'
909       grid_y = 'y'
910       grid_z = 'zu'
911    ELSEIF ( var(1:5) == 'N_bin' )  THEN
912       grid_x = 'x'
913       grid_y = 'y'
914       grid_z = 'zu'
915    ELSEIF ( var(1:4) == 'Ntot' ) THEN
916       grid_x = 'x'
917       grid_y = 'y'
918       grid_z = 'zu'
919    ELSEIF ( var(1:2) == 'PM' )  THEN
920       grid_x = 'x'
921       grid_y = 'y'
922       grid_z = 'zu'
923    ELSEIF ( var(1:2) == 's_' )  THEN
924       grid_x = 'x'
925       grid_y = 'y'
926       grid_z = 'zu'
927    ELSE
928       found  = .FALSE.
929       grid_x = 'none'
930       grid_y = 'none'
931       grid_z = 'none'
932    ENDIF
933
934 END SUBROUTINE salsa_define_netcdf_grid
935
936!------------------------------------------------------------------------------!
937! Description:
938! ------------
939!> Header output for new module
940!------------------------------------------------------------------------------!
941 SUBROUTINE salsa_header( io )
942
943    IMPLICIT NONE
944 
945    INTEGER(iwp), INTENT(IN) ::  io   !< Unit of the output file
946!
947!-- Write SALSA header
948    WRITE( io, 1 )
949    WRITE( io, 2 ) skip_time_do_salsa
950    WRITE( io, 3 ) dt_salsa
951    WRITE( io, 4 )  SHAPE( aerosol_number(1)%conc ), nbins_aerosol
952    IF ( advect_particle_water )  THEN
953       WRITE( io, 5 )  SHAPE( aerosol_mass(1)%conc ), ncomponents_mass*nbins_aerosol,             &
954                        advect_particle_water
955    ELSE
956       WRITE( io, 5 )  SHAPE( aerosol_mass(1)%conc ), ncc*nbins_aerosol, advect_particle_water
957    ENDIF
958    IF ( .NOT. salsa_gases_from_chem )  THEN
959       WRITE( io, 6 )  SHAPE( aerosol_mass(1)%conc ), ngases_salsa, salsa_gases_from_chem
960    ENDIF
961    WRITE( io, 7 )
962    IF ( nsnucl > 0 )  THEN
963       WRITE( io, 8 ) nsnucl, nj3
964    ENDIF
965    IF ( nlcoag )  THEN
966       WRITE( io, 9 )
967    ENDIF
968    IF ( nlcnd )  THEN
969       WRITE( io, 10 ) nlcndgas, nlcndh2oae
970    ENDIF
971    IF ( lspartition )  THEN
972       WRITE( io, 11 )
973    ENDIF
974    IF ( nldepo )  THEN
975       WRITE( io, 12 ) nldepo_pcm, nldepo_surf
976    ENDIF
977    WRITE( io, 13 )  reglim, nbin, bin_low_limits
978    IF ( isdtyp == 0 )  WRITE( io, 14 ) nsect
979    WRITE( io, 15 ) ncc, listspec, mass_fracs_a, mass_fracs_b
980    IF ( .NOT. salsa_gases_from_chem )  THEN
981       WRITE( io, 16 ) ngases_salsa, h2so4_init, hno3_init, nh3_init, ocnv_init, ocsv_init
982    ENDIF
983    WRITE( io, 17 )  isdtyp, igctyp
984    IF ( isdtyp == 0 )  THEN
985       WRITE( io, 18 )  dpg, sigmag, n_lognorm
986    ELSE
987       WRITE( io, 19 )
988    ENDIF
989    IF ( nest_salsa )  WRITE( io, 20 )  nest_salsa
990    WRITE( io, 21 ) salsa_emission_mode
991
992
9931   FORMAT (//' SALSA information:'/                                                               &
994              ' ------------------------------'/)
9952   FORMAT   ('    Starts at: skip_time_do_salsa = ', F10.2, '  s')
9963   FORMAT  (/'    Timestep: dt_salsa = ', F6.2, '  s')
9974   FORMAT  (/'    Array shape (z,y,x,bins):'/                                                     &
998              '       aerosol_number:  ', 4(I3)) 
9995   FORMAT  (/'       aerosol_mass:    ', 4(I3),/                                                  &
1000              '       (advect_particle_water = ', L1, ')')
10016   FORMAT   ('       salsa_gas: ', 4(I3),/                                                        &
1002              '       (salsa_gases_from_chem = ', L1, ')')
10037   FORMAT  (/'    Aerosol dynamic processes included: ')
10048   FORMAT  (/'       nucleation (scheme = ', I1, ' and J3 parametrization = ', I1, ')')
10059   FORMAT  (/'       coagulation')
100610  FORMAT  (/'       condensation (of precursor gases = ', L1, ' and water vapour = ', L1, ')' )
100711  FORMAT  (/'       dissolutional growth by HNO3 and NH3')
100812  FORMAT  (/'       dry deposition (on vegetation = ', L1, ' and on topography = ', L1, ')')
100913  FORMAT  (/'    Aerosol bin subrange limits (in metres): ',  3(ES10.2E3), /                     &
1010              '    Number of size bins for each aerosol subrange: ', 2I3,/                         &
1011              '    Aerosol bin limits (in metres): ', 9(ES10.2E3))
101214  FORMAT   ('    Initial number concentration in bins at the lowest level (#/m**3):', 9(ES10.2E3))
101315  FORMAT  (/'    Number of chemical components used: ', I1,/                                     &
1014              '       Species: ',7(A6),/                                                           &
1015              '    Initial relative contribution of each species to particle volume in:',/         &
1016              '       a-bins: ', 7(F6.3),/                                                         &
1017              '       b-bins: ', 7(F6.3))
101816  FORMAT  (/'    Number of gaseous tracers used: ', I1,/                                         &
1019              '    Initial gas concentrations:',/                                                  &
1020              '       H2SO4: ',ES12.4E3, ' #/m**3',/                                               &
1021              '       HNO3:  ',ES12.4E3, ' #/m**3',/                                               &
1022              '       NH3:   ',ES12.4E3, ' #/m**3',/                                               &
1023              '       OCNV:  ',ES12.4E3, ' #/m**3',/                                               &
1024              '       OCSV:  ',ES12.4E3, ' #/m**3')
102517   FORMAT (/'   Initialising concentrations: ', /                                                &
1026              '      Aerosol size distribution: isdtyp = ', I1,/                                   &
1027              '      Gas concentrations: igctyp = ', I1 )
102818   FORMAT ( '      Mode diametres: dpg(nmod) = ', 7(F7.3), ' (m)', /                             &
1029              '      Standard deviation: sigmag(nmod) = ', 7(F7.2),/                               &
1030              '      Number concentration: n_lognorm(nmod) = ', 7(ES12.4E3), ' (#/m3)' )
103119   FORMAT (/'      Size distribution read from a file.')
103220   FORMAT (/'   Nesting for salsa variables: ', L1 )
103321   FORMAT (/'   Emissions: salsa_emission_mode = ', A )
1034
1035 END SUBROUTINE salsa_header
1036
1037!------------------------------------------------------------------------------!
1038! Description:
1039! ------------
1040!> Allocate SALSA arrays and define pointers if required
1041!------------------------------------------------------------------------------!
1042 SUBROUTINE salsa_init_arrays
1043
1044    USE chem_gasphase_mod,                                                                         &
1045        ONLY:  nvar
1046
1047    USE surface_mod,                                                                               &
1048        ONLY:  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, surf_usm_v
1049
1050    IMPLICIT NONE
1051
1052    INTEGER(iwp) ::  gases_available !< Number of available gas components in the chemistry model
1053    INTEGER(iwp) ::  i               !< loop index for allocating
1054    INTEGER(iwp) ::  l               !< loop index for allocating: surfaces
1055    INTEGER(iwp) ::  lsp             !< loop index for chem species in the chemistry model
1056
1057    gases_available = 0
1058!
1059!-- Allocate prognostic variables (see salsa_swap_timelevel)
1060!
1061!-- Set derived indices:
1062!-- (This does the same as the subroutine salsa_initialize in SALSA/UCLALES-SALSA)
1063    start_subrange_1a = 1  ! 1st index of subrange 1a
1064    start_subrange_2a = start_subrange_1a + nbin(1)  ! 1st index of subrange 2a
1065    end_subrange_1a   = start_subrange_2a - 1        ! last index of subrange 1a
1066    end_subrange_2a   = end_subrange_1a + nbin(2)    ! last index of subrange 2a
1067
1068!
1069!-- If the fraction of insoluble aerosols in subrange 2 is zero: do not allocate arrays for them
1070    IF ( nf2a > 0.999999_wp  .AND.  SUM( mass_fracs_b ) < 0.00001_wp )  THEN
1071       no_insoluble = .TRUE.
1072       start_subrange_2b = end_subrange_2a+1  ! 1st index of subrange 2b
1073       end_subrange_2b   = end_subrange_2a    ! last index of subrange 2b
1074    ELSE
1075       start_subrange_2b = start_subrange_2a + nbin(2)  ! 1st index of subrange 2b
1076       end_subrange_2b   = end_subrange_2a + nbin(2)    ! last index of subrange 2b
1077    ENDIF
1078
1079    nbins_aerosol = end_subrange_2b   ! total number of aerosol size bins
1080!
1081!-- Create index tables for different aerosol components
1082    CALL component_index_constructor( prtcl, ncc, maxspec, listspec )
1083
1084    ncomponents_mass = ncc
1085    IF ( advect_particle_water )  ncomponents_mass = ncc + 1  ! Add water
1086
1087!
1088!-- Allocate:
1089    ALLOCATE( aero(nbins_aerosol), bc_am_t_val(nbins_aerosol*ncomponents_mass),                    &
1090              bc_an_t_val(ngases_salsa), bc_gt_t_val(nbins_aerosol), bin_low_limits(nbins_aerosol),&
1091              nsect(nbins_aerosol), massacc(nbins_aerosol) )
1092    ALLOCATE( k_topo_top(nysg:nyng,nxlg:nxrg) )
1093    IF ( nldepo ) ALLOCATE( sedim_vd(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nbins_aerosol) )
1094    ALLOCATE( ra_dry(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nbins_aerosol) )
1095
1096!
1097!-- Aerosol number concentration
1098    ALLOCATE( aerosol_number(nbins_aerosol) )
1099    ALLOCATE( nconc_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nbins_aerosol),                                &
1100              nconc_2(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nbins_aerosol),                                &
1101              nconc_3(nzb:nzt+1,nysg:nyng,nxlg:nxrg,nbins_aerosol) )
1102    nconc_1 = 0.0_wp
1103    nconc_2 = 0.0_wp
1104    nconc_3 = 0.0_wp
1105
1106    DO i = 1, nbins_aerosol
1107       aerosol_number(i)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => nconc_1(:,:,:,i)
1108       aerosol_number(i)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg)  => nconc_2(:,:,:,i)
1109       aerosol_number(i)%tconc_m(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => nconc_3(:,:,:,i)
1110       ALLOCATE( aerosol_number(i)%flux_s(nzb+1:nzt,0:threads_per_task-1),     &
1111                 aerosol_number(i)%diss_s(nzb+1:nzt,0:threads_per_task-1),     &
1112                 aerosol_number(i)%flux_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),&
1113                 aerosol_number(i)%diss_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),&
1114                 aerosol_number(i)%init(nzb:nzt+1),                            &
1115                 aerosol_number(i)%sums_ws_l(nzb:nzt+1,0:threads_per_task-1) )
1116    ENDDO
1117
1118!
1119!-- Aerosol mass concentration
1120    ALLOCATE( aerosol_mass(ncomponents_mass*nbins_aerosol) )
1121    ALLOCATE( mconc_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ncomponents_mass*nbins_aerosol),               &
1122              mconc_2(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ncomponents_mass*nbins_aerosol),               &
1123              mconc_3(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ncomponents_mass*nbins_aerosol) )
1124    mconc_1 = 0.0_wp
1125    mconc_2 = 0.0_wp
1126    mconc_3 = 0.0_wp
1127
1128    DO i = 1, ncomponents_mass*nbins_aerosol
1129       aerosol_mass(i)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => mconc_1(:,:,:,i)
1130       aerosol_mass(i)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg)  => mconc_2(:,:,:,i)
1131       aerosol_mass(i)%tconc_m(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => mconc_3(:,:,:,i)
1132       ALLOCATE( aerosol_mass(i)%flux_s(nzb+1:nzt,0:threads_per_task-1),                           &
1133                 aerosol_mass(i)%diss_s(nzb+1:nzt,0:threads_per_task-1),                           &
1134                 aerosol_mass(i)%flux_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),                   &
1135                 aerosol_mass(i)%diss_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),                   &
1136                 aerosol_mass(i)%init(nzb:nzt+1),                                                  &
1137                 aerosol_mass(i)%sums_ws_l(nzb:nzt+1,0:threads_per_task-1)  )
1138    ENDDO
1139
1140!
1141!-- Surface fluxes: answs = aerosol number, amsws = aerosol mass
1142!
1143!-- Horizontal surfaces: default type
1144    DO  l = 0, 2   ! upward (l=0), downward (l=1) and model top (l=2)
1145       ALLOCATE( surf_def_h(l)%answs( 1:surf_def_h(l)%ns, nbins_aerosol ) )
1146       ALLOCATE( surf_def_h(l)%amsws( 1:surf_def_h(l)%ns, nbins_aerosol*ncomponents_mass ) )
1147       surf_def_h(l)%answs = 0.0_wp
1148       surf_def_h(l)%amsws = 0.0_wp
1149    ENDDO
1150!
1151!-- Horizontal surfaces: natural type
1152    ALLOCATE( surf_lsm_h%answs( 1:surf_lsm_h%ns, nbins_aerosol ) )
1153    ALLOCATE( surf_lsm_h%amsws( 1:surf_lsm_h%ns, nbins_aerosol*ncomponents_mass ) )
1154    surf_lsm_h%answs = 0.0_wp
1155    surf_lsm_h%amsws = 0.0_wp
1156!
1157!-- Horizontal surfaces: urban type
1158    ALLOCATE( surf_usm_h%answs( 1:surf_usm_h%ns, nbins_aerosol ) )
1159    ALLOCATE( surf_usm_h%amsws( 1:surf_usm_h%ns, nbins_aerosol*ncomponents_mass ) )
1160    surf_usm_h%answs = 0.0_wp
1161    surf_usm_h%amsws = 0.0_wp
1162
1163!
1164!-- Vertical surfaces: northward (l=0), southward (l=1), eastward (l=2) and westward (l=3) facing
1165    DO  l = 0, 3
1166       ALLOCATE( surf_def_v(l)%answs( 1:surf_def_v(l)%ns, nbins_aerosol ) )
1167       surf_def_v(l)%answs = 0.0_wp
1168       ALLOCATE( surf_def_v(l)%amsws( 1:surf_def_v(l)%ns, nbins_aerosol*ncomponents_mass ) )
1169       surf_def_v(l)%amsws = 0.0_wp
1170
1171       ALLOCATE( surf_lsm_v(l)%answs( 1:surf_lsm_v(l)%ns, nbins_aerosol ) )
1172       surf_lsm_v(l)%answs = 0.0_wp
1173       ALLOCATE( surf_lsm_v(l)%amsws( 1:surf_lsm_v(l)%ns, nbins_aerosol*ncomponents_mass ) )
1174       surf_lsm_v(l)%amsws = 0.0_wp
1175
1176       ALLOCATE( surf_usm_v(l)%answs( 1:surf_usm_v(l)%ns, nbins_aerosol ) )
1177       surf_usm_v(l)%answs = 0.0_wp
1178       ALLOCATE( surf_usm_v(l)%amsws( 1:surf_usm_v(l)%ns, nbins_aerosol*ncomponents_mass ) )
1179       surf_usm_v(l)%amsws = 0.0_wp
1180
1181    ENDDO
1182
1183!
1184!-- Concentration of gaseous tracers (1. SO4, 2. HNO3, 3. NH3, 4. OCNV, 5. OCSV)
1185!-- (number concentration (#/m3) )
1186!
1187!-- If chemistry is on, read gas phase concentrations from there. Otherwise,
1188!-- allocate salsa_gas array.
1189
1190    IF ( air_chemistry )  THEN
1191       DO  lsp = 1, nvar
1192          SELECT CASE ( TRIM( chem_species(lsp)%name ) )
1193             CASE ( 'H2SO4', 'h2so4' )
1194                gases_available = gases_available + 1
1195                gas_index_chem(1) = lsp
1196             CASE ( 'HNO3', 'hno3' )
1197                gases_available = gases_available + 1
1198                gas_index_chem(2) = lsp
1199             CASE ( 'NH3', 'nh3' )
1200                gases_available = gases_available + 1
1201                gas_index_chem(3) = lsp
1202             CASE ( 'OCNV', 'ocnv' )
1203                gases_available = gases_available + 1
1204                gas_index_chem(4) = lsp
1205             CASE ( 'OCSV', 'ocsv' )
1206                gases_available = gases_available + 1
1207                gas_index_chem(5) = lsp
1208          END SELECT
1209       ENDDO
1210
1211       IF ( gases_available == ngases_salsa )  THEN
1212          salsa_gases_from_chem = .TRUE.
1213       ELSE
1214          WRITE( message_string, * ) 'SALSA is run together with chemistry but not all gaseous '// &
1215                                     'components are provided by kpp (H2SO4, HNO3, NH3, OCNV, OCSV)'
1216       CALL message( 'check_parameters', 'PA0599', 1, 2, 0, 6, 0 )
1217       ENDIF
1218
1219    ELSE
1220
1221       ALLOCATE( salsa_gas(ngases_salsa) )
1222       ALLOCATE( gconc_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ngases_salsa),                 &
1223                 gconc_2(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ngases_salsa),                 &
1224                 gconc_3(nzb:nzt+1,nysg:nyng,nxlg:nxrg,ngases_salsa) )
1225       gconc_1 = 0.0_wp
1226       gconc_2 = 0.0_wp
1227       gconc_3 = 0.0_wp
1228
1229       DO i = 1, ngases_salsa
1230          salsa_gas(i)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)    => gconc_1(:,:,:,i)
1231          salsa_gas(i)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg)  => gconc_2(:,:,:,i)
1232          salsa_gas(i)%tconc_m(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => gconc_3(:,:,:,i)
1233          ALLOCATE( salsa_gas(i)%flux_s(nzb+1:nzt,0:threads_per_task-1),       &
1234                    salsa_gas(i)%diss_s(nzb+1:nzt,0:threads_per_task-1),       &
1235                    salsa_gas(i)%flux_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),&
1236                    salsa_gas(i)%diss_l(nzb+1:nzt,nys:nyn,0:threads_per_task-1),&
1237                    salsa_gas(i)%init(nzb:nzt+1),                              &
1238                    salsa_gas(i)%sums_ws_l(nzb:nzt+1,0:threads_per_task-1) )
1239       ENDDO
1240!
1241!--    Surface fluxes: gtsws = gaseous tracer flux
1242!
1243!--    Horizontal surfaces: default type
1244       DO  l = 0, 2   ! upward (l=0), downward (l=1) and model top (l=2)
1245          ALLOCATE( surf_def_h(l)%gtsws( 1:surf_def_h(l)%ns, ngases_salsa ) )
1246          surf_def_h(l)%gtsws = 0.0_wp
1247       ENDDO
1248!--    Horizontal surfaces: natural type
1249       ALLOCATE( surf_lsm_h%gtsws( 1:surf_lsm_h%ns, ngases_salsa ) )
1250       surf_lsm_h%gtsws = 0.0_wp
1251!--    Horizontal surfaces: urban type
1252       ALLOCATE( surf_usm_h%gtsws( 1:surf_usm_h%ns, ngases_salsa ) )
1253       surf_usm_h%gtsws = 0.0_wp
1254!
1255!--    Vertical surfaces: northward (l=0), southward (l=1), eastward (l=2) and
1256!--    westward (l=3) facing
1257       DO  l = 0, 3
1258          ALLOCATE( surf_def_v(l)%gtsws( 1:surf_def_v(l)%ns, ngases_salsa ) )
1259          surf_def_v(l)%gtsws = 0.0_wp
1260          ALLOCATE( surf_lsm_v(l)%gtsws( 1:surf_lsm_v(l)%ns, ngases_salsa ) )
1261          surf_lsm_v(l)%gtsws = 0.0_wp
1262          ALLOCATE( surf_usm_v(l)%gtsws( 1:surf_usm_v(l)%ns, ngases_salsa ) )
1263          surf_usm_v(l)%gtsws = 0.0_wp
1264       ENDDO
1265    ENDIF
1266
1267    IF ( ws_scheme_sca )  THEN
1268
1269       IF ( salsa )  THEN
1270          ALLOCATE( sums_salsa_ws_l(nzb:nzt+1,0:threads_per_task-1) )
1271          sums_salsa_ws_l = 0.0_wp
1272       ENDIF
1273
1274    ENDIF
1275
1276 END SUBROUTINE salsa_init_arrays
1277
1278!------------------------------------------------------------------------------!
1279! Description:
1280! ------------
1281!> Initialization of SALSA. Based on salsa_initialize in UCLALES-SALSA.
1282!> Subroutines salsa_initialize, SALSAinit and DiagInitAero in UCLALES-SALSA are
1283!> also merged here.
1284!------------------------------------------------------------------------------!
1285 SUBROUTINE salsa_init
1286
1287    IMPLICIT NONE
1288
1289    INTEGER(iwp) :: i   !<
1290    INTEGER(iwp) :: ib  !< loop index for aerosol number bins
1291    INTEGER(iwp) :: ic  !< loop index for aerosol mass bins
1292    INTEGER(iwp) :: ig  !< loop index for gases
1293    INTEGER(iwp) :: ii  !< index for indexing
1294    INTEGER(iwp) :: j   !<
1295
1296    IF ( debug_output )  CALL debug_message( 'salsa_init', 'start' )
1297
1298    bin_low_limits = 0.0_wp
1299    k_topo_top     = 0
1300    nsect          = 0.0_wp
1301    massacc        = 1.0_wp
1302
1303!
1304!-- Indices for chemical components used (-1 = not used)
1305    ii = 0
1306    IF ( is_used( prtcl, 'SO4' ) )  THEN
1307       index_so4 = get_index( prtcl,'SO4' )
1308       ii = ii + 1
1309    ENDIF
1310    IF ( is_used( prtcl,'OC' ) )  THEN
1311       index_oc = get_index(prtcl, 'OC')
1312       ii = ii + 1
1313    ENDIF
1314    IF ( is_used( prtcl, 'BC' ) )  THEN
1315       index_bc = get_index( prtcl, 'BC' )
1316       ii = ii + 1
1317    ENDIF
1318    IF ( is_used( prtcl, 'DU' ) )  THEN
1319       index_du = get_index( prtcl, 'DU' )
1320       ii = ii + 1
1321    ENDIF
1322    IF ( is_used( prtcl, 'SS' ) )  THEN
1323       index_ss = get_index( prtcl, 'SS' )
1324       ii = ii + 1
1325    ENDIF
1326    IF ( is_used( prtcl, 'NO' ) )  THEN
1327       index_no = get_index( prtcl, 'NO' )
1328       ii = ii + 1
1329    ENDIF
1330    IF ( is_used( prtcl, 'NH' ) )  THEN
1331       index_nh = get_index( prtcl, 'NH' )
1332       ii = ii + 1
1333    ENDIF
1334!
1335!-- All species must be known
1336    IF ( ii /= ncc )  THEN
1337       message_string = 'Unknown aerosol species/component(s) given in the initialization'
1338       CALL message( 'salsa_mod: salsa_init', 'PA0600', 1, 2, 0, 6, 0 )
1339    ENDIF
1340!
1341!-- Partition and dissolutional growth by gaseous HNO3 and NH3
1342    IF ( index_no > 0  .AND.  index_nh > 0  .AND.  index_so4 > 0 )  lspartition = .TRUE.
1343!
1344!-- Initialise
1345!
1346!-- Aerosol size distribution (TYPE t_section)
1347    aero(:)%dwet     = 1.0E-10_wp
1348    aero(:)%veqh2o   = 1.0E-10_wp
1349    aero(:)%numc     = nclim
1350    aero(:)%core     = 1.0E-10_wp
1351    DO ic = 1, maxspec+1    ! 1:SO4, 2:OC, 3:BC, 4:DU, 5:SS, 6:NO, 7:NH, 8:H2O
1352       aero(:)%volc(ic) = 0.0_wp
1353    ENDDO
1354
1355    IF ( nldepo )  sedim_vd = 0.0_wp
1356
1357    DO  ib = 1, nbins_aerosol
1358       IF ( .NOT. read_restart_data_salsa )  aerosol_number(ib)%conc = nclim
1359       aerosol_number(ib)%conc_p    = 0.0_wp
1360       aerosol_number(ib)%tconc_m   = 0.0_wp
1361       aerosol_number(ib)%flux_s    = 0.0_wp
1362       aerosol_number(ib)%diss_s    = 0.0_wp
1363       aerosol_number(ib)%flux_l    = 0.0_wp
1364       aerosol_number(ib)%diss_l    = 0.0_wp
1365       aerosol_number(ib)%init      = nclim
1366       aerosol_number(ib)%sums_ws_l = 0.0_wp
1367    ENDDO
1368    DO  ic = 1, ncomponents_mass*nbins_aerosol
1369       IF ( .NOT. read_restart_data_salsa )  aerosol_mass(ic)%conc = mclim
1370       aerosol_mass(ic)%conc_p    = 0.0_wp
1371       aerosol_mass(ic)%tconc_m   = 0.0_wp
1372       aerosol_mass(ic)%flux_s    = 0.0_wp
1373       aerosol_mass(ic)%diss_s    = 0.0_wp
1374       aerosol_mass(ic)%flux_l    = 0.0_wp
1375       aerosol_mass(ic)%diss_l    = 0.0_wp
1376       aerosol_mass(ic)%init      = mclim
1377       aerosol_mass(ic)%sums_ws_l = 0.0_wp
1378    ENDDO
1379
1380    IF ( .NOT. salsa_gases_from_chem )  THEN
1381       DO  ig = 1, ngases_salsa
1382          salsa_gas(ig)%conc_p    = 0.0_wp
1383          salsa_gas(ig)%tconc_m   = 0.0_wp
1384          salsa_gas(ig)%flux_s    = 0.0_wp
1385          salsa_gas(ig)%diss_s    = 0.0_wp
1386          salsa_gas(ig)%flux_l    = 0.0_wp
1387          salsa_gas(ig)%diss_l    = 0.0_wp
1388          salsa_gas(ig)%sums_ws_l = 0.0_wp
1389       ENDDO
1390       IF ( .NOT. read_restart_data_salsa )  THEN
1391          salsa_gas(1)%conc = h2so4_init
1392          salsa_gas(2)%conc = hno3_init
1393          salsa_gas(3)%conc = nh3_init
1394          salsa_gas(4)%conc = ocnv_init
1395          salsa_gas(5)%conc = ocsv_init
1396       ENDIF
1397!
1398!--    Set initial value for gas compound tracers and initial values
1399       salsa_gas(1)%init = h2so4_init
1400       salsa_gas(2)%init = hno3_init
1401       salsa_gas(3)%init = nh3_init
1402       salsa_gas(4)%init = ocnv_init
1403       salsa_gas(5)%init = ocsv_init
1404    ENDIF
1405!
1406!-- Aerosol radius in each bin: dry and wet (m)
1407    ra_dry = 1.0E-10_wp
1408!
1409!-- Initialise aerosol tracers
1410    aero(:)%vhilim   = 0.0_wp
1411    aero(:)%vlolim   = 0.0_wp
1412    aero(:)%vratiohi = 0.0_wp
1413    aero(:)%vratiolo = 0.0_wp
1414    aero(:)%dmid     = 0.0_wp
1415!
1416!-- Initialise the sectional particle size distribution
1417    CALL set_sizebins
1418!
1419!-- Initialise location-dependent aerosol size distributions and chemical compositions:
1420    CALL aerosol_init
1421!
1422!-- Initalisation run of SALSA + calculate the vertical top index of the topography
1423    DO  i = nxl, nxr
1424       DO  j = nys, nyn
1425
1426          k_topo_top(j,i) = MAXLOC( MERGE( 1, 0, BTEST( wall_flags_0(:,j,i), 12 ) ), DIM = 1 ) - 1
1427
1428          CALL salsa_driver( i, j, 1 )
1429          CALL salsa_diagnostics( i, j )
1430       ENDDO
1431    ENDDO
1432!
1433!-- Initialise the deposition scheme and surface types
1434    IF ( nldepo )  CALL init_deposition
1435
1436    IF ( salsa_emission_mode /= 'no_emission' )  THEN
1437!
1438!--    Read in and initialize emissions
1439       CALL salsa_emission_setup( .TRUE. )
1440       IF ( .NOT. salsa_gases_from_chem  .AND.  salsa_emission_mode == 'read_from_file' )  THEN
1441          CALL salsa_gas_emission_setup( .TRUE. )
1442       ENDIF
1443    ENDIF
1444
1445    IF ( debug_output )  CALL debug_message( 'salsa_init', 'end' )
1446
1447 END SUBROUTINE salsa_init
1448
1449!------------------------------------------------------------------------------!
1450! Description:
1451! ------------
1452!> Initializes particle size distribution grid by calculating size bin limits
1453!> and mid-size for *dry* particles in each bin. Called from salsa_initialize
1454!> (only at the beginning of simulation).
1455!> Size distribution described using:
1456!>   1) moving center method (subranges 1 and 2)
1457!>      (Jacobson, Atmos. Env., 31, 131-144, 1997)
1458!>   2) fixed sectional method (subrange 3)
1459!> Size bins in each subrange are spaced logarithmically
1460!> based on given subrange size limits and bin number.
1461!
1462!> Mona changed 06/2017: Use geometric mean diameter to describe the mean
1463!> particle diameter in a size bin, not the arithmeric mean which clearly
1464!> overestimates the total particle volume concentration.
1465!
1466!> Coded by:
1467!> Hannele Korhonen (FMI) 2005
1468!> Harri Kokkola (FMI) 2006
1469!
1470!> Bug fixes for box model + updated for the new aerosol datatype:
1471!> Juha Tonttila (FMI) 2014
1472!------------------------------------------------------------------------------!
1473 SUBROUTINE set_sizebins
1474
1475    IMPLICIT NONE
1476
1477    INTEGER(iwp) ::  cc  !< running index
1478    INTEGER(iwp) ::  dd  !< running index
1479
1480    REAL(wp) ::  ratio_d  !< ratio of the upper and lower diameter of subranges
1481!
1482!-- vlolim&vhilim: min & max *dry* volumes [fxm]
1483!-- dmid: bin mid *dry* diameter (m)
1484!-- vratiolo&vratiohi: volume ratio between the center and low/high limit
1485!
1486!-- 1) Size subrange 1:
1487    ratio_d = reglim(2) / reglim(1)   ! section spacing (m)
1488    DO  cc = start_subrange_1a, end_subrange_1a
1489       aero(cc)%vlolim = api6 * ( reglim(1) * ratio_d**( REAL( cc-1 ) / nbin(1) ) )**3
1490       aero(cc)%vhilim = api6 * ( reglim(1) * ratio_d**( REAL( cc ) / nbin(1) ) )**3
1491       aero(cc)%dmid = SQRT( ( aero(cc)%vhilim / api6 )**0.33333333_wp *                           &
1492                             ( aero(cc)%vlolim / api6 )**0.33333333_wp )
1493       aero(cc)%vratiohi = aero(cc)%vhilim / ( api6 * aero(cc)%dmid**3 )
1494       aero(cc)%vratiolo = aero(cc)%vlolim / ( api6 * aero(cc)%dmid**3 )
1495    ENDDO
1496!
1497!-- 2) Size subrange 2:
1498!-- 2.1) Sub-subrange 2a: high hygroscopicity
1499    ratio_d = reglim(3) / reglim(2)   ! section spacing
1500    DO  dd = start_subrange_2a, end_subrange_2a
1501       cc = dd - start_subrange_2a
1502       aero(dd)%vlolim = api6 * ( reglim(2) * ratio_d**( REAL( cc ) / nbin(2) ) )**3
1503       aero(dd)%vhilim = api6 * ( reglim(2) * ratio_d**( REAL( cc+1 ) / nbin(2) ) )**3
1504       aero(dd)%dmid = SQRT( ( aero(dd)%vhilim / api6 )**0.33333333_wp *                           &
1505                             ( aero(dd)%vlolim / api6 )**0.33333333_wp )
1506       aero(dd)%vratiohi = aero(dd)%vhilim / ( api6 * aero(dd)%dmid**3 )
1507       aero(dd)%vratiolo = aero(dd)%vlolim / ( api6 * aero(dd)%dmid**3 )
1508    ENDDO
1509!
1510!-- 2.2) Sub-subrange 2b: low hygroscopicity
1511    IF ( .NOT. no_insoluble )  THEN
1512       aero(start_subrange_2b:end_subrange_2b)%vlolim   = aero(start_subrange_2a:end_subrange_2a)%vlolim
1513       aero(start_subrange_2b:end_subrange_2b)%vhilim   = aero(start_subrange_2a:end_subrange_2a)%vhilim
1514       aero(start_subrange_2b:end_subrange_2b)%dmid     = aero(start_subrange_2a:end_subrange_2a)%dmid
1515       aero(start_subrange_2b:end_subrange_2b)%vratiohi = aero(start_subrange_2a:end_subrange_2a)%vratiohi
1516       aero(start_subrange_2b:end_subrange_2b)%vratiolo = aero(start_subrange_2a:end_subrange_2a)%vratiolo
1517    ENDIF
1518!
1519!-- Initialize the wet diameter with the bin dry diameter to avoid numerical problems later
1520    aero(:)%dwet = aero(:)%dmid
1521!
1522!-- Save bin limits (lower diameter) to be delivered to PALM if needed
1523    DO cc = 1, nbins_aerosol
1524       bin_low_limits(cc) = ( aero(cc)%vlolim / api6 )**0.33333333_wp
1525    ENDDO
1526
1527 END SUBROUTINE set_sizebins
1528
1529!------------------------------------------------------------------------------!
1530! Description:
1531! ------------
1532!> Initilize altitude-dependent aerosol size distributions and compositions.
1533!>
1534!> Mona added 06/2017: Correct the number and mass concentrations by normalizing
1535!< by the given total number and mass concentration.
1536!>
1537!> Tomi Raatikainen, FMI, 29.2.2016
1538!------------------------------------------------------------------------------!
1539 SUBROUTINE aerosol_init
1540
1541    USE netcdf_data_input_mod,                                                                     &
1542        ONLY:  get_attribute, get_variable, netcdf_data_input_get_dimension_length, open_read_file
1543
1544    IMPLICIT NONE
1545
1546    CHARACTER(LEN=25), DIMENSION(:), ALLOCATABLE :: cc_name  !< chemical component name
1547
1548    INTEGER(iwp) ::  ee        !< index: end
1549    INTEGER(iwp) ::  i         !< loop index: x-direction
1550    INTEGER(iwp) ::  ib        !< loop index: size bins
1551    INTEGER(iwp) ::  ic        !< loop index: chemical components
1552    INTEGER(iwp) ::  id_dyn    !< NetCDF id of PIDS_DYNAMIC_SALSA
1553    INTEGER(iwp) ::  ig        !< loop index: gases
1554    INTEGER(iwp) ::  j         !< loop index: y-direction
1555    INTEGER(iwp) ::  k         !< loop index: z-direction
1556    INTEGER(iwp) ::  lod_aero  !< level of detail of inital aerosol concentrations
1557    INTEGER(iwp) ::  pr_nbins  !< Number of aerosol size bins in file
1558    INTEGER(iwp) ::  pr_ncc    !< Number of aerosol chemical components in file
1559    INTEGER(iwp) ::  pr_nz     !< Number of vertical grid-points in file
1560    INTEGER(iwp) ::  prunmode  !< running mode of SALSA
1561    INTEGER(iwp) ::  ss        !< index: start
1562
1563    INTEGER(iwp), DIMENSION(maxspec) ::  cc_input_to_model
1564
1565    LOGICAL  ::  netcdf_extend = .FALSE. !< Flag: netcdf file exists
1566
1567    REAL(wp) ::  flag  !< flag to mask topography grid points
1568
1569    REAL(wp), DIMENSION(nbins_aerosol) ::  core   !< size of the bin mid aerosol particle
1570    REAL(wp), DIMENSION(nbins_aerosol) ::  nsect  !< size distribution (#/m3)
1571
1572    REAL(wp), DIMENSION(0:nz+1) ::  pnf2a   !< number fraction in 2a
1573    REAL(wp), DIMENSION(0:nz+1) ::  pmfoc1a !< mass fraction of OC in 1a
1574
1575    REAL(wp), DIMENSION(0:nz+1,nbins_aerosol)   ::  pndist  !< size dist as a function of height (#/m3)
1576    REAL(wp), DIMENSION(0:nz+1,maxspec)         ::  pmf2a   !< mass distributions in subrange 2a
1577    REAL(wp), DIMENSION(0:nz+1,maxspec)         ::  pmf2b   !< mass distributions in subrange 2b
1578
1579    REAL(wp), DIMENSION(:), ALLOCATABLE ::  pr_dmid  !< vertical profile of aerosol bin diameters
1580    REAL(wp), DIMENSION(:), ALLOCATABLE ::  pr_z     !< z levels of profiles
1581
1582    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  pr_mass_fracs_a  !< mass fraction: a
1583    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  pr_mass_fracs_b  !< and b
1584
1585    cc_input_to_model = 0
1586    prunmode = 1
1587!
1588!-- Bin mean aerosol particle volume (m3)
1589    core(:) = 0.0_wp
1590    core(1:nbins_aerosol) = api6 * aero(1:nbins_aerosol)%dmid**3
1591!
1592!-- Set concentrations to zero
1593    nsect(:)     = 0.0_wp
1594    pndist(:,:)  = 0.0_wp
1595    pnf2a(:)     = nf2a
1596    pmf2a(:,:)   = 0.0_wp
1597    pmf2b(:,:)   = 0.0_wp
1598    pmfoc1a(:)   = 0.0_wp
1599
1600    IF ( isdtyp == 1 )  THEN
1601!
1602!--    Read input profiles from PIDS_DYNAMIC_SALSA
1603#if defined( __netcdf )
1604!
1605!--    Location-dependent size distributions and compositions.
1606       INQUIRE( FILE = TRIM( input_file_dynamic ) //  TRIM( coupling_char ), EXIST = netcdf_extend )
1607       IF ( netcdf_extend )  THEN
1608!
1609!--       Open file in read-only mode
1610          CALL open_read_file( input_file_dynamic // TRIM( coupling_char ), id_dyn )
1611!
1612!--       Inquire dimensions:
1613          CALL netcdf_data_input_get_dimension_length( id_dyn, pr_nz, 'z' )
1614          IF ( pr_nz /= nz )  THEN
1615             WRITE( message_string, * ) 'Number of inifor horizontal grid points does not match '//&
1616                                        'the number of numeric grid points.'
1617             CALL message( 'aerosol_init', 'PA0601', 1, 2, 0, 6, 0 )
1618          ENDIF
1619          CALL netcdf_data_input_get_dimension_length( id_dyn, pr_ncc, 'composition_index' )
1620!
1621!--       Allocate memory
1622          ALLOCATE( pr_z(1:pr_nz), pr_mass_fracs_a(nzb:nzt+1,pr_ncc),                            &
1623                    pr_mass_fracs_b(nzb:nzt+1,pr_ncc) )
1624          pr_mass_fracs_a = 0.0_wp
1625          pr_mass_fracs_b = 0.0_wp
1626!
1627!--       Read vertical levels
1628          CALL get_variable( id_dyn, 'z', pr_z )
1629!
1630!--       Read name and index of chemical components
1631          CALL get_variable( id_dyn, 'composition_name', cc_name, pr_ncc )
1632          DO  ic = 1, pr_ncc
1633             SELECT CASE ( TRIM( cc_name(ic) ) )
1634                CASE ( 'H2SO4', 'SO4', 'h2so4', 'so4' )
1635                   cc_input_to_model(1) = ic
1636                CASE ( 'OC', 'oc' )
1637                   cc_input_to_model(2) = ic
1638                CASE ( 'BC', 'bc' )
1639                   cc_input_to_model(3) = ic
1640                CASE ( 'DU', 'du' )
1641                   cc_input_to_model(4) = ic
1642                CASE ( 'SS', 'ss' )
1643                   cc_input_to_model(5) = ic
1644                CASE ( 'HNO3', 'hno3', 'NO', 'no' )
1645                   cc_input_to_model(6) = ic
1646                CASE ( 'NH3', 'nh3', 'NH', 'nh' )
1647                   cc_input_to_model(7) = ic
1648             END SELECT
1649          ENDDO
1650
1651          IF ( SUM( cc_input_to_model ) == 0 )  THEN
1652             message_string = 'None of the aerosol chemical components in ' // TRIM(               &
1653                              input_file_dynamic ) // ' correspond to ones applied in SALSA.'
1654             CALL message( 'salsa_mod: aerosol_init', 'PA0602', 2, 2, 0, 6, 0 )
1655          ENDIF
1656!
1657!--       Vertical profiles of mass fractions of different chemical components:
1658          CALL get_variable( id_dyn, 'init_atmosphere_mass_fracs_a', pr_mass_fracs_a,              &
1659                             0, pr_ncc-1, 0, pr_nz-1 )
1660          CALL get_variable( id_dyn, 'init_atmosphere_mass_fracs_b', pr_mass_fracs_b,              &
1661                             0, pr_ncc-1, 0, pr_nz-1  )
1662!
1663!--       Match the input data with the chemical composition applied in the model
1664          DO  ic = 1, maxspec
1665             ss = cc_input_to_model(ic)
1666             IF ( ss == 0 )  CYCLE
1667             pmf2a(nzb+1:nzt+1,ic) = pr_mass_fracs_a(nzb:nzt,ss)
1668             pmf2b(nzb+1:nzt+1,ic) = pr_mass_fracs_b(nzb:nzt,ss)
1669          ENDDO
1670!
1671!--       Aerosol concentrations: lod=1 (total PM) or lod=2 (sectional number size distribution)
1672          CALL get_attribute( id_dyn, 'lod', lod_aero, .FALSE., 'init_atmosphere_aerosol' )
1673          IF ( lod_aero /= 2 )  THEN
1674             message_string = 'Currently only lod=2 accepted for init_atmosphere_aerosol'
1675             CALL message( 'salsa_mod: aerosol_init', 'PA0603', 2, 2, 0, 6, 0 )
1676          ELSE
1677!
1678!--          Bin mean diameters in the input file
1679             CALL netcdf_data_input_get_dimension_length( id_dyn, pr_nbins, 'Dmid')
1680             IF ( pr_nbins /= nbins_aerosol )  THEN
1681                message_string = 'Number of size bins in init_atmosphere_aerosol does not match '  &
1682                                 // 'with that applied in the model'
1683                CALL message( 'salsa_mod: aerosol_init', 'PA0604', 2, 2, 0, 6, 0 )
1684             ENDIF
1685
1686             ALLOCATE( pr_dmid(pr_nbins) )
1687             pr_dmid    = 0.0_wp
1688
1689             CALL get_variable( id_dyn, 'Dmid', pr_dmid )
1690!
1691!--          Check whether the sectional representation conform to the one
1692!--          applied in the model
1693             IF ( ANY( ABS( ( aero(1:nbins_aerosol)%dmid - pr_dmid ) /                             &
1694                              aero(1:nbins_aerosol)%dmid )  > 0.1_wp )  ) THEN
1695                message_string = 'Mean diameters of the aerosol size bins ' // TRIM(               &
1696                                 input_file_dynamic ) // ' in do not conform to the sectional '//  &
1697                                 'representation of the model.'
1698                CALL message( 'salsa_mod: aerosol_init', 'PA0605', 2, 2, 0, 6, 0 )
1699             ENDIF
1700!
1701!--          Inital aerosol concentrations
1702             CALL get_variable( id_dyn, 'init_atmosphere_aerosol', pndist(nzb+1:nzt,:),            &
1703                                0, pr_nbins-1, 0, pr_nz-1 )
1704          ENDIF
1705!
1706!--       Set bottom and top boundary condition (Neumann)
1707          pmf2a(nzb,:)    = pmf2a(nzb+1,:)
1708          pmf2a(nzt+1,:)  = pmf2a(nzt,:)
1709          pmf2b(nzb,:)    = pmf2b(nzb+1,:)
1710          pmf2b(nzt+1,:)  = pmf2b(nzt,:)
1711          pndist(nzb,:)   = pndist(nzb+1,:)
1712          pndist(nzt+1,:) = pndist(nzt,:)
1713
1714          IF ( index_so4 < 0 )  THEN
1715             pmf2a(:,1) = 0.0_wp
1716             pmf2b(:,1) = 0.0_wp
1717          ENDIF
1718          IF ( index_oc < 0 )  THEN
1719             pmf2a(:,2) = 0.0_wp
1720             pmf2b(:,2) = 0.0_wp
1721          ENDIF
1722          IF ( index_bc < 0 )  THEN
1723             pmf2a(:,3) = 0.0_wp
1724             pmf2b(:,3) = 0.0_wp
1725          ENDIF
1726          IF ( index_du < 0 )  THEN
1727             pmf2a(:,4) = 0.0_wp
1728             pmf2b(:,4) = 0.0_wp
1729          ENDIF
1730          IF ( index_ss < 0 )  THEN
1731             pmf2a(:,5) = 0.0_wp
1732             pmf2b(:,5) = 0.0_wp
1733          ENDIF
1734          IF ( index_no < 0 )  THEN
1735             pmf2a(:,6) = 0.0_wp
1736             pmf2b(:,6) = 0.0_wp
1737          ENDIF
1738          IF ( index_nh < 0 )  THEN
1739             pmf2a(:,7) = 0.0_wp
1740             pmf2b(:,7) = 0.0_wp
1741          ENDIF
1742
1743          IF ( SUM( pmf2a ) < 0.00001_wp  .AND.  SUM( pmf2b ) < 0.00001_wp )  THEN
1744             message_string = 'Error in initialising mass fractions of chemical components. ' //   &
1745                              'Check that all chemical components are included in parameter file!'
1746             CALL message( 'salsa_mod: aerosol_init', 'PA0606', 2, 2, 0, 6, 0 ) 
1747          ENDIF
1748!
1749!--       Then normalise the mass fraction so that SUM = 1
1750          DO  k = nzb, nzt+1
1751             pmf2a(k,:) = pmf2a(k,:) / SUM( pmf2a(k,:) )
1752             IF ( SUM( pmf2b(k,:) ) > 0.0_wp )  pmf2b(k,:) = pmf2b(k,:) / SUM( pmf2b(k,:) )
1753          ENDDO
1754
1755          DEALLOCATE( pr_z, pr_mass_fracs_a, pr_mass_fracs_b )
1756
1757       ELSE
1758          message_string = 'Input file '// TRIM( input_file_dynamic ) // TRIM( coupling_char ) //  &
1759                           ' for SALSA missing!'
1760          CALL message( 'salsa_mod: aerosol_init', 'PA0607', 1, 2, 0, 6, 0 )
1761
1762       ENDIF   ! netcdf_extend
1763
1764#else
1765       message_string = 'isdtyp = 1 but preprocessor directive __netcdf is not used in compiling!'
1766       CALL message( 'salsa_mod: aerosol_init', 'PA0608', 1, 2, 0, 6, 0 )
1767
1768#endif
1769
1770    ELSEIF ( isdtyp == 0 )  THEN
1771!
1772!--    Mass fractions for species in a and b-bins
1773       IF ( index_so4 > 0 )  THEN
1774          pmf2a(:,1) = mass_fracs_a(index_so4)
1775          pmf2b(:,1) = mass_fracs_b(index_so4)
1776       ENDIF
1777       IF ( index_oc > 0 )  THEN
1778          pmf2a(:,2) = mass_fracs_a(index_oc)
1779          pmf2b(:,2) = mass_fracs_b(index_oc)
1780       ENDIF
1781       IF ( index_bc > 0 )  THEN
1782          pmf2a(:,3) = mass_fracs_a(index_bc)
1783          pmf2b(:,3) = mass_fracs_b(index_bc)
1784       ENDIF
1785       IF ( index_du > 0 )  THEN
1786          pmf2a(:,4) = mass_fracs_a(index_du)
1787          pmf2b(:,4) = mass_fracs_b(index_du)
1788       ENDIF
1789       IF ( index_ss > 0 )  THEN
1790          pmf2a(:,5) = mass_fracs_a(index_ss)
1791          pmf2b(:,5) = mass_fracs_b(index_ss)
1792       ENDIF
1793       IF ( index_no > 0 )  THEN
1794          pmf2a(:,6) = mass_fracs_a(index_no)
1795          pmf2b(:,6) = mass_fracs_b(index_no)
1796       ENDIF
1797       IF ( index_nh > 0 )  THEN
1798          pmf2a(:,7) = mass_fracs_a(index_nh)
1799          pmf2b(:,7) = mass_fracs_b(index_nh)
1800       ENDIF
1801       DO  k = nzb, nzt+1
1802          pmf2a(k,:) = pmf2a(k,:) / SUM( pmf2a(k,:) )
1803          IF ( SUM( pmf2b(k,:) ) > 0.0_wp ) pmf2b(k,:) = pmf2b(k,:) / SUM( pmf2b(k,:) )
1804       ENDDO
1805
1806       CALL size_distribution( n_lognorm, dpg, sigmag, nsect )
1807!
1808!--    Normalize by the given total number concentration
1809       nsect = nsect * SUM( n_lognorm ) / SUM( nsect )
1810       DO  ib = start_subrange_1a, end_subrange_2b
1811          pndist(:,ib) = nsect(ib)
1812       ENDDO
1813    ENDIF
1814
1815    IF ( igctyp == 1 )  THEN
1816!
1817!--    Read input profiles from PIDS_CHEM
1818#if defined( __netcdf )
1819!
1820!--    Location-dependent size distributions and compositions.
1821       INQUIRE( FILE = TRIM( input_file_dynamic ) //  TRIM( coupling_char ), EXIST = netcdf_extend )
1822       IF ( netcdf_extend  .AND.  .NOT. salsa_gases_from_chem )  THEN
1823!
1824!--       Open file in read-only mode
1825          CALL open_read_file( input_file_dynamic // TRIM( coupling_char ), id_dyn )
1826!
1827!--       Inquire dimensions:
1828          CALL netcdf_data_input_get_dimension_length( id_dyn, pr_nz, 'z' )
1829          IF ( pr_nz /= nz )  THEN
1830             WRITE( message_string, * ) 'Number of inifor horizontal grid points does not match '//&
1831                                        'the number of numeric grid points.'
1832             CALL message( 'aerosol_init', 'PA0609', 1, 2, 0, 6, 0 )
1833          ENDIF
1834!
1835!--       Read vertical profiles of gases:
1836          CALL get_variable( id_dyn, 'init_atmosphere_h2so4', salsa_gas(1)%init(nzb+1:nzt) )
1837          CALL get_variable( id_dyn, 'init_atmosphere_hno3',  salsa_gas(2)%init(nzb+1:nzt) )
1838          CALL get_variable( id_dyn, 'init_atmosphere_nh3',   salsa_gas(3)%init(nzb+1:nzt) )
1839          CALL get_variable( id_dyn, 'init_atmosphere_ocnv',  salsa_gas(4)%init(nzb+1:nzt) )
1840          CALL get_variable( id_dyn, 'init_atmosphere_ocsv',  salsa_gas(5)%init(nzb+1:nzt) )
1841!
1842!--       Set Neumann top and surface boundary condition for initial + initialise concentrations
1843          DO  ig = 1, ngases_salsa
1844             salsa_gas(ig)%init(nzb)   =  salsa_gas(ig)%init(nzb+1)
1845             salsa_gas(ig)%init(nzt+1) =  salsa_gas(ig)%init(nzt)
1846             DO  k = nzb, nzt+1
1847                salsa_gas(ig)%conc(k,:,:) = salsa_gas(ig)%init(k)
1848             ENDDO
1849          ENDDO
1850
1851       ELSEIF ( .NOT. netcdf_extend  .AND.  .NOT.  salsa_gases_from_chem )  THEN
1852          message_string = 'Input file '// TRIM( input_file_dynamic ) // TRIM( coupling_char ) //  &
1853                           ' for SALSA missing!'
1854          CALL message( 'salsa_mod: aerosol_init', 'PA0610', 1, 2, 0, 6, 0 )
1855       ENDIF   ! netcdf_extend
1856#else
1857       message_string = 'igctyp = 1 but preprocessor directive __netcdf is not used in compiling!'
1858       CALL message( 'salsa_mod: aerosol_init', 'PA0611', 1, 2, 0, 6, 0 )
1859
1860#endif
1861
1862    ENDIF
1863!
1864!-- Both SO4 and OC are included, so use the given mass fractions
1865    IF ( index_oc > 0  .AND.  index_so4 > 0 )  THEN
1866       pmfoc1a(:) = pmf2a(:,2) / ( pmf2a(:,2) + pmf2a(:,1) )  ! Normalize
1867!
1868!-- Pure organic carbon
1869    ELSEIF ( index_oc > 0 )  THEN
1870       pmfoc1a(:) = 1.0_wp
1871!
1872!-- Pure SO4
1873    ELSEIF ( index_so4 > 0 )  THEN
1874       pmfoc1a(:) = 0.0_wp
1875
1876    ELSE
1877       message_string = 'Either OC or SO4 must be active for aerosol region 1a!'
1878       CALL message( 'salsa_mod: aerosol_init', 'PA0612', 1, 2, 0, 6, 0 )
1879    ENDIF
1880
1881!
1882!-- Initialize concentrations
1883    DO  i = nxlg, nxrg
1884       DO  j = nysg, nyng
1885          DO  k = nzb, nzt+1
1886!
1887!--          Predetermine flag to mask topography
1888             flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
1889!
1890!--          a) Number concentrations
1891!--          Region 1:
1892             DO  ib = start_subrange_1a, end_subrange_1a
1893                aerosol_number(ib)%conc(k,j,i) = pndist(k,ib) * flag
1894                IF ( prunmode == 1 )  THEN
1895                   aerosol_number(ib)%init = pndist(:,ib)
1896                ENDIF
1897             ENDDO
1898!
1899!--          Region 2:
1900             IF ( nreg > 1 )  THEN
1901                DO  ib = start_subrange_2a, end_subrange_2a
1902                   aerosol_number(ib)%conc(k,j,i) = MAX( 0.0_wp, pnf2a(k) ) * pndist(k,ib) * flag
1903                   IF ( prunmode == 1 )  THEN
1904                      aerosol_number(ib)%init = MAX( 0.0_wp, nf2a ) * pndist(:,ib)
1905                   ENDIF
1906                ENDDO
1907                IF ( .NOT. no_insoluble )  THEN
1908                   DO  ib = start_subrange_2b, end_subrange_2b
1909                      IF ( pnf2a(k) < 1.0_wp )  THEN
1910                         aerosol_number(ib)%conc(k,j,i) = MAX( 0.0_wp, 1.0_wp - pnf2a(k) ) *       &
1911                                                          pndist(k,ib) * flag
1912                         IF ( prunmode == 1 )  THEN
1913                            aerosol_number(ib)%init = MAX( 0.0_wp, 1.0_wp - nf2a ) * pndist(:,ib)
1914                         ENDIF
1915                      ENDIF
1916                   ENDDO
1917                ENDIF
1918             ENDIF
1919!
1920!--          b) Aerosol mass concentrations
1921!--             bin subrange 1: done here separately due to the SO4/OC convention
1922!
1923!--          SO4:
1924             IF ( index_so4 > 0 )  THEN
1925                ss = ( index_so4 - 1 ) * nbins_aerosol + start_subrange_1a !< start
1926                ee = ( index_so4 - 1 ) * nbins_aerosol + end_subrange_1a !< end
1927                ib = start_subrange_1a
1928                DO  ic = ss, ee
1929                   aerosol_mass(ic)%conc(k,j,i) = MAX( 0.0_wp, 1.0_wp - pmfoc1a(k) ) * pndist(k,ib)&
1930                                                  * core(ib) * arhoh2so4 * flag
1931                   IF ( prunmode == 1 )  THEN
1932                      aerosol_mass(ic)%init(k) = MAX( 0.0_wp, 1.0_wp - pmfoc1a(k) ) * pndist(k,ib) &
1933                                                 * core(ib) * arhoh2so4
1934                   ENDIF
1935                   ib = ib+1
1936                ENDDO
1937             ENDIF
1938!
1939!--          OC:
1940             IF ( index_oc > 0 ) THEN
1941                ss = ( index_oc - 1 ) * nbins_aerosol + start_subrange_1a !< start
1942                ee = ( index_oc - 1 ) * nbins_aerosol + end_subrange_1a !< end
1943                ib = start_subrange_1a
1944                DO  ic = ss, ee
1945                   aerosol_mass(ic)%conc(k,j,i) = MAX( 0.0_wp, pmfoc1a(k) ) * pndist(k,ib) *       &
1946                                                  core(ib) * arhooc * flag
1947                   IF ( prunmode == 1 )  THEN
1948                      aerosol_mass(ic)%init(k) = MAX( 0.0_wp, pmfoc1a(k) ) * pndist(k,ib) *        &
1949                                                 core(ib) * arhooc
1950                   ENDIF
1951                   ib = ib+1
1952                ENDDO
1953             ENDIF
1954          ENDDO !< k
1955
1956          prunmode = 3  ! Init only once
1957
1958       ENDDO !< j
1959    ENDDO !< i
1960
1961!
1962!-- c) Aerosol mass concentrations
1963!--    bin subrange 2:
1964    IF ( nreg > 1 ) THEN
1965
1966       IF ( index_so4 > 0 ) THEN
1967          CALL set_aero_mass( index_so4, pmf2a(:,1), pmf2b(:,1), pnf2a, pndist, core, arhoh2so4 )
1968       ENDIF
1969       IF ( index_oc > 0 ) THEN
1970          CALL set_aero_mass( index_oc, pmf2a(:,2), pmf2b(:,2), pnf2a, pndist, core, arhooc )
1971       ENDIF
1972       IF ( index_bc > 0 ) THEN
1973          CALL set_aero_mass( index_bc, pmf2a(:,3), pmf2b(:,3), pnf2a, pndist, core, arhobc )
1974       ENDIF
1975       IF ( index_du > 0 ) THEN
1976          CALL set_aero_mass( index_du, pmf2a(:,4), pmf2b(:,4), pnf2a, pndist, core, arhodu )
1977       ENDIF
1978       IF ( index_ss > 0 ) THEN
1979          CALL set_aero_mass( index_ss, pmf2a(:,5), pmf2b(:,5), pnf2a, pndist, core, arhoss )
1980       ENDIF
1981       IF ( index_no > 0 ) THEN
1982          CALL set_aero_mass( index_no, pmf2a(:,6), pmf2b(:,6), pnf2a, pndist, core, arhohno3 )
1983       ENDIF
1984       IF ( index_nh > 0 ) THEN
1985          CALL set_aero_mass( index_nh, pmf2a(:,7), pmf2b(:,7), pnf2a, pndist, core, arhonh3 )
1986       ENDIF
1987
1988    ENDIF
1989
1990 END SUBROUTINE aerosol_init
1991
1992!------------------------------------------------------------------------------!
1993! Description:
1994! ------------
1995!> Create a lognormal size distribution and discretise to a sectional
1996!> representation.
1997!------------------------------------------------------------------------------!
1998 SUBROUTINE size_distribution( in_ntot, in_dpg, in_sigma, psd_sect )
1999
2000    IMPLICIT NONE
2001
2002    INTEGER(iwp) ::  ib         !< running index: bin
2003    INTEGER(iwp) ::  iteration  !< running index: iteration
2004
2005    REAL(wp) ::  d1         !< particle diameter (m, dummy)
2006    REAL(wp) ::  d2         !< particle diameter (m, dummy)
2007    REAL(wp) ::  delta_d    !< (d2-d1)/10
2008    REAL(wp) ::  deltadp    !< bin width
2009    REAL(wp) ::  dmidi      !< ( d1 + d2 ) / 2
2010
2011    REAL(wp), DIMENSION(:), INTENT(in) ::  in_dpg    !< geometric mean diameter (m)
2012    REAL(wp), DIMENSION(:), INTENT(in) ::  in_ntot   !< number conc. (#/m3)
2013    REAL(wp), DIMENSION(:), INTENT(in) ::  in_sigma  !< standard deviation
2014
2015    REAL(wp), DIMENSION(:), INTENT(inout) ::  psd_sect  !< sectional size distribution
2016
2017    DO  ib = start_subrange_1a, end_subrange_2b
2018       psd_sect(ib) = 0.0_wp
2019!
2020!--    Particle diameter at the low limit (largest in the bin) (m)
2021       d1 = ( aero(ib)%vlolim / api6 )**0.33333333_wp
2022!
2023!--    Particle diameter at the high limit (smallest in the bin) (m)
2024       d2 = ( aero(ib)%vhilim / api6 )**0.33333333_wp
2025!
2026!--    Span of particle diameter in a bin (m)
2027       delta_d = 0.1_wp * ( d2 - d1 )
2028!
2029!--    Iterate:
2030       DO  iteration = 1, 10
2031          d1 = ( aero(ib)%vlolim / api6 )**0.33333333_wp + ( ib - 1) * delta_d
2032          d2 = d1 + delta_d
2033          dmidi = 0.5_wp * ( d1 + d2 )
2034          deltadp = LOG10( d2 / d1 )
2035!
2036!--       Size distribution
2037!--       in_ntot = total number, total area, or total volume concentration
2038!--       in_dpg = geometric-mean number, area, or volume diameter
2039!--       n(k) = number, area, or volume concentration in a bin
2040          psd_sect(ib) = psd_sect(ib) + SUM( in_ntot * deltadp / ( SQRT( 2.0_wp * pi ) *           &
2041                        LOG10( in_sigma ) ) * EXP( -LOG10( dmidi / in_dpg )**2.0_wp /              &
2042                        ( 2.0_wp * LOG10( in_sigma ) ** 2.0_wp ) ) )
2043
2044       ENDDO
2045    ENDDO
2046
2047 END SUBROUTINE size_distribution
2048
2049!------------------------------------------------------------------------------!
2050! Description:
2051! ------------
2052!> Sets the mass concentrations to aerosol arrays in 2a and 2b.
2053!>
2054!> Tomi Raatikainen, FMI, 29.2.2016
2055!------------------------------------------------------------------------------!
2056 SUBROUTINE set_aero_mass( ispec, pmf2a, pmf2b, pnf2a, pndist, pcore, prho )
2057
2058    IMPLICIT NONE
2059
2060    INTEGER(iwp) ::  ee        !< index: end
2061    INTEGER(iwp) ::  i         !< loop index
2062    INTEGER(iwp) ::  ib        !< loop index
2063    INTEGER(iwp) ::  ic        !< loop index
2064    INTEGER(iwp) ::  j         !< loop index
2065    INTEGER(iwp) ::  k         !< loop index
2066    INTEGER(iwp) ::  prunmode  !< 1 = initialise
2067    INTEGER(iwp) ::  ss        !< index: start
2068
2069    INTEGER(iwp), INTENT(in) :: ispec  !< Aerosol species index
2070
2071    REAL(wp) ::  flag   !< flag to mask topography grid points
2072
2073    REAL(wp), INTENT(in) ::  prho !< Aerosol density
2074
2075    REAL(wp), DIMENSION(nbins_aerosol), INTENT(in) ::  pcore !< Aerosol bin mid core volume
2076    REAL(wp), DIMENSION(0:nz+1), INTENT(in)        ::  pnf2a !< Number fraction for 2a
2077    REAL(wp), DIMENSION(0:nz+1), INTENT(in)        ::  pmf2a !< Mass distributions for a
2078    REAL(wp), DIMENSION(0:nz+1), INTENT(in)        ::  pmf2b !< and b bins
2079
2080    REAL(wp), DIMENSION(0:nz+1,nbins_aerosol), INTENT(in) ::  pndist !< Aerosol size distribution
2081
2082    prunmode = 1
2083
2084    DO i = nxlg, nxrg
2085       DO j = nysg, nyng
2086          DO k = nzb, nzt+1
2087!
2088!--          Predetermine flag to mask topography
2089             flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) ) 
2090!
2091!--          Regime 2a:
2092             ss = ( ispec - 1 ) * nbins_aerosol + start_subrange_2a
2093             ee = ( ispec - 1 ) * nbins_aerosol + end_subrange_2a
2094             ib = start_subrange_2a
2095             DO ic = ss, ee
2096                aerosol_mass(ic)%conc(k,j,i) = MAX( 0.0_wp, pmf2a(k) ) * pnf2a(k) * pndist(k,ib) * &
2097                                              pcore(ib) * prho * flag
2098                IF ( prunmode == 1 )  THEN
2099                   aerosol_mass(ic)%init(k) = MAX( 0.0_wp, pmf2a(k) ) * pnf2a(k) * pndist(k,ib) *  &
2100                                              pcore(ib) * prho
2101                ENDIF
2102                ib = ib + 1
2103             ENDDO
2104!
2105!--          Regime 2b:
2106             IF ( .NOT. no_insoluble )  THEN
2107                ss = ( ispec - 1 ) * nbins_aerosol + start_subrange_2b
2108                ee = ( ispec - 1 ) * nbins_aerosol + end_subrange_2b
2109                ib = start_subrange_2a
2110                DO ic = ss, ee
2111                   aerosol_mass(ic)%conc(k,j,i) = MAX( 0.0_wp, pmf2b(k) ) * ( 1.0_wp - pnf2a(k) ) *&
2112                                                  pndist(k,ib) * pcore(ib) * prho * flag
2113                   IF ( prunmode == 1 )  THEN
2114                      aerosol_mass(ic)%init(k) = MAX( 0.0_wp, pmf2b(k) ) * ( 1.0_wp - pnf2a(k) ) * &
2115                                                 pndist(k,ib) * pcore(ib) * prho
2116                   ENDIF
2117                   ib = ib + 1
2118                ENDDO  ! c
2119
2120             ENDIF
2121          ENDDO   ! k
2122
2123          prunmode = 3  ! Init only once
2124
2125       ENDDO   ! j
2126    ENDDO   ! i
2127
2128 END SUBROUTINE set_aero_mass
2129
2130!------------------------------------------------------------------------------!
2131! Description:
2132! ------------
2133!> Initialise the matching between surface types in LSM and deposition models.
2134!> Do the matching based on Zhang et al. (2001). Atmos. Environ. 35, 549-560
2135!> (here referred as Z01).
2136!------------------------------------------------------------------------------!
2137 SUBROUTINE init_deposition
2138
2139    USE surface_mod,                                                                               &
2140        ONLY:  surf_lsm_h, surf_lsm_v
2141
2142    IMPLICIT NONE
2143
2144    INTEGER(iwp) ::  l  !< loop index for vertical surfaces
2145
2146    IF ( nldepo_surf  .AND.  land_surface )  THEN
2147
2148       ALLOCATE( lsm_to_depo_h%match(1:surf_lsm_h%ns) )
2149       lsm_to_depo_h%match = 0
2150       CALL match_lsm_zhang( surf_lsm_h, lsm_to_depo_h%match )
2151
2152       DO  l = 0, 3
2153          ALLOCATE( lsm_to_depo_v(l)%match(1:surf_lsm_v(l)%ns) )
2154          lsm_to_depo_v(l)%match = 0
2155          CALL match_lsm_zhang( surf_lsm_v(l), lsm_to_depo_v(l)%match )
2156       ENDDO
2157    ENDIF
2158
2159    IF ( nldepo_pcm )  THEN
2160       SELECT CASE ( depo_pcm_type )
2161          CASE ( 'evergreen_needleleaf' )
2162             depo_pcm_type_num = 1
2163          CASE ( 'evergreen_broadleaf' )
2164             depo_pcm_type_num = 2
2165          CASE ( 'deciduous_needleleaf' )
2166             depo_pcm_type_num = 3
2167          CASE ( 'deciduous_broadleaf' )
2168             depo_pcm_type_num = 4
2169          CASE DEFAULT
2170             message_string = 'depo_pcm_type not set correctly.'
2171             CALL message( 'salsa_mod: init_deposition', 'PA0613', 1, 2, 0, 6, 0 )
2172       END SELECT
2173    ENDIF
2174
2175 END SUBROUTINE init_deposition
2176
2177!------------------------------------------------------------------------------!
2178! Description:
2179! ------------
2180!> Match the surface types in PALM and Zhang et al. 2001 deposition module
2181!------------------------------------------------------------------------------!
2182 SUBROUTINE match_lsm_zhang( surf, match_array )
2183
2184    USE surface_mod,                                                           &
2185        ONLY:  ind_pav_green, ind_veg_wall, ind_wat_win, surf_type
2186
2187    IMPLICIT NONE
2188
2189    INTEGER(iwp) ::  m                !< index for surface elements
2190    INTEGER(iwp) ::  pav_type_palm    !< pavement type in PALM
2191    INTEGER(iwp) ::  vege_type_palm   !< vegetation type in PALM
2192    INTEGER(iwp) ::  water_type_palm  !< water type in PALM
2193
2194    INTEGER(iwp), DIMENSION(:), INTENT(inout) ::  match_array !< array matching
2195                                                              !< the surface types
2196    TYPE(surf_type), INTENT(in) :: surf  !< respective surface type
2197
2198    DO  m = 1, surf%ns
2199
2200       IF ( surf%frac(ind_veg_wall,m) > 0 )  THEN
2201          vege_type_palm = surf%vegetation_type(m)
2202          SELECT CASE ( vege_type_palm )
2203             CASE ( 0 )
2204                message_string = 'No vegetation type defined.'
2205                CALL message( 'salsa_mod: init_depo_surfaces', 'PA0614', 1, 2, 0, 6, 0 )
2206             CASE ( 1 )  ! bare soil
2207                match_array(m) = 6  ! grass in Z01
2208             CASE ( 2 )  ! crops, mixed farming
2209                match_array(m) = 7  !  crops, mixed farming Z01
2210             CASE ( 3 )  ! short grass
2211                match_array(m) = 6  ! grass in Z01
2212             CASE ( 4 )  ! evergreen needleleaf trees
2213                 match_array(m) = 1  ! evergreen needleleaf trees in Z01
2214             CASE ( 5 )  ! deciduous needleleaf trees
2215                match_array(m) = 3  ! deciduous needleleaf trees in Z01
2216             CASE ( 6 )  ! evergreen broadleaf trees
2217                match_array(m) = 2  ! evergreen broadleaf trees in Z01
2218             CASE ( 7 )  ! deciduous broadleaf trees
2219                match_array(m) = 4  ! deciduous broadleaf trees in Z01
2220             CASE ( 8 )  ! tall grass
2221                match_array(m) = 6  ! grass in Z01
2222             CASE ( 9 )  ! desert
2223                match_array(m) = 8  ! desert in Z01
2224             CASE ( 10 )  ! tundra
2225                match_array(m) = 9  ! tundra in Z01
2226             CASE ( 11 )  ! irrigated crops
2227                match_array(m) = 7  !  crops, mixed farming Z01
2228             CASE ( 12 )  ! semidesert
2229                match_array(m) = 8  ! desert in Z01
2230             CASE ( 13 )  ! ice caps and glaciers
2231                match_array(m) = 12  ! ice cap and glacier in Z01
2232             CASE ( 14 )  ! bogs and marshes
2233                match_array(m) = 11  ! wetland with plants in Z01
2234             CASE ( 15 )  ! evergreen shrubs
2235                match_array(m) = 10  ! shrubs and interrupted woodlands in Z01
2236             CASE ( 16 )  ! deciduous shrubs
2237                match_array(m) = 10  ! shrubs and interrupted woodlands in Z01
2238             CASE ( 17 )  ! mixed forest/woodland
2239                match_array(m) = 5  ! mixed broadleaf and needleleaf trees in Z01
2240             CASE ( 18 )  ! interrupted forest
2241                match_array(m) = 10  ! shrubs and interrupted woodlands in Z01
2242          END SELECT
2243       ENDIF
2244
2245       IF ( surf%frac(ind_pav_green,m) > 0 )  THEN
2246          pav_type_palm = surf%pavement_type(m)
2247          IF ( pav_type_palm == 0 )  THEN  ! error
2248             message_string = 'No pavement type defined.'
2249             CALL message( 'salsa_mod: match_lsm_zhang', 'PA0615', 1, 2, 0, 6, 0 )
2250          ELSEIF ( pav_type_palm > 0  .AND.  pav_type_palm <= 15 )  THEN
2251             match_array(m) = 15  ! urban in Z01
2252          ENDIF
2253       ENDIF
2254
2255       IF ( surf%frac(ind_wat_win,m) > 0 )  THEN
2256          water_type_palm = surf%water_type(m)
2257          IF ( water_type_palm == 0 )  THEN  ! error
2258             message_string = 'No water type defined.'
2259             CALL message( 'salsa_mod: match_lsm_zhang', 'PA0616', 1, 2, 0, 6, 0 )
2260          ELSEIF ( water_type_palm == 3 )  THEN
2261             match_array(m) = 14  ! ocean in Z01
2262          ELSEIF ( water_type_palm == 1  .OR.  water_type_palm == 2 .OR.  water_type_palm == 4     &
2263                   .OR.  water_type_palm == 5  )  THEN
2264             match_array(m) = 13  ! inland water in Z01
2265          ENDIF
2266       ENDIF
2267
2268    ENDDO
2269
2270 END SUBROUTINE match_lsm_zhang
2271
2272!------------------------------------------------------------------------------!
2273! Description:
2274! ------------
2275!> Swapping of timelevels
2276!------------------------------------------------------------------------------!
2277 SUBROUTINE salsa_swap_timelevel( mod_count )
2278
2279    IMPLICIT NONE
2280
2281    INTEGER(iwp) ::  ib   !<
2282    INTEGER(iwp) ::  ic   !<
2283    INTEGER(iwp) ::  icc  !<
2284    INTEGER(iwp) ::  ig   !<
2285
2286    INTEGER(iwp), INTENT(IN) ::  mod_count  !<
2287
2288    IF ( time_since_reference_point >= skip_time_do_salsa )  THEN
2289
2290       SELECT CASE ( mod_count )
2291
2292          CASE ( 0 )
2293
2294             DO  ib = 1, nbins_aerosol
2295                aerosol_number(ib)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => nconc_1(:,:,:,ib)
2296                aerosol_number(ib)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => nconc_2(:,:,:,ib)
2297
2298                DO  ic = 1, ncomponents_mass
2299                   icc = ( ic-1 ) * nbins_aerosol + ib
2300                   aerosol_mass(icc)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => mconc_1(:,:,:,icc)
2301                   aerosol_mass(icc)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => mconc_2(:,:,:,icc)
2302                ENDDO
2303             ENDDO
2304
2305             IF ( .NOT. salsa_gases_from_chem )  THEN
2306                DO  ig = 1, ngases_salsa
2307                   salsa_gas(ig)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => gconc_1(:,:,:,ig)
2308                   salsa_gas(ig)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => gconc_2(:,:,:,ig)
2309                ENDDO
2310             ENDIF
2311
2312          CASE ( 1 )
2313
2314             DO  ib = 1, nbins_aerosol
2315                aerosol_number(ib)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => nconc_2(:,:,:,ib)
2316                aerosol_number(ib)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => nconc_1(:,:,:,ib)
2317                DO  ic = 1, ncomponents_mass
2318                   icc = ( ic-1 ) * nbins_aerosol + ib
2319                   aerosol_mass(icc)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => mconc_2(:,:,:,icc)
2320                   aerosol_mass(icc)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => mconc_1(:,:,:,icc)
2321                ENDDO
2322             ENDDO
2323
2324             IF ( .NOT. salsa_gases_from_chem )  THEN
2325                DO  ig = 1, ngases_salsa
2326                   salsa_gas(ig)%conc(nzb:nzt+1,nysg:nyng,nxlg:nxrg)   => gconc_2(:,:,:,ig)
2327                   salsa_gas(ig)%conc_p(nzb:nzt+1,nysg:nyng,nxlg:nxrg) => gconc_1(:,:,:,ig)
2328                ENDDO
2329             ENDIF
2330
2331       END SELECT
2332
2333    ENDIF
2334
2335 END SUBROUTINE salsa_swap_timelevel
2336
2337
2338!------------------------------------------------------------------------------!
2339! Description:
2340! ------------
2341!> This routine reads the respective restart data.
2342!------------------------------------------------------------------------------!
2343 SUBROUTINE salsa_rrd_local( k, nxlf, nxlc, nxl_on_file, nxrf, nxrc, nxr_on_file, nynf, nync,      &
2344                             nyn_on_file, nysf, nysc, nys_on_file, tmp_3d, found )
2345
2346    IMPLICIT NONE
2347
2348    INTEGER(iwp) ::  ib              !<
2349    INTEGER(iwp) ::  ic              !<
2350    INTEGER(iwp) ::  ig              !<
2351    INTEGER(iwp) ::  k               !<
2352    INTEGER(iwp) ::  nxlc            !<
2353    INTEGER(iwp) ::  nxlf            !<
2354    INTEGER(iwp) ::  nxl_on_file     !<
2355    INTEGER(iwp) ::  nxrc            !<
2356    INTEGER(iwp) ::  nxrf            !<
2357    INTEGER(iwp) ::  nxr_on_file     !<
2358    INTEGER(iwp) ::  nync            !<
2359    INTEGER(iwp) ::  nynf            !<
2360    INTEGER(iwp) ::  nyn_on_file     !<
2361    INTEGER(iwp) ::  nysc            !<
2362    INTEGER(iwp) ::  nysf            !<
2363    INTEGER(iwp) ::  nys_on_file     !<
2364
2365    LOGICAL, INTENT(OUT)  ::  found  !<
2366
2367    REAL(wp), &
2368       DIMENSION(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp,nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d   !<
2369
2370    found = .FALSE.
2371
2372    IF ( read_restart_data_salsa )  THEN
2373
2374       SELECT CASE ( restart_string(1:length) )
2375
2376          CASE ( 'aerosol_number' )
2377             DO  ib = 1, nbins_aerosol
2378                IF ( k == 1 )  READ ( 13 ) tmp_3d
2379                aerosol_number(ib)%conc(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =               &
2380                                                   tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
2381                found = .TRUE.
2382             ENDDO
2383
2384          CASE ( 'aerosol_mass' )
2385             DO  ic = 1, ncomponents_mass * nbins_aerosol
2386                IF ( k == 1 )  READ ( 13 ) tmp_3d
2387                aerosol_mass(ic)%conc(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =                 &
2388                                                   tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
2389                found = .TRUE.
2390             ENDDO
2391
2392          CASE ( 'salsa_gas' )
2393             DO  ig = 1, ngases_salsa
2394                IF ( k == 1 )  READ ( 13 ) tmp_3d
2395                salsa_gas(ig)%conc(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =                    &
2396                                                   tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
2397                found = .TRUE.
2398             ENDDO
2399
2400          CASE DEFAULT
2401             found = .FALSE.
2402
2403       END SELECT
2404    ENDIF
2405
2406 END SUBROUTINE salsa_rrd_local
2407
2408!------------------------------------------------------------------------------!
2409! Description:
2410! ------------
2411!> This routine writes the respective restart data.
2412!> Note that the following input variables in PARIN have to be equal between
2413!> restart runs:
2414!>    listspec, nbin, nbin2, nf2a, ncc, mass_fracs_a, mass_fracs_b
2415!------------------------------------------------------------------------------!
2416 SUBROUTINE salsa_wrd_local
2417
2418    IMPLICIT NONE
2419
2420    INTEGER(iwp) ::  ib   !<
2421    INTEGER(iwp) ::  ic   !<
2422    INTEGER(iwp) ::  ig  !<
2423
2424    IF ( write_binary  .AND.  write_binary_salsa )  THEN
2425
2426       CALL wrd_write_string( 'aerosol_number' )
2427       DO  ib = 1, nbins_aerosol
2428          WRITE ( 14 )  aerosol_number(ib)%conc
2429       ENDDO
2430
2431       CALL wrd_write_string( 'aerosol_mass' )
2432       DO  ic = 1, nbins_aerosol * ncomponents_mass
2433          WRITE ( 14 )  aerosol_mass(ic)%conc
2434       ENDDO
2435
2436       CALL wrd_write_string( 'salsa_gas' )
2437       DO  ig = 1, ngases_salsa
2438          WRITE ( 14 )  salsa_gas(ig)%conc
2439       ENDDO
2440
2441    ENDIF
2442
2443 END SUBROUTINE salsa_wrd_local
2444
2445!------------------------------------------------------------------------------!
2446! Description:
2447! ------------
2448!> Performs necessary unit and dimension conversion between the host model and
2449!> SALSA module, and calls the main SALSA routine.
2450!> Partially adobted form the original SALSA boxmodel version.
2451!> Now takes masses in as kg/kg from LES!! Converted to m3/m3 for SALSA
2452!> 05/2016 Juha: This routine is still pretty much in its original shape.
2453!>               It's dumb as a mule and twice as ugly, so implementation of
2454!>               an improved solution is necessary sooner or later.
2455!> Juha Tonttila, FMI, 2014
2456!> Jaakko Ahola, FMI, 2016
2457!> Only aerosol processes included, Mona Kurppa, UHel, 2017
2458!------------------------------------------------------------------------------!
2459 SUBROUTINE salsa_driver( i, j, prunmode )
2460
2461    USE arrays_3d,                                                                                 &
2462        ONLY: pt_p, q_p, u, v, w
2463
2464    USE plant_canopy_model_mod,                                                                    &
2465        ONLY: lad_s
2466
2467    USE surface_mod,                                                                               &
2468        ONLY:  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, surf_usm_v
2469
2470    IMPLICIT NONE
2471
2472    INTEGER(iwp) ::  endi    !< end index
2473    INTEGER(iwp) ::  ib      !< loop index
2474    INTEGER(iwp) ::  ic      !< loop index
2475    INTEGER(iwp) ::  ig      !< loop index
2476    INTEGER(iwp) ::  k_wall  !< vertical index of topography top
2477    INTEGER(iwp) ::  k       !< loop index
2478    INTEGER(iwp) ::  l       !< loop index
2479    INTEGER(iwp) ::  nc_h2o  !< index of H2O in the prtcl index table
2480    INTEGER(iwp) ::  ss      !< loop index
2481    INTEGER(iwp) ::  str     !< start index
2482    INTEGER(iwp) ::  vc      !< default index in prtcl
2483
2484    INTEGER(iwp), INTENT(in) ::  i         !< loop index
2485    INTEGER(iwp), INTENT(in) ::  j         !< loop index
2486    INTEGER(iwp), INTENT(in) ::  prunmode  !< 1: Initialization, 2: Spinup, 3: Regular runtime
2487
2488    REAL(wp) ::  cw_old  !< previous H2O mixing ratio
2489    REAL(wp) ::  flag    !< flag to mask topography grid points
2490    REAL(wp) ::  in_lad  !< leaf area density (m2/m3)
2491    REAL(wp) ::  in_rh   !< relative humidity
2492    REAL(wp) ::  zgso4   !< SO4
2493    REAL(wp) ::  zghno3  !< HNO3
2494    REAL(wp) ::  zgnh3   !< NH3
2495    REAL(wp) ::  zgocnv  !< non-volatile OC
2496    REAL(wp) ::  zgocsv  !< semi-volatile OC
2497
2498    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_adn  !< air density (kg/m3)
2499    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_cs   !< H2O sat. vapour conc.
2500    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_cw   !< H2O vapour concentration
2501    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_p    !< pressure (Pa)
2502    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_t    !< temperature (K)
2503    REAL(wp), DIMENSION(nzb:nzt+1) ::  in_u    !< wind magnitude (m/s)
2504    REAL(wp), DIMENSION(nzb:nzt+1) ::  kvis    !< kinematic viscosity of air(m2/s)
2505    REAL(wp), DIMENSION(nzb:nzt+1) ::  ppm_to_nconc  !< Conversion factor from ppm to #/m3
2506
2507    REAL(wp), DIMENSION(nzb:nzt+1,nbins_aerosol) ::  schmidt_num  !< particle Schmidt number
2508    REAL(wp), DIMENSION(nzb:nzt+1,nbins_aerosol) ::  vd           !< particle fall seed (m/s)
2509
2510    TYPE(t_section), DIMENSION(nbins_aerosol) ::  aero_old !< helper array
2511
2512    aero_old(:)%numc = 0.0_wp
2513    in_lad           = 0.0_wp
2514    in_u             = 0.0_wp
2515    kvis             = 0.0_wp
2516    schmidt_num      = 0.0_wp
2517    vd               = 0.0_wp
2518    zgso4            = nclim
2519    zghno3           = nclim
2520    zgnh3            = nclim
2521    zgocnv           = nclim
2522    zgocsv           = nclim
2523!
2524!-- Aerosol number is always set, but mass can be uninitialized
2525    DO ib = 1, nbins_aerosol
2526       aero(ib)%volc(:)     = 0.0_wp
2527       aero_old(ib)%volc(:) = 0.0_wp
2528    ENDDO
2529!
2530!-- Set the salsa runtime config (How to make this more efficient?)
2531    CALL set_salsa_runtime( prunmode )
2532!
2533!-- Calculate thermodynamic quantities needed in SALSA
2534    CALL salsa_thrm_ij( i, j, p_ij=in_p, temp_ij=in_t, cw_ij=in_cw, cs_ij=in_cs, adn_ij=in_adn )
2535!
2536!-- Magnitude of wind: needed for deposition
2537    IF ( lsdepo )  THEN
2538       in_u(nzb+1:nzt) = SQRT( ( 0.5_wp * ( u(nzb+1:nzt,j,i) + u(nzb+1:nzt,j,i+1) ) )**2 +         &
2539                               ( 0.5_wp * ( v(nzb+1:nzt,j,i) + v(nzb+1:nzt,j+1,i) ) )**2 +         &
2540                               ( 0.5_wp * ( w(nzb:nzt-1,j,i) + w(nzb+1:nzt,j,  i) ) )**2 )
2541    ENDIF
2542!
2543!-- Calculate conversion factors for gas concentrations
2544    ppm_to_nconc(:) = for_ppm_to_nconc * in_p(:) / in_t(:)
2545!
2546!-- Determine topography-top index on scalar grid
2547    k_wall = k_topo_top(j,i)
2548
2549    DO k = nzb+1, nzt
2550!
2551!--    Predetermine flag to mask topography
2552       flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
2553!
2554!--    Wind velocity for dry depositon on vegetation
2555       IF ( lsdepo_pcm  .AND.  plant_canopy )  THEN
2556          in_lad = lad_s( MAX( k-k_wall,0 ),j,i)
2557       ENDIF
2558!
2559!--    For initialization and spinup, limit the RH with the parameter rhlim
2560       IF ( prunmode < 3 ) THEN
2561          in_cw(k) = MIN( in_cw(k), in_cs(k) * rhlim )
2562       ELSE
2563          in_cw(k) = in_cw(k)
2564       ENDIF
2565       cw_old = in_cw(k) !* in_adn(k)
2566!
2567!--    Set volume concentrations:
2568!--    Sulphate (SO4) or sulphuric acid H2SO4
2569       IF ( index_so4 > 0 )  THEN
2570          vc = 1
2571          str = ( index_so4-1 ) * nbins_aerosol + 1    ! start index
2572          endi = index_so4 * nbins_aerosol             ! end index
2573          ic = 1
2574          DO ss = str, endi
2575             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhoh2so4
2576             ic = ic+1
2577          ENDDO
2578          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2579       ENDIF
2580!
2581!--    Organic carbon (OC) compounds
2582       IF ( index_oc > 0 )  THEN
2583          vc = 2
2584          str = ( index_oc-1 ) * nbins_aerosol + 1
2585          endi = index_oc * nbins_aerosol
2586          ic = 1
2587          DO ss = str, endi
2588             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhooc
2589             ic = ic+1
2590          ENDDO
2591          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2592       ENDIF
2593!
2594!--    Black carbon (BC)
2595       IF ( index_bc > 0 )  THEN
2596          vc = 3
2597          str = ( index_bc-1 ) * nbins_aerosol + 1 + end_subrange_1a
2598          endi = index_bc * nbins_aerosol
2599          ic = 1 + end_subrange_1a
2600          DO ss = str, endi
2601             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhobc
2602             ic = ic+1
2603          ENDDO
2604          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2605       ENDIF
2606!
2607!--    Dust (DU)
2608       IF ( index_du > 0 )  THEN
2609          vc = 4
2610          str = ( index_du-1 ) * nbins_aerosol + 1 + end_subrange_1a
2611          endi = index_du * nbins_aerosol
2612          ic = 1 + end_subrange_1a
2613          DO ss = str, endi
2614             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhodu
2615             ic = ic+1
2616          ENDDO
2617          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2618       ENDIF
2619!
2620!--    Sea salt (SS)
2621       IF ( index_ss > 0 )  THEN
2622          vc = 5
2623          str = ( index_ss-1 ) * nbins_aerosol + 1 + end_subrange_1a
2624          endi = index_ss * nbins_aerosol
2625          ic = 1 + end_subrange_1a
2626          DO ss = str, endi
2627             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhoss
2628             ic = ic+1
2629          ENDDO
2630          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2631       ENDIF
2632!
2633!--    Nitrate (NO(3-)) or nitric acid HNO3
2634       IF ( index_no > 0 )  THEN
2635          vc = 6
2636          str = ( index_no-1 ) * nbins_aerosol + 1 
2637          endi = index_no * nbins_aerosol
2638          ic = 1
2639          DO ss = str, endi
2640             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhohno3
2641             ic = ic+1
2642          ENDDO
2643          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2644       ENDIF
2645!
2646!--    Ammonium (NH(4+)) or ammonia NH3
2647       IF ( index_nh > 0 )  THEN
2648          vc = 7
2649          str = ( index_nh-1 ) * nbins_aerosol + 1
2650          endi = index_nh * nbins_aerosol
2651          ic = 1
2652          DO ss = str, endi
2653             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhonh3
2654             ic = ic+1
2655          ENDDO
2656          aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2657       ENDIF
2658!
2659!--    Water (always used)
2660       nc_h2o = get_index( prtcl,'H2O' )
2661       vc = 8
2662       str = ( nc_h2o-1 ) * nbins_aerosol + 1
2663       endi = nc_h2o * nbins_aerosol
2664       ic = 1
2665       IF ( advect_particle_water )  THEN
2666          DO ss = str, endi
2667             aero(ic)%volc(vc) = aerosol_mass(ss)%conc(k,j,i) / arhoh2o
2668             ic = ic+1
2669          ENDDO
2670       ELSE
2671         aero(1:nbins_aerosol)%volc(vc) = mclim
2672       ENDIF
2673       aero_old(1:nbins_aerosol)%volc(vc) = aero(1:nbins_aerosol)%volc(vc)
2674!
2675!--    Number concentrations (numc) and particle sizes
2676!--    (dwet = wet diameter, core = dry volume)
2677       DO  ib = 1, nbins_aerosol
2678          aero(ib)%numc = aerosol_number(ib)%conc(k,j,i)
2679          aero_old(ib)%numc = aero(ib)%numc
2680          IF ( aero(ib)%numc > nclim )  THEN
2681             aero(ib)%dwet = ( SUM( aero(ib)%volc(:) ) / aero(ib)%numc / api6 )**0.33333333_wp
2682             aero(ib)%core = SUM( aero(ib)%volc(1:7) ) / aero(ib)%numc
2683          ELSE
2684             aero(ib)%dwet = aero(ib)%dmid
2685             aero(ib)%core = api6 * ( aero(ib)%dwet )**3
2686          ENDIF
2687       ENDDO
2688!
2689!--    On EACH call of salsa_driver, calculate the ambient sizes of
2690!--    particles by equilibrating soluble fraction of particles with water
2691!--    using the ZSR method.
2692       in_rh = in_cw(k) / in_cs(k)
2693       IF ( prunmode==1  .OR.  .NOT. advect_particle_water )  THEN
2694          CALL equilibration( in_rh, in_t(k), aero, .TRUE. )
2695       ENDIF
2696!
2697!--    Gaseous tracer concentrations in #/m3
2698       IF ( salsa_gases_from_chem )  THEN
2699!
2700!--       Convert concentrations in ppm to #/m3
2701          zgso4  = chem_species(gas_index_chem(1))%conc(k,j,i) * ppm_to_nconc(k)
2702          zghno3 = chem_species(gas_index_chem(2))%conc(k,j,i) * ppm_to_nconc(k)
2703          zgnh3  = chem_species(gas_index_chem(3))%conc(k,j,i) * ppm_to_nconc(k)
2704          zgocnv = chem_species(gas_index_chem(4))%conc(k,j,i) * ppm_to_nconc(k)
2705          zgocsv = chem_species(gas_index_chem(5))%conc(k,j,i) * ppm_to_nconc(k)
2706       ELSE
2707          zgso4  = salsa_gas(1)%conc(k,j,i)
2708          zghno3 = salsa_gas(2)%conc(k,j,i)
2709          zgnh3  = salsa_gas(3)%conc(k,j,i)
2710          zgocnv = salsa_gas(4)%conc(k,j,i)
2711          zgocsv = salsa_gas(5)%conc(k,j,i)
2712       ENDIF
2713!
2714!--    Calculate aerosol processes:
2715!--    *********************************************************************************************
2716!
2717!--    Coagulation
2718       IF ( lscoag )   THEN
2719          CALL coagulation( aero, dt_salsa, in_t(k), in_p(k) )
2720       ENDIF
2721!
2722!--    Condensation
2723       IF ( lscnd )   THEN
2724          CALL condensation( aero, zgso4, zgocnv, zgocsv,  zghno3, zgnh3, in_cw(k), in_cs(k),      &
2725                             in_t(k), in_p(k), dt_salsa, prtcl )
2726       ENDIF
2727!
2728!--    Deposition
2729       IF ( lsdepo )  THEN
2730          CALL deposition( aero, in_t(k), in_adn(k), in_u(k), in_lad, kvis(k), schmidt_num(k,:),   &
2731                           vd(k,:) )
2732       ENDIF
2733!
2734!--    Size distribution bin update
2735       IF ( lsdistupdate )   THEN
2736          CALL distr_update( aero )
2737       ENDIF
2738!--    *********************************************************************************************
2739
2740       IF ( lsdepo ) sedim_vd(k,j,i,:) = vd(k,:)
2741!
2742!--    Calculate changes in concentrations
2743       DO ib = 1, nbins_aerosol
2744          aerosol_number(ib)%conc(k,j,i) = aerosol_number(ib)%conc(k,j,i) + ( aero(ib)%numc -      &
2745                                           aero_old(ib)%numc ) * flag
2746       ENDDO
2747
2748       IF ( index_so4 > 0 )  THEN
2749          vc = 1
2750          str = ( index_so4-1 ) * nbins_aerosol + 1
2751          endi = index_so4 * nbins_aerosol
2752          ic = 1
2753          DO ss = str, endi
2754             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2755                                            aero_old(ic)%volc(vc) ) * arhoh2so4 * flag
2756             ic = ic+1
2757          ENDDO
2758       ENDIF
2759
2760       IF ( index_oc > 0 )  THEN
2761          vc = 2
2762          str = ( index_oc-1 ) * nbins_aerosol + 1
2763          endi = index_oc * nbins_aerosol
2764          ic = 1
2765          DO ss = str, endi
2766             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2767                                            aero_old(ic)%volc(vc) ) * arhooc * flag
2768             ic = ic+1
2769          ENDDO
2770       ENDIF
2771
2772       IF ( index_bc > 0 )  THEN
2773          vc = 3
2774          str = ( index_bc-1 ) * nbins_aerosol + 1 + end_subrange_1a
2775          endi = index_bc * nbins_aerosol
2776          ic = 1 + end_subrange_1a
2777          DO ss = str, endi
2778             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2779                                            aero_old(ic)%volc(vc) ) * arhobc * flag
2780             ic = ic+1
2781          ENDDO
2782       ENDIF
2783
2784       IF ( index_du > 0 )  THEN
2785          vc = 4
2786          str = ( index_du-1 ) * nbins_aerosol + 1 + end_subrange_1a
2787          endi = index_du * nbins_aerosol
2788          ic = 1 + end_subrange_1a
2789          DO ss = str, endi
2790             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2791                                            aero_old(ic)%volc(vc) ) * arhodu * flag
2792             ic = ic+1
2793          ENDDO
2794       ENDIF
2795
2796       IF ( index_ss > 0 )  THEN
2797          vc = 5
2798          str = ( index_ss-1 ) * nbins_aerosol + 1 + end_subrange_1a
2799          endi = index_ss * nbins_aerosol
2800          ic = 1 + end_subrange_1a
2801          DO ss = str, endi
2802             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2803                                            aero_old(ic)%volc(vc) ) * arhoss * flag
2804             ic = ic+1
2805          ENDDO
2806       ENDIF
2807
2808       IF ( index_no > 0 )  THEN
2809          vc = 6
2810          str = ( index_no-1 ) * nbins_aerosol + 1
2811          endi = index_no * nbins_aerosol
2812          ic = 1
2813          DO ss = str, endi
2814             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2815                                            aero_old(ic)%volc(vc) ) * arhohno3 * flag
2816             ic = ic+1
2817          ENDDO
2818       ENDIF
2819
2820       IF ( index_nh > 0 )  THEN
2821          vc = 7
2822          str = ( index_nh-1 ) * nbins_aerosol + 1
2823          endi = index_nh * nbins_aerosol
2824          ic = 1
2825          DO ss = str, endi
2826             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2827                                            aero_old(ic)%volc(vc) ) * arhonh3 * flag
2828             ic = ic+1
2829          ENDDO
2830       ENDIF
2831
2832       IF ( advect_particle_water )  THEN
2833          nc_h2o = get_index( prtcl,'H2O' )
2834          vc = 8
2835          str = ( nc_h2o-1 ) * nbins_aerosol + 1
2836          endi = nc_h2o * nbins_aerosol
2837          ic = 1
2838          DO ss = str, endi
2839             aerosol_mass(ss)%conc(k,j,i) = aerosol_mass(ss)%conc(k,j,i) + ( aero(ic)%volc(vc) -   &
2840                                            aero_old(ic)%volc(vc) ) * arhoh2o * flag
2841             IF ( prunmode == 1 )  THEN
2842                aerosol_mass(ss)%init(k) = MAX( aerosol_mass(ss)%init(k),                          &
2843                                                aerosol_mass(ss)%conc(k,j,i) )
2844                IF ( k == nzb+1 )  THEN
2845                   aerosol_mass(ss)%init(k-1) = 0.0_wp
2846                ELSEIF ( k == nzt  )  THEN
2847                   aerosol_mass(ss)%init(k+1) = aerosol_mass(ss)%init(k)
2848                ENDIF
2849             ENDIF
2850             ic = ic+1
2851          ENDDO
2852       ENDIF
2853!
2854!--    Condensation of precursor gases
2855       IF ( lscndgas )  THEN
2856          IF ( salsa_gases_from_chem )  THEN
2857!
2858!--          SO4 (or H2SO4)
2859             ig = gas_index_chem(1)
2860             chem_species(ig)%conc(k,j,i) = chem_species(ig)%conc(k,j,i) + ( zgso4 /               &
2861                                            ppm_to_nconc(k) - chem_species(ig)%conc(k,j,i) ) * flag
2862!
2863!--          HNO3
2864             ig = gas_index_chem(2)
2865             chem_species(ig)%conc(k,j,i) = chem_species(ig)%conc(k,j,i) + ( zghno3 /              &
2866                                            ppm_to_nconc(k) - chem_species(ig)%conc(k,j,i) ) * flag
2867!
2868!--          NH3
2869             ig = gas_index_chem(3)
2870             chem_species(ig)%conc(k,j,i) = chem_species(ig)%conc(k,j,i) + ( zgnh3 /               &
2871                                            ppm_to_nconc(k) - chem_species(ig)%conc(k,j,i) ) * flag
2872!
2873!--          non-volatile OC
2874             ig = gas_index_chem(4)
2875             chem_species(ig)%conc(k,j,i) = chem_species(ig)%conc(k,j,i) + ( zgocnv /              &
2876                                            ppm_to_nconc(k) - chem_species(ig)%conc(k,j,i) ) * flag
2877!
2878!--          semi-volatile OC
2879             ig = gas_index_chem(5)
2880             chem_species(ig)%conc(k,j,i) = chem_species(ig)%conc(k,j,i) + ( zgocsv /              &
2881                                            ppm_to_nconc(k) - chem_species(ig)%conc(k,j,i) ) * flag
2882
2883          ELSE
2884!
2885!--          SO4 (or H2SO4)
2886             salsa_gas(1)%conc(k,j,i) = salsa_gas(1)%conc(k,j,i) + ( zgso4 -                       &
2887                                        salsa_gas(1)%conc(k,j,i) ) * flag
2888!
2889!--          HNO3
2890             salsa_gas(2)%conc(k,j,i) = salsa_gas(2)%conc(k,j,i) + ( zghno3 -                      &
2891                                        salsa_gas(2)%conc(k,j,i) ) * flag
2892!
2893!--          NH3
2894             salsa_gas(3)%conc(k,j,i) = salsa_gas(3)%conc(k,j,i) + ( zgnh3 -                       &
2895                                        salsa_gas(3)%conc(k,j,i) ) * flag
2896!
2897!--          non-volatile OC
2898             salsa_gas(4)%conc(k,j,i) = salsa_gas(4)%conc(k,j,i) + ( zgocnv -                      &
2899                                        salsa_gas(4)%conc(k,j,i) ) * flag
2900!
2901!--          semi-volatile OC
2902             salsa_gas(5)%conc(k,j,i) = salsa_gas(5)%conc(k,j,i) + ( zgocsv -                      &
2903                                        salsa_gas(5)%conc(k,j,i) ) * flag
2904          ENDIF
2905       ENDIF
2906!
2907!--    Tendency of water vapour mixing ratio is obtained from the
2908!--    change in RH during SALSA run. This releases heat and changes pt.
2909!--    Assumes no temperature change during SALSA run.
2910!--    q = r / (1+r), Euler method for integration
2911!
2912       IF ( feedback_to_palm )  THEN
2913          q_p(k,j,i) = q_p(k,j,i) + 1.0_wp / ( in_cw(k) * in_adn(k) + 1.0_wp )**2 *                &
2914                       ( in_cw(k) - cw_old ) * in_adn(k) * flag
2915          pt_p(k,j,i) = pt_p(k,j,i) + alv / c_p * ( in_cw(k) - cw_old ) * in_adn(k) / ( in_cw(k) / &
2916                        in_adn(k) + 1.0_wp )**2 * pt_p(k,j,i) / in_t(k) * flag
2917       ENDIF
2918
2919    ENDDO   ! k
2920!
2921!-- Set surfaces and wall fluxes due to deposition
2922    IF ( lsdepo  .AND.  lsdepo_surf  .AND.  prunmode == 3 )  THEN
2923       IF ( .NOT. land_surface  .AND.  .NOT. urban_surface )  THEN
2924          CALL depo_surf( i, j, surf_def_h(0), vd, schmidt_num, kvis, in_u, .TRUE. )
2925          DO  l = 0, 3
2926             CALL depo_surf( i, j, surf_def_v(l), vd, schmidt_num, kvis, in_u, .FALSE., l )
2927          ENDDO
2928       ELSE
2929          CALL depo_surf( i, j, surf_usm_h, vd, schmidt_num, kvis, in_u, .TRUE. )
2930          DO  l = 0, 3
2931             CALL depo_surf( i, j, surf_usm_v(l), vd, schmidt_num, kvis, in_u, .FALSE., l )
2932          ENDDO
2933          CALL depo_surf( i, j, surf_lsm_h, vd, schmidt_num, kvis, in_u, .TRUE. )
2934          DO  l = 0, 3
2935             CALL depo_surf( i, j, surf_lsm_v(l), vd, schmidt_num, kvis, in_u, .FALSE., l )
2936          ENDDO
2937       ENDIF
2938    ENDIF
2939
2940 END SUBROUTINE salsa_driver
2941
2942!------------------------------------------------------------------------------!
2943! Description:
2944! ------------
2945!> Set logical switches according to the host model state and user-specified
2946!> NAMELIST options.
2947!> Juha Tonttila, FMI, 2014
2948!> Only aerosol processes included, Mona Kurppa, UHel, 2017
2949!------------------------------------------------------------------------------!
2950 SUBROUTINE set_salsa_runtime( prunmode )
2951
2952    IMPLICIT NONE
2953
2954    INTEGER(iwp), INTENT(in) ::  prunmode
2955
2956    SELECT CASE(prunmode)
2957
2958       CASE(1) !< Initialization
2959          lscoag       = .FALSE.
2960          lscnd        = .FALSE.
2961          lscndgas     = .FALSE.
2962          lscndh2oae   = .FALSE.
2963          lsdepo       = .FALSE.
2964          lsdepo_pcm   = .FALSE.
2965          lsdepo_surf  = .FALSE.
2966          lsdistupdate = .TRUE.
2967          lspartition  = .FALSE.
2968
2969       CASE(2)  !< Spinup period
2970          lscoag      = ( .FALSE. .AND. nlcoag   )
2971          lscnd       = ( .TRUE.  .AND. nlcnd    )
2972          lscndgas    = ( .TRUE.  .AND. nlcndgas )
2973          lscndh2oae  = ( .TRUE.  .AND. nlcndh2oae )
2974
2975       CASE(3)  !< Run
2976          lscoag       = nlcoag
2977          lscnd        = nlcnd
2978          lscndgas     = nlcndgas
2979          lscndh2oae   = nlcndh2oae
2980          lsdepo       = nldepo
2981          lsdepo_pcm   = nldepo_pcm
2982          lsdepo_surf  = nldepo_surf
2983          lsdistupdate = nldistupdate
2984    END SELECT
2985
2986
2987 END SUBROUTINE set_salsa_runtime
2988 
2989!------------------------------------------------------------------------------!
2990! Description:
2991! ------------
2992!> Calculates the absolute temperature (using hydrostatic pressure), saturation
2993!> vapour pressure and mixing ratio over water, relative humidity and air
2994!> density needed in the SALSA model.
2995!> NOTE, no saturation adjustment takes place -> the resulting water vapour
2996!> mixing ratio can be supersaturated, allowing the microphysical calculations
2997!> in SALSA.
2998!
2999!> Juha Tonttila, FMI, 2014 (original SALSAthrm)
3000!> Mona Kurppa, UHel, 2017 (adjustment for PALM and only aerosol processes)
3001!------------------------------------------------------------------------------!
3002 SUBROUTINE salsa_thrm_ij( i, j, p_ij, temp_ij, cw_ij, cs_ij, adn_ij )
3003
3004    USE arrays_3d,                                                                                 &
3005        ONLY: pt, q, zu
3006
3007    USE basic_constants_and_equations_mod,                                                         &
3008        ONLY:  barometric_formula, exner_function, ideal_gas_law_rho, magnus
3009
3010    USE control_parameters,                                                                        &
3011        ONLY: pt_surface, surface_pressure
3012
3013    IMPLICIT NONE
3014
3015    INTEGER(iwp), INTENT(in) ::  i  !<
3016    INTEGER(iwp), INTENT(in) ::  j  !<
3017
3018    REAL(wp) ::  t_surface  !< absolute surface temperature (K)
3019
3020    REAL(wp), DIMENSION(nzb:nzt+1) ::  e_s  !< saturation vapour pressure over water (Pa)
3021
3022    REAL(wp), DIMENSION(:), INTENT(inout) ::  adn_ij   !< air density (kg/m3)
3023    REAL(wp), DIMENSION(:), INTENT(inout) ::  p_ij     !< air pressure (Pa)
3024    REAL(wp), DIMENSION(:), INTENT(inout) ::  temp_ij  !< air temperature (K)
3025
3026    REAL(wp), DIMENSION(:), INTENT(inout), OPTIONAL ::  cw_ij  !< water vapour concentration (kg/m3)
3027    REAL(wp), DIMENSION(:), INTENT(inout), OPTIONAL ::  cs_ij  !< saturation water vap. conc.(kg/m3)
3028!
3029!-- Pressure p_ijk (Pa) = hydrostatic pressure
3030    t_surface = pt_surface * exner_function( surface_pressure * 100.0_wp )
3031    p_ij(:) = barometric_formula( zu, t_surface, surface_pressure * 100.0_wp )
3032!
3033!-- Absolute ambient temperature (K)
3034    temp_ij(:) = pt(:,j,i) * exner_function( p_ij(:) )
3035!
3036!-- Air density
3037    adn_ij(:) = ideal_gas_law_rho( p_ij(:), temp_ij(:) )
3038!
3039!-- Water vapour concentration r_v (kg/m3)
3040    IF ( PRESENT( cw_ij ) )  THEN
3041       cw_ij(:) = ( q(:,j,i) / ( 1.0_wp - q(:,j,i) ) ) * adn_ij(:)
3042    ENDIF
3043!
3044!-- Saturation mixing ratio r_s (kg/kg) from vapour pressure at temp (Pa)
3045    IF ( PRESENT( cs_ij ) )  THEN
3046       e_s(:) = 611.0_wp * EXP( alv_d_rv * ( 3.6609E-3_wp - 1.0_wp /           &
3047                temp_ij(:) ) )! magnus( temp_ij(:) )
3048       cs_ij(:) = ( 0.622_wp * e_s / ( p_ij(:) - e_s(:) ) ) * adn_ij(:)
3049    ENDIF
3050
3051 END SUBROUTINE salsa_thrm_ij
3052
3053!------------------------------------------------------------------------------!
3054! Description:
3055! ------------
3056!> Calculates ambient sizes of particles by equilibrating soluble fraction of
3057!> particles with water using the ZSR method (Stokes and Robinson, 1966).
3058!> Method:
3059!> Following chemical components are assumed water-soluble
3060!> - (ammonium) sulphate (100%)
3061!> - sea salt (100 %)
3062!> - organic carbon (epsoc * 100%)
3063!> Exact thermodynamic considerations neglected.
3064!> - If particles contain no sea salt, calculation according to sulphate
3065!>   properties
3066!> - If contain sea salt but no sulphate, calculation according to sea salt
3067!>   properties
3068!> - If contain both sulphate and sea salt -> the molar fraction of these
3069!>   compounds determines which one of them is used as the basis of calculation.
3070!> If sulphate and sea salt coexist in a particle, it is assumed that the Cl is
3071!> replaced by sulphate; thus only either sulphate + organics or sea salt +
3072!> organics is included in the calculation of soluble fraction.
3073!> Molality parameterizations taken from Table 1 of Tang: Thermodynamic and
3074!> optical properties of mixed-salt aerosols of atmospheric importance,
3075!> J. Geophys. Res., 102 (D2), 1883-1893 (1997)
3076!
3077!> Coded by:
3078!> Hannele Korhonen (FMI) 2005
3079!> Harri Kokkola (FMI) 2006
3080!> Matti Niskanen(FMI) 2012
3081!> Anton Laakso  (FMI) 2013
3082!> Modified for the new aerosol datatype, Juha Tonttila (FMI) 2014
3083!
3084!> fxm: should sea salt form a solid particle when prh is very low (even though
3085!> it could be mixed with e.g. sulphate)?
3086!> fxm: crashes if no sulphate or sea salt
3087!> fxm: do we really need to consider Kelvin effect for subrange 2
3088!------------------------------------------------------------------------------!
3089 SUBROUTINE equilibration( prh, ptemp, paero, init )
3090
3091    IMPLICIT NONE
3092
3093    INTEGER(iwp) :: ib      !< loop index
3094    INTEGER(iwp) :: counti  !< loop index
3095
3096    LOGICAL, INTENT(in) ::  init   !< TRUE: Initialization, FALSE: Normal runtime: update water
3097                                   !< content only for 1a
3098
3099    REAL(wp) ::  zaw      !< water activity [0-1]
3100    REAL(wp) ::  zcore    !< Volume of dry particle
3101    REAL(wp) ::  zdold    !< Old diameter
3102    REAL(wp) ::  zdwet    !< Wet diameter or mean droplet diameter
3103    REAL(wp) ::  zke      !< Kelvin term in the Köhler equation
3104    REAL(wp) ::  zlwc     !< liquid water content [kg/m3-air]
3105    REAL(wp) ::  zrh      !< Relative humidity
3106
3107    REAL(wp), DIMENSION(maxspec) ::  zbinmol  !< binary molality of each components (mol/kg)
3108    REAL(wp), DIMENSION(maxspec) ::  zvpart   !< volume of chem. compounds in one particle
3109
3110    REAL(wp), INTENT(in) ::  prh    !< relative humidity [0-1]
3111    REAL(wp), INTENT(in) ::  ptemp  !< temperature (K)
3112
3113    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< aerosol properties
3114
3115    zaw       = 0.0_wp
3116    zlwc      = 0.0_wp
3117!
3118!-- Relative humidity:
3119    zrh = prh
3120    zrh = MAX( zrh, 0.05_wp )
3121    zrh = MIN( zrh, 0.98_wp)
3122!
3123!-- 1) Regime 1: sulphate and partly water-soluble OC. Done for every CALL
3124    DO  ib = start_subrange_1a, end_subrange_1a   ! size bin
3125
3126       zbinmol = 0.0_wp
3127       zdold   = 1.0_wp
3128       zke     = 1.02_wp
3129
3130       IF ( paero(ib)%numc > nclim )  THEN
3131!
3132!--       Volume in one particle
3133          zvpart = 0.0_wp
3134          zvpart(1:2) = paero(ib)%volc(1:2) / paero(ib)%numc
3135          zvpart(6:7) = paero(ib)%volc(6:7) / paero(ib)%numc
3136!
3137!--       Total volume and wet diameter of one dry particle
3138          zcore = SUM( zvpart(1:2) )
3139          zdwet = paero(ib)%dwet
3140
3141          counti = 0
3142          DO  WHILE ( ABS( zdwet / zdold - 1.0_wp ) > 1.0E-2_wp )
3143
3144             zdold = MAX( zdwet, 1.0E-20_wp )
3145             zaw = MAX( 1.0E-3_wp, zrh / zke ) ! To avoid underflow
3146!
3147!--          Binary molalities (mol/kg):
3148!--          Sulphate
3149             zbinmol(1) = 1.1065495E+2_wp - 3.6759197E+2_wp * zaw + 5.0462934E+2_wp * zaw**2 -     &
3150                          3.1543839E+2_wp * zaw**3 + 6.770824E+1_wp  * zaw**4
3151!--          Organic carbon
3152             zbinmol(2) = 1.0_wp / ( zaw * amh2o ) - 1.0_wp / amh2o
3153!--          Nitric acid
3154             zbinmol(6) = 2.306844303E+1_wp - 3.563608869E+1_wp * zaw - 6.210577919E+1_wp * zaw**2 &
3155                          + 5.510176187E+2_wp * zaw**3 - 1.460055286E+3_wp * zaw**4                &
3156                          + 1.894467542E+3_wp * zaw**5 - 1.220611402E+3_wp * zaw**6                &
3157                          + 3.098597737E+2_wp * zaw**7
3158!
3159!--          Calculate the liquid water content (kg/m3-air) using ZSR (see e.g. Eq. 10.98 in
3160!--          Seinfeld and Pandis (2006))
3161             zlwc = ( paero(ib)%volc(1) * ( arhoh2so4 / amh2so4 ) ) / zbinmol(1) +                 &
3162                    epsoc * paero(ib)%volc(2) * ( arhooc / amoc ) / zbinmol(2) +                   &
3163                    ( paero(ib)%volc(6) * ( arhohno3/amhno3 ) ) / zbinmol(6)
3164!
3165!--          Particle wet diameter (m)
3166             zdwet = ( zlwc / paero(ib)%numc / arhoh2o / api6 + ( SUM( zvpart(6:7) ) / api6 ) +    &
3167                       zcore / api6 )**0.33333333_wp
3168!
3169!--          Kelvin effect (Eq. 10.85 in in Seinfeld and Pandis (2006)). Avoid
3170!--          overflow.
3171             zke = EXP( MIN( 50.0_wp, 4.0_wp * surfw0 * amvh2so4 / ( abo * ptemp *  zdwet ) ) )
3172
3173             counti = counti + 1
3174             IF ( counti > 1000 )  THEN
3175                message_string = 'Subrange 1: no convergence!'
3176                CALL message( 'salsa_mod: equilibration', 'PA0617', 1, 2, 0, 6, 0 )
3177             ENDIF
3178          ENDDO
3179!
3180!--       Instead of lwc, use the volume concentration of water from now on
3181!--       (easy to convert...)
3182          paero(ib)%volc(8) = zlwc / arhoh2o
3183!
3184!--       If this is initialization, update the core and wet diameter
3185          IF ( init )  THEN
3186             paero(ib)%dwet = zdwet
3187             paero(ib)%core = zcore
3188          ENDIF
3189
3190       ELSE
3191!--       If initialization
3192!--       1.2) empty bins given bin average values
3193          IF ( init )  THEN
3194             paero(ib)%dwet = paero(ib)%dmid
3195             paero(ib)%core = api6 * paero(ib)%dmid**3
3196          ENDIF
3197
3198       ENDIF
3199
3200    ENDDO  ! ib
3201!
3202!-- 2) Regime 2a: sulphate, OC, BC and sea salt
3203!--    This is done only for initialization call, otherwise the water contents
3204!--    are computed via condensation
3205    IF ( init )  THEN
3206       DO  ib = start_subrange_2a, end_subrange_2b
3207!
3208!--       Initialize
3209          zke     = 1.02_wp
3210          zbinmol = 0.0_wp
3211          zdold   = 1.0_wp
3212!
3213!--       1) Particle properties calculated for non-empty bins
3214          IF ( paero(ib)%numc > nclim )  THEN
3215!
3216!--          Volume in one particle [fxm]
3217             zvpart = 0.0_wp
3218             zvpart(1:7) = paero(ib)%volc(1:7) / paero(ib)%numc
3219!
3220!--          Total volume and wet diameter of one dry particle [fxm]
3221             zcore = SUM( zvpart(1:5) )
3222             zdwet = paero(ib)%dwet
3223
3224             counti = 0
3225             DO  WHILE ( ABS( zdwet / zdold - 1.0_wp ) > 1.0E-12_wp )
3226
3227                zdold = MAX( zdwet, 1.0E-20_wp )
3228                zaw = zrh / zke
3229!
3230!--             Binary molalities (mol/kg):
3231!--             Sulphate
3232                zbinmol(1) = 1.1065495E+2_wp - 3.6759197E+2_wp * zaw + 5.0462934E+2_wp * zaw**2 -  &
3233                             3.1543839E+2_wp * zaw**3 + 6.770824E+1_wp  * zaw**4
3234!--             Organic carbon
3235                zbinmol(2) = 1.0_wp / ( zaw * amh2o ) - 1.0_wp / amh2o
3236!--             Nitric acid
3237                zbinmol(6) = 2.306844303E+1_wp          - 3.563608869E+1_wp * zaw -                &
3238                             6.210577919E+1_wp * zaw**2 + 5.510176187E+2_wp * zaw**3 -             &
3239                             1.460055286E+3_wp * zaw**4 + 1.894467542E+3_wp * zaw**5 -             &
3240                             1.220611402E+3_wp * zaw**6 + 3.098597737E+2_wp * zaw**7 
3241!--             Sea salt (natrium chloride)
3242                zbinmol(5) = 5.875248E+1_wp - 1.8781997E+2_wp * zaw + 2.7211377E+2_wp * zaw**2 -   &
3243                             1.8458287E+2_wp * zaw**3 + 4.153689E+1_wp  * zaw**4
3244!
3245!--             Calculate the liquid water content (kg/m3-air)
3246                zlwc = ( paero(ib)%volc(1) * ( arhoh2so4 / amh2so4 ) ) / zbinmol(1) +              &
3247                       epsoc * ( paero(ib)%volc(2) * ( arhooc / amoc ) ) / zbinmol(2) +            &
3248                       ( paero(ib)%volc(6) * ( arhohno3 / amhno3 ) ) / zbinmol(6) +                &
3249                       ( paero(ib)%volc(5) * ( arhoss / amss ) ) / zbinmol(5)
3250
3251!--             Particle wet radius (m)
3252                zdwet = ( zlwc / paero(ib)%numc / arhoh2o / api6 + ( SUM( zvpart(6:7) ) / api6 )  + &
3253                           zcore / api6 )**0.33333333_wp
3254!
3255!--             Kelvin effect (Eq. 10.85 in Seinfeld and Pandis (2006))
3256                zke = EXP( MIN( 50.0_wp, 4.0_wp * surfw0 * amvh2so4 / ( abo * zdwet * ptemp ) ) )
3257
3258                counti = counti + 1
3259                IF ( counti > 1000 )  THEN
3260                   message_string = 'Subrange 2: no convergence!'
3261                CALL message( 'salsa_mod: equilibration', 'PA0618', 1, 2, 0, 6, 0 )
3262                ENDIF
3263             ENDDO
3264!
3265!--          Liquid water content; instead of LWC use the volume concentration
3266             paero(ib)%volc(8) = zlwc / arhoh2o
3267             paero(ib)%dwet    = zdwet
3268             paero(ib)%core    = zcore
3269
3270          ELSE
3271!--          2.2) empty bins given bin average values
3272             paero(ib)%dwet = paero(ib)%dmid
3273             paero(ib)%core = api6 * paero(ib)%dmid**3
3274          ENDIF
3275
3276       ENDDO   ! ib
3277    ENDIF
3278
3279 END SUBROUTINE equilibration
3280
3281!------------------------------------------------------------------------------!
3282!> Description:
3283!> ------------
3284!> Calculation of the settling velocity vc (m/s) per aerosol size bin and
3285!> deposition on plant canopy (lsdepo_pcm).
3286!
3287!> Deposition is based on either the scheme presented in:
3288!> Zhang et al. (2001), Atmos. Environ. 35, 549-560 (includes collection due to
3289!> Brownian diffusion, impaction, interception and sedimentation; hereafter ZO1)
3290!> OR
3291!> Petroff & Zhang (2010), Geosci. Model Dev. 3, 753-769 (includes also
3292!> collection due to turbulent impaction, hereafter P10)
3293!
3294!> Equation numbers refer to equation in Jacobson (2005): Fundamentals of
3295!> Atmospheric Modeling, 2nd Edition.
3296!
3297!> Subroutine follows closely sedim_SALSA in UCLALES-SALSA written by Juha
3298!> Tonttila (KIT/FMI) and Zubair Maalick (UEF).
3299!> Rewritten to PALM by Mona Kurppa (UH), 2017.
3300!
3301!> Call for grid point i,j,k
3302!------------------------------------------------------------------------------!
3303
3304 SUBROUTINE deposition( paero, tk, adn, mag_u, lad, kvis, schmidt_num, vc )
3305
3306    USE plant_canopy_model_mod,                                                &
3307        ONLY: cdc
3308
3309    IMPLICIT NONE
3310
3311    INTEGER(iwp) ::  ib     !< loop index
3312
3313    REAL(wp) ::  avis       !< molecular viscocity of air (kg/(m*s))
3314    REAL(wp) ::  Cc         !< Cunningham slip-flow correction factor
3315    REAL(wp) ::  Kn         !< Knudsen number
3316    REAL(wp) ::  lambda     !< molecular mean free path (m)
3317    REAL(wp) ::  mdiff      !< particle diffusivity coefficient
3318    REAL(wp) ::  pdn        !< particle density (kg/m3)
3319    REAL(wp) ::  ustar      !< friction velocity (m/s)
3320    REAL(wp) ::  va         !< thermal speed of an air molecule (m/s)
3321    REAL(wp) ::  zdwet      !< wet diameter (m)
3322
3323    REAL(wp), INTENT(in) ::  adn    !< air density (kg/m3)
3324    REAL(wp), INTENT(in) ::  lad    !< leaf area density (m2/m3)
3325    REAL(wp), INTENT(in) ::  mag_u  !< wind velocity (m/s)
3326    REAL(wp), INTENT(in) ::  tk     !< abs.temperature (K)
3327
3328    REAL(wp), INTENT(inout) ::  kvis   !< kinematic viscosity of air (m2/s)
3329
3330    REAL(wp), DIMENSION(:), INTENT(inout) ::  schmidt_num  !< particle Schmidt number
3331    REAL(wp), DIMENSION(:), INTENT(inout) ::  vc  !< critical fall speed i.e. settling velocity of
3332                                                  !< an aerosol particle (m/s)
3333
3334    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< aerosol properties
3335!
3336!-- Initialise
3337    pdn           = 1500.0_wp    ! default value
3338    ustar         = 0.0_wp
3339!
3340!-- Molecular viscosity of air (Eq. 4.54)
3341    avis = 1.8325E-5_wp * ( 416.16_wp / ( tk + 120.0_wp ) ) * ( tk / 296.16_wp )**1.5_wp
3342!
3343!-- Kinematic viscosity (Eq. 4.55)
3344    kvis =  avis / adn
3345!
3346!-- Thermal velocity of an air molecule (Eq. 15.32)
3347    va = SQRT( 8.0_wp * abo * tk / ( pi * am_airmol ) )
3348!
3349!-- Mean free path (m) (Eq. 15.24)
3350    lambda = 2.0_wp * avis / ( adn * va )
3351
3352    DO  ib = 1, nbins_aerosol
3353
3354       IF ( paero(ib)%numc < nclim )  CYCLE
3355       zdwet = paero(ib)%dwet
3356!
3357!--    Knudsen number (Eq. 15.23)
3358       Kn = MAX( 1.0E-2_wp, lambda / ( zdwet * 0.5_wp ) ) ! To avoid underflow
3359!
3360!--    Cunningham slip-flow correction (Eq. 15.30)
3361       Cc = 1.0_wp + Kn * ( 1.249_wp + 0.42_wp * EXP( -0.87_wp / Kn ) )
3362
3363!--    Particle diffusivity coefficient (Eq. 15.29)
3364       mdiff = ( abo * tk * Cc ) / ( 3.0_wp * pi * avis * zdwet )
3365!
3366!--    Particle Schmidt number (Eq. 15.36)
3367       schmidt_num(ib) = kvis / mdiff
3368!
3369!--    Critical fall speed i.e. settling velocity  (Eq. 20.4)
3370       vc(ib) = MIN( 1.0_wp, terminal_vel( 0.5_wp * zdwet, pdn, adn, avis, Cc) )
3371!
3372!--    Friction velocity for deposition on vegetation. Calculated following Prandtl (1925):
3373       IF ( lsdepo_pcm  .AND.  plant_canopy  .AND.  lad > 0.0_wp )  THEN
3374          ustar = SQRT( cdc ) * mag_u
3375          CALL depo_pcm( paero, ib, vc(ib), mag_u, ustar, kvis, schmidt_num(ib), lad )
3376       ENDIF
3377    ENDDO
3378
3379 END SUBROUTINE deposition
3380
3381!------------------------------------------------------------------------------!
3382! Description:
3383! ------------
3384!> Calculate change in number and volume concentrations due to deposition on
3385!> plant canopy.
3386!------------------------------------------------------------------------------!
3387 SUBROUTINE depo_pcm( paero, ib, vc, mag_u, ustar, kvis_a, schmidt_num, lad )
3388
3389    IMPLICIT NONE
3390
3391    INTEGER(iwp) ::  ic      !< loop index
3392
3393    INTEGER(iwp), INTENT(in) ::  ib  !< loop index
3394
3395    REAL(wp) ::  alpha             !< parameter, Table 3 in Z01
3396    REAL(wp) ::  beta_im           !< parameter for turbulent impaction
3397    REAL(wp) ::  depo              !< deposition efficiency
3398    REAL(wp) ::  c_brownian_diff   !< coefficient for Brownian diffusion
3399    REAL(wp) ::  c_impaction       !< coefficient for inertial impaction
3400    REAL(wp) ::  c_interception    !< coefficient for interception
3401    REAL(wp) ::  c_turb_impaction  !< coefficient for turbulent impaction
3402    REAL(wp) ::  gamma             !< parameter, Table 3 in Z01
3403    REAL(wp) ::  par_a             !< parameter A for the characteristic radius of collectors,
3404                                   !< Table 3 in Z01
3405    REAL(wp) ::  par_l             !< obstacle characteristic dimension in P10
3406    REAL(wp) ::  rs                !< overall quasi-laminar resistance for particles
3407    REAL(wp) ::  stokes_num        !< Stokes number for smooth or bluff surfaces
3408    REAL(wp) ::  tau_plus          !< dimensionless particle relaxation time
3409    REAL(wp) ::  v_bd              !< deposition velocity due to Brownian diffusion
3410    REAL(wp) ::  v_im              !< deposition velocity due to impaction
3411    REAL(wp) ::  v_in              !< deposition velocity due to interception
3412    REAL(wp) ::  v_it              !< deposition velocity due to turbulent impaction
3413
3414    REAL(wp), INTENT(in) ::  kvis_a       !< kinematic viscosity of air (m2/s)
3415    REAL(wp), INTENT(in) ::  lad          !< leaf area density (m2/m3)
3416    REAL(wp), INTENT(in) ::  mag_u        !< wind velocity (m/s)
3417    REAL(wp), INTENT(in) ::  schmidt_num  !< particle Schmidt number
3418    REAL(wp), INTENT(in) ::  ustar        !< friction velocity (m/s)
3419    REAL(wp), INTENT(in) ::  vc           !< terminal velocity (m/s)
3420
3421    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< aerosol properties
3422!
3423!-- Initialise
3424    rs       = 0.0_wp
3425    tau_plus = 0.0_wp
3426    v_bd     = 0.0_wp
3427    v_im     = 0.0_wp
3428    v_in     = 0.0_wp
3429    v_it     = 0.0_wp
3430
3431    IF ( depo_pcm_par == 'zhang2001' )  THEN
3432!
3433!--    Parameters for the land use category 'deciduous broadleaf trees'(Table 3)
3434       alpha   = alpha_z01(depo_pcm_type_num)
3435       gamma   = gamma_z01(depo_pcm_type_num)
3436       par_a   = A_z01(depo_pcm_type_num, season) * 1.0E-3_wp
3437!
3438!--    Stokes number for vegetated surfaces (Seinfeld & Pandis (2006): Eq.19.24)
3439       stokes_num = vc * ustar / ( g * par_a )
3440!
3441!--    The overall quasi-laminar resistance for particles (Zhang et al., Eq. 5)
3442       rs = MAX( EPSILON( 1.0_wp ), ( 3.0_wp * ustar * EXP( -stokes_num**0.5_wp ) *                &
3443                 ( schmidt_num**( -gamma ) + ( stokes_num / ( alpha + stokes_num ) )**2 +          &
3444                 0.5_wp * ( paero(ib)%dwet / par_a )**2 ) ) )
3445
3446       depo = ( rs + vc ) * lad
3447
3448    ELSEIF ( depo_pcm_par == 'petroff2010' )  THEN
3449!
3450!--    vd = v_BD + v_IN + v_IM + v_IT + vc
3451!--    Deposition efficiencies from Table 1. Constants from Table 2.
3452       par_l   = l_p10(depo_pcm_type_num) * 0.01_wp
3453       c_brownian_diff     = c_b_p10(depo_pcm_type_num)
3454       c_interception    = c_in_p10(depo_pcm_type_num)
3455       c_impaction    = c_im_p10(depo_pcm_type_num)
3456       beta_im = beta_im_p10(depo_pcm_type_num)
3457       c_turb_impaction    = c_it_p10(depo_pcm_type_num)
3458!
3459!--    Stokes number for vegetated surfaces (Seinfeld & Pandis (2006): Eq.19.24)
3460       stokes_num = vc * ustar / ( g * par_l )
3461!
3462!--    Non-dimensional relexation time of the particle on top of canopy
3463       tau_plus = vc * ustar**2 / ( kvis_a * g )
3464!
3465!--    Brownian diffusion
3466       v_bd = mag_u * c_brownian_diff * schmidt_num**( -0.66666666_wp ) *                          &
3467              ( mag_u * par_l / kvis_a )**( -0.5_wp )
3468!
3469!--    Interception
3470       v_in = mag_u * c_interception * paero(ib)%dwet / par_l * ( 2.0_wp + LOG( 2.0_wp * par_l /    &
3471              paero(ib)%dwet ) )
3472!
3473!--    Impaction: Petroff (2009) Eq. 18
3474       v_im = mag_u * c_impaction * ( stokes_num / ( stokes_num + beta_im ) )**2
3475!
3476!--    Turbulent impaction
3477       IF ( tau_plus < 20.0_wp )  THEN
3478          v_it = 2.5E-3_wp * c_turb_impaction * tau_plus**2
3479       ELSE
3480          v_it = c_turb_impaction
3481       ENDIF
3482
3483       depo = ( v_bd + v_in + v_im + v_it + vc ) * lad
3484
3485    ENDIF
3486!
3487!-- Calculate the change in concentrations
3488    paero(ib)%numc = paero(ib)%numc - depo * paero(ib)%numc * dt_salsa
3489    DO  ic = 1, maxspec+1
3490       paero(ib)%volc(ic) = paero(ib)%volc(ic) - depo * paero(ib)%volc(ic) * dt_salsa
3491    ENDDO
3492
3493 END SUBROUTINE depo_pcm
3494
3495!------------------------------------------------------------------------------!
3496! Description:
3497! ------------
3498!> Calculate the dry deposition on horizontal and vertical surfaces. Implement
3499!> as a surface flux.
3500!> @todo aerodynamic resistance ignored for now (not important for
3501!        high-resolution simulations)
3502!------------------------------------------------------------------------------!
3503 SUBROUTINE depo_surf( i, j, surf, vc, schmidt_num, kvis, mag_u, norm, l )
3504
3505    USE arrays_3d,                                                             &
3506        ONLY: rho_air_zw
3507
3508    USE surface_mod,                                                           &
3509        ONLY:  surf_type
3510
3511    IMPLICIT NONE
3512
3513    INTEGER(iwp) ::  ib      !< loop index
3514    INTEGER(iwp) ::  ic      !< loop index
3515    INTEGER(iwp) ::  icc     !< additional loop index
3516    INTEGER(iwp) ::  k       !< loop index
3517    INTEGER(iwp) ::  m       !< loop index
3518    INTEGER(iwp) ::  surf_e  !< End index of surface elements at (j,i)-gridpoint
3519    INTEGER(iwp) ::  surf_s  !< Start index of surface elements at (j,i)-gridpoint
3520
3521    INTEGER(iwp), INTENT(in) ::  i     !< loop index
3522    INTEGER(iwp), INTENT(in) ::  j     !< loop index
3523
3524    INTEGER(iwp), INTENT(in), OPTIONAL ::  l  !< index variable for surface facing
3525
3526    LOGICAL, INTENT(in) ::  norm      !< to normalise or not
3527
3528    REAL(wp) ::  alpha             !< parameter, Table 3 in Z01
3529    REAL(wp) ::  beta_im           !< parameter for turbulent impaction
3530    REAL(wp) ::  c_brownian_diff   !< coefficient for Brownian diffusion
3531    REAL(wp) ::  c_impaction       !< coefficient for inertial impaction
3532    REAL(wp) ::  c_interception    !< coefficient for interception
3533    REAL(wp) ::  c_turb_impaction  !< coefficient for turbulent impaction
3534    REAL(wp) ::  depo              !< deposition efficiency
3535    REAL(wp) ::  gamma             !< parameter, Table 3 in Z01
3536    REAL(wp) ::  norm_fac          !< normalisation factor (usually air density)
3537    REAL(wp) ::  par_a             !< parameter A for the characteristic radius of collectors,
3538                                   !< Table 3 in Z01
3539    REAL(wp) ::  par_l             !< obstacle characteristic dimension in P10
3540    REAL(wp) ::  rs                !< the overall quasi-laminar resistance for particles
3541    REAL(wp) ::  stokes_num        !< Stokes number for bluff surface elements
3542    REAL(wp) ::  tau_plus          !< dimensionless particle relaxation time
3543    REAL(wp) ::  v_bd              !< deposition velocity due to Brownian diffusion
3544    REAL(wp) ::  v_im              !< deposition velocity due to impaction
3545    REAL(wp) ::  v_in              !< deposition velocity due to interception
3546    REAL(wp) ::  v_it              !< deposition velocity due to turbulent impaction
3547
3548    REAL(wp), DIMENSION(:), INTENT(in) ::  kvis   !< kinematic viscosity of air (m2/s)
3549    REAL(wp), DIMENSION(:), INTENT(in) ::  mag_u  !< wind velocity (m/s)
3550
3551    REAL(wp), DIMENSION(:,:), INTENT(in) ::  schmidt_num   !< particle Schmidt number
3552    REAL(wp), DIMENSION(:,:), INTENT(in) ::  vc            !< terminal velocity (m/s)
3553
3554    TYPE(surf_type), INTENT(inout) :: surf  !< respective surface type
3555!
3556!-- Initialise
3557    rs       = 0.0_wp
3558    surf_s   = surf%start_index(j,i)
3559    surf_e   = surf%end_index(j,i)
3560    tau_plus = 0.0_wp
3561    v_bd     = 0.0_wp
3562    v_im     = 0.0_wp
3563    v_in     = 0.0_wp
3564    v_it     = 0.0_wp
3565!
3566!-- Model parameters for the land use category. If LSM is applied, import
3567!-- characteristics. Otherwise, apply surface type "urban".
3568    alpha   = alpha_z01(luc_urban)
3569    gamma   = gamma_z01(luc_urban)
3570    par_a   = A_z01(luc_urban, season) * 1.0E-3_wp
3571
3572    par_l            = l_p10(luc_urban) * 0.01_wp
3573    c_brownian_diff  = c_b_p10(luc_urban)
3574    c_interception   = c_in_p10(luc_urban)
3575    c_impaction      = c_im_p10(luc_urban)
3576    beta_im          = beta_im_p10(luc_urban)
3577    c_turb_impaction = c_it_p10(luc_urban)
3578
3579    DO  m = surf_s, surf_e
3580       k = surf%k(m)
3581
3582       IF ( norm )  THEN
3583          norm_fac = rho_air_zw(k)
3584          IF ( land_surface )  THEN
3585             alpha            = alpha_z01( lsm_to_depo_h%match(m) )
3586             beta_im          = beta_im_p10( lsm_to_depo_h%match(m) )
3587             c_brownian_diff  = c_b_p10( lsm_to_depo_h%match(m) )
3588             c_impaction      = c_im_p10( lsm_to_depo_h%match(m) )
3589             c_interception   = c_in_p10( lsm_to_depo_h%match(m) )
3590             c_turb_impaction = c_it_p10( lsm_to_depo_h%match(m) )
3591             gamma            = gamma_z01( lsm_to_depo_h%match(m) )
3592             par_a            = A_z01( lsm_to_depo_h%match(m), season ) * 1.0E-3_wp
3593             par_l            = l_p10( lsm_to_depo_h%match(m) ) * 0.01_wp
3594          ENDIF
3595       ELSE
3596          norm_fac = 0.0_wp
3597          IF ( land_surface )  THEN
3598             alpha            = alpha_z01( lsm_to_depo_v(l)%match(m) )
3599             beta_im          = beta_im_p10( lsm_to_depo_v(l)%match(m) )
3600             c_brownian_diff  = c_b_p10( lsm_to_depo_v(l)%match(m) )
3601             c_impaction      = c_im_p10( lsm_to_depo_v(l)%match(m) )
3602             c_interception   = c_in_p10( lsm_to_depo_v(l)%match(m) )
3603             c_turb_impaction = c_it_p10( lsm_to_depo_v(l)%match(m) )
3604             gamma            = gamma_z01( lsm_to_depo_v(l)%match(m) )
3605             par_a            = A_z01( lsm_to_depo_v(l)%match(m), season ) * 1.0E-3_wp
3606             par_l            = l_p10( lsm_to_depo_v(l)%match(m) ) * 0.01_wp
3607          ENDIF
3608       ENDIF
3609
3610       DO  ib = 1, nbins_aerosol
3611          IF ( aerosol_number(ib)%conc(k,j,i) <= nclim  .OR.  schmidt_num(k+1,ib) < 1.0_wp )  CYCLE
3612
3613          IF ( depo_surf_par == 'zhang2001' )  THEN
3614!
3615!--          Stokes number for smooth surfaces or surfaces with bluff roughness
3616!--          elements (Seinfeld and Pandis, 2nd edition (2006): Eq. 19.23)
3617             stokes_num = MAX( 0.01_wp, vc(k+1,ib) * surf%us(m)**2 / ( g * kvis(k+1)  ) )
3618!
3619!--          The overall quasi-laminar resistance for particles (Eq. 5)
3620             rs = MAX( EPSILON( 1.0_wp ), ( 3.0_wp * surf%us(m) * ( schmidt_num(k+1,ib)**( -gamma )&
3621                       + ( stokes_num / ( alpha + stokes_num ) )**2 + 0.5_wp * ( ra_dry(k,j,i,ib) /&
3622                       par_a )**2 ) * EXP( -stokes_num**0.5_wp ) ) )
3623             depo = vc(k+1,ib) + rs
3624
3625          ELSEIF ( depo_surf_par == 'petroff2010' )  THEN 
3626!
3627!--          vd = v_BD + v_IN + v_IM + v_IT + vc
3628!
3629!--          Stokes number for smooth surfaces or surfaces with bluff roughness
3630!--          elements (Seinfeld and Pandis, 2nd edition (2006): Eq. 19.23)
3631             stokes_num = MAX( 0.01_wp, vc(k+1,ib) * surf%us(m)**2 / ( g *  kvis(k+1) ) )
3632!
3633!--          Non-dimensional relexation time of the particle on top of canopy
3634             tau_plus = vc(k+1,ib) * surf%us(m)**2 / ( kvis(k+1) * g )
3635!
3636!--          Brownian diffusion
3637             v_bd = mag_u(k+1) * c_brownian_diff * schmidt_num(k+1,ib)**( -0.666666_wp ) *         &
3638                    ( mag_u(k+1) * par_l / kvis(k+1) )**( -0.5_wp )
3639!
3640!--          Interception
3641             v_in = mag_u(k+1) * c_interception * ra_dry(k,j,i,ib)/ par_l *                        &
3642                    ( 2.0_wp + LOG( 2.0_wp * par_l / ra_dry(k,j,i,ib) ) )
3643!
3644!--          Impaction: Petroff (2009) Eq. 18
3645             v_im = mag_u(k+1) * c_impaction * ( stokes_num / ( stokes_num + beta_im ) )**2
3646
3647             IF ( tau_plus < 20.0_wp )  THEN
3648                v_it = 2.5E-3_wp * c_turb_impaction * tau_plus**2
3649             ELSE
3650                v_it = c_turb_impaction
3651             ENDIF
3652             depo =  v_bd + v_in + v_im + v_it + vc(k+1,ib)
3653
3654          ENDIF
3655!
3656!--       Calculate changes in surface fluxes due to dry deposition
3657          IF ( aero_emission_att%lod == 2  .OR.  salsa_emission_mode ==  'no_emission' )  THEN
3658             surf%answs(m,ib) = -depo * norm_fac * aerosol_number(ib)%conc(k,j,i)
3659             DO  ic = 1, ncomponents_mass
3660                icc = ( ic - 1 ) * nbins_aerosol + ib
3661                surf%amsws(m,icc) = -depo *  norm_fac * aerosol_mass(icc)%conc(k,j,i)
3662             ENDDO    ! ic
3663          ELSE
3664             surf%answs(m,ib) = aerosol_number(ib)%source(j,i) -                                   &
3665                                MAX( 0.0_wp, depo * norm_fac * aerosol_number(ib)%conc(k,j,i) )
3666             DO  ic = 1, ncomponents_mass
3667                icc = ( ic - 1 ) * nbins_aerosol + ib
3668                surf%amsws(m,icc) = aerosol_mass(icc)%source(j,i) -                                &
3669                                    MAX( 0.0_wp, depo *  norm_fac * aerosol_mass(icc)%conc(k,j,i) )
3670             ENDDO  ! ic
3671          ENDIF
3672       ENDDO    ! ib
3673    ENDDO    ! m
3674
3675 END SUBROUTINE depo_surf
3676
3677!------------------------------------------------------------------------------!
3678! Description:
3679! ------------
3680! Function for calculating terminal velocities for different particles sizes.
3681!------------------------------------------------------------------------------!
3682 REAL(wp) FUNCTION terminal_vel( radius, rhop, rhoa, visc, beta )
3683
3684    IMPLICIT NONE
3685
3686    REAL(wp), INTENT(in) ::  beta    !< Cunningham correction factor
3687    REAL(wp), INTENT(in) ::  radius  !< particle radius (m)
3688    REAL(wp), INTENT(in) ::  rhop    !< particle density (kg/m3)
3689    REAL(wp), INTENT(in) ::  rhoa    !< air density (kg/m3)
3690    REAL(wp), INTENT(in) ::  visc    !< molecular viscosity of air (kg/(m*s))
3691
3692!
3693!-- Stokes law with Cunningham slip correction factor
3694    terminal_vel = 4.0_wp * radius**2 * ( rhop - rhoa ) * g * beta / ( 18.0_wp * visc ) ! (m/s)
3695
3696 END FUNCTION terminal_vel
3697
3698!------------------------------------------------------------------------------!
3699! Description:
3700! ------------
3701!> Calculates particle loss and change in size distribution due to (Brownian)
3702!> coagulation. Only for particles with dwet < 30 micrometres.
3703!
3704!> Method:
3705!> Semi-implicit, non-iterative method: (Jacobson, 1994)
3706!> Volume concentrations of the smaller colliding particles added to the bin of
3707!> the larger colliding particles. Start from first bin and use the updated
3708!> number and volume for calculation of following bins. NB! Our bin numbering
3709!> does not follow particle size in subrange 2.
3710!
3711!> Schematic for bin numbers in different subranges:
3712!>             1                            2
3713!>    +-------------------------------------------+
3714!>  a | 1 | 2 | 3 || 4 | 5 | 6 | 7 |  8 |  9 | 10||
3715!>  b |           ||11 |12 |13 |14 | 15 | 16 | 17||
3716!>    +-------------------------------------------+
3717!
3718!> Exact coagulation coefficients for each pressure level are scaled according
3719!> to current particle wet size (linear scaling).
3720!> Bins are organized in terms of the dry size of the condensation nucleus,
3721!> while coagulation kernell is calculated with the actual hydrometeor
3722!> size.
3723!
3724!> Called from salsa_driver
3725!> fxm: Process selection should be made smarter - now just lots of IFs inside
3726!>      loops
3727!
3728!> Coded by:
3729!> Hannele Korhonen (FMI) 2005
3730!> Harri Kokkola (FMI) 2006
3731!> Tommi Bergman (FMI) 2012
3732!> Matti Niskanen(FMI) 2012
3733!> Anton Laakso  (FMI) 2013
3734!> Juha Tonttila (FMI) 2014
3735!------------------------------------------------------------------------------!
3736 SUBROUTINE coagulation( paero, ptstep, ptemp, ppres )
3737
3738    IMPLICIT NONE
3739
3740    INTEGER(iwp) ::  index_2a !< corresponding bin in subrange 2a
3741    INTEGER(iwp) ::  index_2b !< corresponding bin in subrange 2b
3742    INTEGER(iwp) ::  ib       !< loop index
3743    INTEGER(iwp) ::  ll       !< loop index
3744    INTEGER(iwp) ::  mm       !< loop index
3745    INTEGER(iwp) ::  nn       !< loop index
3746
3747    REAL(wp) ::  pressi          !< pressure
3748    REAL(wp) ::  temppi          !< temperature
3749    REAL(wp) ::  zdpart_mm       !< diameter of particle (m)
3750    REAL(wp) ::  zdpart_nn       !< diameter of particle (m)
3751    REAL(wp) ::  zminusterm      !< coagulation loss in a bin (1/s)
3752
3753    REAL(wp), INTENT(in) ::  ppres  !< ambient pressure (Pa)
3754    REAL(wp), INTENT(in) ::  ptemp  !< ambient temperature (K)
3755    REAL(wp), INTENT(in) ::  ptstep !< time step (s)
3756
3757    REAL(wp), DIMENSION(nbins_aerosol) ::  zmpart     !< approximate mass of particles (kg)
3758    REAL(wp), DIMENSION(maxspec+1)     ::  zplusterm  !< coagulation gain in a bin (for each
3759                                                      !< chemical compound)
3760    REAL(wp), DIMENSION(nbins_aerosol,nbins_aerosol) ::  zcc  !< updated coagulation coefficients (m3/s)
3761
3762    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< Aerosol properties
3763
3764    zdpart_mm = 0.0_wp
3765    zdpart_nn = 0.0_wp
3766!
3767!-- 1) Coagulation to coarse mode calculated in a simplified way:
3768!--    CoagSink ~ Dp in continuum subrange, thus we calculate 'effective'
3769!--    number concentration of coarse particles
3770
3771!-- 2) Updating coagulation coefficients
3772!
3773!-- Aerosol mass (kg). Density of 1500 kg/m3 assumed
3774    zmpart(1:end_subrange_2b) = api6 * ( MIN( paero(1:end_subrange_2b)%dwet, 30.0E-6_wp )**3 )     &
3775                                * 1500.0_wp
3776    temppi = ptemp
3777    pressi = ppres
3778    zcc    = 0.0_wp
3779!
3780!-- Aero-aero coagulation
3781    DO  mm = 1, end_subrange_2b   ! smaller colliding particle
3782       IF ( paero(mm)%numc < nclim )  CYCLE
3783       DO  nn = mm, end_subrange_2b   ! larger colliding particle
3784          IF ( paero(nn)%numc < nclim )  CYCLE
3785
3786          zdpart_mm = MIN( paero(mm)%dwet, 30.0E-6_wp )     ! Limit to 30 um
3787          zdpart_nn = MIN( paero(nn)%dwet, 30.0E-6_wp )     ! Limit to 30 um
3788!
3789!--       Coagulation coefficient of particles (m3/s)
3790          zcc(mm,nn) = coagc( zdpart_mm, zdpart_nn, zmpart(mm), zmpart(nn), temppi, pressi )
3791          zcc(nn,mm) = zcc(mm,nn)
3792       ENDDO
3793    ENDDO
3794
3795!
3796!-- 3) New particle and volume concentrations after coagulation:
3797!--    Calculated according to Jacobson (2005) eq. 15.9
3798!
3799!-- Aerosols in subrange 1a:
3800    DO  ib = start_subrange_1a, end_subrange_1a
3801       IF ( paero(ib)%numc < nclim )  CYCLE
3802       zminusterm   = 0.0_wp
3803       zplusterm(:) = 0.0_wp
3804!
3805!--    Particles lost by coagulation with larger aerosols
3806       DO  ll = ib+1, end_subrange_2b
3807          zminusterm = zminusterm + zcc(ib,ll) * paero(ll)%numc
3808       ENDDO
3809!
3810!--    Coagulation gain in a bin: change in volume conc. (cm3/cm3):
3811       DO ll = start_subrange_1a, ib - 1
3812          zplusterm(1:2) = zplusterm(1:2) + zcc(ll,ib) * paero(ll)%volc(1:2)
3813          zplusterm(6:7) = zplusterm(6:7) + zcc(ll,ib) * paero(ll)%volc(6:7)
3814          zplusterm(8)   = zplusterm(8)   + zcc(ll,ib) * paero(ll)%volc(8)
3815       ENDDO
3816!
3817!--    Volume and number concentrations after coagulation update [fxm]
3818       paero(ib)%volc(1:2) = ( paero(ib)%volc(1:2) + ptstep * zplusterm(1:2) * paero(ib)%numc ) /  &
3819                            ( 1.0_wp + ptstep * zminusterm )
3820       paero(ib)%volc(6:8) = ( paero(ib)%volc(6:8) + ptstep * zplusterm(6:8) * paero(ib)%numc ) /  &
3821                            ( 1.0_wp + ptstep * zminusterm )
3822       paero(ib)%numc = paero(ib)%numc / ( 1.0_wp + ptstep * zminusterm + 0.5_wp * ptstep *        &
3823                        zcc(ib,ib) * paero(ib)%numc )
3824    ENDDO
3825!
3826!-- Aerosols in subrange 2a:
3827    DO  ib = start_subrange_2a, end_subrange_2a
3828       IF ( paero(ib)%numc < nclim )  CYCLE
3829       zminusterm   = 0.0_wp
3830       zplusterm(:) = 0.0_wp
3831!
3832!--    Find corresponding size bin in subrange 2b
3833       index_2b = ib - start_subrange_2a + start_subrange_2b
3834!
3835!--    Particles lost by larger particles in 2a
3836       DO  ll = ib+1, end_subrange_2a
3837          zminusterm = zminusterm + zcc(ib,ll) * paero(ll)%numc
3838       ENDDO
3839!
3840!--    Particles lost by larger particles in 2b
3841       IF ( .NOT. no_insoluble )  THEN
3842          DO  ll = index_2b+1, end_subrange_2b
3843             zminusterm = zminusterm + zcc(ib,ll) * paero(ll)%numc
3844          ENDDO
3845       ENDIF
3846!
3847!--    Particle volume gained from smaller particles in subranges 1, 2a and 2b
3848       DO  ll = start_subrange_1a, ib-1
3849          zplusterm(1:2) = zplusterm(1:2) + zcc(ll,ib) * paero(ll)%volc(1:2)
3850          zplusterm(6:8) = zplusterm(6:8) + zcc(ll,ib) * paero(ll)%volc(6:8)
3851       ENDDO
3852!
3853!--    Particle volume gained from smaller particles in 2a
3854!--    (Note, for components not included in the previous loop!)
3855       DO  ll = start_subrange_2a, ib-1
3856          zplusterm(3:5) = zplusterm(3:5) + zcc(ll,ib)*paero(ll)%volc(3:5)
3857       ENDDO
3858!
3859!--    Particle volume gained from smaller (and equal) particles in 2b
3860       IF ( .NOT. no_insoluble )  THEN
3861          DO  ll = start_subrange_2b, index_2b
3862             zplusterm(1:8) = zplusterm(1:8) + zcc(ll,ib) * paero(ll)%volc(1:8)
3863          ENDDO
3864       ENDIF
3865!
3866!--    Volume and number concentrations after coagulation update [fxm]
3867       paero(ib)%volc(1:8) = ( paero(ib)%volc(1:8) + ptstep * zplusterm(1:8) * paero(ib)%numc ) /  &
3868                            ( 1.0_wp + ptstep * zminusterm )
3869       paero(ib)%numc = paero(ib)%numc / ( 1.0_wp + ptstep * zminusterm + 0.5_wp * ptstep *        &
3870                        zcc(ib,ib) * paero(ib)%numc )
3871    ENDDO
3872!
3873!-- Aerosols in subrange 2b:
3874    IF ( .NOT. no_insoluble )  THEN
3875       DO  ib = start_subrange_2b, end_subrange_2b
3876          IF ( paero(ib)%numc < nclim )  CYCLE
3877          zminusterm   = 0.0_wp
3878          zplusterm(:) = 0.0_wp
3879!
3880!--       Find corresponding size bin in subsubrange 2a
3881          index_2a = ib - start_subrange_2b + start_subrange_2a
3882!
3883!--       Particles lost to larger particles in subranges 2b
3884          DO  ll = ib + 1, end_subrange_2b
3885             zminusterm = zminusterm + zcc(ib,ll) * paero(ll)%numc
3886          ENDDO
3887!
3888!--       Particles lost to larger and equal particles in 2a
3889          DO  ll = index_2a, end_subrange_2a
3890             zminusterm = zminusterm + zcc(ib,ll) * paero(ll)%numc
3891          ENDDO
3892!
3893!--       Particle volume gained from smaller particles in subranges 1 & 2a
3894          DO  ll = start_subrange_1a, index_2a - 1
3895             zplusterm(1:8) = zplusterm(1:8) + zcc(ll,ib) * paero(ll)%volc(1:8)
3896          ENDDO
3897!
3898!--       Particle volume gained from smaller particles in 2b
3899          DO  ll = start_subrange_2b, ib - 1
3900             zplusterm(1:8) = zplusterm(1:8) + zcc(ll,ib) * paero(ll)%volc(1:8)
3901          ENDDO
3902!
3903!--       Volume and number concentrations after coagulation update [fxm]
3904          paero(ib)%volc(1:8) = ( paero(ib)%volc(1:8) + ptstep * zplusterm(1:8) * paero(ib)%numc ) &
3905                                / ( 1.0_wp + ptstep * zminusterm )
3906          paero(ib)%numc = paero(ib)%numc / ( 1.0_wp + ptstep * zminusterm + 0.5_wp * ptstep *     &
3907                           zcc(ib,ib) * paero(ib)%numc )
3908       ENDDO
3909    ENDIF
3910
3911 END SUBROUTINE coagulation
3912
3913!------------------------------------------------------------------------------!
3914! Description:
3915! ------------
3916!> Calculation of coagulation coefficients. Extended version of the function
3917!> originally found in mo_salsa_init.
3918!
3919!> J. Tonttila, FMI, 05/2014
3920!------------------------------------------------------------------------------!
3921 REAL(wp) FUNCTION coagc( diam1, diam2, mass1, mass2, temp, pres )
3922
3923    IMPLICIT NONE
3924
3925    REAL(wp) ::  fmdist  !< distance of flux matching (m)
3926    REAL(wp) ::  knud_p  !< particle Knudsen number
3927    REAL(wp) ::  mdiam   !< mean diameter of colliding particles (m)
3928    REAL(wp) ::  mfp     !< mean free path of air molecules (m)
3929    REAL(wp) ::  visc    !< viscosity of air (kg/(m s))
3930
3931    REAL(wp), INTENT(in) ::  diam1  !< diameter of colliding particle 1 (m)
3932    REAL(wp), INTENT(in) ::  diam2  !< diameter of colliding particle 2 (m)
3933    REAL(wp), INTENT(in) ::  mass1  !< mass of colliding particle 1 (kg)
3934    REAL(wp), INTENT(in) ::  mass2  !< mass of colliding particle 2 (kg)
3935    REAL(wp), INTENT(in) ::  pres   !< ambient pressure (Pa?) [fxm]
3936    REAL(wp), INTENT(in) ::  temp   !< ambient temperature (K)
3937
3938    REAL(wp), DIMENSION (2) ::  beta    !< Cunningham correction factor
3939    REAL(wp), DIMENSION (2) ::  dfpart  !< particle diffusion coefficient (m2/s)
3940    REAL(wp), DIMENSION (2) ::  diam    !< diameters of particles (m)
3941    REAL(wp), DIMENSION (2) ::  flux    !< flux in continuum and free molec. regime (m/s)
3942    REAL(wp), DIMENSION (2) ::  knud    !< particle Knudsen number
3943    REAL(wp), DIMENSION (2) ::  mpart   !< masses of particles (kg)
3944    REAL(wp), DIMENSION (2) ::  mtvel   !< particle mean thermal velocity (m/s)
3945    REAL(wp), DIMENSION (2) ::  omega   !< particle mean free path
3946    REAL(wp), DIMENSION (2) ::  tva     !< temporary variable (m)
3947!
3948!-- Initialisation
3949    coagc   = 0.0_wp
3950!
3951!-- 1) Initializing particle and ambient air variables
3952    diam  = (/ diam1, diam2 /) !< particle diameters (m)
3953    mpart = (/ mass1, mass2 /) !< particle masses (kg)
3954!
3955!-- Viscosity of air (kg/(m s))
3956    visc = ( 7.44523E-3_wp * temp ** 1.5_wp ) / ( 5093.0_wp * ( temp + 110.4_wp ) )
3957!
3958!-- Mean free path of air (m)
3959    mfp = ( 1.656E-10_wp * temp + 1.828E-8_wp ) * ( p_0 + 1325.0_wp ) / pres
3960!
3961!-- 2) Slip correction factor for small particles
3962    knud = 2.0_wp * EXP( LOG(mfp) - LOG(diam) )! Knudsen number for air (15.23)
3963!
3964!-- Cunningham correction factor (Allen and Raabe, Aerosol Sci. Tech. 4, 269)
3965    beta = 1.0_wp + knud * ( 1.142_wp + 0.558_wp * EXP( -0.999_wp / knud ) )
3966!
3967!-- 3) Particle properties
3968!-- Diffusion coefficient (m2/s) (Jacobson (2005) eq. 15.29)
3969    dfpart = beta * abo * temp / ( 3.0_wp * pi * visc * diam )
3970!
3971!-- Mean thermal velocity (m/s) (Jacobson (2005) eq. 15.32)
3972    mtvel = SQRT( ( 8.0_wp * abo * temp ) / ( pi * mpart ) )
3973!
3974!-- Particle mean free path (m) (Jacobson (2005) eq. 15.34 )
3975    omega = 8.0_wp * dfpart / ( pi * mtvel )
3976!
3977!-- Mean diameter (m)
3978    mdiam = 0.5_wp * ( diam(1) + diam(2) )
3979!
3980!-- 4) Calculation of fluxes (Brownian collision kernels) and flux matching
3981!-- following Jacobson (2005):
3982!
3983!-- Flux in continuum regime (m3/s) (eq. 15.28)
3984    flux(1) = 4.0_wp * pi * mdiam * ( dfpart(1) + dfpart(2) )
3985!
3986!-- Flux in free molec. regime (m3/s) (eq. 15.31)
3987    flux(2) = pi * SQRT( ( mtvel(1)**2 ) + ( mtvel(2)**2 ) ) * ( mdiam**2 )
3988!
3989!-- temporary variables (m) to calculate flux matching distance (m)
3990    tva(1) = ( ( mdiam + omega(1) )**3 - ( mdiam**2 + omega(1)**2 ) * SQRT( ( mdiam**2 +           &
3991               omega(1)**2 ) ) ) / ( 3.0_wp * mdiam * omega(1) ) - mdiam
3992    tva(2) = ( ( mdiam + omega(2) )**3 - ( mdiam**2 + omega(2)**2 ) * SQRT( ( mdiam**2 +           &
3993               omega(2)**2 ) ) ) / ( 3.0_wp * mdiam * omega(2) ) - mdiam
3994!
3995!-- Flux matching distance (m): the mean distance from the centre of a sphere reached by particles
3996!-- that leave sphere's surface and travel a distance of particle mean free path (eq. 15.34)
3997    fmdist = SQRT( tva(1)**2 + tva(2)**2 )
3998!
3999!-- 5) Coagulation coefficient = coalescence efficiency * collision kernel (m3/s) (eq. 15.33).
4000!--    Here assumed coalescence efficiency 1!!
4001    coagc = flux(1) / ( mdiam / ( mdiam + fmdist) + flux(1) / flux(2) )
4002!
4003!-- Corrected collision kernel (Karl et al., 2016 (ACP)): Include van der Waals and viscous forces
4004    IF ( van_der_waals_coagc )  THEN
4005       knud_p = SQRT( omega(1)**2 + omega(2)**2 ) / mdiam
4006       IF ( knud_p >= 0.1_wp  .AND.  knud_p <= 10.0_wp )  THEN
4007          coagc = coagc * ( 2.0_wp + 0.4_wp * LOG( knud_p ) )
4008       ELSE
4009          coagc = coagc * 3.0_wp
4010       ENDIF
4011    ENDIF
4012
4013 END FUNCTION coagc
4014
4015!------------------------------------------------------------------------------!
4016! Description:
4017! ------------
4018!> Calculates the change in particle volume and gas phase
4019!> concentrations due to nucleation, condensation and dissolutional growth.
4020!
4021!> Sulphuric acid and organic vapour: only condensation and no evaporation.
4022!
4023!> New gas and aerosol phase concentrations calculated according to Jacobson
4024!> (1997): Numerical techniques to solve condensational and dissolutional growth
4025!> equations when growth is coupled to reversible reactions, Aerosol Sci. Tech.,
4026!> 27, pp 491-498.
4027!
4028!> Following parameterization has been used:
4029!> Molecular diffusion coefficient of condensing vapour (m2/s)
4030!> (Reid et al. (1987): Properties of gases and liquids, McGraw-Hill, New York.)
4031!> D = {1.d-7*sqrt(1/M_air + 1/M_gas)*T^1.75} / &
4032!      {p_atm/p_stand * (d_air^(1/3) + d_gas^(1/3))^2 }
4033!> M_air = 28.965 : molar mass of air (g/mol)
4034!> d_air = 19.70  : diffusion volume of air
4035!> M_h2so4 = 98.08 : molar mass of h2so4 (g/mol)
4036!> d_h2so4 = 51.96  : diffusion volume of h2so4
4037!
4038!> Called from main aerosol model
4039!> For equations, see Jacobson, Fundamentals of Atmospheric Modeling, 2nd Edition (2005)
4040!
4041!> Coded by:
4042!> Hannele Korhonen (FMI) 2005
4043!> Harri Kokkola (FMI) 2006
4044!> Juha Tonttila (FMI) 2014
4045!> Rewritten to PALM by Mona Kurppa (UHel) 2017
4046!------------------------------------------------------------------------------!
4047 SUBROUTINE condensation( paero, pc_sa, pc_ocnv, pcocsv, pchno3, pc_nh3, pcw, pcs, ptemp, ppres,   &
4048                          ptstep, prtcl )
4049
4050    IMPLICIT NONE
4051
4052    INTEGER(iwp) ::  ss      !< start index
4053    INTEGER(iwp) ::  ee      !< end index
4054
4055    REAL(wp) ::  zcs_ocnv    !< condensation sink of nonvolatile organics (1/s)
4056    REAL(wp) ::  zcs_ocsv    !< condensation sink of semivolatile organics (1/s)
4057    REAL(wp) ::  zcs_su      !< condensation sink of sulfate (1/s)
4058    REAL(wp) ::  zcs_tot     !< total condensation sink (1/s) (gases)
4059    REAL(wp) ::  zcvap_new1  !< vapour concentration after time step (#/m3): sulphuric acid
4060    REAL(wp) ::  zcvap_new2  !< nonvolatile organics
4061    REAL(wp) ::  zcvap_new3  !< semivolatile organics
4062    REAL(wp) ::  zdfvap      !< air diffusion coefficient (m2/s)
4063    REAL(wp) ::  zdvap1      !< change in vapour concentration (#/m3): sulphuric acid
4064    REAL(wp) ::  zdvap2      !< nonvolatile organics
4065    REAL(wp) ::  zdvap3      !< semivolatile organics
4066    REAL(wp) ::  zmfp        !< mean free path of condensing vapour (m)
4067    REAL(wp) ::  zrh         !< Relative humidity [0-1]
4068    REAL(wp) ::  zvisc       !< viscosity of air (kg/(m s))
4069    REAL(wp) ::  zn_vs_c     !< ratio of nucleation of all mass transfer in the smallest bin
4070    REAL(wp) ::  zxocnv      !< ratio of organic vapour in 3nm particles
4071    REAL(wp) ::  zxsa        !< Ratio in 3nm particles: sulphuric acid
4072
4073    REAL(wp), INTENT(in) ::  ppres   !< ambient pressure (Pa)
4074    REAL(wp), INTENT(in) ::  pcs     !< Water vapour saturation concentration (kg/m3)
4075    REAL(wp), INTENT(in) ::  ptemp   !< ambient temperature (K)
4076    REAL(wp), INTENT(in) ::  ptstep  !< timestep (s)
4077
4078    REAL(wp), INTENT(inout) ::  pchno3   !< Gas concentrations (#/m3): nitric acid HNO3
4079    REAL(wp), INTENT(inout) ::  pc_nh3   !< ammonia NH3
4080    REAL(wp), INTENT(inout) ::  pc_ocnv  !< non-volatile organics
4081    REAL(wp), INTENT(inout) ::  pcocsv   !< semi-volatile organics
4082    REAL(wp), INTENT(inout) ::  pc_sa    !< sulphuric acid H2SO4
4083    REAL(wp), INTENT(inout) ::  pcw      !< Water vapor concentration (kg/m3)
4084
4085    REAL(wp), DIMENSION(nbins_aerosol)               ::  zbeta          !< transitional correction factor
4086    REAL(wp), DIMENSION(nbins_aerosol)               ::  zcolrate       !< collision rate (1/s)
4087    REAL(wp), DIMENSION(nbins_aerosol)               ::  zcolrate_ocnv  !< collision rate of non-vol. OC (1/s)
4088    REAL(wp), DIMENSION(start_subrange_1a+1) ::  zdfpart        !< particle diffusion coefficient (m2/s)
4089    REAL(wp), DIMENSION(nbins_aerosol)               ::  zdvoloc        !< change of organics volume
4090    REAL(wp), DIMENSION(nbins_aerosol)               ::  zdvolsa        !< change of sulphate volume
4091    REAL(wp), DIMENSION(2)                   ::  zj3n3          !< Formation massrate of molecules
4092                                                                !< in nucleation, (molec/m3s),
4093                                                                !< 1: H2SO4 and 2: organic vapor
4094    REAL(wp), DIMENSION(nbins_aerosol)   ::  zknud          !< particle Knudsen number
4095
4096    TYPE(component_index), INTENT(in) :: prtcl  !< Keeps track which substances are used
4097
4098    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< Aerosol properties
4099
4100    zj3n3  = 0.0_wp
4101    zrh    = pcw / pcs
4102    zxocnv = 0.0_wp
4103    zxsa   = 0.0_wp
4104!
4105!-- Nucleation
4106    IF ( nsnucl > 0 )  THEN
4107       CALL nucleation( paero, ptemp, zrh, ppres, pc_sa, pc_ocnv, pc_nh3, ptstep, zj3n3, zxsa,     &
4108                        zxocnv )
4109    ENDIF
4110!
4111!-- Condensation on pre-existing particles
4112    IF ( lscndgas )  THEN
4113!
4114!--    Initialise:
4115       zdvolsa = 0.0_wp
4116       zdvoloc = 0.0_wp
4117       zcolrate = 0.0_wp
4118!
4119!--    1) Properties of air and condensing gases:
4120!--    Viscosity of air (kg/(m s)) (Eq. 4.54 in Jabonson (2005))
4121       zvisc = ( 7.44523E-3_wp * ptemp ** 1.5_wp ) / ( 5093.0_wp * ( ptemp + 110.4_wp ) )
4122!
4123!--    Diffusion coefficient of air (m2/s)
4124       zdfvap = 5.1111E-10_wp * ptemp ** 1.75_wp * ( p_0 + 1325.0_wp ) / ppres
4125!
4126!--    Mean free path (m): same for H2SO4 and organic compounds
4127       zmfp = 3.0_wp * zdfvap * SQRT( pi * amh2so4 / ( 8.0_wp * argas * ptemp ) )
4128!
4129!--    2) Transition regime correction factor zbeta for particles (Fuchs and Sutugin (1971)):
4130!--       Size of condensing molecule considered only for nucleation mode (3 - 20 nm).
4131!
4132!--    Particle Knudsen number: condensation of gases on aerosols
4133       ss = start_subrange_1a
4134       ee = start_subrange_1a+1
4135       zknud(ss:ee) = 2.0_wp * zmfp / ( paero(ss:ee)%dwet + d_sa )
4136       ss = start_subrange_1a+2
4137       ee = end_subrange_2b
4138       zknud(ss:ee) = 2.0_wp * zmfp / paero(ss:ee)%dwet
4139!
4140!--    Transitional correction factor: aerosol + gas (the semi-empirical Fuchs- Sutugin
4141!--    interpolation function (Fuchs and Sutugin, 1971))
4142       zbeta = ( zknud + 1.0_wp ) / ( 0.377_wp * zknud + 1.0_wp + 4.0_wp / ( 3.0_wp * massacc ) *  &
4143               ( zknud + zknud ** 2 ) )
4144!
4145!--    3) Collision rate of molecules to particles
4146!--       Particle diffusion coefficient considered only for nucleation mode (3 - 20 nm)
4147!
4148!--    Particle diffusion coefficient (m2/s) (e.g. Eq. 15.29 in Jacobson (2005))
4149       zdfpart = abo * ptemp * zbeta(start_subrange_1a:start_subrange_1a+1) / ( 3.0_wp * pi * zvisc&
4150                 * paero(start_subrange_1a:start_subrange_1a+1)%dwet)
4151!
4152!--    Collision rate (mass-transfer coefficient): gases on aerosols (1/s) (Eq. 16.64 in
4153!--    Jacobson (2005))
4154       ss = start_subrange_1a
4155       ee = start_subrange_1a+1
4156       zcolrate(ss:ee) = MERGE( 2.0_wp * pi * ( paero(ss:ee)%dwet + d_sa ) * ( zdfvap + zdfpart ) *&
4157                               zbeta(ss:ee) * paero(ss:ee)%numc, 0.0_wp, paero(ss:ee)%numc > nclim )
4158       ss = start_subrange_1a+2
4159       ee = end_subrange_2b
4160       zcolrate(ss:ee) = MERGE( 2.0_wp * pi * paero(ss:ee)%dwet * zdfvap * zbeta(ss:ee) *          &
4161                                paero(ss:ee)%numc, 0.0_wp, paero(ss:ee)%numc > nclim )
4162!
4163!-- 4) Condensation sink (1/s)
4164       zcs_tot = SUM( zcolrate )   ! total sink
4165!
4166!--    5) Changes in gas-phase concentrations and particle volume
4167!
4168!--    5.1) Organic vapours
4169!
4170!--    5.1.1) Non-volatile organic compound: condenses onto all bins
4171       IF ( pc_ocnv > 1.0E+10_wp  .AND.  zcs_tot > 1.0E-30_wp  .AND. index_oc > 0 )  &
4172       THEN
4173!--       Ratio of nucleation vs. condensation rates in the smallest bin
4174          zn_vs_c = 0.0_wp
4175          IF ( zj3n3(2) > 1.0_wp )  THEN
4176             zn_vs_c = ( zj3n3(2) ) / ( zj3n3(2) + pc_ocnv * zcolrate(start_subrange_1a) )
4177          ENDIF
4178!
4179!--       Collision rate in the smallest bin, including nucleation and condensation (see
4180!--       Jacobson (2005), eq. (16.73) )
4181          zcolrate_ocnv = zcolrate
4182          zcolrate_ocnv(start_subrange_1a) = zcolrate_ocnv(start_subrange_1a) + zj3n3(2) / pc_ocnv
4183!
4184!--       Total sink for organic vapor
4185          zcs_ocnv = zcs_tot + zj3n3(2) / pc_ocnv
4186!
4187!--       New gas phase concentration (#/m3)
4188          zcvap_new2 = pc_ocnv / ( 1.0_wp + ptstep * zcs_ocnv )
4189!
4190!--       Change in gas concentration (#/m3)
4191          zdvap2 = pc_ocnv - zcvap_new2
4192!
4193!--       Updated vapour concentration (#/m3)
4194          pc_ocnv = zcvap_new2
4195!
4196!--       Volume change of particles (m3(OC)/m3(air))
4197          zdvoloc = zcolrate_ocnv(start_subrange_1a:end_subrange_2b) / zcs_ocnv * amvoc * zdvap2
4198!
4199!--       Change of volume due to condensation in 1a-2b
4200          paero(start_subrange_1a:end_subrange_2b)%volc(2) =                                       &
4201                                          paero(start_subrange_1a:end_subrange_2b)%volc(2) + zdvoloc
4202!
4203!--       Change of number concentration in the smallest bin caused by nucleation (Jacobson (2005),
4204!--       eq. (16.75)). If zxocnv = 0, then the chosen nucleation mechanism doesn't take into
4205!--       account the non-volatile organic vapors and thus the paero doesn't have to be updated.
4206          IF ( zxocnv > 0.0_wp )  THEN
4207             paero(start_subrange_1a)%numc = paero(start_subrange_1a)%numc + zn_vs_c *             &
4208                                             zdvoloc(start_subrange_1a) / amvoc / ( n3 * zxocnv )
4209          ENDIF
4210       ENDIF
4211!
4212!--    5.1.2) Semivolatile organic compound: all bins except subrange 1
4213       zcs_ocsv = SUM( zcolrate(start_subrange_2a:end_subrange_2b) ) !< sink for semi-volatile organics
4214       IF ( pcocsv > 1.0E+10_wp  .AND.  zcs_ocsv > 1.0E-30  .AND. is_used( prtcl,'OC') )  THEN
4215!
4216!--       New gas phase concentration (#/m3)
4217          zcvap_new3 = pcocsv / ( 1.0_wp + ptstep * zcs_ocsv )
4218!
4219!--       Change in gas concentration (#/m3)
4220          zdvap3 = pcocsv - zcvap_new3
4221!
4222!--       Updated gas concentration (#/m3)
4223          pcocsv = zcvap_new3
4224!
4225!--       Volume change of particles (m3(OC)/m3(air))
4226          ss = start_subrange_2a
4227          ee = end_subrange_2b
4228          zdvoloc(ss:ee) = zdvoloc(ss:ee) + zcolrate(ss:ee) / zcs_ocsv * amvoc * zdvap3
4229!
4230!--       Change of volume due to condensation in 1a-2b
4231          paero(start_subrange_1a:end_subrange_2b)%volc(2) =                                       &
4232                                          paero(start_subrange_1a:end_subrange_2b)%volc(2) + zdvoloc
4233       ENDIF
4234!
4235!--    5.2) Sulphate: condensed on all bins
4236       IF ( pc_sa > 1.0E+10_wp  .AND.  zcs_tot > 1.0E-30_wp  .AND.  index_so4 > 0 )  THEN
4237!
4238!--    Ratio of mass transfer between nucleation and condensation
4239          zn_vs_c = 0.0_wp
4240          IF ( zj3n3(1) > 1.0_wp )  THEN
4241             zn_vs_c = ( zj3n3(1) ) / ( zj3n3(1) + pc_sa * zcolrate(start_subrange_1a) )
4242          ENDIF
4243!
4244!--       Collision rate in the smallest bin, including nucleation and condensation (see
4245!--       Jacobson (2005), eq. (16.73))
4246          zcolrate(start_subrange_1a) = zcolrate(start_subrange_1a) + zj3n3(1) / pc_sa
4247!
4248!--       Total sink for sulfate (1/s)
4249          zcs_su = zcs_tot + zj3n3(1) / pc_sa
4250!
4251!--       Sulphuric acid:
4252!--       New gas phase concentration (#/m3)
4253          zcvap_new1 = pc_sa / ( 1.0_wp + ptstep * zcs_su )
4254!
4255!--       Change in gas concentration (#/m3)
4256          zdvap1 = pc_sa - zcvap_new1
4257!
4258!--       Updating vapour concentration (#/m3)
4259          pc_sa = zcvap_new1
4260!
4261!--       Volume change of particles (m3(SO4)/m3(air)) by condensation
4262          zdvolsa = zcolrate(start_subrange_1a:end_subrange_2b) / zcs_su * amvh2so4 * zdvap1
4263!
4264!--       Change of volume concentration of sulphate in aerosol [fxm]
4265          paero(start_subrange_1a:end_subrange_2b)%volc(1) =                                       &
4266                                          paero(start_subrange_1a:end_subrange_2b)%volc(1) + zdvolsa
4267!
4268!--       Change of number concentration in the smallest bin caused by nucleation
4269!--       (Jacobson (2005), equation (16.75))
4270          IF ( zxsa > 0.0_wp )  THEN
4271             paero(start_subrange_1a)%numc = paero(start_subrange_1a)%numc + zn_vs_c *             &
4272                                             zdvolsa(start_subrange_1a) / amvh2so4 / ( n3 * zxsa)
4273          ENDIF
4274       ENDIF
4275!
4276!--    Partitioning of H2O, HNO3, and NH3: Dissolutional growth
4277       IF ( lspartition  .AND.  ( pchno3 > 1.0E+10_wp  .OR.  pc_nh3 > 1.0E+10_wp ) )  THEN
4278          CALL gpparthno3( ppres, ptemp, paero, pchno3, pc_nh3, pcw, pcs, zbeta, ptstep )
4279       ENDIF
4280    ENDIF
4281!
4282!-- Condensation of water vapour
4283    IF ( lscndh2oae )  THEN
4284       CALL gpparth2o( paero, ptemp, ppres, pcs, pcw, ptstep )
4285    ENDIF
4286
4287 END SUBROUTINE condensation
4288
4289!------------------------------------------------------------------------------!
4290! Description:
4291! ------------
4292!> Calculates the particle number and volume increase, and gas-phase
4293!> concentration decrease due to nucleation subsequent growth to detectable size
4294!> of 3 nm.
4295!
4296!> Method:
4297!> When the formed clusters grow by condensation (possibly also by self-
4298!> coagulation), their number is reduced due to scavenging to pre-existing
4299!> particles. Thus, the apparent nucleation rate at 3 nm is significantly lower
4300!> than the real nucleation rate (at ~1 nm).
4301!
4302!> Calculation of the formation rate of detectable particles at 3 nm (i.e. J3):
4303!> nj3 = 1: Kerminen, V.-M. and Kulmala, M. (2002), J. Aerosol Sci.,33, 609-622.
4304!> nj3 = 2: Lehtinen et al. (2007), J. Aerosol Sci., 38(9), 988-994.
4305!> nj3 = 3: Anttila et al. (2010), J. Aerosol Sci., 41(7), 621-636.
4306!
4307!> c = aerosol of critical radius (1 nm)
4308!> x = aerosol with radius 3 nm
4309!> 2 = wet or mean droplet
4310!
4311!> Called from subroutine condensation (in module salsa_dynamics_mod.f90)
4312!
4313!> Calls one of the following subroutines:
4314!>  - binnucl
4315!>  - ternucl
4316!>  - kinnucl
4317!>  - actnucl
4318!
4319!> fxm: currently only sulphuric acid grows particles from 1 to 3 nm
4320!>  (if asked from Markku, this is terribly wrong!!!)
4321!
4322!> Coded by:
4323!> Hannele Korhonen (FMI) 2005
4324!> Harri Kokkola (FMI) 2006
4325!> Matti Niskanen(FMI) 2012
4326!> Anton Laakso  (FMI) 2013
4327!------------------------------------------------------------------------------!
4328
4329 SUBROUTINE nucleation( paero, ptemp, prh, ppres, pc_sa, pc_ocnv, pc_nh3, ptstep, pj3n3, pxsa,     &
4330                        pxocnv )
4331
4332    IMPLICIT NONE
4333
4334    INTEGER(iwp) ::  iteration
4335
4336    REAL(wp) ::  zc_h2so4     !< H2SO4 conc. (#/cm3) !UNITS!
4337    REAL(wp) ::  zc_org       !< organic vapour conc. (#/cm3)
4338    REAL(wp) ::  zcc_c        !< Cunningham correct factor for c = critical (1nm)
4339    REAL(wp) ::  zcc_x        !< Cunningham correct factor for x = 3nm
4340    REAL(wp) ::  zcoags_c     !< coagulation sink (1/s) for c = critical (1nm)
4341    REAL(wp) ::  zcoags_x     !< coagulation sink (1/s) for x = 3nm
4342    REAL(wp) ::  zcoagstot    !< total particle losses due to coagulation, including condensation
4343                              !< and self-coagulation
4344    REAL(wp) ::  zcocnv_local !< organic vapour conc. (#/m3)
4345    REAL(wp) ::  zcsink       !< condensational sink (#/m2)
4346    REAL(wp) ::  zcsa_local   !< H2SO4 conc. (#/m3)
4347    REAL(wp) ::  zcv_c        !< mean relative thermal velocity (m/s) for c = critical (1nm)
4348    REAL(wp) ::  zcv_x        !< mean relative thermal velocity (m/s) for x = 3nm
4349    REAL(wp) ::  zdcrit       !< diameter of critical cluster (m)
4350    REAL(wp) ::  zdelta_vap   !< change of H2SO4 and organic vapour concentration (#/m3)
4351    REAL(wp) ::  zdfvap       !< air diffusion coefficient (m2/s)
4352    REAL(wp) ::  zdmean       !< mean diameter of existing particles (m)
4353    REAL(wp) ::  zeta         !< constant: proportional to ratio of CS/GR (m)
4354                              !< (condensation sink / growth rate)
4355    REAL(wp) ::  zgamma       !< proportionality factor ((nm2*m2)/h)
4356    REAL(wp) ::  z_gr_clust   !< growth rate of formed clusters (nm/h)
4357    REAL(wp) ::  z_gr_tot     !< total growth rate
4358    REAL(wp) ::  zj3          !< number conc. of formed 3nm particles (#/m3)
4359    REAL(wp) ::  zjnuc        !< nucleation rate at ~1nm (#/m3s)
4360    REAL(wp) ::  z_k_eff      !< effective cogulation coefficient for freshly nucleated particles
4361    REAL(wp) ::  zknud_c      !< Knudsen number for c = critical (1nm)
4362    REAL(wp) ::  zknud_x      !< Knudsen number for x = 3nm
4363    REAL(wp) ::  zkocnv       !< lever: zkocnv=1 --> organic compounds involved in nucleation
4364    REAL(wp) ::  zksa         !< lever: zksa=1 --> H2SO4 involved in nucleation
4365    REAL(wp) ::  zlambda      !< parameter for adjusting the growth rate due to self-coagulation
4366    REAL(wp) ::  zm_c         !< particle mass (kg) for c = critical (1nm)
4367    REAL(wp) ::  zm_para      !< Parameter m for calculating the coagulation sink (Eq. 5&6 in
4368                              !< Lehtinen et al. 2007)
4369    REAL(wp) ::  zm_x         !< particle mass (kg) for x = 3nm
4370    REAL(wp) ::  zmfp         !< mean free path of condesing vapour(m)
4371    REAL(wp) ::  zmixnh3      !< ammonia mixing ratio (ppt)
4372    REAL(wp) ::  zmyy         !< gas dynamic viscosity (N*s/m2)
4373    REAL(wp) ::  z_n_nuc      !< number of clusters/particles at the size range d1-dx (#/m3)
4374    REAL(wp) ::  znoc         !< number of organic molecules in critical cluster
4375    REAL(wp) ::  znsa         !< number of H2SO4 molecules in critical cluster
4376
4377    REAL(wp), INTENT(in) ::  pc_nh3   !< ammonia concentration (#/m3)
4378    REAL(wp), INTENT(in) ::  pc_ocnv  !< conc. of non-volatile OC (#/m3)
4379    REAL(wp), INTENT(in) ::  pc_sa    !< sulphuric acid conc. (#/m3)
4380    REAL(wp), INTENT(in) ::  ppres    !< ambient air pressure (Pa)
4381    REAL(wp), INTENT(in) ::  prh      !< ambient rel. humidity [0-1]
4382    REAL(wp), INTENT(in) ::  ptemp    !< ambient temperature (K)
4383    REAL(wp), INTENT(in) ::  ptstep   !< time step (s) of SALSA
4384
4385    REAL(wp), INTENT(inout) ::  pj3n3(2) !< formation mass rate of molecules (molec/m3s) for
4386                                         !< 1: H2SO4 and 2: organic vapour
4387
4388    REAL(wp), INTENT(out) ::  pxocnv  !< ratio of non-volatile organic vapours in 3 nm particles
4389    REAL(wp), INTENT(out) ::  pxsa    !< ratio of H2SO4 in 3 nm aerosol particles
4390
4391    REAL(wp), DIMENSION(nbins_aerosol) ::  zbeta       !< transitional correction factor
4392    REAL(wp), DIMENSION(nbins_aerosol) ::  zcc_2       !< Cunningham correct factor:2
4393    REAL(wp), DIMENSION(nbins_aerosol) ::  zcv_2       !< mean relative thermal velocity (m/s): 2
4394    REAL(wp), DIMENSION(nbins_aerosol) ::  zcv_c2      !< average velocity after coagulation: c & 2
4395    REAL(wp), DIMENSION(nbins_aerosol) ::  zcv_x2      !< average velocity after coagulation: x & 2
4396    REAL(wp), DIMENSION(nbins_aerosol) ::  zdc_2       !< particle diffusion coefficient (m2/s): 2
4397    REAL(wp), DIMENSION(nbins_aerosol) ::  zdc_c       !< particle diffusion coefficient (m2/s): c
4398    REAL(wp), DIMENSION(nbins_aerosol) ::  zdc_c2      !< sum of diffusion coef. for c and 2
4399    REAL(wp), DIMENSION(nbins_aerosol) ::  zdc_x       !< particle diffusion coefficient (m2/s): x
4400    REAL(wp), DIMENSION(nbins_aerosol) ::  zdc_x2      !< sum of diffusion coef. for: x & 2
4401    REAL(wp), DIMENSION(nbins_aerosol) ::  zgamma_f_2  !< zgamma_f for calculating zomega
4402    REAL(wp), DIMENSION(nbins_aerosol) ::  zgamma_f_c  !< zgamma_f for calculating zomega
4403    REAL(wp), DIMENSION(nbins_aerosol) ::  zgamma_f_x  !< zgamma_f for calculating zomega
4404    REAL(wp), DIMENSION(nbins_aerosol) ::  z_k_c2      !< coagulation coef. in the continuum
4405                                                       !< regime: c & 2
4406    REAL(wp), DIMENSION(nbins_aerosol) ::  z_k_x2      !< coagulation coef. in the continuum
4407                                                       !< regime: x & 2
4408    REAL(wp), DIMENSION(nbins_aerosol) ::  zknud       !< particle Knudsen number
4409    REAL(wp), DIMENSION(nbins_aerosol) ::  zknud_2     !< particle Knudsen number: 2
4410    REAL(wp), DIMENSION(nbins_aerosol) ::  zm_2        !< particle mass (kg): 2
4411    REAL(wp), DIMENSION(nbins_aerosol) ::  zomega_2c   !< zomega (m) for calculating zsigma: c & 2
4412    REAL(wp), DIMENSION(nbins_aerosol) ::  zomega_2x   !< zomega (m) for calculating zsigma: x & 2
4413    REAL(wp), DIMENSION(nbins_aerosol) ::  zomega_c    !< zomega (m) for calculating zsigma: c
4414    REAL(wp), DIMENSION(nbins_aerosol) ::  zomega_x    !< zomega (m) for calculating zsigma: x
4415    REAL(wp), DIMENSION(nbins_aerosol) ::  z_r_c2      !< sum of the radii: c & 2
4416    REAL(wp), DIMENSION(nbins_aerosol) ::  z_r_x2      !< sum of the radii: x & 2
4417    REAL(wp), DIMENSION(nbins_aerosol) ::  zsigma_c2   !<
4418    REAL(wp), DIMENSION(nbins_aerosol) ::  zsigma_x2   !<
4419
4420    TYPE(t_section), DIMENSION(nbins_aerosol), INTENT(inout) ::  paero  !< aerosol properties
4421!
4422!-- 1) Nucleation rate (zjnuc) and diameter of critical cluster (zdcrit)
4423    zjnuc  = 0.0_wp
4424    znsa   = 0.0_wp
4425    znoc   = 0.0_wp
4426    zdcrit = 0.0_wp
4427    zksa   = 0.0_wp
4428    zkocnv = 0.0_wp
4429
4430    SELECT CASE ( nsnucl )
4431!
4432!--    Binary H2SO4-H2O nucleation
4433       CASE(1)
4434
4435          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4436          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit,  zksa, zkocnv )
4437!
4438!--    Activation type nucleation
4439       CASE(2)
4440
4441          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4442          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa,  znoc, zdcrit, zksa, zkocnv )
4443          CALL actnucl( pc_sa, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv, act_coeff )
4444!
4445!--    Kinetically limited nucleation of (NH4)HSO4 clusters
4446       CASE(3)
4447
4448          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4449          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4450          CALL kinnucl( zc_h2so4, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4451!
4452!--    Ternary H2SO4-H2O-NH3 nucleation
4453       CASE(4)
4454
4455          zmixnh3 = pc_nh3 * ptemp * argas / ( ppres * avo )
4456          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4457          CALL ternucl( zc_h2so4, zmixnh3, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4458!
4459!--    Organic nucleation, J~[ORG] or J~[ORG]**2
4460       CASE(5)
4461
4462          zc_org = pc_ocnv * 1.0E-6_wp   ! conc. of non-volatile OC to #/cm3
4463          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4464          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4465          CALL orgnucl( pc_ocnv, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4466!
4467!--    Sum of H2SO4 and organic activation type nucleation, J~[H2SO4]+[ORG]
4468       CASE(6)
4469
4470          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4471          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4472          CALL sumnucl( pc_sa, pc_ocnv, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4473!
4474!--    Heteromolecular nucleation, J~[H2SO4]*[ORG]
4475       CASE(7)
4476
4477          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4478          zc_org = pc_ocnv * 1.0E-6_wp   ! conc. of non-volatile OC to #/cm3
4479          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4480          CALL hetnucl( zc_h2so4, zc_org, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4481!
4482!--    Homomolecular nucleation of H2SO4 and heteromolecular nucleation of H2SO4 and organic vapour,
4483!--    J~[H2SO4]**2 + [H2SO4]*[ORG] (EUCAARI project)
4484       CASE(8)
4485          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4486          zc_org = pc_ocnv * 1.0E-6_wp   ! conc. of non-volatile OC to #/cm3
4487          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4488          CALL SAnucl( zc_h2so4, zc_org, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4489!
4490!--    Homomolecular nucleation of H2SO4 and organic vapour and heteromolecular nucleation of H2SO4
4491!--    and organic vapour, J~[H2SO4]**2 + [H2SO4]*[ORG]+[ORG]**2 (EUCAARI project)
4492       CASE(9)
4493
4494          zc_h2so4 = pc_sa * 1.0E-6_wp   ! sulphuric acid conc. to #/cm3
4495          zc_org = pc_ocnv * 1.0E-6_wp   ! conc. of non-volatile OC to #/cm3
4496          CALL binnucl( zc_h2so4, ptemp, prh, zjnuc, znsa, znoc, zdcrit, zksa, zkocnv )
4497          CALL SAORGnucl( zc_h2so4, zc_org, zjnuc, zdcrit, znsa, znoc, zksa, zkocnv )
4498
4499    END SELECT
4500
4501    zcsa_local = pc_sa
4502    zcocnv_local = pc_ocnv
4503!
4504!-- 2) Change of particle and gas concentrations due to nucleation
4505!
4506!-- 2.1) Check that there is enough H2SO4 and organic vapour to produce the nucleation
4507    IF ( nsnucl <= 4 )  THEN 
4508!
4509!--    If the chosen nucleation scheme is 1-4, nucleation occurs only due to H2SO4. All of the total
4510!--    vapour concentration that is taking part to the nucleation is there for sulphuric acid
4511!--    (sa = H2SO4) and non-volatile organic vapour is zero.
4512       pxsa   = 1.0_wp   ! ratio of sulphuric acid in 3nm particles
4513       pxocnv = 0.0_wp   ! ratio of non-volatile origanic vapour
4514                                ! in 3nm particles
4515    ELSEIF ( nsnucl > 4 )  THEN
4516!
4517!--    If the chosen nucleation scheme is 5-9, nucleation occurs due to organic vapour or the
4518!--    combination of organic vapour and H2SO4. The number of needed molecules depends on the chosen
4519!--    nucleation type and it has an effect also on the minimum ratio of the molecules present.
4520       IF ( pc_sa * znsa + pc_ocnv * znoc < 1.E-14_wp )  THEN
4521          pxsa   = 0.0_wp
4522          pxocnv = 0.0_wp
4523       ELSE
4524          pxsa   = pc_sa * znsa / ( pc_sa * znsa + pc_ocnv * znoc ) 
4525          pxocnv = pc_ocnv * znoc / ( pc_sa * znsa + pc_ocnv * znoc )
4526       ENDIF
4527    ENDIF
4528!
4529!-- The change in total vapour concentration is the sum of the concentrations of the vapours taking
4530!-- part to the nucleation (depends on the chosen nucleation scheme)
4531    zdelta_vap = MIN( zjnuc * ( znoc + znsa ), ( pc_ocnv * zkocnv + pc_sa * zksa ) / ptstep )
4532!
4533!-- Nucleation rate J at ~1nm (#/m3s)
4534    zjnuc = zdelta_vap / ( znoc + znsa )
4535!
4536!-- H2SO4 concentration after nucleation (#/m3)
4537    zcsa_local = MAX( 1.0_wp, pc_sa - zdelta_vap * pxsa )
4538!
4539!-- Non-volative organic vapour concentration after nucleation (#/m3)
4540    zcocnv_local = MAX( 1.0_wp, pc_ocnv - zdelta_vap * pxocnv )
4541!
4542!-- 2.2) Formation rate of 3 nm particles (Kerminen & Kulmala, 2002)
4543!
4544!-- Growth rate by H2SO4 and organic vapour (nm/h, Eq. 21)
4545    z_gr_clust = 2.3623E-15_wp * SQRT( ptemp ) * ( zcsa_local + zcocnv_local )
4546!
4547!-- 2.2.2) Condensational sink of pre-existing particle population
4548!
4549!-- Diffusion coefficient (m2/s)
4550    zdfvap = 5.1111E-10_wp * ptemp**1.75_wp * ( p_0 + 1325.0_wp ) / ppres
4551!
4552!-- Mean free path of condensing vapour (m) (Jacobson (2005), Eq. 15.25 and 16.29)
4553    zmfp = 3.0_wp * zdfvap * SQRT( pi * amh2so4 / ( 8.0_wp * argas * ptemp ) )
4554!
4555!-- Knudsen number
4556    zknud = 2.0_wp * zmfp / ( paero(:)%dwet + d_sa )
4557!
4558!-- Transitional regime correction factor (zbeta) according to Fuchs and Sutugin (1971) (Eq. 4 in
4559!-- Kerminen and Kulmala, 2002)
4560    zbeta = ( zknud + 1.0_wp) / ( 0.377_wp * zknud + 1.0_wp + 4.0_wp / ( 3.0_wp * massacc ) *      &
4561            ( zknud + zknud**2 ) )
4562!
4563!-- Condensational sink (#/m2, Eq. 3)
4564    zcsink = SUM( paero(:)%dwet * zbeta * paero(:)%numc )
4565!
4566!-- 2.2.3) Parameterised formation rate of detectable 3 nm particles (i.e. J3)
4567    IF ( nj3 == 1 )  THEN   ! Kerminen and Kulmala (2002)
4568!
4569!--    Constants needed for the parameterisation: dapp = 3 nm and dens_nuc = 1830 kg/m3
4570       IF ( zcsink < 1.0E-30_wp )  THEN
4571          zeta = 0._dp
4572       ELSE
4573!
4574!--       Mean diameter of backgroud population (nm)
4575          zdmean = 1.0_wp / SUM( paero(:)%numc ) * SUM( paero(:)%numc * paero(:)%dwet ) * 1.0E+9_wp
4576!
4577!--       Proportionality factor (nm2*m2/h) (Eq. 22)
4578          zgamma = 0.23_wp * ( zdcrit * 1.0E+9_wp )**0.2_wp * ( zdmean / 150.0_wp )**0.048_wp *    &
4579                   ( ptemp / 293.0_wp )**( -0.75_wp ) * ( arhoh2so4 / 1000.0_wp )**( -0.33_wp )
4580!
4581!--       Factor eta (nm, Eq. 11)
4582          zeta = MIN( zgamma * zcsink / z_gr_clust, zdcrit * 1.0E11_wp )
4583       ENDIF
4584!
4585!--    Number conc. of clusters surviving to 3 nm in a time step (#/m3, Eq.14)
4586       zj3 = zjnuc * EXP( MIN( 0.0_wp, zeta / 3.0_wp - zeta / ( zdcrit * 1.0E9_wp ) ) )
4587
4588    ELSEIF ( nj3 > 1 )  THEN   ! Lehtinen et al. (2007) or Anttila et al. (2010)
4589!
4590!--    Defining the parameter m (zm_para) for calculating the coagulation sink onto background
4591!--    particles (Eq. 5&6 in Lehtinen et al. 2007). The growth is investigated between
4592!--    [d1,reglim(1)] = [zdcrit,3nm] and m = LOG( CoagS_dx / CoagX_zdcrit ) / LOG( reglim / zdcrit )
4593!--    (Lehtinen et al. 2007, Eq. 6).
4594!--    The steps for the coagulation sink for reglim = 3nm and zdcrit ~= 1nm are explained in
4595!--    Kulmala et al. (2001). The particles of diameter zdcrit ~1.14 nm  and reglim = 3nm are both
4596!--    in turn the "number 1" variables (Kulmala et al. 2001).
4597!--    c = critical (1nm), x = 3nm, 2 = wet or mean droplet
4598!
4599!--    Sum of the radii, R12 = R1 + R2 (m) of two particles 1 and 2
4600       z_r_c2 = zdcrit / 2.0_wp + paero(:)%dwet / 2.0_wp
4601       z_r_x2 = reglim(1) / 2.0_wp + paero(:)%dwet / 2.0_wp
4602!
4603!--    Particle mass (kg) (comes only from H2SO4)
4604       zm_c = 4.0_wp / 3.0_wp * pi * ( zdcrit / 2.0_wp )**3 * arhoh2so4
4605       zm_x = 4.0_wp / 3.0_wp * pi * ( reglim(1) / 2.0_wp )**3 * arhoh2so4
4606       zm_2 = 4.0_wp / 3.0_wp * pi * ( 0.5_wp * paero(:)%dwet )**3 * arhoh2so4
4607!
4608!--    Mean relative thermal velocity between the particles (m/s)
4609       zcv_c = SQRT( 8.0_wp * abo * ptemp / ( pi * zm_c ) )
4610       zcv_x = SQRT( 8.0_wp * abo * ptemp / ( pi * zm_x ) )
4611       zcv_2 = SQRT( 8.0_wp * abo * ptemp / ( pi * zm_2 ) )
4612!
4613!--    Average velocity after coagulation
4614       zcv_c2(:) = SQRT( zcv_c**2 + zcv_2**2 )
4615       zcv_x2(:) = SQRT( zcv_x**2 + zcv_2**2 )
4616!
4617!--    Knudsen number (zmfp = mean free path of condensing vapour)
4618       zknud_c = 2.0_wp * zmfp / zdcrit
4619       zknud_x = 2.0_wp * zmfp / reglim(1)
4620       zknud_2(:) = MAX( 0.0_wp, 2.0_wp * zmfp / paero(:)%dwet )
4621!
4622!--    Cunningham correction factors (Allen and Raabe, 1985)
4623       zcc_c    = 1.0_wp + zknud_c    * ( 1.142_wp + 0.558_wp * EXP( -0.999_wp / zknud_c ) )
4624       zcc_x    = 1.0_wp + zknud_x    * ( 1.142_wp + 0.558_wp * EXP( -0.999_wp / zknud_x ) )
4625       zcc_2(:) = 1.0_wp + zknud_2(:) * ( 1.142_wp + 0.558_wp * EXP( -0.999_wp / zknud_2(:) ) )
4626!
4627!--    Gas dynamic viscosity (N*s/m2). Here, viscocity(air @20C) = 1.81e-5_dp N/m2 *s (Hinds, p. 25)
4628       zmyy = 1.81E-5_wp * ( ptemp / 293.0_wp )**0.74_wp
4629!
4630!--    Particle diffusion coefficient (m2/s) (continuum regime)
4631       zdc_c(:) = abo * ptemp * zcc_c    / ( 3.0_wp * pi * zmyy * zdcrit )
4632       zdc_x(:) = abo * ptemp * zcc_x    / ( 3.0_wp * pi * zmyy * reglim(1) )
4633       zdc_2(:) = abo * ptemp * zcc_2(:) / ( 3.0_wp * pi * zmyy * paero(:)%dwet )
4634!
4635!--    D12 = D1+D2 (Seinfield and Pandis, 2nd ed. Eq. 13.38)
4636       zdc_c2 = zdc_c + zdc_2
4637       zdc_x2 = zdc_x + zdc_2
4638!
4639!--    zgamma_f = 8*D/pi/zcv (m) for calculating zomega (Fuchs, 1964)
4640       zgamma_f_c = 8.0_wp * zdc_c / pi / zcv_c
4641       zgamma_f_x = 8.0_wp * zdc_x / pi / zcv_x
4642       zgamma_f_2 = 8.0_wp * zdc_2 / pi / zcv_2
4643!
4644!--    zomega (m) for calculating zsigma
4645       zomega_c = ( ( z_r_c2 + zgamma_f_c )**3 - ( z_r_c2 ** 2 + zgamma_f_c )**1.5_wp ) /          &
4646                  ( 3.0_wp * z_r_c2 * zgamma_f_c ) - z_r_c2
4647       zomega_x = ( ( z_r_x2 + zgamma_f_x )**3 - ( z_r_x2**2 + zgamma_f_x )** 1.5_wp ) /           &
4648                  ( 3.0_wp * z_r_x2 * zgamma_f_x ) - z_r_x2
4649       zomega_2c = ( ( z_r_c2 + zgamma_f_2 )**3 - ( z_r_c2**2 + zgamma_f_2 )**1.5_wp ) /           &
4650                   ( 3.0_wp * z_r_c2 * zgamma_f_2 ) - z_r_c2
4651       zomega_2x = ( ( z_r_x2 + zgamma_f_2 )**3 - ( z_r_x2**2 + zgamma_f_2 )**1.5_wp ) /           &
4652                   ( 3.0_wp * z_r_x2 * zgamma_f_2 ) - z_r_x2
4653!
4654!--    The distance (m) at which the two fluxes are matched (condensation and coagulation sinks)
4655       zsigma_c2 = SQRT( zomega_c**2 + zomega_2c**2 )
4656       zsigma_x2 = SQRT( zomega_x**2 + zomega_2x**2 )
4657!
4658!--    Coagulation coefficient in the continuum regime (m*m2/s, Eq. 17 in Kulmala et al., 2001)
4659       z_k_c2 = 4.0_wp * pi * z_r_c2 * zdc_c2 / ( z_r_c2 / ( z_r_c2 + zsigma_c2 ) +                &
4660               4.0_wp * zdc_c2 / ( zcv_c2 * z_r_c2 ) )
4661       z_k_x2 = 4.0_wp * pi * z_r_x2 * zdc_x2 / ( z_r_x2 / ( z_r_x2 + zsigma_x2 ) +                &
4662               4.0_wp * zdc_x2 / ( zcv_x2 * z_r_x2 ) )
4663!
4664!--    Coagulation sink (1/s, Eq. 16 in Kulmala et al., 2001)
4665       zcoags_c = MAX( 1.0E-20_wp, SUM( z_k_c2 * paero(:)%numc ) )
4666       zcoags_x = MAX( 1.0E-20_wp, SUM( z_k_x2 * paero(:)%numc ) )
4667!
4668!--    Parameter m for calculating the coagulation sink onto background particles (Eq. 5&6 in
4669!--    Lehtinen et al. 2007)
4670       zm_para = LOG( zcoags_x / zcoags_c ) / LOG( reglim(1) / zdcrit )
4671!
4672!--    Parameter gamma for calculating the formation rate J of particles having
4673!--    a diameter zdcrit < d < reglim(1) (Anttila et al. 2010, eq. 5 or Lehtinen et al.,2007, eq. 7)
4674       zgamma = ( ( ( reglim(1) / zdcrit )**( zm_para + 1.0_wp ) ) - 1.0_wp ) / ( zm_para + 1.0_wp )
4675
4676       IF ( nj3 == 2 )  THEN   ! Lehtinen et al. (2007): coagulation sink
4677!
4678!--       Formation rate J before iteration (#/m3s)
4679          zj3 = zjnuc * EXP( MIN( 0.0_wp, -zgamma * zdcrit * zcoags_c / ( z_gr_clust * 1.0E-9_wp / &
4680                60.0_wp**2 ) ) )
4681
4682       ELSEIF ( nj3 == 3 )  THEN  ! Anttila et al. (2010): coagulation sink and self-coag.
4683!
4684!--       If air is polluted, the self-coagulation becomes important. Self-coagulation of small
4685!--       particles < 3 nm.
4686!
4687!--       "Effective" coagulation coefficient between freshly-nucleated particles:
4688          z_k_eff = 5.0E-16_wp   ! m3/s
4689!
4690!--       zlambda parameter for "adjusting" the growth rate due to the self-coagulation
4691          zlambda = 6.0_wp
4692
4693          IF ( reglim(1) >= 10.0E-9_wp )  THEN   ! for particles >10 nm:
4694             z_k_eff   = 5.0E-17_wp
4695             zlambda = 3.0_wp
4696          ENDIF
4697!
4698!--       Initial values for coagulation sink and growth rate  (m/s)
4699          zcoagstot = zcoags_c
4700          z_gr_tot = z_gr_clust * 1.0E-9_wp / 60.0_wp**2
4701!
4702!--       Number of clusters/particles at the size range [d1,dx] (#/m3):
4703          z_n_nuc = zjnuc / zcoagstot !< Initial guess
4704!
4705!--       Coagulation sink and growth rate due to self-coagulation:
4706          DO  iteration = 1, 5
4707             zcoagstot = zcoags_c + z_k_eff * z_n_nuc * 1.0E-6_wp   ! (1/s, Anttila et al., eq. 1)
4708             z_gr_tot = z_gr_clust * 2.77777777E-7_wp +  1.5708E-6_wp * zlambda * zdcrit**3 *      &
4709                      ( z_n_nuc * 1.0E-6_wp ) * zcv_c * avo * 2.77777777E-7_wp ! (Eq. 3)
4710             zeta = - zcoagstot / ( ( zm_para + 1.0_wp ) * z_gr_tot * ( zdcrit**zm_para ) ) ! (Eq. 7b)
4711!
4712!--          Calculate Eq. 7a (Taylor series for the number of particles between [d1,dx])
4713             z_n_nuc =  z_n_nuc_tayl( zdcrit, reglim(1), zm_para, zjnuc, zeta, z_gr_tot )
4714          ENDDO
4715!
4716!--       Calculate the final values with new z_n_nuc:
4717          zcoagstot = zcoags_c + z_k_eff * z_n_nuc * 1.0E-6_wp   ! (1/s)
4718          z_gr_tot = z_gr_clust * 1.0E-9_wp / 3600.0_wp + 1.5708E-6_wp *  zlambda * zdcrit**3 *    &
4719                   ( z_n_nuc * 1.0E-6_wp ) * zcv_c * avo * 1.0E-9_wp / 3600.0_wp !< (m/s)
4720          zj3 = zjnuc * EXP( MIN( 0.0_wp, -zgamma * zdcrit * zcoagstot / z_gr_tot ) ) ! (#/m3s, Eq. 5a)
4721
4722       ENDIF
4723    ENDIF
4724!
4725!-- If J3 very small (< 1 #/cm3), neglect particle formation. In real atmosphere this would mean
4726!-- that clusters form but coagulate to pre-existing particles who gain sulphate. Since
4727!-- CoagS ~ CS (4piD*CS'), we do *not* update H2SO4 concentration here but let condensation take
4728!-- care of it. Formation mass rate of molecules (molec/m3s) for 1: H2SO4 and 2: organic vapour
4729    pj3n3(1) = zj3 * n3 * pxsa
4730    pj3n3(2) = zj3 * n3 * pxocnv
4731
4732 END SUBROUTINE nucleation
4733
4734!------------------------------------------------------------------------------!
4735! Description:
4736! ------------
4737!> Calculate the nucleation rate and the size of critical clusters assuming
4738!> binary nucleation.
4739!> Parametrisation according to Vehkamaki et al. (2002), J. Geophys. Res.,
4740!> 107(D22), 4622. Called from subroutine nucleation.
4741!------------------------------------------------------------------------------!
4742 SUBROUTINE binnucl( pc_sa, ptemp, prh, pnuc_rate, pn_crit_sa, pn_crit_ocnv, pd_crit, pk_sa,       &
4743                     pk_ocnv )
4744
4745    IMPLICIT NONE
4746
4747    REAL(wp) ::  za      !<
4748    REAL(wp