ROMS
Loading...
Searching...
No Matches
ice_albedo.F
Go to the documentation of this file.
1#include "cppdefs.h"
3
4#if defined ICE_MODEL && defined ICE_ALBEDO
5!
6!git $Id$
7!================================================== Hernan G. Arango ===
8! Copyright (c) 2002-2025 The ROMS Group !
9! Licensed under a MIT/X style license !
10! See License_ROMS.md !
11!=======================================================================
12! !
13! This module computes the surface albedo over seawater, snow, or ice !
14! using selected formulation. !
15! !
16! References: !
17! !
18! Briegleb, B.P., P. Minnis, V. Ramanathan, and E. Harrison, !
19! 1986: Comparison of Regional Clear-Sky Albedos Inferred !
20! from Satellite Observations and Model Computations, J. !
21! Climate and Appled Meteor., 25, 214-226. !
22! !
23! Ebert, E.E. and J.A. Curry, 1992: A parameterization of ice !
24! cloud optical properties for climate models, J. Geophys. !
25! Res., 97, 3831-3836, doi: doi.org/10.1029/91jD02472. !
26! !
27!=======================================================================
28!
29 USE mod_param
30 USE mod_forces
31 USE mod_grid
32 USE mod_ice
33 USE mod_scalars
34!
35 USE dateclock_mod, ONLY : caldate
37# ifdef DISTRIBUTE
39# endif
40!
41 implicit none
42!
43 PUBLIC :: ice_albedo
44 PRIVATE
45!
46 CONTAINS
47!
48!***********************************************************************
49 SUBROUTINE ice_albedo (ng, tile, model)
50!***********************************************************************
51!
52 USE mod_stepping
53!
54! Imported variable declarations.
55!
56 integer, intent(in) :: ng, tile, model
57!
58! Local variable declarations.
59!
60 character (len=*), parameter :: MyFile = &
61 & __FILE__
62!
63# include "tile.h"
64!
65# ifdef PROFILE
66 CALL wclock_on (ng, model, 42, __line__, myfile)
67# endif
68 CALL ice_albedo_tile (ng, tile, model, &
69 & lbi, ubi, lbj, ubj, &
70 & imins, imaxs, jmins, jmaxs, &
71 & liold(ng), linew(ng), &
72# if defined SHORTWAVE && (defined ALBEDO_CURVE || defined ALBEDO_SZO)
73 & grid(ng) % lonr, &
74 & grid(ng) % latr, &
75# endif
76 & ice(ng) % Fi, &
77 & ice(ng) % Si, &
78 & forces(ng) % albedo_ice, &
79 & forces(ng) % albedo)
80# ifdef PROFILE
81 CALL wclock_off (ng, model, 42, __line__, myfile)
82# endif
83!
84 RETURN
85 END SUBROUTINE ice_albedo
86!
87!***********************************************************************
88 SUBROUTINE ice_albedo_tile (ng, tile, model, &
89 & LBi, UBi, LBj, UBj, &
90 & IminS, ImaxS, JminS, JmaxS, &
91 & liold, linew, &
92# if defined SHORTWAVE && (defined ALBEDO_CURVE || defined ALBEDO_SZO)
93 & lonr, latr, &
94# endif
95 & fi, si, &
96 & albedo_ice, albedo)
97!***********************************************************************
98!
99! Imported variable declarations.
100!
101 integer, intent(in) :: ng, tile, model
102 integer, intent(in) :: LBi, UBi, LBj, UBj
103 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
104 integer, intent(in) :: liold, linew
105!
106# ifdef ASSUMED_SHAPE
107# if defined SHORTWAVE && (defined ALBEDO_CURVE || defined ALBEDO_SZO)
108 real(r8), intent(in) :: lonr(LBi:,LBj:)
109 real(r8), intent(in) :: latr(LBi:,LBj:)
110# endif
111 real(r8), intent(in) :: Fi(LBi:,LBj:,:)
112 real(r8), intent(in) :: Si(LBi:,LBj:,:,:)
113 real(r8), intent(out) :: albedo_ice(LBi:,LBj:)
114 real(r8), intent(out) :: albedo(LBi:,LBj:)
115
116# else
117
118# if defined SHORTWAVE && (defined ALBEDO_CURVE || defined ALBEDO_SZO)
119 real(r8), intent(in) :: lonr(LBi:UBi,LBj:UBj)
120 real(r8), intent(in) :: latr(LBi:UBi,LBj:UBj)
121# endif
122 real(r8), intent(in) :: Fi(LBi:UBi,LBj:UBj,nIceF)
123 real(r8), intent(in) :: Si(LBi:UBi,LBj:UBj,2,nIceS)
124 real(r8), intent(out) :: albedo_ice(LBi:UBi,LBj:UBj)
125 real(r8), intent(out) :: albedo(LBi:UBi,LBj:UBj)
126# endif
127!
128! Local variable declarations.
129!
130 integer :: i, j, li_stp
131# if defined ALBEDO_SZO
132 integer :: iday, month, year
133# endif
134!
135 real(r8), parameter :: alb_w = 0.06_r8
136
137# ifdef ALBEDO_CSIM
138 real(r8), parameter :: alb_i_thick = 0.54_r8
139 real(r8), parameter :: alb_s_dry = 0.83_r8
140 real(r8), parameter :: alb_s_wet = 0.70_r8
141# else
142 real(r8), parameter :: alb_i_dry = 0.65_r8
143 real(r8), parameter :: alb_i_wet = 0.60_r8
144 real(r8), parameter :: alb_s_dry = 0.85_r8
145 real(r8), parameter :: alb_s_wet = 0.72_r8
146# endif
147
148# ifdef ICE_ALB_EC92
149 real(r8) :: alb_ice, alb_snow, Hice, Hsnow
150# endif
151# if defined ALBEDO_SZO
152 real(r8) :: Dangle, Hangle, LatRad, zenith
153 real(dp) :: hour, yday
154# endif
155 real(r8) :: cff, cff1, cff2, sfc_temp
156!
157 real(r8), dimension(IminS:ImaxS,JminS:JmaxS) :: ice_thick
158 real(r8), dimension(IminS:ImaxS,JminS:JmaxS) :: snow_thick
159
160# include "set_bounds.h"
161!
162!=======================================================================
163! Compute the surface albedo over seawater, snow or ice
164!=======================================================================
165!
166! Set ice model time level.
167!
168 IF (perfectrst(ng).and.(iic(ng).eq.ntstart(ng))) THEN
169 li_stp=liold
170 ELSE
171 li_stp=linew
172 END IF
173
174# if defined ALBEDO_SZO
175!
176! Calculate the solar zenith angle and approximate the ocean albedo
177! using Briegleb et al. (1986) empirical formulation.
178!
179 CALL caldate (tdays(ng), h_dp=hour, yd_dp=yday)
180!
181! Estimate solar declination angle (radians).
182!
183 dangle=23.44_r8*cos((172.0_r8-yday)*2.0_r8*pi/365.25_r8)
184 dangle=dangle*deg2rad
185!
186! Compute hour angle (radians).
187!
188 hangle=(12.0_r8-hour)*pi/12.0_r8
189# endif
190!
191!-----------------------------------------------------------------------
192! Compute surface albedo.
193!-----------------------------------------------------------------------
194!
195 DO j=jstrt,jendt
196 DO i=istrt,iendt
197!
198! Compute the ice/snow albedo
199!
200 cff=1.0_r8/(si(i,j,li_stp,isaice)+0.001_r8)
201 ice_thick(i,j)=cff*si(i,j,li_stp,ishice)
202 snow_thick(i,j)=cff*si(i,j,li_stp,ishsno)
203 sfc_temp=fi(i,j,icisst)
204
205# ifdef ICE_ALB_EC92
206!
207! Ice and snow albedo is calculated from Ebert and Curry (1992).
208!
209 alb_ice=0.0_r8
210 alb_snow=0.0_r8
211
212 IF (si(i,j,li_stp,isaice).gt.min_ai(ng)) THEN
213 hice =ice_thick(i,j)
214 hsnow=snow_thick(i,j)
215!
216! The threshold test can still lead to a negative albedo, so we modify
217! the minimum ice thickness for this estimate to something more
218! reasonable (SMD).
219!
220 hice=max(hice, 0.01_r8)
221 IF (hice.ge.2.0_r8) THEN
222 alb_ice=0.561632_r8
223 ELSE IF (hice.ge.1.0_r8) THEN
224 alb_ice=0.07616_r8*hice+0.414492_r8
225 ELSE
226 alb_ice=0.082409_r8*log(hice)+0.485472_r8
227 END IF
228!
229! Approximated values for alb_snow depends on COSZ, but small
230! variation.
231!
232 IF (si(i,j,li_stp,ishmel).gt.0.0_r8) THEN
233 IF (hsnow.ge.0.1_r8) THEN
234 alb_snow=0.701009_r8
235 ELSE
236 alb_snow=alb_ice+(0.701009_r8-alb_ice)*hsnow/0.1_r8
237 END IF
238 ELSE
239 alb_snow=0.83_r8
240 END IF
241!
242! Ebert and Curry estimate the melt pond albedo to be between 0.14 and
243! 0.26, depending on the thickness of the meltwater ponds. But of
244! course, the meltwater ponds do not cover all the ice surface, except
245! maybe effectively when the ice consists of small pieces with little
246! freeboard. So let's try the idea that the effective albedo of the
247! ice/melt pond/snow is that of ice for bare ice, that of snow
248! (potentially modified by meltwater if snow is present), and the
249! average of the high-end melt pond (0.26) and the low-end ice bare
250! ice (0.56) when melt ponds of more than a few centimeters deep are
251! present (SMD).
252!
253 IF (si(i,j,li_stp,ishsno).gt.0.0_r8) THEN
254 albedo_ice(i,j)=alb_snow
255 ELSE IF (si(i,j,li_stp,ishmel).gt.0.02_r8) THEN
256 albedo_ice(i,j)=0.42_r8
257 ELSE
258 albedo_ice(i,j)=alb_ice
259 END IF
260 ELSE
261 albedo_ice(i,j)=alb_w ! water albedo
262 ENDIF
263
264# elif defined ALBEDO_CSIM
265!
266! Community Sea Ice Model (CSIM) formulation.
267!
268 fhi=min(atan(4.0_r8*ice_thick(i,j))/atan(2.0_r8), 1.0_r8)
269 fsn=snow_thick(i,j)/(snow_thick(i,j)+0.02_r8)
270 alb_i_dry=alb_w*(1-fh)+alb_i_thick*fh
271 cff1=alb_s_wet-alb_s_dry
272 cff2=-0.075 ! alb_i_wet - alb_i_dry
273 IF (si(i,j,li_stp,isaice).gt.min_ai(ng)) THEN
274 IF (sfc_temp-273.16_r8.gt. -1.0_r8) THEN
275 alb_snow=cff1*(sfc_temp-272.16_r8)+alb_s_dry
276 ELSE
277 alb_snow=alb_s_dry
278 ENDIF
279 IF (sfc_temp-273.16_r8.gt. -1._r8) THEN
280 alb_ice=cff2*(sfc_temp-272.16_r8)+alb_i_dry
281 ELSE
282 alb_ice=alb_i_dry
283 END IF
284 albedo_ice(i,j)=fsn*alb_snow+(1-fsn)*alb_ice
285 ELSE
286 albedo_ice(i,j)=alb_w ! water albedo
287 END IF
288# else
289!
290! Default formulation.
291!
292 cff1=alb_s_wet-alb_s_dry
293 cff2=alb_i_wet-alb_i_dry
294 IF (si(i,j,li_stp,isaice).gt.min_ai(ng)) THEN
295 IF (si(i,j,li_stp,ishsno).gt.0.0_r8) THEN
296 IF ((sfc_temp-273.16_r8).gt.-1.0_r8) THEN
297 albedo_ice(i,j)=cff1*(sfc_temp-272.16_r8)+alb_s_dry
298 ELSE
299 albedo_ice(i,j)=alb_s_dry
300 END IF
301 ELSE
302 IF ((sfc_temp-273.16_r8).gt.-1.0_r8) THEN
303 albedo_ice(i,j)=cff2*(sfc_temp-272.16_r8)+alb_i_dry
304 ELSE
305 albedo_ice(i,j)=alb_i_dry
306 END IF
307 END IF
308 ELSE
309 albedo_ice(i,j)=alb_w ! water albedo
310 END IF
311# endif
312
313# ifdef ALBEDO_CURVE
314!
315! Compute seawater albedo from curve.
316!
317 albedo(i,j)=0.069_r8- &
318 & 0.011_r8*cos(2.0_r8*deg2rad*latr(i,j))
319
320# elif defined ALBEDO_SZO
321!
322! Compute albedo over water based on the calendar day and time. It
323! ASSUMES that the forcing file contains the TOTAL INCIDENT SHORTWAVE
324! RADIATION (SMD).
325!
326! Local daylight is a function of the declination (Dangle) and hour
327! angle adjusted for the local meridian (Hangle-lonr(i,j)/15.0).
328! The 15.0 factor is because the sun moves 15 degrees every hour.
329!
330 latrad=latr(i,j)*deg2rad
331 cff1=sin(latrad)*sin(dangle)
332 cff2=cos(latrad)*cos(dangle)
333 zenith=max(cff1+cff2*cos(hangle-lonr(i,j)*deg2rad &
334 & -pi/12.0_r8),0.0_r8)
335!
336! Use albedo formula from Briegleb et al. (1986).
337!
338 albedo(i,j)=0.026_r8/(zenith**1.7_r8+0.065_r8)+ &
339 & 0.15_r8*(zenith-0.1_r8)* &
340 & (zenith-0.5_r8)*(zenith-1.0_r8)
341# else
342!
343! Default constant seawater albedo.
344!
345 albedo(i,j)=alb_w
346# endif
347 END DO
348 END DO
349!
350!-----------------------------------------------------------------------
351! Exchange boundary data.
352!-----------------------------------------------------------------------
353!
354 IF (ewperiodic(ng).or.nsperiodic(ng)) THEN
355 CALL exchange_r2d_tile (ng, tile, &
356 & lbi, ubi, lbj, ubj, &
357 & albedo_ice)
358
359 CALL exchange_r2d_tile (ng, tile, &
360 & lbi, ubi, lbj, ubj, &
361 & albedo)
362 END IF
363
364# ifdef DISTRIBUTE
365!
366 CALL mp_exchange2d (ng, tile, model, 2, &
367 & lbi, ubi, lbj, ubj, &
368 & nghostpoints, &
369 & ewperiodic(ng), nsperiodic(ng), &
370 & albedo, albedo_ice)
371# endif
372!
373 RETURN
374 END SUBROUTINE ice_albedo_tile
375!
376#endif
377 END module ice_albedo_mod
subroutine, public caldate(currenttime, yy_i, yd_i, mm_i, dd_i, h_i, m_i, s_i, yd_dp, dd_dp, h_dp, m_dp, s_dp)
Definition dateclock.F:76
subroutine exchange_r2d_tile(ng, tile, lbi, ubi, lbj, ubj, a)
type(t_forces), dimension(:), allocatable forces
Definition mod_forces.F:554
type(t_grid), dimension(:), allocatable grid
Definition mod_grid.F:365
integer, parameter ishsno
Definition ice_mod.h:140
type(t_ice), dimension(:), allocatable ice
Definition ice_mod.h:283
real(r8), dimension(:), allocatable min_ai
Definition ice_mod.h:241
integer, parameter ishmel
Definition ice_mod.h:139
integer, parameter isaice
Definition ice_mod.h:137
integer, parameter ishice
Definition ice_mod.h:138
integer, parameter icisst
Definition ice_mod.h:179
integer nghostpoints
Definition mod_param.F:710
integer, dimension(:), allocatable iic
logical, dimension(:), allocatable ewperiodic
logical, dimension(:), allocatable nsperiodic
real(dp), dimension(:), allocatable tdays
real(dp), parameter deg2rad
logical, dimension(:), allocatable perfectrst
integer, dimension(:), allocatable ntstart
real(dp), parameter pi
subroutine mp_exchange2d(ng, tile, model, nvar, lbi, ubi, lbj, ubj, nghost, ew_periodic, ns_periodic, a, b, c, d)
recursive subroutine wclock_off(ng, model, region, line, routine)
Definition timers.F:148
recursive subroutine wclock_on(ng, model, region, line, routine)
Definition timers.F:3