-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathgsolve.F90
101 lines (83 loc) · 4.43 KB
/
gsolve.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
! 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 gas concentrations.
!!
!! @author Andy Ackerman, Bill McKie, Chuck Bardeen
!! @version Dec-1995, Sep-1997, Nov-2009
subroutine gsolve(carma, cstate, iz, previous_ice, previous_liquid, scale_threshold, 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
real(kind=f), intent(in) :: previous_ice(NGAS) !! total ice at the start of substep
real(kind=f), intent(in) :: previous_liquid(NGAS) !! total liquid at the start of substep
real(kind=f) :: scale_threshold !! Scaling factor for convergence thresholds
integer, intent(inout) :: rc !! return code, negative indicates failure
! Local Variables
integer :: igas !! gas index
real(kind=f) :: gc_cgs
real(kind=f) :: rvap
real(kind=f) :: total_ice(NGAS) ! total ice
real(kind=f) :: total_liquid(NGAS) ! total liquid
real(kind=f) :: threshold ! convergence threshold
1 format(/,'gsolve::ERROR - negative gas concentration for ',a,' : iz=',i4,',xc=', &
f7.2,',yc=',f7.2,',gc=',e10.3,',gasprod=',e10.3,',supsati=',e10.3, &
',supsatl=',e10.3,',t=',f6.2)
2 format('gsolve::ERROR - conditions at beginning of the step : gc=',e10.3,',supsati=',e17.10, &
',supsatl=',e17.10,',t=',f6.2,',d_gc=',e10.3,',d_t=',f6.2)
3 format(/,'microfast::WARNING - gas concentration change exceeds threshold: ',a,' : iz=',i4,',xc=', &
f7.2,',yc=',f7.2, ', (gc-gcl)/gcl=', e10.3)
! Determine the total amount of condensate for each gas.
call totalcondensate(carma, cstate, iz, total_ice, total_liquid, rc)
do igas = 1,NGAS
! We do not seem to be conserving mass and energy, so rather than relying upon gasprod
! and rlheat, recalculate the total change in condensate to determine the change
! in gas and energy.
!
! This is because in the old scheme, the particles were solved for implicitly, but the
! gas and latent heat were solved for explicitly using the same rates.
gasprod(igas) = ((previous_ice(igas) - total_ice(igas)) + (previous_liquid(igas) - total_liquid(igas))) / dtime
rlprod = rlprod - ((previous_ice(igas) - total_ice(igas)) * (rlhe(iz,igas) + rlhm(iz,igas)) + &
(previous_liquid(igas) - total_liquid(igas)) * (rlhe(iz,igas))) / (CP * rhoa(iz) * dtime)
! Don't let the gas concentration go negative.
gc(iz,igas) = gc(iz,igas) + dtime * gasprod(igas)
if (gc(iz,igas) < 0.0_f) then
if (do_substep) then
if (nretries == maxretries) then
if (do_print) write(LUNOPRT,1) trim(gasname(igas)), iz, xc, yc, gc(iz,igas), gasprod(igas), &
supsati(iz,igas), supsatl(iz,igas), t(iz)
if (do_print) write(LUNOPRT,2) gcl(iz,igas), supsatiold(iz,igas), supsatlold(iz,igas), told(iz), d_gc(iz,igas), d_t(iz)
end if
else
if (do_print) write(LUNOPRT,1) trim(gasname(igas)), iz, xc, yc, gc(iz,igas), gasprod(igas), &
supsati(iz, igas), supsatl(iz,igas), t(iz)
end if
rc = RC_WARNING_RETRY
end if
! If gas changes by too much, then retry the calculation.
threshold = dgc_threshold(igas) / scale_threshold
if (threshold /= 0._f) then
if ((dtime * gasprod(igas) / gc(iz,igas)) > threshold) then
if (do_substep) then
if (nretries == maxretries) then
if (do_print) write(LUNOPRT,3) trim(gasname(igas)), iz, xc, yc, dtime * gasprod(igas) / gc(iz,igas)
if (do_print) write(LUNOPRT,2) gcl(iz,igas), supsatiold(iz,igas), supsatlold(iz,igas), told(iz), d_gc(iz,igas), d_t(iz)
end if
else
if (do_print) write(LUNOPRT,3) trim(gasname(igas)), iz, xc, yc, dtime * gasprod(igas) / gc(iz,igas)
end if
rc = RC_WARNING_RETRY
end if
end if
end do
! Return to caller with new gas concentrations.
return
end