Changeset 26635
- Timestamp:
- 11/18/21 01:08:12 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/classes/stochasticforcing.py
r26620 r26635 1 1 import numpy as np 2 3 2 from checkfield import checkfield 4 3 from fielddisplay import fielddisplay 5 from MatlabFuncs import *6 4 from WriteData import WriteData 5 7 6 8 7 class stochasticforcing(object): … … 15 14 def __init__(self, *args): # {{{ 16 15 self.isstochasticforcing = 0 17 self.fields 18 self.defaultdimension 19 self.default_id 20 self.covariance 21 self.randomflag 16 self.fields = np.nan 17 self.defaultdimension = 0 18 self.default_id = np.nan 19 self.covariance = np.nan 20 self.randomflag = 1 22 21 23 22 if len(args) == 0: 24 23 self.setdefaultparameters() 25 24 else: 26 error('constructor not supported')25 raise RuntimeError('constructor not supported for stochasticforcing') 27 26 28 27 def __repr__(self): # {{{ … … 43 42 def setdefaultparameters(self): # {{{ 44 43 # Type of stabilization used 45 self.isstochasticforcing = 0 # stochasticforcing is turned off by default46 self.fields = []# Need to initialize to list to avoid "RuntimeError: object of type 'float' has no len()" on import of class47 self.randomflag = 1# true randomness is implemented by default44 self.isstochasticforcing = 0 # stochasticforcing is turned off by default 45 self.fields = [] # Need to initialize to list to avoid "RuntimeError: object of type 'float' has no len()" on import of class 46 self.randomflag = 1 # true randomness is implemented by default 48 47 return self 49 48 #}}} … … 54 53 return md 55 54 56 num_fields = numel(self.fields)55 num_fields = len(self.fields) 57 56 58 #Check that covariance matrix is positive definite 59 try: 60 np.linalg.cholesky(self.covariance); 61 except: 62 error('md.stochasticforcing.covariance is not positive definite'); 57 #Check that covariance matrix is positive definite this is done internaly by linalg 58 np.linalg.cholesky(self.covariance) 63 59 64 60 # Check that all fields agree with the corresponding md class 65 61 checkdefaults = False 66 62 for field in self.fields: 67 if (contains(field, 'SMB')):68 if not (type(md.smb) == field):69 error('md.smb does not agree with stochasticforcing field {}'.format(field))70 if (contains(field, 'frontalforcings')):71 if not (type(md.frontalforcings) == field):72 error('md.frontalforcings does not agree with stochasticforcing field {}'.format(field))63 if 'SMB' in field: 64 if type(md.smb).__name__ != field: 65 raise TypeError('md.smb does not agree with stochasticforcing field {}'.format(field)) 66 if 'frontalforcings' in field: 67 if type(md.frontalforcings).__name__ != field: 68 raise TypeError('md.frontalforcings does not agree with stochasticforcing field {}'.format(field)) 73 69 #Checking for specific dimensions 74 if (field!='SMBautoregression' or field!='FrontalForcingsRignotAutoregression'):75 checkdefaults = True #field with non-specific dimensionality70 if not (field == 'SMBautoregression' or field == 'FrontalForcingsRignotAutoregression'): 71 checkdefaults = True #field with non-specific dimensionality 76 72 77 73 #Retrieve sum of all the field dimensionalities 78 size_tot = self.defaultdimension*num_fields;79 indSMBar = -1 ;#about to check for index of SMBautoregression80 indTFar = -1;#about to check for index of FrontalForcingsRignotAutoregression74 size_tot = self.defaultdimension * num_fields 75 indSMBar = -1 #about to check for index of SMBautoregression 76 indTFar = -1 #about to check for index of FrontalForcingsRignotAutoregression 81 77 if ('SMBautoregression' in self.fields): 82 size_tot = size_tot -self.defaultdimension+md.smb.num_basins83 indSMBar = np.where(self.fields=='SMBautoregression')[0][0]78 size_tot = size_tot - self.defaultdimension + md.smb.num_basins 79 indSMBar = self.fields.index('SMBautoregression') 84 80 if ('FrontalForcingsRignotAutoregression' in self.fields): 85 size_tot = size_tot-self.defaultdimension+md.frontalforcings.num_basins 86 indSMBar = np.where(self.fields=='FrontalForcingsRignotAutoregression')[0][0] 87 if (indSMBar!=-1 and indTFar!=-1): 88 if((md.smb.ar_timestep!=md.frontalforcings.ar_timestep) and np.any(self.covariance[np.sum(self.dimensions[0:indSMBar]).astype(int):np.sum(self.dimensions[0:indSMBar+1]).astype(int),np.sum(self.dimensions[0:indTFar]).astype(int):np.sum(self.dimensions[0:indTFar+1]).astype(int)]!=0)): 89 error('SMBautoregression and FrontalForcingsRignotAutoregression have different ar_timestep and non-zero covariance') 81 size_tot = size_tot - self.defaultdimension + md.frontalforcings.num_basins 82 indSMBar = self.fields.index('FrontalForcingsRignotAutoregression') 83 if (indSMBar != -1 and indTFar != -1): 84 covsum = self.covariance[np.sum(self.defaultdimensions[0:indSMBar]).astype(int):np.sum(self.defaultdimensions[0:indSMBar + 1]).astype(int), np.sum(self.defaultdimensions[0:indTFar]).astype(int):np.sum(self.defaultdimensions[0:indTFar + 1]).astype(int)] 85 if((md.smb.ar_timestep != md.frontalforcings.ar_timestep) and np.any(covsum != 0)): 86 raise IOError('SMBautoregression and FrontalForcingsRignotAutoregression have different ar_timestep and non-zero covariance') 90 87 91 88 md = checkfield(md, 'fieldname', 'stochasticforcing.isstochasticforcing', 'values', [0, 1]) 92 89 md = checkfield(md, 'fieldname', 'stochasticforcing.fields', 'numel', num_fields, 'cell', 1, 'values', supportedstochforcings()) 93 90 #md = checkfield(md, 'fieldname', 'stochasticforcing.dimensions', 'NaN', 1, 'Inf', 1, '>', 0, 'size', [num_fields]) # specific dimension for each field; NOTE: As opposed to MATLAB implementation, pass list 94 md = checkfield(md, 'fieldname', 'stochasticforcing.covariance', 'NaN', 1, 'Inf', 1, 'size', [size_tot, size_tot]) # global covariance matrix91 md = checkfield(md, 'fieldname', 'stochasticforcing.covariance', 'NaN', 1, 'Inf', 1, 'size', [size_tot, size_tot]) # global covariance matrix 95 92 md = checkfield(md, 'fieldname', 'stochasticforcing.randomflag', 'numel', [1], 'values', [0, 1]) 96 93 if (checkdefaults): 97 94 md = checkfield(md, 'fieldname', 'stochasticforcing.defaultdimension', 'numel', 1, 'NaN', 1, 'Inf', 1, '>', 0) 98 md = checkfield(md, 'fieldname', 'stochasticforcing.default_id', 'Inf', 1, '>=', 0, '<=', self.defaultdimension, 'size', [md.mesh.numberofelements, 1])95 md = checkfield(md, 'fieldname', 'stochasticforcing.default_id', 'Inf', 1, '>=', 0, '<=', self.defaultdimension, 'size', [md.mesh.numberofelements, 1]) 99 96 return md 100 97 # }}} … … 114 111 else: 115 112 #Retrieve dimensionality of each field 116 dimensions = self.defaultdimension *np.ones(num_fields)117 for ind, field in enumerate(self.fields):113 dimensions = self.defaultdimension * np.ones(num_fields) 114 for ind, field in enumerate(self.fields): 118 115 #Checking for specific dimensions 119 if (field =='SMBautoregression'):116 if (field == 'SMBautoregression'): 120 117 dimensions[ind] = md.smb.num_basins 121 if (field =='FrontalForcingsRignotAutoregression'):118 if (field == 'FrontalForcingsRignotAutoregression'): 122 119 dimensions[ind] = md.frontalforcings.num_basins 123 120 124 121 # Scaling covariance matrix (scale column-by-column and row-by-row) 125 scaledfields = ['DefaultCalving', 'SMBautoregression']# list of fields that need scaling * 1/yts122 scaledfields = ['DefaultCalving', 'SMBautoregression'] # list of fields that need scaling * 1/yts 126 123 tempcovariance = np.copy(self.covariance) 127 124 for i in range(num_fields): 128 125 if self.fields[i] in scaledfields: 129 inds = range(int(np.sum( self.dimensions[0:i])), int(np.sum(self.dimensions[0:i + 1])))130 for row in inds: # scale rows corresponding to scaled field126 inds = range(int(np.sum(dimensions[0:i])), int(np.sum(dimensions[0:i + 1]))) 127 for row in inds: # scale rows corresponding to scaled field 131 128 tempcovariance[row, :] = 1 / yts * tempcovariance[row, :] 132 for col in inds: # scale columns corresponding to scaled field129 for col in inds: # scale columns corresponding to scaled field 133 130 tempcovariance[:, col] = 1 / yts * tempcovariance[:, col] 134 131 #Set dummy default_id vector if defaults not used 135 132 if np.isnan(self.default_id): 136 self.default_id = np.zeros(md.mesh.numberofelements)133 self.default_id = np.zeros(md.mesh.numberofelements) 137 134 WriteData(fid, prefix, 'data', num_fields, 'name', 'md.stochasticforcing.num_fields', 'format', 'Integer') 138 135 WriteData(fid, prefix, 'object', self, 'fieldname', 'fields', 'format', 'StringArray') 139 WriteData(fid, prefix, 'data', 'dimensions', 'name', 'md.stochasticforcing.dimensions', 'format', 'IntMat')140 WriteData(fid, prefix, 'object', self, 'fieldname', 'default_id', 'format', 'IntMat') #12Nov2021 make sure this is zero-indexed!141 WriteData(fid, prefix, 'object', self, 'fieldname', 'defaultdimension', 'format', 'Integer') 136 WriteData(fid, prefix, 'data', dimensions, 'name', 'md.stochasticforcing.dimensions', 'format', 'IntMat') 137 WriteData(fid, prefix, 'object', self, 'fieldname', 'default_id', 'format', 'IntMat') #12Nov2021 make sure this is zero-indexed! 138 WriteData(fid, prefix, 'object', self, 'fieldname', 'defaultdimension', 'format', 'Integer') 142 139 WriteData(fid, prefix, 'data', tempcovariance, 'name', 'md.stochasticforcing.covariance', 'format', 'DoubleMat') 143 140 WriteData(fid, prefix, 'object', self, 'fieldname', 'randomflag', 'format', 'Boolean') 144 141 # }}} 142 145 143 146 144 def supportedstochforcings():
Note:
See TracChangeset
for help on using the changeset viewer.