Skip to content

Commit 9b410f6

Browse files
committed
Use chem calculation at every ls step. Allow setpt=Teq for automatic substitution of Teq into initial tp. Set Z and CO by log-space in grid
1 parent 7dff62d commit 9b410f6

8 files changed

Lines changed: 367 additions & 275 deletions

File tree

docs/src/usage.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,15 @@ Configure plotting routines all of these should be `true` or `false`.
254254

255255
* `execution.initial_state` describes the initial temperature profile applied to the atmosphere. This is a list of strings which are applied in the given order, which allows the user to describe a specific state as required. The descriptors are listed below, some of which take a single argument that needs to immediately follow the descriptor in the list order.
256256
- `dry` : integrate the dry adiabatic lapse rate from the surface upwards
257-
- `str`, `arg` : apply an isothermal stratosphere at `arg` kelvin
258-
- `iso`, `arg` : set the whole atmosphere to be isothermal at `arg` kelvin
259-
- `csv`, `arg` : set the temperature profile using the CSV file at the file path `arg`
260-
- `sat`, `arg` : apply Clausius-Clapeyron saturation curve for the gas `arg`
261-
- `ncdf`, `arg` : load profile from the NetCDF file located at `arg`
262-
- `loglin`, `arg` : log-linear profile between `tmp_surf` at the bottom and `arg` at the top
257+
- `str`, `tmp` : apply an isothermal stratosphere at temperature `tmp`
258+
- `iso`, `tmp` : set the whole atmosphere to be isothermal at temperature `tmp`
259+
- `csv`, `pth` : set the temperature profile using the CSV file at the file path `pth`
260+
- `sat`, `gas` : apply Clausius-Clapeyron saturation curve for the gas `gas`
261+
- `ncdf`, `pth` : load profile from the NetCDF file located at `pth`
262+
- `loglin`, `tmp` : log-linear profile between `tmp_surf` at the bottom and `tmp` at the top
263263
- `ana` : use the Guillot ([2010](https://arxiv.org/abs/1006.4702)) analytical temperature solution
264264

265-
For example, setting `initial_state = ["dry", "sat", "H2O", "str", "180"]` will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model.
265+
For example, setting `initial_state = ["dry", "sat", "H2O", "str", "180"]` will set T(p) to follow the dry adiabat from the surface, the water condensation curve above that, and then to be isothermal at 180 K until the top of the model. Provide `tmp="Teq"` to have AGNI automatically substitute-in the planet's radiative equilibrium temperature here.
266266

267267
* `physics.chemistry` enables a calculation of equilibrium thermochemistry in the atmosphere. This is handled externally by FastChem, so you must set the environment variable `FC_DIR` to point to the FastChem directory. More information on the chemistry is available on the [Equilibrium chemistry](@ref) page.
268268

misc/grid/consolidate.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ using Glob
77
using CSV
88
using DataFrames
99
using NCDatasets
10+
using Printf
1011

1112
# Get output dir from ARGS
1213
output_dir::String = ""
@@ -46,6 +47,12 @@ CSV.write(outpath, combined)
4647
println(" wrote $(nrow(combined))x$(ncol(combined)) table to '$outpath'")
4748
println(" ")
4849

50+
println("Statistics...")
51+
@printf(" total: %7d \n",nrow( filter(row -> row["succ"] != 0.0, combined) ) )
52+
@printf(" success: %7d \n",nrow( filter(row -> row["succ"] > 0.0, combined) ) )
53+
@printf(" failure: %7d \n",nrow( filter(row -> row["succ"] < 0.0, combined) ) )
54+
println(" ")
55+
4956
# Combined fluxes dataframe
5057
println("Combining emission fluxes...")
5158
dfs_emits = DataFrame[] # not sorted

misc/grid/plot.ipynb

Lines changed: 240 additions & 202 deletions
Large diffs are not rendered by default.

misc/grid/slurm.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#!/bin/bash
22

3-
#SBATCH --time=00-15:00:00
4-
#SBATCH --cpus-per-task=30
3+
#SBATCH --time=00-20:00:00
4+
#SBATCH --cpus-per-task=25
55

66
#SBATCH --nodes=1
77
#SBATCH --ntasks-per-node=1
8-
#SBATCH --mem-per-cpu=1200M
8+
#SBATCH --mem-per-cpu=1600M
99
#SBATCH --output=slurm-grid-%j.log
1010

1111
echo "Allocated workers: $SLURM_CPUS_PER_TASK"

misc/grid/worker.jl

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const SGL_RUNTIME::Float64 = 10.0 # estimated runtime for a single gridpoint [
2828
const cfg_base = "res/config/struct_grid.toml"
2929

3030
# Mass array with custom spacing
31-
const mass_arr::Array{Float64, 1} = 10.0 .^ vcat( range(start=log10(0.5), stop=log10(4.5), length=8),
31+
const mass_arr::Array{Float64, 1} = 10.0 .^ vcat( range(start=log10(0.7), stop=log10(4.5), length=8),
3232
range(start=log10(5.0), stop=log10(10.0), length=8)
3333
)
3434

@@ -49,8 +49,8 @@ const grid::OrderedDict = OrderedDict{String,Array{Float64,1}}((
4949
# "metal_C" => 10 .^ range(start=-4.0, stop=0.0, step=2.0),
5050

5151
# NEW METHOD...
52-
"metal_Z" => 10 .^ range(start=-1.0, stop=1.5, step=0.5), # total metallicity
53-
"metal_CO" => 10 .^ range(start=-3.0, stop=0.0, step=1.0), # C/O mass ratio
52+
"logZ" => range(start=-1.0, stop=1.5, step=0.5), # total metallicity
53+
"logCO" => range(start=-3.0, stop=0.0, step=1.0), # C/O mass ratio
5454

5555
"instellation" => Float64[1.0, 10.0, 100.0, 300.0, 1000.0], # S_earth
5656
"Teff" => range(start=2500, stop=5500, step=600.0),
@@ -66,12 +66,12 @@ const output_keys = ["succ", "flux_loss", "r_bound",
6666
# Grid management options
6767
const save_netcdfs = false # NetCDF file for each case
6868
const save_plots = false # plots for each case
69-
const modwrite::Int = 25 # Write CSV file every `modwrite` gridpoints
70-
const modplot::Int = 2 # Plot every `modplot` solver steps (debug)
69+
const modwrite::Int = 40 # Write CSV file every `modwrite` gridpoints
70+
const modplot::Int = 1 # Plot every `modplot` solver steps (debug)
7171
const frac_min::Float64 = 0.0005 # 0.001 -> 1170 bar for Earth
7272
const frac_max::Float64 = 0.999
7373
const transspec_p::Float64 = 2e3 # Pa
74-
const fc_floor::Float64 = 500.0 # K
74+
const fc_floor::Float64 = 600.0 # K
7575
const fc_wellmixed::Bool = false # calculate abundances as well-mixed ?
7676

7777

@@ -157,8 +157,8 @@ frac_core = 0.325
157157
frac_atm = 0.01
158158
stellar_Teff = cfg["planet"]["star_Teff"]
159159
input_star = cfg["files"]["input_star"]
160-
metal_Z = 100.0
161-
metal_CO = 1.0
160+
logZ = 2.0
161+
logCO = 0.0
162162

163163
# Get the keys from the grid dictionary
164164
input_keys = collect(keys(grid))
@@ -255,7 +255,7 @@ if (id_work == 1) || !isfile(gpfile)
255255
row *= @sprintf("%08d,",p["worker"])
256256

257257
# Other keys
258-
row *= join([@sprintf("%.6e",p[k]) for k in input_keys], ",") * "\n"
258+
row *= join([@sprintf("%.5e",p[k]) for k in input_keys], ",") * "\n"
259259

260260
# Write out
261261
write(hdl,row)
@@ -302,7 +302,7 @@ function write_table()
302302

303303
row = @sprintf("%08d",i)
304304
for k in output_keys
305-
row *= @sprintf(",%.6e",result_table[i][k])
305+
row *= @sprintf(",%.5e",result_table[i][k])
306306
end
307307
write(hdl,row*"\n")
308308
end
@@ -328,7 +328,7 @@ function write_emits()
328328
# Header of wavelength values
329329
head = "0.0"
330330
for b in 1:bands
331-
head *= @sprintf(",%.6e",wlarr[b]*1e9) # convert to nm
331+
head *= @sprintf(",%.5e",wlarr[b]*1e9) # convert to nm
332332
end
333333
head *= "\n"
334334
write(hdl,head)
@@ -343,7 +343,7 @@ function write_emits()
343343

344344
row = @sprintf("%08d",i)
345345
for b in 1:bands
346-
row *= @sprintf(",%.6e",result_emits[i,b])
346+
row *= @sprintf(",%.5e",result_emits[i,b])
347347
end
348348
write(hdl,row*"\n")
349349
end
@@ -444,7 +444,11 @@ end
444444
"""
445445
Update metallicity (by */H mol) from Z and C/O mass ratios
446446
"""
447-
function update_metallicity!(atmos, Z, CO)
447+
function update_metallicity!(atmos, _logZ, _logCO)
448+
449+
# Convert from log-scale to linear
450+
Z = 10^_logZ
451+
CO = 10^_logCO
448452

449453
# Need to work out what the X/H mass ratios are...
450454

@@ -532,6 +536,7 @@ function init_atmos(OUT_DIR::String)
532536
end
533537

534538
# Set PT
539+
atm.tmp_surf = Float64(cfg["planet"]["tmp_surf"])
535540
setpt.request!(atm, cfg["execution"]["initial_state"])
536541

537542
return atm
@@ -580,8 +585,8 @@ for (i,p) in enumerate(grid_flat)
580585
global save_plots
581586
global wlarr
582587
global stellar_Teff
583-
global metal_Z
584-
global metal_CO
588+
global logZ
589+
global logCO
585590

586591
# Check that this worker is assigned to this grid point, by index
587592
if grid_flat[i]["worker"] != id_work
@@ -591,6 +596,7 @@ for (i,p) in enumerate(grid_flat)
591596
@info @sprintf("Grid point %d of %d total (number %d of chunk)",i,gridsize,i_counter)
592597

593598
succ_last = succ
599+
updated_k = false
594600

595601
# Update parameters
596602
for (idx,(k,val)) in enumerate(p)
@@ -618,7 +624,8 @@ for (i,p) in enumerate(grid_flat)
618624
end
619625

620626
# set other parameter...
621-
if (i==1) || Bool(grid_flat[i-1][k] != grid_flat[i][k])
627+
updated_k = (i==1) || Bool(grid_flat[i-1][k] != grid_flat[i][k])
628+
if updated_k
622629
@info " updated $k = $val"
623630
else
624631
@info " use $k = $val"
@@ -652,19 +659,22 @@ for (i,p) in enumerate(grid_flat)
652659
atmos.instellation = val * 1361.0 # W/m^2
653660

654661
# set T(p) = loglinear up to Teq
655-
setpt.request!(atmos, ["loglin","$(phys.calc_Teq(atmos.instellation,atmos.albedo_b))"])
662+
if updated_k
663+
atmos.tmp_surf = Float64(cfg["planet"]["tmp_surf"])
664+
setpt.request!(atmos, ["loglin","Teq"])
665+
end
656666

657667
elseif startswith(k, "vmr_")
658668
gas = split(k,"_")[2]
659669
atmos.gas_vmr[gas][:] .= val
660670

661-
elseif k == "metal_Z"
662-
metal_Z = val
663-
update_metallicity!(atmos, metal_Z, metal_CO)
671+
elseif k == "logZ"
672+
logZ = val
673+
update_metallicity!(atmos, logZ, logCO)
664674

665-
elseif k == "metal_CO"
666-
metal_CO = val
667-
update_metallicity!(atmos, metal_Z, metal_CO)
675+
elseif k == "logCO"
676+
logCO = val
677+
update_metallicity!(atmos, logZ, logCO)
668678

669679
elseif k == "Teff"
670680
# already handled
@@ -707,8 +717,8 @@ for (i,p) in enumerate(grid_flat)
707717
setpt.fromarrays!(atmos, result_profs[i-1]["p"], result_profs[i-1]["t"])
708718
easy_start = false
709719
else
710-
# last iter failed -> restore initial guess for T(p)
711-
# setpt.request!(atmos, cfg["execution"]["initial_state"])
720+
# last iter failed
721+
setpt.request!(atmos, cfg["execution"]["initial_state"])
712722
easy_start = Bool(cfg["execution"]["easy_start"])
713723
end
714724

@@ -717,7 +727,7 @@ for (i,p) in enumerate(grid_flat)
717727
max_steps *= 2
718728
end
719729

720-
solver.ls_increase = 1.08
730+
# solver.ls_increase = 0.7
721731

722732
# Solve for RCE
723733
succ = solver.solve_energy!(atmos, sol_type=cfg["execution"]["solution_type"],

res/config/struct_grid.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title = "Base config for structure calcs"
33

44
[planet]
5-
tmp_surf = 1200.0
5+
tmp_surf = 1800.0
66
instellation = 1e6 #3.402500e6
77
albedo_b = 0.18
88
s0_fact = 0.25
@@ -32,11 +32,11 @@ title = "Base config for structure calcs"
3232
verbosity = 1
3333
max_steps = 50
3434
max_runtime = 200
35-
num_levels = 30
35+
num_levels = 32
3636
solution_type = 3
3737
solver = "newton"
3838
dx_max = 300.0
39-
dx_min = 1e-5
39+
dx_min = 1e-9
4040
initial_state = ["iso","1200"]
4141
linesearch = 2
4242
easy_start = false

src/setpt.jl

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ module setpt
2020
using LoggingExtras
2121
import Interpolations: interpolate, Gridded, Linear, Flat, extrapolate, Extrapolation
2222

23+
function _parse_tmp_str(atmos::atmosphere.Atmos_t, tmp)::Float64
24+
25+
if tmp isa String
26+
if lowercase(tmp) == "teq"
27+
return phys.calc_Teq(atmos.instellation, atmos.albedo_b)
28+
else
29+
return parse(Float64, tmp)
30+
end
31+
elseif tmp isa Number
32+
return Float64(tmp)
33+
else
34+
error("Invalid temperature choice '$(tmp)'")
35+
end
36+
end
37+
2338
# Process a series of requests describing T(p)
2439
function request!(atmos::atmosphere.Atmos_t, request::Array{String,1})::Bool
2540
num_req::Int = length(request) # Number of requests
@@ -66,10 +81,6 @@ module setpt
6681
idx_req += 1
6782
setpt.add!(atmos,parse(Float64, request[idx_req]))
6883

69-
elseif str_req == "teq"
70-
# add isothermal at Teq
71-
setpt.Teq!(atmos)
72-
7384
elseif str_req == "surfsat"
7485
# ensure surface is not super-saturated
7586
chemistry.restore_composition!(atmos)
@@ -280,23 +291,21 @@ module setpt
280291
end # end load_ncdf
281292

282293
# Set atmosphere to be isothermal at the given temperature
283-
function isothermal!(atmos::atmosphere.Atmos_t, set_tmp::Float64)
294+
function isothermal!(atmos::atmosphere.Atmos_t, set_tmp)
284295
if !atmos.is_param
285296
@error "setpt: Atmosphere parameters not set"
286297
return
287298
end
299+
300+
301+
set_tmp = _parse_tmp_str(atmos, set_tmp)
302+
288303
fill!(atmos.tmpl, set_tmp)
289304
fill!(atmos.tmp , set_tmp)
290305

291306
return
292307
end
293308

294-
# Set atmosphere to be isothermal at the radiative equilibrium temperature
295-
function Teq!(atmos::atmosphere.Atmos_t)
296-
stratosphere!(atmos, phys.calc_Teq(atmos.instellation,atmos.albedo_b))
297-
return
298-
end
299-
300309
# Set atmosphere to be isothermal at the given temperature
301310
function add!(atmos::atmosphere.Atmos_t, delta::Float64)
302311
if !atmos.is_param
@@ -354,7 +363,9 @@ module setpt
354363
end
355364

356365
# Set atmosphere to have an isothermal stratosphere
357-
function stratosphere!(atmos::atmosphere.Atmos_t, strat_tmp::Float64)
366+
function stratosphere!(atmos::atmosphere.Atmos_t, strat_tmp)
367+
368+
strat_tmp = _parse_tmp_str(atmos, strat_tmp)
358369

359370
# Keep stratosphere below tmp_surf value
360371
strat_tmp = min(strat_tmp, atmos.tmp_surf)
@@ -381,7 +392,9 @@ module setpt
381392
end
382393

383394
# Set atmosphere to have a log-linear T(p) profile
384-
function loglinear!(atmos::atmosphere.Atmos_t, top_tmp::Float64)
395+
function loglinear!(atmos::atmosphere.Atmos_t, top_tmp)
396+
397+
top_tmp = _parse_tmp_str(atmos, top_tmp)
385398

386399
# Keep top_tmp below tmp_surf value
387400
top_tmp = min(top_tmp, atmos.tmp_surf)
@@ -403,7 +416,6 @@ module setpt
403416

404417

405418

406-
407419
"""
408420
**Set T = max(T,T_dew) for a specified gas.**
409421

0 commit comments

Comments
 (0)