diff --git a/src/c/fabm_c.F90 b/src/c/fabm_c.F90 index abdbacfb..c522969a 100644 --- a/src/c/fabm_c.F90 +++ b/src/c/fabm_c.F90 @@ -476,7 +476,7 @@ function get_variable(pmodel, category, index) bind(c) result(pvariable) case (HORIZONTAL_DIAGNOSTIC_VARIABLE) variable => model%p%horizontal_diagnostic_variables(index)%original case (CONSERVED_QUANTITY) - variable => model%p%conserved_quantities(index)%target + variable => model%p%conserved_quantities(index)%target_hz case (INTERIOR_DEPENDENCY, HORIZONTAL_DEPENDENCY, SCALAR_DEPENDENCY) select case (category) case (INTERIOR_DEPENDENCY); domain = domain_interior diff --git a/src/pyfabm/__init__.py b/src/pyfabm/__init__.py index 17d612d8..a2da3b62 100644 --- a/src/pyfabm/__init__.py +++ b/src/pyfabm/__init__.py @@ -592,7 +592,7 @@ def __getitem__(self, key: str) -> Union[float, int, bool]: raise KeyError -class Variable(object): +class Variable: def __init__( self, model: "Model", @@ -855,6 +855,19 @@ def reset(self): self.model._update_configuration(settings) +class ConservedQuantity(Variable): + def __init__( + self, model: "Model", name: str, units: str, variable_pointer: ctypes.c_void_p + ): + super().__init__(model, name, units, name.replace("_", " ")) + self._pvariable = variable_pointer + + @property + def missing_value(self) -> float: + """Value that indicates missing data, for instance, on land.""" + return self.model.fabm.variable_get_missing_value(self._pvariable) + + class StandardVariable: def __init__(self, model: "Model", pointer: ctypes.c_void_p): self.model = model @@ -1055,7 +1068,7 @@ def __init__( self.bottom_state_variables: NamedObjectList[StateVariable] = NamedObjectList() self.interior_diagnostic_variables: NamedObjectList[DiagnosticVariable] = NamedObjectList() self.horizontal_diagnostic_variables: NamedObjectList[DiagnosticVariable] = NamedObjectList() - self.conserved_quantities: NamedObjectList[Variable] = NamedObjectList() + self.conserved_quantities: NamedObjectList[ConservedQuantity] = NamedObjectList() self.parameters: NamedObjectList[Parameter] = NamedObjectList() self.interior_dependencies: NamedObjectList[Dependency] = NamedObjectList() self.horizontal_dependencies: NamedObjectList[Dependency] = NamedObjectList() @@ -1364,13 +1377,13 @@ def _update_configuration(self, settings: Optional[Tuple] = None): strlong_name, strpath, ) + ptr = self.fabm.get_variable(self.pmodel, CONSERVED_QUANTITY, i + 1) self.conserved_quantities._data.append( - Variable( + ConservedQuantity( self, strname.value.decode("ascii"), strunits.value.decode("ascii"), - strlong_name.value.decode("ascii"), - strpath.value.decode("ascii"), + ptr, ) ) for i in range(nparameters.value): @@ -1427,7 +1440,9 @@ def _update_configuration(self, settings: Optional[Tuple] = None): self.itime = -1.0 - def getRates(self, t: Optional[float] = None, surface: bool = True, bottom: bool = True): + def getRates( + self, t: Optional[float] = None, surface: bool = True, bottom: bool = True + ): """Returns the local rate of change in state variables, given the current state and environment. """ @@ -1501,6 +1516,9 @@ def get_vertical_movement(self, out: Optional[np.ndarray] = None) -> np.ndarray: return out def get_conserved_quantities(self, out: Optional[np.ndarray] = None) -> np.ndarray: + """Return depth-integrated values across the horizontal domain for all + conserved quantities + """ assert ( self._cell_thickness is not None ), "You must assign model.cell_thickness to use get_conserved_quantities"