FieldExchanger
This module contains general functions for the exchange of fields between the atmospheric and surface component models.
The main function of the FieldExchanger is exchange!, which does the following:
- imports atmospheric fields into the coupler fields, via
import_atmos_fields! - imports area fraction-weighted surface fields into the coupler fields, via
import_combined_surface_fields! - updates all component models with the newly-updated coupler fields, via
update_model_sims!
The specific fields that are exchanged depend on the requirements of the component models:
The fields imported from the atmosphere to the coupler are specified by extending FieldExchanger.import_atmos_fields! The default import_atmos_fields! imports radiative fluxes, liquid precipitation, and snow precipitation.
The fields of a component model that get updated by the coupler are specified by extending FieldExchanger.update_sim!. The default update_sim! for an atmosphere model updates the direct and diffuse surface albedos, the surface temperature, and the turbulent fluxes. The default update_sim! for a surface model updates the air density, radiative fluxes, liquid precipitation, and snow precipitation. These updates are done via the update_field! function, which must be extended for the particular variable and component model. If an update_field! function is not defined for a particular component model, it will be ignored.
Note that turbulent fluxes are not updated in update_sim!, but rather via FluxCalculator.update_turbulent_fluxes!, where fluxes are computed between the atmosphere and each surface model.
FieldExchanger API
ClimaCoupler.FieldExchanger.exchange! — Functionexchange!(cs::Interfacer.CoupledSimulation)Exchange fields between the surface and atmosphere models. This is done in 2 steps:
- Import the atmosphere fields and surface fields into the coupler.
- Update the component model simulations with the coupler fields.
The order of these steps is important, as importing the surface fields requires the atmosphere fields to be updated so that surface humidity can be computed.
ClimaCoupler.FieldExchanger.update_sim! — Functionupdate_sim!(sim::BucketSimulation, csf)Updates the surface component model cache with the current coupler fields besides turbulent fluxes.
Arguments
sim: [Interfacer.AbstractSurfaceSimulation] containing a surface model simulation object.csf: [NamedTuple] containing coupler fields.
FieldExchanger.update_sim!(sim::OceananigansSimulation, csf)Update the ocean simulation with the provided fields, which have been filled in by the coupler.
Update the portion of the surfacefluxes for T and S that is due to radiation and precipitation. The rest will be updated in `updateturbulent_fluxes!`.
This function sets the surface fluxes directly, overwriting any previous values. Additional contributions will be made in update_turbulent_fluxes! and ocean_seaice_fluxes!.
A note on sign conventions: ClimaAtmos and Oceananigans both use the convention that a positive flux is an upward flux. No sign change is needed during the exchange, except for precipitation/salinity fluxes. ClimaAtmos provides precipitation as a negative flux at the surface, and Oceananigans represents precipitation as a positive salinity flux, so a sign change is needed when we convert from precipitation to salinity flux.
FieldExchanger.update_sim!(sim::ClimaSeaIceSimulation, csf)Update the sea ice simulation with the provided fields, which have been filled in by the coupler.
Update the portion of the surfacefluxes for T and S that is due to radiation and precipitation. The rest will be updated in `updateturbulent_fluxes!`.
Note that currently precipitation has no effect on the sea ice model, which has constant salinity.
A note on sign conventions: ClimaAtmos and ClimaSeaIce both use the convention that a positive flux is an upward flux. No sign change is needed during the exchange, except for precipitation/salinity fluxes. ClimaAtmos provides precipitation as a negative flux at the surface, and ClimaSeaIce represents precipitation as a positive salinity flux, so a sign change is needed when we convert from precipitation to salinity flux.
update_sim!(atmos_sim::Interfacer.AbstractAtmosSimulation, csf)Updates the atmosphere's fields for surface direct and diffuse albedos, emissivity,and temperature.
Arguments
atmos_sim: [Interfacer.AbstractAtmosSimulation] containing an atmospheric model simulation object.csf: [NamedTuple] containing coupler fields.
update_sim!(sim::AbstractSurfaceSimulation, csf)Updates the surface component model cache with the current coupler fields besides turbulent fluxes, which are updated in update_turbulent_fluxes.
Note that upwelling longwave and shortwave radiation are not computed here, and are expected to be computed internally by the surface model. Some component models extend this function and compute the upwelling longwave and shortwave radiation in their methods of update_sim!.
Arguments
sim: [Interfacer.AbstractSurfaceSimulation] containing a surface model simulation object.csf: [NamedTuple] containing coupler fields.
FieldExchanger.update_sim!(::PrescribedOceanSimulation, csf)Update the wind velocity (needed for the turbulent flux calculation) and the direct and diffuse albedos of the ocean.
ClimaCoupler.FieldExchanger.step_model_sims! — Functionstep_model_sims!(model_sims, t, coupler_fields, thermo_params)
step_model_sims!(cs::CoupledSimulation)Iterates step! over all component model simulations saved in cs.model_sims.
Arguments
model_sims: [NamedTuple] containingAbstractComponentSimulations.t: [AbstractFloat or ITime] denoting the simulation time.
ClimaCoupler.FieldExchanger.update_surface_fractions! — Functionupdate_surface_fractions!(cs::Interfacer.CoupledSimulation)Updates dynamically changing area fractions. Maintains the invariant that the sum of area fractions is 1 at all points. Area fractions are expected to be defined on the boundary space of the coupled simulation, since they are used by the coupler.
If a surface model is not present, the area fraction is set to 0.
Arguments
cs: [Interfacer.CoupledSimulation] containing area fraction information.
ClimaCoupler.FieldExchanger.set_caches! — Functionset_caches!(cs::Interfacer.CoupledSimulation)Perform any initialization of the component model caches that cannot be done before the initial exchange. This is useful in handling cache interdependencies between component models.
For example, the radiation callback in the atmosphere model needs to be initialized with the surface temperatures, which are only available after the initial exchange. The integrated land, in turn, requires its drivers in the cache to be filled with the initial radiation fluxes, so that it can propagate these to the rest of its cache (e.g. in canopy radative transfer).
This function can also be used to set exchanged fields that are static over the simulation, since it is only called at initialization.
FieldExchanger Internal Functions
ClimaCoupler.FieldExchanger.combine_surfaces! — Functioncombine_surfaces!(csf, sims, field_name_val::Val{field_name}) where {field_name}Sums the surface fields specified by field_name_val, weighted by the respective area fractions of all surface simulations. The result is saved in the coupler field specified by field_name_val.
For surface temperature, upward longwave radiation is computed from the temperatures of each surface, weighted by their area fractions, and then the combined temperature is computed from the combined upward longwave radiation.
Arguments
csf: [NamedTuple] containing coupler fields. Note: For the surface temperature, all coupler fields are passed in a NamedTuple.sims: [NamedTuple] containing simulations.field_name_val: [Val] containing the name Symbol of the field to be extracted by theInterfacer.get_fieldfunctions.
Example
combine_surfaces!(temp_field, cs.model_sims, Val(:emissivity))
ClimaCoupler.FieldExchanger.resolve_area_fractions! — FunctionFieldExchanger.resolve_area_fractions!(ocean_sim, ice_sim, land_fraction)Ensure the ocean and ice area fractions are consistent with each other. This matters in the case of a LatitudeLongitudeGrid, which is only defined between -80 and 80 degrees latitude. In this case, we set the ice and ocean area fractions to 0 and the land fraction to 1 on [78°S, 90°S] and on [78°N, 90°N]. Note the overlap between 78° and 80° to avoid any gaps introduced by the cubed sphere not aligning with latitude lines.
This function also updates the ice concentration field in the ocean simulation so that it can be used for weighting flux updates.
resolve_area_fractions!(ocean_sim, ice_sim, land_fraction)Ensure that the ocean and ice fractions are consistent with each other. For most ocean and ice models, this does nothing since the ocean fraction is defined as 1 - ice_fraction - land_fraction. However, some models may have additional constraints on the ice and ocean fractions that need to be enforced. This function can be extended for such models.
ClimaCoupler.FieldExchanger.import_atmos_fields! — FunctionFieldExchanger.importatmosfields!(csf, sim::BucketSimulation, atmos_sim)
Import non-default coupler fields from the atmosphere simulation into the coupler fields. These include the diffuse fraction of light, shortwave and longwave downwelling radiation, air pressure, and CO2 concentration.
The default coupler fields will be imported by the default method implemented in FieldExchanger.jl.
FieldExchanger.importatmosfields!(csf, sim::ClimaLandSimulation, atmos_sim)
Import non-default coupler fields from the atmosphere simulation into the coupler fields. These include the diffuse fraction of light, shortwave and longwave downwelling radiation, air pressure, and CO2 concentration.
The default coupler fields will be imported by the default method implemented in FieldExchanger.jl.
import_atmos_fields!(csf, model_sims)Update the coupler with quantities from the atmosphere model. By default, this updates the coupler fields for quantities required for turbulent flux calculations, radiative fluxes, and precipitation. This function should be extended for any model that requires additional fields from the atmosphere.
Arguments
csf: [NamedTuple] containing coupler fields.model_sims: [NamedTuple] containingAbstractComponentSimulations.
import_atmos_fields!(csf, ::Interfacer.AbstractComponentSimulation, atmos_sim)Updates the coupler simulation fields with atmospheric fluxes from the atmosphere simulation. This function should be extended for any surface model that requires additional fields from the atmosphere. Any fields added in a method of this function should also be added in the corresponding method of Interfacer.add_coupler_fields!. The combination of these two functions defines any extra atmosphere fields provided to the surface.
FieldExchanger.import_atmos_fields!(csf, sim::PrescribedOceanSimulation, atmos_sim)Import wind from atmos.