@@ -15,6 +15,7 @@ module atmosphere
1515 using LinearAlgebra
1616 using Statistics
1717 using Logging
18+ using LoopVectorization
1819
1920 # Local files
2021 include (joinpath (ENV [" RAD_DIR" ]," julia/src/SOCRATES.jl" ))
@@ -73,10 +74,12 @@ module atmosphere
7374 grav_surf:: Float64 # Surface gravity [m s-2]
7475 overlap_method:: Int # Absorber overlap method to be used
7576
76- # Band edges
77+ # Spectral bands
7778 nbands:: Int
7879 bands_min:: Array{Float64,1} # Lower wavelength [m]
7980 bands_max:: Array{Float64,1} # Upper wavelength [m]
81+ bands_cen:: Array{Float64,1} # Midpoint [m]
82+ bands_wid:: Array{Float64,1} # Width [m]
8083
8184 # Pressure-temperature grid (with i=1 at the top of the model)
8285 nlev_c:: Int # Cell centre (count)
@@ -151,6 +154,9 @@ module atmosphere
151154 band_u_sw:: Array{Float64,2} # up component, sw
152155 band_n_sw:: Array{Float64,2} # net upward, sw
153156
157+ # Surface planck emission (incl. emissivity)
158+ surf_flux:: Array{Float64, 1}
159+
154160 # Contribution function (to outgoing flux) per-band
155161 contfunc_norm:: Array{Float64,2} # LW only, and normalised by maximum value
156162
@@ -313,7 +319,7 @@ module atmosphere
313319 end
314320
315321 # Code versions
316- atmos. AGNI_VERSION = " 0.7 .0"
322+ atmos. AGNI_VERSION = " 0.8 .0"
317323 atmos. SOCRATES_VERSION = readchomp (joinpath (ENV [" RAD_DIR" ]," version" ))
318324 @debug " AGNI VERSION = $(atmos. AGNI_VERSION) "
319325 @debug " Using SOCRATES at $(ENV [" RAD_DIR" ]) "
@@ -572,7 +578,7 @@ module atmosphere
572578 # backup mixing ratios from current state
573579 for k in keys (atmos. gas_vmr)
574580 atmos. gas_ovmr[k] = zeros (Float64, atmos. nlev_c)
575- atmos. gas_ovmr[k][:] . = atmos. gas_vmr[k][: ]
581+ @turbo @. atmos. gas_ovmr[k] = atmos. gas_vmr[k]
576582 end
577583
578584 # set condensation mask and yield values [kg]
@@ -729,59 +735,45 @@ module atmosphere
729735 """
730736 function calc_layer_props! (atmos:: atmosphere.Atmos_t ; ignore_errors:: Bool = false ):: Bool
731737 if ! atmos. is_param
732- error (" atmosphere parameters have not been set" )
738+ error (" Atmosphere parameters have not been set" )
733739 end
734740
735- ok:: Bool = true
736- dz_max:: Float64 = 1e9
737-
738- # Set pressure arrays in SOCRATES
739- atmos. atm. p[1 , :] .= atmos. p[:]
740- atmos. atm. p_level[1 , 0 : end ] .= atmos. pl[:]
741-
742- # Set MMW at each level
743- fill! (atmos. layer_mmw, 0.0 )
744- for i in 1 : atmos. nlev_c
745- for gas in atmos. gas_names
746- atmos. layer_mmw[i] += atmos. gas_vmr[gas][i] * atmos. gas_dat[gas]. mmw
747- end
748- end
749-
750- # Temporary values
751- mmr:: Float64 = 0.0
752- g1:: Float64 = 0.0 ; p1:: Float64 = 0.0 ; t1:: Float64 = 0.0
753- g2:: Float64 = 0.0 ; p2:: Float64 = 0.0 ; t2:: Float64 = 0.0
754- dzc:: Float64 = 0.0 ; dzl:: Float64 = 0.0
755- GMpl:: Float64 = atmos. grav_surf * (atmos. rp^ 2.0 )
756-
757741 # Reset arrays
758742 fill! (atmos. z , 0.0 )
759743 fill! (atmos. zl , 0.0 )
760744 fill! (atmos. layer_grav, 0.0 )
761745 fill! (atmos. layer_thick, 0.0 )
762746 fill! (atmos. layer_density,0.0 )
763- fill! (atmos. layer_cp ,0.0 )
764- fill! (atmos. layer_kc ,0.0 )
765747 fill! (atmos. layer_mass ,0.0 )
748+ fill! (atmos. layer_cp, 0.0 )
749+ fill! (atmos. layer_kc, 0.0 )
750+ fill! (atmos. layer_mmw, 0.0 )
766751
767- # Integrate from bottom upwards
768- for i in range (start= atmos. nlev_c, stop= 1 , step= - 1 )
752+ # Temporary values
753+ g1:: Float64 = 0.0 ; p1:: Float64 = 0.0 ; t1:: Float64 = 0.0
754+ g2:: Float64 = 0.0 ; p2:: Float64 = 0.0 ; t2:: Float64 = 0.0
755+ dzc:: Float64 = 0.0 ; dzl:: Float64 = 0.0
756+ GMpl:: Float64 = atmos. grav_surf * (atmos. rp^ 2.0 )
757+ mmr:: Float64 = 0.0
758+ ok:: Bool = true
759+ dz_max:: Float64 = 1e8
769760
770- # Set cp, kc at this level
771- atmos. layer_cp[i] = 0.0
772- atmos. layer_kc[i] = 0.0
773- for gas in atmos. gas_names
761+ # Set MMW at each level
762+ for gas in atmos. gas_names
763+ @turbo @. atmos. layer_mmw += atmos. gas_vmr[gas] * atmos. gas_dat[gas]. mmw
764+ end
765+
766+ # Set cp, kc at each level
767+ for gas in atmos. gas_names
768+ @inbounds for i in 1 : atmos. nlev_c
774769 mmr = atmos. gas_vmr[gas][i] * atmos. gas_dat[gas]. mmw/ atmos. layer_mmw[i]
775770 atmos. layer_cp[i] += mmr * phys. get_Cp (atmos. gas_dat[gas], atmos. tmp[i])
776771 atmos. layer_kc[i] += mmr * phys. get_Kc (atmos. gas_dat[gas], atmos. tmp[i])
777772 end
773+ end
778774
779- # Temporarily copy this cp, kc to the level above
780- # since they are needed for doing the hydrostatic integration
781- if i > 1
782- atmos. layer_cp[i- 1 ] = atmos. layer_cp[i]
783- atmos. layer_kc[i- 1 ] = atmos. layer_kc[i]
784- end
775+ # Integrate from bottom upwards
776+ for i in range (start= atmos. nlev_c, stop= 1 , step= - 1 )
785777
786778 # Technically, g and z should be integrated as coupled equations,
787779 # but here they are not. This loose integration has been found to
@@ -832,7 +824,7 @@ module atmosphere
832824
833825 # Mass (per unit area, kg m-2) and density (kg m-3)
834826 # Loop from top downards
835- for i in 1 : atmos. nlev_c
827+ @inbounds for i in 1 : atmos. nlev_c
836828 atmos. layer_mass[i] = (atmos. pl[i+ 1 ] - atmos. pl[i])/ atmos. layer_grav[i]
837829 atmos. atm. mass[1 , i] = atmos. layer_mass[i] # pass to SOCRATES
838830
@@ -885,8 +877,8 @@ module atmosphere
885877 atmos. p[1 : end ] .= 0.5 .* (atmos. pl[1 : end - 1 ] .+ atmos. pl[2 : end ])
886878
887879 # Finally, convert arrays to 'real' pressure units
888- atmos. p[:] . = 10.0 . ^ atmos. p[:]
889- atmos. pl[:] . = 10.0 . ^ atmos. pl[:]
880+ @turbo @. atmos. p = 10.0 ^ atmos. p
881+ @turbo @. atmos. pl = 10.0 ^ atmos. pl
890882
891883 return nothing
892884 end
@@ -990,13 +982,17 @@ module atmosphere
990982 end
991983
992984 atmos. nbands = atmos. spectrum. Basic. n_band
993- atmos. bands_max = zeros (Float64, atmos. spectrum. Basic. n_band)
994- atmos. bands_min = zeros (Float64, atmos. spectrum. Basic. n_band)
985+ atmos. bands_max = zeros (Float64, atmos. nbands)
986+ atmos. bands_min = zeros (Float64, atmos. nbands)
987+ atmos. bands_cen = zeros (Float64, atmos. nbands)
988+ atmos. bands_wid = zeros (Float64, atmos. nbands)
995989
996990 for i in 1 : atmos. nbands
997991 atmos. bands_min[i] = atmos. spectrum. Basic. wavelength_short[i]
998992 atmos. bands_max[i] = atmos. spectrum. Basic. wavelength_long[i]
999993 end
994+ @turbo @. atmos. bands_cen = 0.5 * (atmos. bands_max + atmos. bands_min)
995+ @turbo @. atmos. bands_wid = abs (atmos. bands_max - atmos. bands_min)
1000996
1001997 # modules_gen/dimensions_field_cdf_ucf.f90
1002998 npd_direction = 1 # Maximum number of directions for radiances
@@ -1065,7 +1061,7 @@ module atmosphere
10651061 SOCRATES. allocate_bound (atmos. bound, atmos. dimen, atmos. spectrum)
10661062
10671063 # Fill with zeros - will be set inside of radtrans function at call time
1068- atmos. bound. flux_ground[ 1 , :] . = 0.0
1064+ fill! ( atmos. bound. flux_ground, 0.0 )
10691065
10701066
10711067 # ##########################################
@@ -1103,7 +1099,7 @@ module atmosphere
11031099 end
11041100
11051101 # Calculate the weighting for the bands.
1106- atmos. control. weight_band . = 1.0
1102+ fill! ( atmos. control. weight_band, 1.0 )
11071103
11081104 # 'Entre treatment of optical depth for direct solar flux (0/1/2)'
11091105 # '0: no scaling; 1: delta-scaling; 2: circumsolar scaling'
@@ -1318,17 +1314,17 @@ module atmosphere
13181314 push! (_alb_s, _alb_s[end ])
13191315
13201316 # convert ss albedo to gamma values (eq 14.3 from Hapke 2012)
1321- _alb_s[:] . = sqrt .( 1 . - _alb_s[:] ) # operating in place
1317+ @turbo @. _alb_s = sqrt ( 1.0 - _alb_s) # operating in place
13221318
13231319 # create interpolator on gamma
13241320 _gamma:: Interpolator = Interpolator (_alb_w, _alb_s)
13251321
13261322 # use interpolator to fill band values
13271323 ga:: Float64 = 0.0
13281324 mu:: Float64 = cosd (atmos. zenith_degrees)
1329- for i in 1 : atmos. nbands
1325+ @inbounds for i in 1 : atmos. nbands
13301326 # evaluate gamma at band centre, converting from m to nm
1331- ga = _gamma (0.5 * 1.0e9 * ( atmos. bands_min [i]+ atmos . bands_max[i]) )
1327+ ga = _gamma (1.0e9 * atmos. bands_cen [i])
13321328
13331329 # calculate dh reflectance (eq 3 from Hammond24)
13341330 atmos. surf_r_arr[i] = (1 - ga) / (1 + 2 * ga* mu)
@@ -1361,6 +1357,8 @@ module atmosphere
13611357 atmos. band_u_sw = zeros (Float64, (atmos. nlev_l,atmos. nbands))
13621358 atmos. band_n_sw = zeros (Float64, (atmos. nlev_l,atmos. nbands))
13631359
1360+ atmos. surf_flux = zeros (Float64, atmos. nbands)
1361+
13641362 atmos. contfunc_norm = zeros (Float64, (atmos. nlev_c,atmos. nbands))
13651363
13661364 atmos. flux_sens = 0.0
@@ -1614,7 +1612,7 @@ module atmosphere
16141612 # matched?
16151613 if match
16161614 N_g = data[i,:] # number densities for this gas
1617- atmos. gas_vmr[g_in][:] . += N_g[:] . / N_t[:] # VMR for this gas
1615+ @. atmos. gas_vmr[g_in] += N_g / N_t # VMR for this gas
16181616 end
16191617 end
16201618
@@ -1724,9 +1722,9 @@ module atmosphere
17241722 # Reset phase change flags
17251723 # Reset condensation yield values
17261724 for g in atmos. gas_names
1727- atmos. gas_vmr[g][1 : end - 1 ] . = atmos. gas_vmr[g][end ]
1728- atmos. gas_sat[g][:] . = false
1729- atmos. gas_yield[g][:] . = 0.0
1725+ fill! ( atmos. gas_vmr[g][1 : end - 1 ], atmos. gas_vmr[g][end ])
1726+ fill! ( atmos. gas_sat[g], false )
1727+ fill! ( atmos. gas_yield[g], 0.0 )
17301728 end
17311729
17321730 # Reset water cloud
@@ -1990,7 +1988,7 @@ module atmosphere
19901988 if back_interp
19911989 clamp! (atmos. tmpl, atmos. tmp_floor, atmos. tmp_ceiling)
19921990 itp = Interpolator (log .(atmos. pl), atmos. tmpl)
1993- atmos. tmp[:] . = itp . (log . (atmos. p[:] ))
1991+ @. atmos. tmp = itp (log (atmos. p))
19941992 end
19951993
19961994 return nothing
0 commit comments