@@ -33,7 +33,7 @@ module atmosphere
3333 import .. spectrum
3434
3535 # Code versions
36- const AGNI_VERSION:: String = " 1.8.6 " # current agni version
36+ const AGNI_VERSION:: String = " 1.8.7 " # current agni version
3737 const SOCVER_minimum:: Float64 = 2407.2 # minimum required socrates version
3838
3939 # Hydrostatic+gravity+mass calculation (constants and limits)
@@ -62,51 +62,6 @@ module atmosphere
6262 # Enum of available radiative transfer schemes
6363 @enum RTSCHEME RT_SOCRATES= 1 RT_GREYGAS= 2
6464
65- """
66- **Parameters for deep atmospheric heating.**
67-
68- AGNI treats deep heating as an *additional upward energy flux* that is deposited
69- within the column following a Gaussian profile in log-pressure space.
70-
71- Two power modes are supported:
72- - `:efficiency` — heating flux = `efficiency × instellation` (stellar efficiency)
73- - `:flux` — heating flux = `F_total` (fixed radiative flux in W m⁻²)
74-
75- Additional design choices:
76- - Pressure-normalised deposition (dF/dP profile; legacy behaviour)
77- - Mass-normalised deposition (dm-weighted; aligns with ∂L/∂m forms)
78- - Handling deposition below the model bottom as a *bottom boundary flux*
79-
80- Notes:
81- - Pressures are in Pa throughout AGNI.
82- - `efficiency` is always clamped to [0,1].
83-
84- Fields:
85- - `active::Bool` Enable/disable deep heating.
86- - `P_dep::Float64` Deposition pressure centre [Pa].
87- - `sigma_P::Float64` Width of Gaussian in log-pressure space [dimensionless].
88- - `efficiency::Float64` Heating efficiency (fraction of instellation), used when `power_mode=:efficiency`.
89- - `normalization::Symbol` `:pressure` (legacy) or `:mass` (dm-weighted).
90- - `below_domain::Symbol` `:clamp` or `:boundary_flux`.
91- - `power_mode::Symbol` `:efficiency` | `:flux`.
92- - `F_total::Float64` Total deposited flux [W m-2], used when `power_mode=:flux`.
93- """
94- struct DeepHeatingParams
95- active:: Bool
96- P_dep:: Float64
97- sigma_P:: Float64
98- efficiency:: Float64
99- normalization:: Symbol
100- below_domain:: Symbol
101- power_mode:: Symbol
102- F_total:: Float64
103- end
104-
105- # Default constructor with heating disabled
106- DeepHeatingParams () = DeepHeatingParams (false , 1.0e5 , 1.0 , 0.0 ,
107- :pressure , :clamp ,
108- :efficiency , 0.0 )
109-
11065 # Contains data pertaining to the atmosphere (fluxes, temperature, etc.)
11166 mutable struct Atmos_t
11267
@@ -331,8 +286,14 @@ module atmosphere
331286 flux_advect:: Array{Float64, 1} # Energy flux advected into each cell [W m-2], treated as entering into its bottom edge
332287
333288 # Deep atmospheric heating
334- deep_heating:: DeepHeatingParams # Parameters for deep heating
335- flux_deep:: Array{Float64,1} # Deep heating flux at cell edges [W m-2] # should add at lw flux level
289+ deepheat_norm_method:: Symbol # Normalisation method for deep heating (:pressure or :mass)
290+ deepheat_Pmid:: Float64 # Deposition pressur centre [Pa]
291+ deepheat_Pwid:: Float64 # Width of Gaussian in log-pressure space [logPa]
292+ deepheat_domain:: Symbol # Method for treating deep heating below the model domain (:clamp or :boundary_flux)
293+ deepheat_power_mode:: Symbol # Method for setting total flux (:off, :rel, or :abs)
294+ deepheat_flux_rel:: Float64 # Total heating as fraction of instellation, used when `power_mode=:rel`.
295+ deepheat_flux_abs:: Float64 # Total heating flux [W m-2], used when `power_mode=:abs`.
296+ flux_deep:: Array{Float64,1} # Deep heating flux at cell edges [W m-2] # should add at lw flux level
336297
337298 # Total energy flux
338299 flux_dif:: Array{Float64,1} # Flux lost at each level [W m-2] (positive is heating up)
@@ -1174,7 +1135,13 @@ module atmosphere
11741135 end
11751136
11761137 # Deep atmospheric heating (default: disabled)
1177- atmos. deep_heating = DeepHeatingParams ()
1138+ atmos. deepheat_norm_method = :pressure
1139+ atmos. deepheat_Pmid = 1e5
1140+ atmos. deepheat_Pwid = 1.0
1141+ atmos. deepheat_domain = :clamp
1142+ atmos. deepheat_power_mode = :off
1143+ atmos. deepheat_flux_rel = 0.0
1144+ atmos. deepheat_flux_abs = 0.0
11781145
11791146 # Record that the parameters are set
11801147 atmos. is_param = true
@@ -1193,64 +1160,77 @@ module atmosphere
11931160 which deposits energy as a Gaussian distribution in log-pressure space.
11941161
11951162 Arguments:
1196- - `atmos::Atmos_t` the atmosphere struct instance to be used.
1197- - `active::Bool` enable/disable deep heating.
1198- - `P_dep::Float64` deposition pressure [Pa].
1199- - `sigma_P::Float64` width of Gaussian in log-pressure space [dimensionless].
1200- - `efficiency::Float64` heating efficiency as fraction of instellation.
1163+ - `atmos::Atmos_t` the atmosphere struct instance to be used.
1164+ - `Pmid::Float64` deposition pressure [Pa].
1165+ - `Pwid::Float64` width of Gaussian in log-pressure space [logPa].
1166+ - `flux_rel::Float64` heating flux relative to instellation.
1167+ - `flux_abs::Float64` heating flux absolute [W m-2].
1168+ - `norm_method::Symbol` method for normalising the Gaussian (:pressure, :mass).
1169+ - `domain::Symbol` how to handle deposition pressures outside the domain (:clamp, :below_domain).
1170+ - `power_mode::Symbol` off, or relative/absolute flux (:off, :rel, :abs).
12011171
12021172 Returns:
1203- Nothing
1173+ - `Bool` indicating success or failure of the operation.
12041174 """
1205- function set_deep_heating! (atmos:: atmosphere.Atmos_t ;
1206- active:: Bool = false ,
1207- P_dep:: Float64 = 1.0e5 ,
1208- sigma_P:: Float64 = 1.0 ,
1209- efficiency:: Float64 = 0.0 ,
1210- normalization:: Symbol = :pressure ,
1211- below_domain:: Symbol = :clamp ,
1212- power_mode:: Symbol = :efficiency ,
1213- F_total:: Float64 = 0.0 )
1214-
1215- # Validate/normalise parameters
1216- sigma_P = max (sigma_P, 0.01 ) # Prevent division issues
1217- efficiency = clamp (efficiency, 0.0 , 1.0 )
1218-
1219- # Normalise symbols
1220- if ! (normalization in (:pressure , :mass ))
1221- error (" Invalid deep heating normalization: $(normalization) " )
1222- end
1223- if ! (below_domain in (:clamp , :boundary_flux ))
1224- error (" Invalid deep heating below_domain: $(below_domain) " )
1175+ function set_deep_heating! (atmos:: atmosphere.Atmos_t ,
1176+ Pmid:: Float64 ,
1177+ Pwid:: Float64 ,
1178+ flux_rel:: Float64 ,
1179+ flux_abs:: Float64 ,
1180+ norm_method:: Symbol ,
1181+ domain:: Symbol ,
1182+ power_mode:: Symbol
1183+ ):: Bool
1184+
1185+ # Fail safe mode
1186+ atmos. deepheat_power_mode = :off
1187+ if power_mode == :off
1188+ atmos. deepheat_power_mode = :off
1189+ return true
1190+ elseif ! (power_mode in (:rel , :abs ))
1191+ @error " Invalid deep heating power mode: $(power_mode) "
1192+ return false
12251193 end
1226- if ! (power_mode in (:efficiency , :flux ))
1227- error (" Invalid deep heating power_mode: $(power_mode) " )
1194+
1195+ # Normalisation coordinate
1196+ if ! (norm_method in (:pressure , :mass ))
1197+ @error " Invalid deep heating normalisation: $(norm_method) "
1198+ return false
1199+ else
1200+ atmos. deepheat_norm_method = norm_method
12281201 end
12291202
1203+ # Set centre and width of Gaussian
1204+ atmos. deepheat_Pmid = max (Pmid, 0.0 ) # Pascals
1205+ atmos. deepheat_Pwid = max (Pwid, 0.01 ) # relative
1206+
12301207 # Deposition pressure handling
1231- if below_domain == :clamp
1232- P_dep = clamp (P_dep, atmos. p_toa, atmos. p_boa)
1208+ if domain == :clamp
1209+ atmos. deepheat_Pmid = clamp (atmos. deepheat_Pmid, atmos. p_toa, atmos. p_boa)
1210+ elseif domain == :below_domain
1211+ # Allow Poutside domain
1212+ atmos. deepheat_Pmid = max (atmos. deepheat_Pmid, atmos. p_toa)
12331213 else
1234- # Allow P_dep outside domain (used as a signal for boundary-flux mode)
1235- P_dep = max (P_dep, atmos . p_toa)
1214+ @error " Invalid deep heating domain treatment: $(domain) "
1215+ return false
12361216 end
12371217
1238- # Create and store the parameters
1239- atmos. deep_heating = DeepHeatingParams (active, P_dep, sigma_P, efficiency,
1240- normalization, below_domain,
1241- power_mode, F_total)
1242-
1243- if active
1244- @info @sprintf (" Deep heating enabled: norm=%s below=%s mode=%s" ,
1245- String (normalization), String (below_domain), String (power_mode))
1246- if power_mode == :efficiency
1247- @info @sprintf (" P_dep=%.2e Pa, σ_P=%.2f, ε=%.4f" , P_dep, sigma_P, efficiency)
1248- else
1249- @info @sprintf (" P_dep=%.2e Pa, σ_P=%.2f, F_total=%.4e W/m²" , P_dep, sigma_P, F_total)
1250- end
1218+ # Set power mode
1219+ atmos. deepheat_power_mode = power_mode
1220+ atmos. deepheat_flux_rel = flux_rel
1221+ atmos. deepheat_flux_abs = flux_abs
1222+ @info " Deep heating configured with power_mode=$(atmos. deepheat_power_mode) "
1223+ if power_mode == :rel
1224+ @info @sprintf (" Pmid=%.2e Pa, Pwid=%.2f, ε=%.4f" ,
1225+ atmos. deepheat_Pmid, atmos. deepheat_Pwid, flux_rel)
1226+ elseif power_mode == :abs
1227+ @info @sprintf (" Pmid=%.2e Pa, Pwid=%.2f, F_total=%.4e W/m²" ,
1228+ atmos. deepheat_Pmid, atmos. deepheat_Pwid, flux_abs)
12511229 end
1230+ @info " norm_method=$(atmos. deepheat_norm_method) , domain=$(atmos. deepheat_domain) "
12521231
1253- return nothing
1232+
1233+ return true
12541234 end
12551235
12561236
0 commit comments