-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpsolve.F90
85 lines (69 loc) · 3.29 KB
/
psolve.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
! Include shortname defintions, so that the F77 code does not have to be modified to
! reference the CARMA structure.
#include "carma_globaer.h"
!! This routine calculates new particle concentrations.
!!
!! The basic form from which the solution is derived is
!! ( new_value - old_value ) / dtime = source_term - loss_rate*new_value
!!
!! Modified Sep-1997 (McKie)
!! New particle concentrations due to coagulation processes
!! were moved to the csolve routine. Csolve is called to
!! update particle concentrations due to coagulation.
!! This new psolve now updates particle concentrations due
!! to the faster calcs of the non-coag microphysical processes.
!!
!! @author Eric Jensen, Bill McKie
!! @version Oct-1995, Sep-1997
subroutine psolve(carma, cstate, iz, ibin, ielem, rc)
! types
use carma_precision_mod
use carma_enums_mod
use carma_constants_mod
use carma_types_mod
use carmastate_mod
use carma_mod
implicit none
type(carma_type), intent(in) :: carma !! the carma object
type(carmastate_type), intent(inout) :: cstate !! the carma state object
integer, intent(in) :: iz !! z index
integer, intent(in) :: ibin !! bin index
integer, intent(in) :: ielem !! element index
integer, intent(inout) :: rc !! return code, negative indicates failure
! Local declarations
integer :: igroup ! group index
integer :: iepart
integer :: igto
integer :: iz_no_sed
real(kind=f) :: ppd ! particle prodocution rate
real(kind=f) :: pc_nonuc ! particles - no nucleation
real(kind=f) :: pls ! particle loss rate
real(kind=f) :: sed_rate
real(kind=f) :: rnuclgtot
real(kind=f) :: dsed
! Define current group & particle number concentration element indices
igroup = igelem(ielem)
iepart = ienconc(igroup)
if(do_grow) then
! Compute total production rate
ppd = rnucpe(ibin,ielem) + rhompe(ibin,ielem) + growpe(ibin,ielem) + evappe(ibin,ielem)
! Sum up nucleation loss rates
rnuclgtot = sum(rnuclg(ibin,igroup,:))
! Compute total loss rate
pls = rnuclgtot + growlg(ibin,igroup) + evaplg(ibin,igroup)
! Figure out the new particle concentration without nucleation.
pc_nonuc = (pc(iz,ibin,ielem) + dtime * (ppd - rnucpe(ibin,ielem) - rhompe(ibin,ielem))) / (ONE + (pls - rnuclgtot) * dtime)
! Update net particle number concentration during current timestep
! due to production and loss rates.
pc(iz,ibin,ielem) = (pc(iz,ibin,ielem) + dtime * ppd) / (ONE + pls * dtime)
! Now determine the number of particles produced by nucleation as the difference
! between the actual particle count and that done without nucleation rates.
!
! NOTE: This is for statistics and is done as a total for the step, not per substep.
pc_nucl(iz,ibin,ielem) = pc_nucl(iz,ibin,ielem) + (pc(iz,ibin,ielem) - pc_nonuc)
end if
! Prevent particle concentrations from dropping below SMALL_PC
call smallconc(carma, cstate, iz, ibin, ielem, rc)
! Return to caller with new particle number concentrations.
return
end