Source code for pycif.plugins.models.chimere.io.outputs.make_aout

import xarray as xr
import numpy as np

from ......utils.hdf5 import _hdf5_lock


[docs] def make_aout(self, runsubdir, ddi): """Create zeroed adjoint output files expected by the CHIMERE adjoint executable. Writes four NetCDF3 CLASSIC files into *runsubdir*: * ``aout.aemis.nc`` — adjoint sensitivities w.r.t. anthropogenic emissions; shape ``(nhours+1, nlevemis, nlat, nlon)`` per species. * ``aout.bemis.nc`` — adjoint sensitivities w.r.t. biogenic emissions; shape ``(nhours+1, nlevemis_bio, nlat, nlon)`` per species. * ``aout.ini.nc`` — adjoint sensitivities w.r.t. initial concentrations; shape ``(nivout, nlat, nlon)`` per species. * ``aout.bc.nc`` — adjoint sensitivities w.r.t. boundary conditions; contains ``top_conc`` and ``lat_conc`` tensors. All arrays are initialised to zero; the CHIMERE adjoint executable accumulates sensitivities into them during the backward run. Args: self: CHIMERE model plugin instance (carries ``domain``, ``chemistry.acspecies``, ``chemistry.emis_species``, ``chemistry.bio_species``, ``nhours``, ``nlevemis``, ``nlevemis_bio``, ``nivout``). runsubdir (str): path to the period run directory. ddi (datetime): period start date (unused; kept for API symmetry with other io functions). """ # Domain domain = self.domain # Active species acspec = self.chemistry.acspecies.attributes[:] aemis_species = self.chemistry.emis_species.attributes[:] bemis_species = self.chemistry.bio_species.attributes[:] # Aout.aemis.nc ds = xr.Dataset( {s: (("Time", "bottom_top", "south_north", "west_east"), np.zeros((self.nhours + 1, self.nlevemis, domain.nlat, domain.nlon))) for s in aemis_species} ) spec_dtype = np.dtype(('S', 23)) ds["species"] = xr.DataArray( [s.ljust(23) for s in aemis_species], dims=["Species"]).astype(spec_dtype) with _hdf5_lock: ds.to_netcdf(f"{runsubdir}/aout.aemis.nc", "w", format="NETCDF3_CLASSIC", encoding={'species': {'char_dim_name': 'SpStrLen'}}) # Aout.bemis.nc ds = xr.Dataset( {s: (("Time", "bottom_top", "south_north", "west_east"), np.zeros((self.nhours + 1, self.nlevemis_bio, domain.nlat, domain.nlon))) for s in bemis_species} ) spec_dtype = np.dtype(('S', 23)) ds["species"] = xr.DataArray( [s.ljust(23) for s in bemis_species], dims=["Species"]).astype(spec_dtype) with _hdf5_lock: ds.to_netcdf(f"{runsubdir}/aout.bemis.nc", "w", format="NETCDF3_CLASSIC", encoding={'species': {'char_dim_name': 'SpStrLen'}}) # Aout.ini.nc ds = xr.Dataset( {s: (("bottom_top", "south_north", "west_east"), np.zeros((self.nivout, domain.nlat, domain.nlon))) for s in acspec} ) spec_dtype = np.dtype(('S', 23)) ds["species"] = xr.DataArray( [s.ljust(23) for s in acspec], dims=["Species"]).astype(spec_dtype) with _hdf5_lock: ds.to_netcdf(f"{runsubdir}/aout.ini.nc", "w", format="NETCDF3_CLASSIC", encoding={'species': {'char_dim_name': 'SpStrLen'}}) # Aout.bc.nc ds = xr.Dataset({ "top_conc": (("Time", "south_north", "west_east", "Species"), np.zeros((self.nhours + 1, domain.nlat, domain.nlon, len(acspec)))), "lat_conc": (("Time", "bottom_top", "h_boundary", "Species"), np.zeros((self.nhours + 1, self.nivout, domain.nlon_side, len(acspec)))) }) spec_dtype = np.dtype(('S', 23)) ds["species"] = xr.DataArray( [s.ljust(23) for s in acspec], dims=["Species"]).astype(spec_dtype) with _hdf5_lock: ds.to_netcdf(f"{runsubdir}/aout.bc.nc", "w", format="NETCDF3_CLASSIC", encoding={'species': {'char_dim_name': 'SpStrLen'}})