@@ -386,6 +386,92 @@ function overwrite_initial_conditions!(
386386 )
387387end
388388
389+ """
390+ correct_surface_pressure_for_topography!(
391+ p_sfc,
392+ file_path,
393+ face_space,
394+ Y,
395+ ᶜT,
396+ ᶜq_tot,
397+ thermo_params,
398+ regridder_kwargs;
399+ surface_altitude_var = "z_sfc",
400+ )
401+
402+ Adjusts the surface pressure field `p_sfc` to account for mismatches between
403+ ERA5 (file) surface altitude and the model orography when specifying pressure.
404+
405+ Δz = z_model_surface - z_sfc
406+
407+ and applies a hydrostatic correction at the surface using the local moist gas
408+ constant and temperature at the surface:
409+
410+ p_sfc .= p_sfc .* exp.(-Δz * g ./ (R_m_sfc .* T_sfc))
411+
412+ where:
413+ - `g` is gravitational acceleration from `thermo_params`
414+ - `R_m_sfc` is the moist-air gas constant evaluated from `ᶜq_tot` at the surface
415+ - `T_sfc` is the air temperature from `ᶜT` at the surface
416+
417+ Returns `true` if the correction is applied; returns `false` if the surface
418+ altitude field cannot be loaded.
419+
420+ Arguments
421+ - `p_sfc`: face field of surface pressure to be corrected (modified in-place)
422+ - `file_path`: path to the ERA5-derived initialization NetCDF file
423+ - `face_space`: face space of the model grid (for reading/regridding)
424+ - `Y`: prognostic state, used to obtain model surface height
425+ - `ᶜT`: center field of temperature
426+ - `ᶜq_tot`: center field of total specific humidity
427+ - `thermo_params`: thermodynamics parameter set
428+ - `regridder_kwargs`: keyword arguments forwarded to the regridder
429+ - `surface_altitude_var`: variable name for surface altitude (default `"z_sfc"`)
430+ """
431+ function correct_surface_pressure_for_topography! (
432+ p_sfc,
433+ file_path,
434+ face_space,
435+ Y,
436+ ᶜT,
437+ ᶜq_tot,
438+ thermo_params,
439+ regridder_kwargs;
440+ surface_altitude_var = " z_sfc" ,
441+ )
442+ ᶠz_surface = Fields. level (
443+ SpaceVaryingInputs. SpaceVaryingInput (
444+ file_path,
445+ surface_altitude_var,
446+ face_space,
447+ regridder_kwargs = regridder_kwargs,
448+ ),
449+ Fields. half,
450+ )
451+
452+ if ᶠz_surface === nothing
453+ return false
454+ end
455+
456+ FT = eltype (thermo_params)
457+ grav = thermo_params. grav
458+
459+ ᶠz_model_surface = Fields. level (Fields. coordinate_field (Y. f). z, Fields. half)
460+ ᶠΔz = zeros (face_space)
461+ @. ᶠΔz = ᶠz_model_surface - ᶠz_surface
462+
463+ ᶠR_m = ᶠinterp .(TD. gas_constant_air .(thermo_params, TD. PhasePartition .(ᶜq_tot)))
464+ ᶠR_m_sfc = Fields. level (ᶠR_m, Fields. half)
465+
466+ ᶠT = ᶠinterp .(ᶜT)
467+ ᶠT_sfc = Fields. level (ᶠT, Fields. half)
468+
469+ @. p_sfc = p_sfc * exp (FT (- 1 ) * ᶠΔz * grav / (ᶠR_m_sfc * ᶠT_sfc))
470+
471+ @info " Adjusted surface pressure to account for ERA5/model surface-height differences."
472+ return true
473+ end
474+
389475# WeatherModel function using the shared implementation
390476function overwrite_initial_conditions! (
391477 initial_condition:: WeatherModel ,
@@ -436,6 +522,26 @@ function overwrite_initial_conditions!(
436522 center_space,
437523 regridder_kwargs = regridder_kwargs,
438524 )
525+ # Apply hydrostatic surface-pressure correction only if surface altitude is available
526+ surface_altitude_var = " z_sfc"
527+ has_surface_altitude = NC. NCDataset (file_path) do ds
528+ haskey (ds, surface_altitude_var)
529+ end
530+ if has_surface_altitude
531+ correct_surface_pressure_for_topography! (
532+ p_sfc,
533+ file_path,
534+ face_space,
535+ Y,
536+ ᶜT,
537+ ᶜq_tot,
538+ thermo_params,
539+ regridder_kwargs;
540+ surface_altitude_var = surface_altitude_var,
541+ )
542+ else
543+ @warn " Skipping topographic correction because variable `$surface_altitude_var ` is missing from $(file_path) ."
544+ end
439545
440546 # With the known temperature (ᶜT) and moisture (ᶜq_tot) profile,
441547 # recompute the pressure levels assuming hydrostatic balance is maintained.
0 commit comments