Index: environment.yml =================================================================== diff -u -r07f2b223fbd014cc1c66fda97607d55b8118238f -r060a4825462d4eceaf175cb9730049d47d9602ea --- environment.yml (.../environment.yml) (revision 07f2b223fbd014cc1c66fda97607d55b8118238f) +++ environment.yml (.../environment.yml) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -1,16 +1,17 @@ -name: wflow +name: wflow_pcr channels: - conda-forge - defaults dependencies: - - python=3.6 + - python=3.7 + - pcraster - numpy>=1.12 - scipy>=1.0 - gdal>=3 - netcdf4>=1.4.1 - - cftime=1.0.4 + - cftime>=1.0.4 - xarray>=0.11 - pyproj=2.4 - thrift>=0.11 Index: tests/test_BMI.py =================================================================== diff -u -rc5362fb4ba379eb1e90a1b9a93afe5137e3c3e5e -r060a4825462d4eceaf175cb9730049d47d9602ea --- tests/test_BMI.py (.../test_BMI.py) (revision c5362fb4ba379eb1e90a1b9a93afe5137e3c3e5e) +++ tests/test_BMI.py (.../test_BMI.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -15,48 +15,51 @@ class MyTest(unittest.TestCase): + + def testbmifuncs(self): + grid_id = 1 bmiobj = bmi.wflowbmi_csdms() bmiobj.initialize("wflow_sceleton/wflow_sceleton.ini", loglevel=logging.ERROR) print("-------------- Grid origin: ") - gorigin = bmiobj.get_grid_origin("Altitude") + gorigin = bmiobj.get_grid_origin(grid_id) # print(gorigin) self.assertAlmostEqual( sum([45.875934703275561, 5.2088299822062254]), sum(gorigin), places=4 ) print("-------------- Grid shape: ") - print((bmiobj.get_grid_shape("Altitude"))) + print((bmiobj.get_grid_shape(grid_id))) self.assertAlmostEqual( - sum([169, 187]), sum(bmiobj.get_grid_shape("Altitude")), places=4 + sum([169, 187]), sum(bmiobj.get_grid_shape(grid_id)), places=4 ) print("-------------- Grid spacing: ") - print((bmiobj.get_grid_spacing("Altitude"))) + print((bmiobj.get_grid_spacing(grid_id))) self.assertAlmostEqual( sum([0.036666665, 0.036666665]), - sum(bmiobj.get_grid_spacing("Altitude")), + sum(bmiobj.get_grid_spacing(grid_id)), places=4, ) print("-------------- Grid X: ") - print((bmiobj.get_grid_x("Altitude"))) + print((bmiobj.get_grid_x(grid_id))) self.assertAlmostEqual( - 5.22716331, bmiobj.get_grid_x("Altitude")[0, 0], places=4 + 5.22716331, bmiobj.get_grid_x(grid_id)[0], places=4 ) print("-------------- Grid Y: ") - print((bmiobj.get_grid_y("Altitude"))) + print((bmiobj.get_grid_y(grid_id))) self.assertAlmostEqual( - 45.89426804, bmiobj.get_grid_y("Altitude")[0, 0], places=4 + 45.89426804, bmiobj.get_grid_y(grid_id)[0], places=4 ) print("-------------- Grid Z: ") - print((bmiobj.get_grid_z("Altitude"))) + print((bmiobj.get_grid_z(grid_id))) self.assertAlmostEqual( - 218.44944763, bmiobj.get_grid_z("Altitude")[0, 0], places=4 + 218.44944763, bmiobj.get_grid_z(grid_id)[0,0], places=4 ) print("-------------- Name: ") @@ -113,7 +116,7 @@ print((time.localtime(bmiobj.get_end_time()))) print("-------------- Grid type: ") - print((bmiobj.get_grid_type("Altitude"))) + print((bmiobj.get_grid_type(grid_id))) print("-------------- Var type: ") print((bmiobj.get_var_type("Altitude"))) Index: wflow/bmi.py =================================================================== diff -u -rfbd077ecd824c16e9e207b542e5ee2f9f9ff92dd -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/bmi.py (.../bmi.py) (revision fbd077ecd824c16e9e207b542e5ee2f9f9ff92dd) +++ wflow/bmi.py (.../bmi.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -14,6 +14,13 @@ 4. Added comments. Where the original version of the CSDMS BMI Python Language Binding was ambiguous, the information from http://csdms.colorado.edu/wiki/BMI_Description and common sense were used to fill in most of the gaps. """ +""" +2018-2-10 +Netherlands eScience Center +Gijs van den Oord +Modifications to comply with modern csdms BMI. +""" + from abc import ABCMeta, abstractmethod @@ -22,11 +29,10 @@ Enumeration with grid types. """ - UNKNOWN = 0 - UNIFORM = 1 - RECTILINEAR = 2 - STRUCTURED = 3 - UNSTRUCTURED = 4 + UNIFORM = "uniform_rectilinear" + RECTILINEAR = "rectilinear" + STRUCTURED = "structured_quadrilateral" + UNSTRUCTURED = "unstructured" class Bmi(object, metaclass=ABCMeta): @@ -176,11 +182,22 @@ String long_var_name: identifier of a variable in the model. Return value: - ???: ??? + Integer: total number of bytes taken by the return array of get_var(long_var_name) """ raise NotImplementedError @abstractmethod + def get_var_itemsize(self, long_var_name): + """ + Input parameters: + String long_var_name: identifier of a variable in the model. + + Return value: + Integer: size, in bytes, of each item of the variable + """ + raise NotImplementedError + + @abstractmethod def get_start_time(self): """ Return value: @@ -231,7 +248,8 @@ String long_var_name: identifier of a variable in the model. Return value: - Numpy array of values in the data type returned by the function get_var_type: all values of the given variable. + Flat numpy array of values in the data type returned by the function get_var_type: all values of the given + variable. """ raise NotImplementedError @@ -240,12 +258,10 @@ """ Input parameters: String long_var_name: identifier of a variable in the model. - List of Lists of integers inds: each nested List contains one index for each dimension of the given variable, - i.e. each nested List indicates one element in the multi-dimensional variable array, - e.g. [[0, 0, 0], [0, 0, 1], [0, 15, 19], [0, 15, 20], [0, 15, 21]] indicates 5 elements in a 3D grid. - + Lists of integers inds: denotes the indices within the flattened list that get_value(long_var_name) returns. Return value: - Numpy array of values in the data type returned by the function get_var_type: one value for each of the indicated elements. + Numpy array of values in the data type returned by the function get_var_type: one value for each of the + indicated elements. """ raise NotImplementedError @@ -263,9 +279,7 @@ """ Input parameters: String long_var_name: identifier of a variable in the model. - List of Lists of integers inds: each nested List contains one index for each dimension of the given variable, - i.e. each nested List indicates one element in the multi-dimensional variable array, - e.g. [[0, 0], [0, 1], [15, 19], [15, 20], [15, 21]] indicates 5 elements in a 2D grid. + Lists of integers inds: denotes the indices within the flattened list that get_value(long_var_name) returns. Numpy array of values src: one value to set for each of the indicated elements. """ raise NotImplementedError @@ -275,119 +289,157 @@ """ @abstractmethod - def get_grid_type(self, long_var_name): + def get_var_grid(self, long_var_name): """ Input parameters: String long_var_name: identifier of a variable in the model. Return value: - BmiGridType type of the grid geometry of the given variable. + Integer: identifier for the grid on which the variable is defined. """ raise NotImplementedError @abstractmethod - def get_grid_shape(self, long_var_name): + def get_grid_type(self, grid_id): """ + Input parameters: + Integer grid_id: identifier of a grid in the model. + + Return value: + string type of the grid geometry of the given variable. + """ + raise NotImplementedError + + @abstractmethod + def get_grid_rank(self, grid_id): + """ + Input parameters: + Integer grid_id: identifier of a grid in the model. + + Return value: + Integer: number of values returned by get_grid_shape(grid_id) + """ + raise NotImplementedError + + @abstractmethod + def get_grid_shape(self, grid_id): + """ Only return something for variables with a uniform, rectilinear or structured grid. Otherwise raise ValueError. Input parameters: - String long_var_name: identifier of a variable in the model. + Integer grid_id: identifier of a grid in the model. Return value: - List of integers: the sizes of the dimensions of the given variable, e.g. [500, 400] for a 2D grid with 500x400 grid cells. + List of integers: the sizes of the dimensions of the given variable, e.g. [500, 400] for a 2D grid with 500x400 + grid cells. """ raise NotImplementedError @abstractmethod - def get_grid_spacing(self, long_var_name): + def get_grid_size(self, grid_id): """ + Input parameters: + Integer grid_id: identifier of a grid in the model. + Integer: The total size (nr of cells) of the grid with identifier grid_id + """ + raise NotImplementedError + + @abstractmethod + def get_grid_spacing(self, grid_id): + """ Only return something for variables with a uniform grid. Otherwise raise ValueError. Input parameters: - String long_var_name: identifier of a variable in the model. + Integer grid_id: identifier of a grid in the model. Return value: - List of doubles: the size of a grid cell for each of the dimensions of the given variable, e.g. [width, height] for a 2D grid cell. + Double: in case of a uniform equidistant grid, returns the distance between two neighboring cell centres. """ raise NotImplementedError @abstractmethod - def get_grid_origin(self, long_var_name): + def get_grid_origin(self, grid_id): """ Only return something for variables with a uniform grid. Otherwise raise ValueError. Input parameters: - String long_var_name: identifier of a variable in the model. + Integer grid_id: identifier of a grid in the model. Return value: - List of doubles: the coordinate of the grid origin for each of the dimensions of the given variable. For a 2D grid this must be the lower left corner of the grid. + List of doubles: components of the location of the lower-left corner of the grid """ raise NotImplementedError @abstractmethod - def get_grid_x(self, long_var_name): + def get_grid_x(self, grid_id): """ - Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise ValueError. + Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise + ValueError. Input parameters: String long_var_name: identifier of a variable in the model. Return value: - Numpy array of doubles: x coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. + Numpy array of doubles: x coordinate of grid cell center for each grid cell, in the same order as the values + returned by function get_value. For a rectilinear grid: x coordinate of column center for each column. """ raise NotImplementedError @abstractmethod - def get_grid_y(self, long_var_name): + def get_grid_y(self, grid_id): """ - Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise ValueError. + Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise + ValueError. Input parameters: String long_var_name: identifier of a variable in the model. Return value: - Numpy array of doubles: y coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. + Numpy array of doubles: y coordinate of grid cell center for each grid cell, in the same order as the values + returned by function get_value. For a rectilinear grid: y coordinate of row center for each row. """ raise NotImplementedError @abstractmethod - def get_grid_z(self, long_var_name): + def get_grid_z(self, grid_id): """ - Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise ValueError. + Only return something for variables with a rectilinear, structured or unstructured grid. Otherwise raise + ValueError. Input parameters: String long_var_name: identifier of a variable in the model. Return value: - Numpy array of doubles: z coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. + Numpy array of doubles: z coordinate of grid cell center for each grid cell, in the same order as the values + returned by function get_value. For a rectilinear grid: z coordinate of layer center for each layer. """ raise NotImplementedError @abstractmethod - def get_grid_connectivity(self, long_var_name): + def get_grid_connectivity(self, grid_id): """ Only return something for variables with an unstructured grid. Otherwise raise ValueError. Input parameters: String long_var_name: identifier of a variable in the model. Return value: - ??? + List of integers, defining the cell corners for each cell. """ raise NotImplementedError @abstractmethod - def get_grid_offset(self, long_var_name): + def get_grid_offset(self, grid_id): """ Only return something for variables with an unstructured grid. Otherwise raise ValueError. Input parameters: String long_var_name: identifier of a variable in the model. Return value: - ??? + List of integers, defining the grid offset for each cell. """ raise NotImplementedError Index: wflow/wf_netcdfio.py =================================================================== diff -u -ra9498adee6baab0a0abaa331041be8948510167b -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/wf_netcdfio.py (.../wf_netcdfio.py) (revision a9498adee6baab0a0abaa331041be8948510167b) +++ wflow/wf_netcdfio.py (.../wf_netcdfio.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -724,11 +724,9 @@ if self.datetimelist.size < ncindex + 1: ncindex = self.datetimelist.size - 1 - + if tsdatetime != None: - if tsdatetime.replace(tzinfo=None) != self.datetimelist[ncindex].replace( - tzinfo=None - ): + if tsdatetime.replace(tzinfo=None) != self.datetimelist[ncindex]: logging.warning( "Date/time does not match. Wanted " + str(tsdatetime) @@ -932,8 +930,7 @@ if var in self.dataset.variables: if tsdatetime != None: if tsdatetime.replace(tzinfo=None) != self.datetimelist[ - ncindex - ].replace(tzinfo=None): + ncindex]: logging.warning( "Date/time of state (" + var Index: wflow/wflow_bmi.py =================================================================== diff -u -r863f54c4ef95282d58cc4ab083d54d836c194dca -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/wflow_bmi.py (.../wflow_bmi.py) (revision 863f54c4ef95282d58cc4ab083d54d836c194dca) +++ wflow/wflow_bmi.py (.../wflow_bmi.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -8,6 +8,7 @@ import numpy as np import wflow.bmi as bmi import wflow.wflow_floodmap +import wflow.wflow_topoflex import wflow.wflow_hbv import wflow.wflow_lintul import wflow.wflow_routing @@ -25,6 +26,7 @@ wflow_models = [ wflow.wflow_sbm, wflow.wflow_hbv, + wflow.wflow_topoflex, wflow.wflow_routing, wflow.wflow_floodmap, wflow.wflow_lintul, @@ -1007,6 +1009,18 @@ self.bmilogger.debug("get_var_nbytes: " + str(npmap.size * npmap.itemsize)) return npmap.size * npmap.itemsize + def get_var_itemsize(self, long_var_name): + """ + Gets the number of bytes occupied in memory for a given variable grid point value. + + :var String long_var_name: identifier of a variable in the model: + :return: number of bytes contained in the given variable bytes per element. + """ + npmap = self.dynModel.wf_supplyMapAsNumpy(long_var_name) + + self.bmilogger.debug("get_var_itemsize: " + str(npmap.itemsize)) + return npmap.itemsize + def get_start_time(self): """ Gets the start time of the model. @@ -1121,7 +1135,7 @@ "get_value_at_indices: " + long_var_name + " at " + str(inds) ) npmap = self.dynModel.wf_supplyMapAsNumpy(long_var_name) - return npmap[inds] + return npmap.flat[inds] else: self.bmilogger.error( "get_value_at_indices: " @@ -1160,112 +1174,134 @@ "set_value_at_indices: " + long_var_name + " at " + str(inds) ) npmap = self.dynModel.wf_supplyMapAsNumpy(long_var_name) - npmap[inds] = src + npmap.flat[inds] = src self.dynModel.wf_setValuesAsNumpy(long_var_name, npmap) - def get_grid_type(self, long_var_name): + def get_var_grid(self, long_var_name): """ + Input parameters: + String long_var_name: identifier of a variable in the model. + + Return value: + Integer: identifier for the grid on which the variable is defined. + """ + if long_var_name in self.get_input_var_names() + self.get_output_var_names(): + return 1 + return -1 + + def get_grid_type(self, grid_id): + """ Get the grid type according to the enumeration in BmiGridType - :var String long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: BmiGridType type of the grid geometry of the given variable. """ - ret = BmiGridType() + if grid_id == 1: + ret = bmi.BmiGridType() + self.bmilogger.debug("get_grid_type: " + str(grid_id) + ' result: ' + str(ret.UNIFORM)) + return ret.UNIFORM + else: + raise Exception("Unknown grid id %d" % grid_id) - self.bmilogger.debug( - "get_grid_type: " + long_var_name + " result: " + str(ret.UNIFORM) - ) - - return ret.UNIFORM - - def get_grid_shape(self, long_var_name): + def get_grid_shape(self, grid_id): """ Return the shape of the grid. Only return something for variables with a uniform, rectilinear or structured grid. Otherwise raise ValueError. - :var long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: List of integers: the sizes of the dimensions of the given variable, e.g. [500, 400] for a 2D grid with 500x400 grid cells. """ - dim = self.dynModel.wf_supplyGridDim() - # [ Xll, Yll, xsize, ysize, rows, cols] + if grid_id == 1: + dim = self.dynModel.wf_supplyGridDim() + #[ Xll, Yll, xsize, ysize, rows, cols] - self.bmilogger.debug( - "get_grid_shape: " + long_var_name + " result: " + str([dim[4], dim[5]]) - ) + self.bmilogger.debug("get_grid_shape: " + str(grid_id) + ' result: ' + str([dim[4], dim[5]])) - return [dim[4], dim[5]] + return [dim[4], dim[5]] + else: + raise Exception("Unknown grid id %d" % grid_id) - def get_grid_spacing(self, long_var_name): + def get_grid_spacing(self, grid_id): """ Only return something for variables with a uniform grid. Otherwise raise ValueError. - :var long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: The size of a grid cell for each of the dimensions of the given variable, e.g. [width, height]: for a 2D grid cell. """ - dims = self.dynModel.wf_supplyGridDim()[2:4] - x = dims[0] - y = dims[1] - self.bmilogger.debug( - "get_grid_spacing: " + long_var_name + " result: " + str([y, x]) - ) - return [y, x] + if grid_id == 1: + dims = self.dynModel.wf_supplyGridDim()[2:4] + x = dims[0] + y = dims[1] + self.bmilogger.debug("get_grid_spacing: " + str(grid_id) + ' result: ' + str([y, x])) + return [y, x] + else: + raise Exception("Unknown grid id %d" % grid_id) - def get_grid_origin(self, long_var_name): + def get_grid_origin(self, grid_id): """ gets the origin of the model grid. - :var String long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: X, Y: ,the lower left corner of the grid. """ - dims = self.dynModel.wf_supplyGridDim() # returns in cell centre + if grid_id == 1: + dims = self.dynModel.wf_supplyGridDim() # returns in cell centre + xsize = dims[2] + ysize = dims[3] + x = dims[0] - (xsize * 0.5) + y = dims[7] - (ysize * 0.5) + self.bmilogger.debug("get_grid_origin: " + str(grid_id) + ' result: ' + str([y, x])) + return [y, x] + else: + raise Exception("Unknown grid id %d" % grid_id) - xsize = dims[2] - ysize = dims[3] - x = dims[0] - (xsize * 0.5) - y = dims[7] - (ysize * 0.5) - self.bmilogger.debug( - "get_grid_origin: " + long_var_name + " result: " + str([y, x]) - ) - return [y, x] - - def get_grid_x(self, long_var_name): + def get_grid_x(self, grid_id): """ Give X coordinates of point in the model grid - :var String long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: Numpy array of doubles: x coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. """ - self.bmilogger.debug("get_grid_x: " + long_var_name) - return self.dynModel.wf_supplyMapXAsNumpy() + if grid_id == 1: + self.bmilogger.debug("get_grid_x: " + str(grid_id)) + return self.dynModel.wf_supplyMapXAsNumpy()[0,:] + else: + raise Exception("Unknown grid id %d" % grid_id) - def get_grid_y(self, long_var_name): + def get_grid_y(self, grid_id): """ Give Y coordinates of point in the model grid - :var String long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: Numpy array of doubles: y coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. """ - self.bmilogger.debug("get_grid_y: " + long_var_name) - return self.dynModel.wf_supplyMapYAsNumpy() + if grid_id == 1: + self.bmilogger.debug("get_grid_y: " + str(grid_id)) + return self.dynModel.wf_supplyMapYAsNumpy()[:,0] + else: + raise Exception("Unknown grid id %d" % grid_id) - def get_grid_z(self, long_var_name): + def get_grid_z(self, grid_id): """ Give Z coordinates of point in the model grid - :var String long_var_name: identifier of a variable in the model. + :var Integer grid_id: identifier of a grid in the model. :return: Numpy array of doubles: z coordinate of grid cell center for each grid cell, in the same order as the values returned by function get_value. """ - self.bmilogger.debug("get_grid_z: " + long_var_name) - return self.dynModel.wf_supplyMapZAsNumpy() + if grid_id == 1: + self.bmilogger.debug("get_grid_z: " + str(grid_id)) + return self.dynModel.wf_supplyMapZAsNumpy() + else: + raise Exception("Unknown grid id %d" % grid_id) def get_var_units(self, long_var_name): """ @@ -1327,23 +1363,102 @@ self.bmilogger.debug("set_value: (grid) " + long_var_name) self.dynModel.wf_setValuesAsNumpy(long_var_name, src) - def get_grid_connectivity(self, long_var_name): + def get_grid_connectivity(self, grid_id): """ Not applicable, raises NotImplementedError Should return the ldd if present!! """ raise NotImplementedError - def get_grid_offset(self, long_var_name): + def get_grid_offset(self, grid_id): """ Not applicable raises NotImplementedError """ raise NotImplementedError + def get_grid_rank(self, grid_id): + """ + gets the grid rank. -class BmiGridType(object): - UNKNOWN = 0 - UNIFORM = 1 - RECTILINEAR = 2 - STRUCTURED = 3 - UNSTRUCTURED = 4 + :var int grid_id: identifier of grid. + + :return: id + """ + if grid_id == 1: + return 2 + else: + raise Exception("Unknown grid id %d" % grid_id) + + + def get_grid_size(self, grid_id): + """ + Not applicable raises NotImplementedError + """ + if grid_id == 1: + dim = self.dynModel.wf_supplyGridDim() + #[ Xll, Yll, xsize, ysize, rows, cols] + self.bmilogger.debug("get_grid_shape: " + str(grid_id) + ' result: ' + str([dim[4], dim[5]])) + return dim[4] * dim[5] + else: + raise Exception("Unknown grid id %d" % grid_id) + + + def get_var_units(self, long_var_name): + """ + Supply units as defined in the API section of the ini file + + :var long_var_name: identifier of a variable in the model. + + :return: String: unit of the values of the given variable. Return a string formatted + using the UDUNITS standard from Unidata. (only if set properly in the ini file) + """ + + nru = self.dynModel.wf_supplyVariableNamesAndRoles() + + unit = "mm" + + for it in nru: + if long_var_name == it[0]: + unit = it[2] + + self.bmilogger.debug("get_var_units: " + long_var_name + " result: " + unit) + return unit + + def set_value(self, long_var_name, src): + """ + Set the values(s) in a map using a numpy array as source + + :var long_var_name: identifier of a variable in the model. + :var src: all values to set for the given variable. If only one value + is present a uniform map will be set in the wflow model. + """ + + self.bmilogger.debug("set_value: " + long_var_name + ":" + str(src)) + if self.wrtodisk: + fname = str(self.currenttimestep) + "_set_" + long_var_name + ".map" + arpcr = numpy2pcr(Scalar, src, -999) + self.bmilogger.debug("Writing to disk: " + fname) + report(arpcr, fname) + + if long_var_name in self.outputonlyvars: + self.bmilogger.error( + "set_value: " + + long_var_name + + " is listed as an output only variable, cannot set. " + + str(self.outputonlyvars) + ) + raise ValueError( + "set_value: " + + long_var_name + + " is listed as an output only variable, cannot set. " + + str(self.outputonlyvars) + ) + else: + if len(src) == 1: + self.bmilogger.debug( + "set_value: (uniform value) " + long_var_name + "(" + str(src) + ")" + ) + self.dynModel.wf_setValues(long_var_name, float(src)) + else: + self.bmilogger.debug("set_value: (grid) " + long_var_name) + self.dynModel.wf_setValuesAsNumpy(long_var_name, src) \ No newline at end of file Index: wflow/wflow_bmi_combined.py =================================================================== diff -u -r472c7219b66f1ae4d014ec133ffed81e3712a810 -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/wflow_bmi_combined.py (.../wflow_bmi_combined.py) (revision 472c7219b66f1ae4d014ec133ffed81e3712a810) +++ wflow/wflow_bmi_combined.py (.../wflow_bmi_combined.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -834,3 +834,27 @@ Not applicable raises NotImplementedError """ raise NotImplementedError + + def get_grid_rank(self, grid_id): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_grid_size(self, grid_id): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_var_grid(self, long_var_name): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_var_itemsize(self, long_var_name): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError Index: wflow/wflow_bmi_combined_mp.py =================================================================== diff -u -rc427e9b948a7fbad40a1c828b68355cb277dc5e0 -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/wflow_bmi_combined_mp.py (.../wflow_bmi_combined_mp.py) (revision c427e9b948a7fbad40a1c828b68355cb277dc5e0) +++ wflow/wflow_bmi_combined_mp.py (.../wflow_bmi_combined_mp.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -686,3 +686,27 @@ Not applicable raises NotImplementedError """ raise NotImplementedError + + def get_grid_rank(self, grid_id): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_grid_size(self, grid_id): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_var_grid(self, long_var_name): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError + + def get_var_itemsize(self, long_var_name): + """ + Not applicable raises NotImplementedError + """ + raise NotImplementedError Index: wflow/wflow_sbm.py =================================================================== diff -u -re8b265539079b4f44244f8d17bebe0fa530d77ba -r060a4825462d4eceaf175cb9730049d47d9602ea --- wflow/wflow_sbm.py (.../wflow_sbm.py) (revision e8b265539079b4f44244f8d17bebe0fa530d77ba) +++ wflow/wflow_sbm.py (.../wflow_sbm.py) (revision 060a4825462d4eceaf175cb9730049d47d9602ea) @@ -2535,16 +2535,22 @@ self.PondingDepth = pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['PondingDepth'].reshape(self.shape)),self.mv) # Determine transpiration - self.Transpiration = (pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['ActEvapUStore'].reshape(self.shape)),self.mv) + - pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['ActEvapSat'].reshape(self.shape)),self.mv)) - + self.ActEvapUStore = pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['ActEvapUStore'].reshape(self.shape)),self.mv) + self.ActEvapSat = pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['ActEvapSat'].reshape(self.shape)),self.mv) + self.Transpiration = self.ActEvapUStore + self.ActEvapSat + + self.soilevap = pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['soilevap'].reshape(self.shape)),self.mv) + self.ActEvap = ( - pcr.numpy2pcr(pcr.Scalar,np.copy(self.dyn['soilevap'].reshape(self.shape)),self.mv) + self.soilevap + self.Transpiration + self.ActEvapOpenWaterRiver + self.ActEvapOpenWaterLand + self.ActEvapPond ) + + self.PotTrans = self.PotTransSoil - self.soilevap - self.ActEvapOpenWaterLand - self.ActEvapOpenWaterRiver + self.Recharge = self.Transfer - self.CapFlux - self.ActEvapSat # Run only if we have irrigation areas or an externally given demand, determine irrigation demand based on potrans and acttrans if self.nrirri > 0 or hasattr(self, "IrriDemandExternal"):