@@ -121,19 +121,34 @@ Updates the coupler with the surface properties. The `Interfacer.get_field`
121121functions for (`:surface_temperature`, `:surface_direct_albedo`,
122122`:surface_diffuse_albedo`) need to be specified for each surface model.
123123
124- Note: The calculation of surface humidity uses atmospheric properties stored in
124+ Note: The calculation of surface humidity done here uses atmospheric properties stored in
125125the coupled fields. For these values to be correct, this function should be called
126126after `import_atmos_fields!` in a timestep.
127127
128+ Note 2: Not all surface fields are imported here. Some quantities are retrieved
129+ from each surface model when surface fluxes are computed, in `compute_surface_fluxes!`.
130+
128131# Arguments
129132- `csf`: [NamedTuple] containing coupler fields.
130133- `model_sims`: [NamedTuple] containing `ComponentModelSimulation`s.
131134- `thermo_params`: [TD.Parameters.ThermodynamicsParameters] the thermodynamic parameters.
132135"""
133136function import_combined_surface_fields! (csf, model_sims, thermo_params)
134- combine_surfaces! (csf. T_sfc, model_sims, Val (:surface_temperature ))
135- combine_surfaces! (csf. surface_direct_albedo, model_sims, Val (:surface_direct_albedo ))
136- combine_surfaces! (csf. surface_diffuse_albedo, model_sims, Val (:surface_diffuse_albedo ))
137+ combine_surfaces! (csf. emissivity, model_sims, Val (:emissivity ), csf. temp1)
138+ combine_surfaces! (
139+ csf. surface_direct_albedo,
140+ model_sims,
141+ Val (:surface_direct_albedo ),
142+ csf. temp1,
143+ )
144+ combine_surfaces! (
145+ csf. surface_diffuse_albedo,
146+ model_sims,
147+ Val (:surface_diffuse_albedo ),
148+ csf. temp1,
149+ )
150+ # Temperature requires emissivity, so we provide all the coupler fields
151+ combine_surfaces! (csf, model_sims, Val (:surface_temperature ))
137152
138153 # q_sfc is computed from the atmosphere state and surface temperature, so it's handled differently
139154 # This is computed on the exchange grid, so there's no need to remap
181196"""
182197 update_sim!(atmos_sim::Interfacer.AtmosModelSimulation, csf)
183198
184- Updates the surface fields for temperature, roughness length, albedo, and specific humidity.
199+ Updates the atmosphere's fields for surface direct and diffuse albedos, emissivity, and temperature,
200+ as well as the turbulent fluxes.
185201
186202# Arguments
187203- `atmos_sim`: [Interfacer.AtmosModelSimulation] containing an atmospheric model simulation object.
@@ -198,6 +214,7 @@ function update_sim!(atmos_sim::Interfacer.AtmosModelSimulation, csf)
198214 Val (:surface_diffuse_albedo ),
199215 csf. surface_diffuse_albedo,
200216 )
217+ Interfacer. update_field! (atmos_sim, Val (:emissivity ), csf. emissivity)
201218 Interfacer. update_field! (atmos_sim, Val (:surface_temperature ), csf)
202219 Interfacer. update_field! (atmos_sim, Val (:turbulent_fluxes ), csf)
203220 return nothing
@@ -270,36 +287,79 @@ function step_model_sims!(cs::Interfacer.CoupledSimulation)
270287end
271288
272289"""
273- combine_surfaces!(combined_field::CC.Fields.Field, sims, field_name::Val)
290+ combine_surfaces!(combined_field::CC.Fields.Field, sims, field_name::Val, temp1 )
274291
275292Sums the fields, specified by `field_name`, weighted by the respective area fractions of all
276293surface simulations. THe result is saved in `combined_field`.
277294
295+ For surface temperature, upward longwave radiation is computed from the temperatures
296+ of each surface, weighted by their area fractions, and then the combined temperature
297+ is computed from the combined upward longwave radiation.
298+
278299# Arguments
279300- `combined_field`: [CC.Fields.Field] output object containing weighted values.
301+ Note: For the surface temperature, all coupler fields are passed in a NamedTuple.
280302- `sims`: [NamedTuple] containing simulations .
281303- `field_name`: [Val] containing the name Symbol of the field t be extracted by the `Interfacer.get_field` functions.
304+ - `temp1`: [CC.Fields.Field] temporary field for intermediate calculations.
305+ Omitted for surface temperature method.
282306
283307# Example
284308- `combine_surfaces!(temp_field, cs.model_sims, Val(:surface_temperature))`
285309"""
286- function combine_surfaces! (combined_field, sims, field_name)
310+ function combine_surfaces! (combined_field, sims, field_name, temp1 )
287311 boundary_space = axes (combined_field)
288312 combined_field .= 0
289313 for sim in sims
290314 if sim isa Interfacer. SurfaceModelSimulation
291- # Zero out the contribution from this surface if the area fraction is zero
315+ # Store the area fraction of this simulation in `temp1`
316+ Interfacer. get_field! (temp1, sim, Val (:area_fraction ))
317+ # Zero out the contribution from this surface if the area fraction is zero.
292318 # Note that multiplying by `area_fraction` is not sufficient in the case of NaNs
293- area_fraction = Interfacer. get_field (sim, Val (:area_fraction ))
294319 combined_field .+ =
295- area_fraction .*
320+ temp1 .*
296321 ifelse .(
297- area_fraction .≈ 0 ,
322+ temp1 .≈ 0 ,
298323 zero (combined_field),
299324 Interfacer. get_field (sim, field_name, boundary_space),
300325 )
301326 end
302327 end
328+ return nothing
329+ end
330+ function combine_surfaces! (csf, sims, field_name:: Val{:surface_temperature} )
331+ # extract the coupler fields we need to get the surface temperature
332+ T_sfc = csf. T_sfc
333+ emissivity_sfc = csf. emissivity
334+
335+ boundary_space = axes (T_sfc)
336+ FT = CC. Spaces. undertype (boundary_space)
337+
338+ T_sfc .= FT (0 )
339+ for sim in sims
340+ if sim isa Interfacer. SurfaceModelSimulation
341+ # Store the area fraction and emissivity of this simulation in temp fields
342+ Interfacer. get_field! (csf. temp1, sim, Val (:area_fraction ))
343+ area_fraction = csf. temp1
344+ Interfacer. get_field! (csf. temp2, sim, Val (:emissivity ))
345+ emissivity_sim = csf. temp2
346+
347+ # Zero out the contribution from this surface if the area fraction is zero.
348+ # Note that multiplying by `area_fraction` is not sufficient in the case of NaNs
349+ # Compute upward longwave radiation from surface temperature for this simulation
350+ T_sfc .+ =
351+ area_fraction .*
352+ ifelse .(
353+ area_fraction .≈ 0 ,
354+ zero (T_sfc),
355+ emissivity_sim .*
356+ Interfacer. get_field (sim, field_name, boundary_space) .^ FT (4 ),
357+ )
358+ end
359+ end
360+ # Convert the combined upward longwave radiation into a surface temperature
361+ @. T_sfc = (T_sfc / emissivity_sfc)^ FT (1 / 4 )
362+ return nothing
303363end
304364
305365"""
0 commit comments