1 | module thermalmodelparam_mars |
---|
2 | ! parameters for thermal model |
---|
3 | ! they are only used in the subroutines below |
---|
4 | real(8), parameter :: dt = 0.02 ! in units of Mars solar days |
---|
5 | !real(8), parameter :: Fgeotherm = 0. |
---|
6 | real(8), parameter :: Fgeotherm = 0 !0.028 ! [W/m^2] |
---|
7 | real(8), parameter :: Lco2frost=6.0e5, co2albedo=0.60, co2emiss=1. |
---|
8 | real(8), parameter :: emiss0 = 1. ! emissivity of dry surface |
---|
9 | integer, parameter :: EQUILTIME =15 ! [Mars years] |
---|
10 | end module thermalmodelparam_mars |
---|
11 | |
---|
12 | |
---|
13 | !***************************************************** |
---|
14 | ! Subroutines for fast method |
---|
15 | ! written by Norbert Schorghofer 2007-2011 |
---|
16 | !***************************************************** |
---|
17 | |
---|
18 | |
---|
19 | subroutine icelayer_mars(bigstep,nz,NP,thIn,rhoc,z,porosity,pfrost, & |
---|
20 | & Tb,zdepthF,zdepthE,porefill,Tmean1,Tmean3,zdepthG, & |
---|
21 | & albedo,p0,icefrac,zdepthT,avrho1, & |
---|
22 | & avrho1prescribed) |
---|
23 | !************************************************************************* |
---|
24 | ! bigstep = time step [Earth years] |
---|
25 | ! latitude [degree] |
---|
26 | !************************************************************************* |
---|
27 | use miscparameters, only : d2r, NMAX, icedensity |
---|
28 | use allinterfaces, except_this_one => icelayer_mars |
---|
29 | !use omp_lib |
---|
30 | implicit none |
---|
31 | integer, intent(IN) :: nz, NP |
---|
32 | real(8), intent(IN) :: bigstep |
---|
33 | real(8), intent(IN) :: thIn(NP), rhoc(NP), z(NMAX), porosity, pfrost(NP) |
---|
34 | real(8), intent(INOUT) :: porefill(nz,NP), zdepthF(NP), zdepthT(NP) |
---|
35 | real(8), intent(INOUT) :: Tb(nz) |
---|
36 | real(8), intent(OUT), dimension(NP) :: zdepthE, Tmean1, Tmean3, zdepthG |
---|
37 | real(8), intent(IN), dimension(NP) :: albedo, p0 |
---|
38 | real(8), intent(IN) :: icefrac |
---|
39 | real(8), intent(OUT) :: avrho1(NP) |
---|
40 | real(8), intent(IN), optional :: avrho1prescribed(NP) ! <0 means absent |
---|
41 | |
---|
42 | integer k, typeF, typeG, typeT, j, jump, typeP |
---|
43 | real(8) fracIR, fracDust, ti(NMAX), rhocv(NMAX) |
---|
44 | real(8) Diff, ypp(nz), avdrho(NP), avdrhoP(NP), B, deltaz |
---|
45 | real(8), SAVE :: avdrho_old(100), zdepth_old(100) ! NP<=100 |
---|
46 | logical mode2 |
---|
47 | |
---|
48 | !$omp parallel & |
---|
49 | !$omp private(Diff,fracIR,fracDust,B,typeT,j,ti,rhocv,typeF,jump,typeG) |
---|
50 | !$omp do |
---|
51 | do k=1,NP ! big loop |
---|
52 | |
---|
53 | Diff = 4e-4*600./p0(k) |
---|
54 | fracIR = 0.04*p0(k)/600.; fracDust = 0.02*p0(k)/600. |
---|
55 | B = Diff*bigstep*86400.*365.24/(porosity*icedensity) |
---|
56 | |
---|
57 | typeT = -9 |
---|
58 | if (zdepthT(k)>=0. .and. zdepthT(k)<z(nz)) then |
---|
59 | do j=1,nz |
---|
60 | if (z(j)>zdepthT(k)) then ! ice |
---|
61 | typeT = j ! first point in ice |
---|
62 | exit |
---|
63 | endif |
---|
64 | enddo |
---|
65 | endif |
---|
66 | |
---|
67 | ! call assignthermalproperties(nz,thIn(k),rhoc(k),ti,rhocv, & |
---|
68 | ! & typeT,icefrac,porosity,porefill(:,k)) |
---|
69 | |
---|
70 | !----run thermal model |
---|
71 | call ajsub_mars(typeT, albedo(k), pfrost(k), nz, z, & |
---|
72 | & ti, rhocv, fracIR, fracDust, p0(k), & |
---|
73 | & avdrho(k), avdrhoP(k), avrho1(k), Tb(k), zdepthE(k), typeF, & |
---|
74 | & zdepthF(k), ypp, porefill(:,k), Tmean1(k), Tmean3(k), B, & |
---|
75 | & typeG, zdepthG(k), avrho1prescribed(k)) |
---|
76 | |
---|
77 | if (typeF*zdepthF(k)<0.) stop 'error in icelayer_mars' |
---|
78 | ! diagnose |
---|
79 | if (zdepthT(k)>=0.) then |
---|
80 | jump = 0 |
---|
81 | do j=1,nz |
---|
82 | if (zdepth_old(k)<z(j) .and. zdepthT(k)>z(j)) jump = jump+1 |
---|
83 | enddo |
---|
84 | else |
---|
85 | jump = -9 |
---|
86 | endif |
---|
87 | if (zdepthT(k)>=0. .and. avdrho(k)*avdrho_old(k)<0.) then |
---|
88 | write(34,*) '# zdepth arrested' |
---|
89 | if (jump>1) write(34,*) '# previous step was too large',jump |
---|
90 | endif |
---|
91 | ! write(34,'(f8.3,1x,f6.2,1x,f11.5,2(1x,g11.4),1x,i3)') & |
---|
92 | ! & bigstep,latitude(k),zdepthT(k),avdrho(k),avdrhoP(k),jump |
---|
93 | zdepth_old(k) = zdepthT(k) |
---|
94 | avdrho_old(k) = avdrho(k) |
---|
95 | |
---|
96 | !----mode 2 growth |
---|
97 | typeP = -9; mode2 = .FALSE. |
---|
98 | do j=1,nz |
---|
99 | if (porefill(j,k)>0.) then |
---|
100 | typeP = j ! first point with ice |
---|
101 | exit |
---|
102 | endif |
---|
103 | enddo |
---|
104 | if (typeT>0 .and. typeP>2 .and. zdepthE(k)>0.) then |
---|
105 | if (porefill(typeP,k)>=1. .and. porefill(typeP-1,k)==0. .and. & |
---|
106 | & zdepthE(k)<z(typeP) .and. & |
---|
107 | & z(typeP)-zdepthE(k)>2*(z(typeP)-z(typeP-1))) then ! trick that avoids oscillations |
---|
108 | deltaz = -avdrhoP(k)/z(typeP)*18./8314.*B ! conservation of mass |
---|
109 | if (deltaz>z(typeP)-z(typeP-1)) then ! also implies avdrhoP<0. |
---|
110 | mode2 = .TRUE. |
---|
111 | endif |
---|
112 | endif |
---|
113 | endif |
---|
114 | |
---|
115 | !call icechanges_poreonly(nz,z,typeF,typeG,avdrhoP(k),ypp,B,porefill(:,k)) |
---|
116 | call icechanges(nz,z(:),typeF,avdrho(k),avdrhoP(k),ypp(:), & |
---|
117 | & Diff,porosity,icefrac,bigstep,zdepthT(k),porefill(:,k),typeG) |
---|
118 | |
---|
119 | if (mode2 .and. porefill(typeP,k)>=1. .and. porefill(typeP-1,k)==0.) then ! nothing changed |
---|
120 | porefill(typeP-1,k)=1. ! paste a layer |
---|
121 | ! write(34,*) '# mode 2 growth occurred',typeP,typeF,typeT |
---|
122 | endif |
---|
123 | |
---|
124 | enddo ! end of big loop |
---|
125 | !$omp end do |
---|
126 | !$omp end parallel |
---|
127 | end subroutine icelayer_mars |
---|
128 | |
---|
129 | |
---|
130 | |
---|
131 | subroutine ajsub_mars(typeT, albedo0, pfrost, nz, z, ti, rhocv, & |
---|
132 | & fracIR, fracDust, patm, avdrho, avdrhoP, avrho1, & |
---|
133 | & Tb, zdepthE, typeF, zdepthF, ypp, porefill, Tmean1, Tmean3, & |
---|
134 | & B, typeG, zdepthG, avrho1prescribed) |
---|
135 | !*********************************************************************** |
---|
136 | ! A 1D thermal model that returns various averaged quantities |
---|
137 | ! |
---|
138 | ! Tb<0 initializes temperatures |
---|
139 | ! Tb>0 initializes temperatures with Tb |
---|
140 | !*********************************************************************** |
---|
141 | use miscparameters |
---|
142 | use thermalmodelparam_mars |
---|
143 | use allinterfaces, except_this_one => ajsub_mars |
---|
144 | implicit none |
---|
145 | integer, intent(IN) :: nz, typeT |
---|
146 | ! real(8), intent(IN) :: latitude ! in radians |
---|
147 | real(8), intent(IN) :: albedo0, pfrost, z(NMAX) |
---|
148 | real(8), intent(IN) :: ti(NMAX), rhocv(NMAX), fracIR, fracDust, patm |
---|
149 | real(8), intent(IN) :: porefill(nz) |
---|
150 | real(8), intent(OUT) :: avdrho, avdrhoP ! difference in annual mean vapor density |
---|
151 | real(8), intent(OUT) :: avrho1 ! mean vapor density on surface |
---|
152 | real(8), intent(INOUT) :: Tmean1 |
---|
153 | real(8), intent(INOUT) :: Tb(nz) |
---|
154 | integer, intent(OUT) :: typeF ! index of depth below which filling occurs |
---|
155 | real(8), intent(OUT) :: zdepthE, zdepthF |
---|
156 | real(8), intent(OUT) :: ypp(nz) ! (d rho/dt)/Diff |
---|
157 | real(8), intent(OUT) :: Tmean3, zdepthG |
---|
158 | real(8), intent(IN) :: B ! just passing through |
---|
159 | integer, intent(OUT) :: typeG |
---|
160 | real(8), intent(IN), optional :: avrho1prescribed |
---|
161 | real(8), parameter :: a = 1.52366 ! Mars semimajor axis in A.U. |
---|
162 | integer nsteps, n, i, nm, typeP |
---|
163 | real(8) tmax, time, Qn, Qnp1, tdays |
---|
164 | real(8) marsR, marsLs, marsDec, HA |
---|
165 | real(8) Tsurf, Tco2frost, albedo, Fsurf, m, dE, emiss, T(NMAX) |
---|
166 | real(8) Told(nz), Fsurfold, Tsurfold, Tmean0, avrho2 |
---|
167 | real(8) rhosatav0, rhosatav(nz), rlow |
---|
168 | real(8), external :: psv, tfrostco2 |
---|
169 | |
---|
170 | tmax = EQUILTIME*solsperyear |
---|
171 | nsteps = int(tmax/dt) ! calculate total number of timesteps |
---|
172 | |
---|
173 | Tco2frost = tfrostco2(patm) |
---|
174 | |
---|
175 | !if (Tb<=0.) then ! initialize |
---|
176 | !Tmean0 = 210.15 ! black-body temperature of planet |
---|
177 | !Tmean0 = (589.*(1.-albedo0)*cos(latitude)/(pi*emiss0*sigSB))**0.25 ! better estimate |
---|
178 | !Tmean0 = Tmean0-5. |
---|
179 | !write(34,*) '# initialized with temperature estimate at',latitude/d2r,'of',Tmean0,'K' |
---|
180 | !T(1:nz) = Tmean0 |
---|
181 | !else |
---|
182 | T(1:nz) = Tb |
---|
183 | ! not so good when Fgeotherm is on |
---|
184 | !endif |
---|
185 | |
---|
186 | albedo = albedo0 |
---|
187 | emiss = emiss0 |
---|
188 | do i=1,nz |
---|
189 | if (T(i)<Tco2frost) T(i)=Tco2frost |
---|
190 | enddo |
---|
191 | Tsurf = T(1) |
---|
192 | m=0.; Fsurf=0. |
---|
193 | |
---|
194 | nm=0 |
---|
195 | avrho1=0.; avrho2=0. |
---|
196 | Tmean1=0.; Tmean3=0. |
---|
197 | rhosatav0 = 0. |
---|
198 | rhosatav(:) = 0. |
---|
199 | |
---|
200 | time=0. |
---|
201 | !call generalorbit(0.d0,a,ecc,omega,eps,marsLs,marsDec,marsR) |
---|
202 | !HA = 2.*pi*time ! hour angle |
---|
203 | ! Qn=flux(marsR,marsDec,latitude,HA,albedo,fracir,fracdust,0.d0,0.d0) |
---|
204 | !Qn = flux_mars77(marsR,marsDec,latitude,HA,albedo,fracir,fracdust) |
---|
205 | !----loop over time steps |
---|
206 | do n=0,nsteps-1 |
---|
207 | time = (n+1)*dt ! time at n+1 |
---|
208 | tdays = time*(marsDay/earthDay) ! parenthesis may improve roundoff |
---|
209 | ! call generalorbit(tdays,a,ecc,omega,eps,marsLs,marsDec,marsR) |
---|
210 | ! HA = 2.*pi*mod(time,1.d0) ! hour angle |
---|
211 | ! Qnp1=flux(marsR,marsDec,latitude,HA,albedo,fracir,fracdust,0.d0,0.d0) |
---|
212 | !Qnp1 = flux_mars77(marsR,marsDec,latitude,HA,albedo,fracir,fracdust) |
---|
213 | |
---|
214 | Tsurfold = Tsurf |
---|
215 | Fsurfold = Fsurf |
---|
216 | Told(1:nz) = T(1:nz) |
---|
217 | if (m<=0. .or. Tsurf>Tco2frost) then |
---|
218 | ! call conductionQ(nz,z,dt*marsDay,Qn,Qnp1,T,ti,rhocv,emiss, & |
---|
219 | ! & Tsurf,Fgeotherm,Fsurf) |
---|
220 | endif |
---|
221 | if (Tsurf<Tco2frost .or. m>0.) then ! CO2 condensation |
---|
222 | T(1:nz) = Told(1:nz) |
---|
223 | !call conductionT(nz,z,dt*marsDay,T,Tsurfold,Tco2frost,ti, & |
---|
224 | !& rhocv,Fgeotherm,Fsurf) |
---|
225 | Tsurf = Tco2frost |
---|
226 | ! dE = (- Qn - Qnp1 + Fsurfold + Fsurf + & |
---|
227 | ! & emiss*sigSB*(Tsurfold**4+Tsurf**4)/2. |
---|
228 | m = m + dt*marsDay*dE/Lco2frost |
---|
229 | endif |
---|
230 | if (Tsurf>Tco2frost .or. m<=0.) then |
---|
231 | albedo = albedo0 |
---|
232 | emiss = emiss0 |
---|
233 | else |
---|
234 | albedo = co2albedo |
---|
235 | emiss = co2emiss |
---|
236 | endif |
---|
237 | !Qn=Qnp1 |
---|
238 | |
---|
239 | if (time>=tmax-solsperyear) then |
---|
240 | Tmean1 = Tmean1 + Tsurf |
---|
241 | Tmean3 = Tmean3 + T(nz) |
---|
242 | avrho1 = avrho1 + min(psv(Tsurf),pfrost)/Tsurf |
---|
243 | rhosatav0 = rhosatav0 + psv(Tsurf)/Tsurf |
---|
244 | do i=1,nz |
---|
245 | rhosatav(i) = rhosatav(i) + psv(T(i))/T(i) |
---|
246 | enddo |
---|
247 | nm = nm+1 |
---|
248 | endif |
---|
249 | |
---|
250 | enddo ! end of time loop |
---|
251 | |
---|
252 | avrho1 = avrho1/nm |
---|
253 | if (present(avrho1prescribed)) then |
---|
254 | if (avrho1prescribed>=0.) avrho1=avrho1prescribed |
---|
255 | endif |
---|
256 | Tmean1 = Tmean1/nm; Tmean3 = Tmean3/nm |
---|
257 | rhosatav0 = rhosatav0/nm; rhosatav(:)=rhosatav(:)/nm |
---|
258 | if (typeT>0) then |
---|
259 | avrho2 = rhosatav(typeT) |
---|
260 | else |
---|
261 | avrho2 = rhosatav(nz) ! no ice |
---|
262 | endif |
---|
263 | avdrho = avrho2-avrho1 |
---|
264 | typeP = -9 |
---|
265 | do i=1,nz |
---|
266 | if (porefill(i)>0.) then |
---|
267 | typeP = i ! first point with ice |
---|
268 | exit |
---|
269 | endif |
---|
270 | enddo |
---|
271 | if (typeP>0) then |
---|
272 | avdrhoP = rhosatav(typeP) - avrho1 |
---|
273 | else |
---|
274 | avdrhoP = -9999. |
---|
275 | end if |
---|
276 | |
---|
277 | zdepthE = equildepth(nz, z, rhosatav, rhosatav0, avrho1) |
---|
278 | |
---|
279 | if (Fgeotherm>0.) then |
---|
280 | Tb = Tmean1 |
---|
281 | typeG = 1 ! will be overwritten by depths_avmeth |
---|
282 | rlow = 2*rhosatav(nz)-rhosatav(nz-1) |
---|
283 | else |
---|
284 | Tb = T(nz) |
---|
285 | typeG = -9 |
---|
286 | rlow = rhosatav(nz-1) |
---|
287 | endif |
---|
288 | call depths_avmeth(typeT, nz, z, rhosatav(:), rhosatav0, rlow, avrho1, & |
---|
289 | & porefill(:), typeF, zdepthF, B, ypp(:), typeG, zdepthG) |
---|
290 | |
---|
291 | end subroutine ajsub_mars |
---|
292 | |
---|
293 | |
---|
294 | |
---|
295 | subroutine outputmoduleparameters |
---|
296 | use miscparameters |
---|
297 | use thermalmodelparam_mars |
---|
298 | implicit none |
---|
299 | ! print *,'Parameters stored in modules' |
---|
300 | ! print *,' Ice bulk density',icedensity,'kg/m^3' |
---|
301 | ! print *,' dt=',dt,'Mars solar days' |
---|
302 | ! print *,' Fgeotherm=',Fgeotherm,'W/m^2' |
---|
303 | ! write(6,'(2x,a27,1x,f5.3)') 'Emissivity of dry surface=',emiss0 |
---|
304 | ! write(6,'(2x,a12,1x,f5.3,2x,a16,1x,f5.3)') 'CO2 albedo=',co2albedo,'CO2 emissivity=',co2emiss |
---|
305 | ! print *,' Thermal model equilibration time',EQUILTIME,'Mars years' |
---|
306 | end subroutine outputmoduleparameters |
---|
307 | |
---|
308 | |
---|
309 | |
---|