| 1 | import numpy as np | 
|---|
| 2 |  | 
|---|
| 3 | from MatlabArray import * | 
|---|
| 4 | from MatlabFuncs import * | 
|---|
| 5 | from fielddisplay import fielddisplay | 
|---|
| 6 | from pairoptions import pairoptions | 
|---|
| 7 | from partition_npart import * | 
|---|
| 8 | from qmupart2npart import qmupart2npart | 
|---|
| 9 |  | 
|---|
| 10 |  | 
|---|
| 11 | class uniform_uncertain(object): | 
|---|
| 12 | ''' | 
|---|
| 13 | UNIFORM_UNCERTAIN class definition | 
|---|
| 14 |  | 
|---|
| 15 | Usage: | 
|---|
| 16 | [uuv] = uniform_uncertain( | 
|---|
| 17 | 'descriptor', descriptor, | 
|---|
| 18 | 'lower', lower, | 
|---|
| 19 | 'upper', upper, | 
|---|
| 20 | 'partition', partition | 
|---|
| 21 | ) | 
|---|
| 22 |  | 
|---|
| 23 | where uuv is the uniform_uncertain object returned by the constructor, | 
|---|
| 24 | lower and upper are the pdf distribution bounds, and partition is the | 
|---|
| 25 | partition vector for distributed variables. Can be a partition vector | 
|---|
| 26 | over elements or vertices. | 
|---|
| 27 |  | 
|---|
| 28 | Example: | 
|---|
| 29 | md.qmu.variables.rheology = uniform_uncertain( | 
|---|
| 30 | 'descriptor', 'RheologyBBar', | 
|---|
| 31 | 'lower', 1e8, | 
|---|
| 32 | 'upper', 1e9 | 
|---|
| 33 | ) | 
|---|
| 34 | md.qmu.variables.rheology = uniform_uncertain( | 
|---|
| 35 | 'descriptor', 'RheologyBBar', | 
|---|
| 36 | 'lower', 1e8, | 
|---|
| 37 | 'upper', 1e9, | 
|---|
| 38 | 'partition', vpartition | 
|---|
| 39 | ) | 
|---|
| 40 | ''' | 
|---|
| 41 | def __init__(self):  # {{{ | 
|---|
| 42 | self.descriptor = '' | 
|---|
| 43 | self.lower      = -np.inf | 
|---|
| 44 | self.upper      = np.inf | 
|---|
| 45 | self.partition  = [] | 
|---|
| 46 | self.nsteps     = 0 | 
|---|
| 47 | # }}} | 
|---|
| 48 |  | 
|---|
| 49 | @staticmethod | 
|---|
| 50 | def uniform_uncertain(*args):  # {{{ | 
|---|
| 51 | nargin = len(args) | 
|---|
| 52 |  | 
|---|
| 53 | # create a default object | 
|---|
| 54 | if nargin == 0: | 
|---|
| 55 | return uniform_uncertain() | 
|---|
| 56 |  | 
|---|
| 57 | # copy the object | 
|---|
| 58 | elif nargin == 1: | 
|---|
| 59 | if isinstance(args[0], uniform_uncertain): | 
|---|
| 60 | uuv = args[0] | 
|---|
| 61 | else: | 
|---|
| 62 | raise Exception('Object ' + str(args[0]) + ' is a ' + str(type(args[0])) + ' class object, not "uniform_uncertain".') | 
|---|
| 63 |  | 
|---|
| 64 | # create the object from the input | 
|---|
| 65 | else: | 
|---|
| 66 | uuv = uniform_uncertain() | 
|---|
| 67 |  | 
|---|
| 68 | #recover options: | 
|---|
| 69 | options = pairoptions(*args) | 
|---|
| 70 |  | 
|---|
| 71 | #initialize fields: | 
|---|
| 72 | uuv.descriptor = options.getfieldvalue('descriptor') | 
|---|
| 73 | uuv.lower      = options.getfieldvalue('lower') | 
|---|
| 74 | uuv.upper      = options.getfieldvalue('upper') | 
|---|
| 75 |  | 
|---|
| 76 | #if the variable is scaled, a partition vector should have been | 
|---|
| 77 | #supplied, and  that partition vector should have as many | 
|---|
| 78 | #partitions as the lower and upper vectors: | 
|---|
| 79 | if uuv.isscaled(): | 
|---|
| 80 | uuv.partition = options.getfieldvalue('partition') | 
|---|
| 81 | uuv.nsteps = options.getfieldvalue('nsteps', 1) | 
|---|
| 82 | npart = qmupart2npart(uuv.partition) | 
|---|
| 83 | if npart != uuv.upper.shape[0]: | 
|---|
| 84 | raise Exception("uniform_uncertain constructor: for the scaled variable %s the upper field is not currently a vector of values for all the partitions described in the partition vector" % uuv.descriptor) | 
|---|
| 85 | if npart != uuv.lower.shape[0]: | 
|---|
| 86 | raise Exception("uniform_uncertain constructor: for the scaled variable %s the lower field is not currently a vector of values for all the partitions described in the partition vector" % uuv.descriptor) | 
|---|
| 87 | if uuv.nsteps != uuv.upper.shape[1]: | 
|---|
| 88 | raise Exception("uniform_uncertain constructor: for the scaled variable %s the col size of the upper field should be identical to the number of time steps" % uuv.descriptor) | 
|---|
| 89 | if uuv.nsteps != uuv.lower.shape[1]: | 
|---|
| 90 | raise Exception("uniform_uncertain constructor: for the scaled variable %s the col size of the lower field should be identical to the number of time steps" % uuv.descriptor) | 
|---|
| 91 |  | 
|---|
| 92 | return [uuv] # Always return a list, so we have something akin to a MATLAB single row matrix | 
|---|
| 93 | # }}} | 
|---|
| 94 |  | 
|---|
| 95 | def __repr__(self):  # {{{ | 
|---|
| 96 | string = '   uniform uncertain variable: ' | 
|---|
| 97 | string = "%s\n%s" % (string, fielddisplay(self, 'descriptor', 'name tag')) | 
|---|
| 98 | string = "%s\n%s" % (string, fielddisplay(self, 'lower', 'pdf lower bound')) | 
|---|
| 99 | string = "%s\n%s" % (string, fielddisplay(self, 'upper', 'pdf upper bound')) | 
|---|
| 100 | if self.partition != []: | 
|---|
| 101 | string = "%s\n%s" % (string, fielddisplay(self, 'partition', 'partition vector defining where sampling will occur')) | 
|---|
| 102 | string = "%s\n%s" % (string, fielddisplay(self, 'nsteps', 'number of time steps')) | 
|---|
| 103 |  | 
|---|
| 104 | return string | 
|---|
| 105 | # }}} | 
|---|
| 106 |  | 
|---|
| 107 | def __len__(self):  # {{{ | 
|---|
| 108 | if type(self.lower) in [list, np.ndarray]: | 
|---|
| 109 | return len(self.lower) | 
|---|
| 110 | else: | 
|---|
| 111 | return 1 | 
|---|
| 112 | # }}} | 
|---|
| 113 |  | 
|---|
| 114 | def checkconsistency(self, md, solution, analyses):  # {{{ | 
|---|
| 115 | md = checkfield(md, 'field', self.upper, 'fieldname', 'uniform_uncertain.upper', 'NaN', 1, 'Inf', 1, '>', self.lower, 'numel', len(self.lower)) | 
|---|
| 116 | md = checkfield(md, 'field', self.lower, 'fieldname', 'uniform_uncertain.upper', 'NaN', 1, 'Inf', 1, '<', self.upper, 'numel', len(self.upper)) | 
|---|
| 117 | if self.isscaled(): | 
|---|
| 118 | if self.partition == []: | 
|---|
| 119 | raise Exception("uniform_uncertain is a scaled variable, but it's missing a partition vector") | 
|---|
| 120 | #better have a partition vector that has as many partitions as | 
|---|
| 121 | #upper and lower's size: | 
|---|
| 122 | if self.upper.shape[0] != partition_npart(self.partititon): | 
|---|
| 123 | raise Exception("uniform_uncertain error message: row size of upper and partition size should be identical") | 
|---|
| 124 | if self.lower.shape[0] != partition_npart(self.partition): | 
|---|
| 125 | raise Exception("uniform_uncertain error message: row size of lower and partition size should be identical") | 
|---|
| 126 | #we need as steps in upper and lower as there are time steps | 
|---|
| 127 | if self.stddev.shape[1] != self.nsteps: | 
|---|
| 128 | raise Exception("uniform_uncertain error message: col size of upper and partition size should be identical") | 
|---|
| 129 | if self.mean.shape[1] != self.nsteps: | 
|---|
| 130 | raise Exception("uniform_uncertain error message: col size of lower and partition size should be identical") | 
|---|
| 131 | md = checkfield(md, 'field', self.partition, 'fieldname', 'uniform_uncertain.partition', 'NaN', 1, 'Inf', 1, '>=', -1, 'numel', [md.mesh.numberofvertices, md.mesh.numberofvertices]) | 
|---|
| 132 | if self.partition.shape[1] > 1: | 
|---|
| 133 | raise Exception("uniform_uncertain error message: partition should be a column vector") | 
|---|
| 134 | partcheck = np.unique(self.partition) | 
|---|
| 135 | partmin = min(partcheck) | 
|---|
| 136 | partmax = max(partcheck) | 
|---|
| 137 | if partmax < -1: | 
|---|
| 138 | raise Exception("uniform_uncertain error message: partition vector's min value should be -1 (for no partition), or start at 0") | 
|---|
| 139 | nmax = max(md.mesh.numberofelements, md.mesh.numberofvertices) | 
|---|
| 140 | if partmax > nmax: | 
|---|
| 141 | raise Exception("uniform_uncertain error message: partition vector's values cannot go over the number of vertices or elements") | 
|---|
| 142 | # }}} | 
|---|
| 143 |  | 
|---|
| 144 | #virtual functions needed by qmu processing algorithms: | 
|---|
| 145 | #implemented: | 
|---|
| 146 |  | 
|---|
| 147 | @staticmethod | 
|---|
| 148 | def prop_desc(uuv, dstr):  # {{{ | 
|---|
| 149 | desc = ['' for i in range(np.size(uuv))] | 
|---|
| 150 | for i in range(np.size(uuv)): | 
|---|
| 151 | if uuv[i].descriptor != '' or type(uuv[i].descriptor) != str: | 
|---|
| 152 | desc[i] = str(uuv[i].descriptor) | 
|---|
| 153 | elif dstr != '': | 
|---|
| 154 | desc[i] = str(dstr) + str(string_dim(uuv, i, 'vector')) | 
|---|
| 155 | else: | 
|---|
| 156 | desc[i] = 'uuv' + str(string_dim(uuv, i, 'vector')) | 
|---|
| 157 |  | 
|---|
| 158 | desc = allempty(desc) | 
|---|
| 159 |  | 
|---|
| 160 | return desc | 
|---|
| 161 | # }}} | 
|---|
| 162 |  | 
|---|
| 163 | @staticmethod | 
|---|
| 164 | def prop_stddev(uuv):  # {{{ | 
|---|
| 165 | stddev = [] | 
|---|
| 166 | return stddev | 
|---|
| 167 | # }}} | 
|---|
| 168 |  | 
|---|
| 169 | @staticmethod | 
|---|
| 170 | def prop_mean(uuv):  # {{{ | 
|---|
| 171 | mean = [] | 
|---|
| 172 | return mean | 
|---|
| 173 | # }}} | 
|---|
| 174 |  | 
|---|
| 175 | @staticmethod | 
|---|
| 176 | def prop_lower(uuv):  # {{{ | 
|---|
| 177 | lower = np.zeros(np.size(uuv)) | 
|---|
| 178 | for i in range(np.size(uuv)): | 
|---|
| 179 | lower[i] = uuv[i].lower | 
|---|
| 180 |  | 
|---|
| 181 | lower = allequal(lower, -np.inf) | 
|---|
| 182 |  | 
|---|
| 183 | return lower | 
|---|
| 184 | # }}} | 
|---|
| 185 |  | 
|---|
| 186 | @staticmethod | 
|---|
| 187 | def prop_upper(uuv):  # {{{ | 
|---|
| 188 | upper = np.zeros(np.size(uuv)) | 
|---|
| 189 | for i in range(np.size(uuv)): | 
|---|
| 190 | upper[i] = uuv[i].upper | 
|---|
| 191 |  | 
|---|
| 192 | #upper = allequal(upper, np.inf) | 
|---|
| 193 |  | 
|---|
| 194 | return upper | 
|---|
| 195 | # }}} | 
|---|
| 196 |  | 
|---|
| 197 | @staticmethod | 
|---|
| 198 | def prop_abscissas(hbu):  # {{{ | 
|---|
| 199 | abscissas = [] | 
|---|
| 200 | return abscissas | 
|---|
| 201 | # }}} | 
|---|
| 202 |  | 
|---|
| 203 | @staticmethod | 
|---|
| 204 | def prop_pairs_per_variable(hbu):  # {{{ | 
|---|
| 205 | pairs_per_variable = [] | 
|---|
| 206 | return pairs_per_variable | 
|---|
| 207 | # }}} | 
|---|
| 208 |  | 
|---|
| 209 | @staticmethod | 
|---|
| 210 | def prop_counts(hbu):  # {{{ | 
|---|
| 211 | counts = [] | 
|---|
| 212 | return counts | 
|---|
| 213 | # }}} | 
|---|
| 214 |  | 
|---|
| 215 | @staticmethod | 
|---|
| 216 | def prop_initpt(uuv):  # {{{ | 
|---|
| 217 | initpt = [] | 
|---|
| 218 | return initpt | 
|---|
| 219 | # }}} | 
|---|
| 220 |  | 
|---|
| 221 | @staticmethod | 
|---|
| 222 | def prop_initst(uuv):  # {{{ | 
|---|
| 223 | initst = [] | 
|---|
| 224 | return initst | 
|---|
| 225 | # }}} | 
|---|
| 226 |  | 
|---|
| 227 | @staticmethod | 
|---|
| 228 | def prop_stype(uuv):  # {{{ | 
|---|
| 229 | stype = [] | 
|---|
| 230 | return stype | 
|---|
| 231 | # }}} | 
|---|
| 232 |  | 
|---|
| 233 | @staticmethod | 
|---|
| 234 | def prop_scale(uuv):  # {{{ | 
|---|
| 235 | scale = [] | 
|---|
| 236 | return scale | 
|---|
| 237 | # }}} | 
|---|
| 238 |  | 
|---|
| 239 | #new methods: | 
|---|
| 240 | def isscaled(self):  # {{{ | 
|---|
| 241 | if strncmp(self.descriptor, 'scaled_', 7): | 
|---|
| 242 | return True | 
|---|
| 243 | else: | 
|---|
| 244 | return False | 
|---|
| 245 | # }}} | 
|---|
| 246 |  | 
|---|
| 247 | @staticmethod | 
|---|
| 248 | def dakota_write(fidi, dvar):  # {{{ | 
|---|
| 249 | # possible namespace pollution, the above import seems not to work | 
|---|
| 250 | from vlist_write import vlist_write | 
|---|
| 251 | # collect only the variables of the appropriate class | 
|---|
| 252 | uuv = deepcopy(dvar) | 
|---|
| 253 | fields = fieldnames(uuv) | 
|---|
| 254 | for field in fields: | 
|---|
| 255 | if getattr(uuv, field)[0].__class__.__name__ != 'uniform_uncertain': | 
|---|
| 256 | delattr(uuv, field) | 
|---|
| 257 | if len(uuv) > 0: | 
|---|
| 258 | vlist_write(fidi, 'uniform_uncertain', 'uuv', uuv) | 
|---|
| 259 | # }}} | 
|---|