goPEST 0.0.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- goPEST-0.0.11.dist-info/LICENSE +11 -0
- goPEST-0.0.11.dist-info/METADATA +95 -0
- goPEST-0.0.11.dist-info/RECORD +30 -0
- goPEST-0.0.11.dist-info/WHEEL +5 -0
- goPEST-0.0.11.dist-info/entry_points.txt +2 -0
- goPEST-0.0.11.dist-info/top_level.txt +1 -0
- gopest/__init__.py +11 -0
- gopest/_version.py +16 -0
- gopest/check_slaves.py +402 -0
- gopest/commands.py +80 -0
- gopest/common.py +194 -0
- gopest/data/case.pst +67 -0
- gopest/data/goPESTconfig.aut2.toml +95 -0
- gopest/data/goPESTconfig.toml +94 -0
- gopest/data/goPESTobs.list +793 -0
- gopest/data/goPESTpar.list +95 -0
- gopest/make_case_pst.py +229 -0
- gopest/obs.py +297 -0
- gopest/obs_def.py +2086 -0
- gopest/par.py +332 -0
- gopest/par_def.py +313 -0
- gopest/pest_model.py +245 -0
- gopest/rename_latest_files.py +35 -0
- gopest/run_beopest.py +205 -0
- gopest/run_ns_pr.py +617 -0
- gopest/submit_beopest.py +931 -0
- gopest/utils/__init__.py +0 -0
- gopest/utils/gener_groups.py +192 -0
- gopest/utils/t2listingh5.py +376 -0
- gopest/utils/waiwera_listing.py +587 -0
gopest/par.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from os.path import splitext, basename, isfile
|
|
3
|
+
import inspect
|
|
4
|
+
import functools
|
|
5
|
+
from collections import OrderedDict
|
|
6
|
+
|
|
7
|
+
from t2data import *
|
|
8
|
+
|
|
9
|
+
from gopest.common import TwoWayDict
|
|
10
|
+
from gopest.common import Singleton
|
|
11
|
+
from gopest.common import readList
|
|
12
|
+
from gopest.common import updateObj
|
|
13
|
+
from gopest.common import private_cleanup_name
|
|
14
|
+
|
|
15
|
+
# implementation:
|
|
16
|
+
# a user entry is something simple a user can undersand and easily enter
|
|
17
|
+
# these are entered as groups, each with type and settings. these are
|
|
18
|
+
# turned into what PEST requires.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
# i need a dictionary, leys of parameter data type (short), which maps to
|
|
22
|
+
# functions from the user defined functions that can modify t2data objects
|
|
23
|
+
|
|
24
|
+
from gopest.common import config as cfg
|
|
25
|
+
INPUT_TYPE = cfg['simulator']['input-type']
|
|
26
|
+
|
|
27
|
+
from gopest import par_def
|
|
28
|
+
par_classes = {}
|
|
29
|
+
for n,c in inspect.getmembers(par_def, inspect.isclass):
|
|
30
|
+
if issubclass(c, par_def.ParDef):
|
|
31
|
+
par_classes[n] = c
|
|
32
|
+
|
|
33
|
+
class PestParamGroups(object):
|
|
34
|
+
""" representation of entries in PEST * parameter groups """
|
|
35
|
+
def __init__(self,name,INCTYP='relative',DERINC=0.01,DERINCLB=0.0,
|
|
36
|
+
FORCEN='switch',DERINCMUL=2.0,DERMTHD='parabolic'):
|
|
37
|
+
self.PARGPNME = name
|
|
38
|
+
self.INCTYP = INCTYP
|
|
39
|
+
self.DERINC=DERINC
|
|
40
|
+
self.DERINCLB=DERINCLB
|
|
41
|
+
self.FORCEN=FORCEN
|
|
42
|
+
self.DERINCMUL=DERINCMUL
|
|
43
|
+
self.DERMTHD=DERINCMUL
|
|
44
|
+
|
|
45
|
+
self.defPARLBND = 0.0
|
|
46
|
+
self.defPARUBND = 0.0
|
|
47
|
+
|
|
48
|
+
class PestParamData(object):
|
|
49
|
+
""" this is equalivalent to each of * parameter data in PEST. it is
|
|
50
|
+
able to write entries for PEST control file (.pst), and PEST template
|
|
51
|
+
file (.tpl). It is also responsible of reading PEST generated 'model'
|
|
52
|
+
file and make real changes into Tough2 input file """
|
|
53
|
+
#? do I have too many tasks for this class?
|
|
54
|
+
def __init__(self,name='',PARTRANS='none',PARCHGLIM='factor',PARVAL1=1.0,
|
|
55
|
+
PARLBND=0.5,PARUBND=1.5,PARGP='grp',SCALE=1.0,OFFSET=0.0,DERCOM=1,
|
|
56
|
+
TEMPLATEWIDTH=7):
|
|
57
|
+
self.PARNME = name
|
|
58
|
+
self.PARTRANS=PARTRANS
|
|
59
|
+
self.PARCHGLIM=PARCHGLIM
|
|
60
|
+
self.PARVAL1=PARVAL1
|
|
61
|
+
self.PARLBND=PARLBND
|
|
62
|
+
self.PARUBND=PARUBND
|
|
63
|
+
self.PARGP=PARGP
|
|
64
|
+
self.SCALE=SCALE
|
|
65
|
+
self.OFFSET=OFFSET
|
|
66
|
+
self.DERCOM=DERCOM
|
|
67
|
+
|
|
68
|
+
# this is not part of PEST's design, used by goPEST to determine the
|
|
69
|
+
# correct template field width, which is related to the precision of
|
|
70
|
+
# TOUGH2 input. It should be 7 for a standard TOUGH2 entry, with 2
|
|
71
|
+
# less for starting- and ending-mark, and one less because PEST has
|
|
72
|
+
# better ability to squeeze one extra precision than Python using the
|
|
73
|
+
# same width. If using .pdat, you should probably use 12 (15-3) to get
|
|
74
|
+
# the precision effect.
|
|
75
|
+
self.TEMPLATEWIDTH = TEMPLATEWIDTH
|
|
76
|
+
|
|
77
|
+
def write(self, f=None):
|
|
78
|
+
""" expects f to be a file object ready to write(), otherwise print to screen """
|
|
79
|
+
line = ' '.join([str(a) for a in [
|
|
80
|
+
self.PARNME,
|
|
81
|
+
self.PARTRANS,
|
|
82
|
+
self.PARCHGLIM,
|
|
83
|
+
self.PARVAL1,
|
|
84
|
+
self.PARLBND,
|
|
85
|
+
self.PARUBND,
|
|
86
|
+
self.PARGP,
|
|
87
|
+
self.SCALE,
|
|
88
|
+
self.OFFSET,
|
|
89
|
+
self.DERCOM,
|
|
90
|
+
]])
|
|
91
|
+
if f is None:
|
|
92
|
+
print(line)
|
|
93
|
+
else:
|
|
94
|
+
f.write(line + '\n')
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
PARAM_ALIAS = TwoWayDict(par_def.shortNames)
|
|
98
|
+
|
|
99
|
+
class PestParamDataName(Singleton):
|
|
100
|
+
""" remembers a list of parameter data and observation data """
|
|
101
|
+
def __init__(self):
|
|
102
|
+
self.names = set([])
|
|
103
|
+
def newName(self,basename):
|
|
104
|
+
apnd = ' 01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
105
|
+
i = 0
|
|
106
|
+
newname = (basename + apnd[i]).strip()
|
|
107
|
+
while newname in self.names:
|
|
108
|
+
i += 1
|
|
109
|
+
if i >= len(apnd):
|
|
110
|
+
raise Exception('Unable to find unused parameter name for:' + basename)
|
|
111
|
+
break
|
|
112
|
+
newname = (basename + apnd[i]).strip()
|
|
113
|
+
return newname
|
|
114
|
+
def add(self,newname):
|
|
115
|
+
self.names.add(newname)
|
|
116
|
+
|
|
117
|
+
class UserEntryParam(object):
|
|
118
|
+
""" understands user entry group and its setings, type. and will be
|
|
119
|
+
responsible of creating PestParamData objects, as each * parameter data
|
|
120
|
+
in PEST """
|
|
121
|
+
ListType = ['ForEach','SingleValue','TiedValues']
|
|
122
|
+
def __init__(self, paramListType, paramList, t2objListType, t2objList, t2objType,
|
|
123
|
+
dat, defaults=None):
|
|
124
|
+
# paramListType 'ForEach' or 'SingleValue' or 'TiedValues'
|
|
125
|
+
# paramList a list of 'permeability_1' or 'porosity' etc
|
|
126
|
+
# t2objListType 'ForEach' or 'SingleValue' or 'TiedValues'
|
|
127
|
+
# t2objList a list of PyTOUGH objects names 'aaa15' or 'BA***' etc
|
|
128
|
+
# t2objType one of 'Rocktype', 'Element', or 'Generator'
|
|
129
|
+
# defaults dict of default PestParamData of each PARAM_TYPE
|
|
130
|
+
if paramListType not in self.ListType: raise Exception(paramListType, ' is not in ', ListType)
|
|
131
|
+
if t2objListType not in self.ListType: raise Exception(t2objListType, ' is not in ', ListType)
|
|
132
|
+
for p in [p for p in paramList if p not in par_classes]: raise Exception(p, ' is not valid')
|
|
133
|
+
self.t2objList = t2objList
|
|
134
|
+
self.t2objType = t2objType
|
|
135
|
+
self.paramListType=paramListType
|
|
136
|
+
self.paramList=paramList
|
|
137
|
+
self.t2objListType=t2objListType
|
|
138
|
+
from copy import deepcopy
|
|
139
|
+
self.defaults=deepcopy(defaults)
|
|
140
|
+
|
|
141
|
+
# generate these by calling makeParamDataNames, pest * parameter data entries
|
|
142
|
+
self.paramData = None
|
|
143
|
+
self.ties = None
|
|
144
|
+
|
|
145
|
+
def makeParamData(self,dat,tpl):
|
|
146
|
+
""" generate a list of paramData and write to PEST template file"""
|
|
147
|
+
# ??? Maybe I should make it spit tpl file entries, instead of write directly into file?
|
|
148
|
+
if (self.paramData is not None) and (self.ties is not None): return
|
|
149
|
+
self.paramData = []
|
|
150
|
+
self.ties = []
|
|
151
|
+
|
|
152
|
+
# reuse ParDef instances (used as getter/setter here) for param type
|
|
153
|
+
par_getters = {}
|
|
154
|
+
for pt in self.paramList:
|
|
155
|
+
if pt not in par_getters:
|
|
156
|
+
par_getters[pt] = par_classes[pt](INPUT_TYPE)
|
|
157
|
+
|
|
158
|
+
# obtain a list of names that exists in all self.paramList and self.t2objList
|
|
159
|
+
# use OrderedDict as an ordered set, to remember order (ordr is noce to have)
|
|
160
|
+
names = []
|
|
161
|
+
intersect = None
|
|
162
|
+
for pt in self.paramList:
|
|
163
|
+
for pattern in self.t2objList:
|
|
164
|
+
a = par_getters[pt].find_names(dat, pattern)
|
|
165
|
+
names += a
|
|
166
|
+
if intersect is None:
|
|
167
|
+
intersect = set(a)
|
|
168
|
+
else:
|
|
169
|
+
intersect = intersect & set(a)
|
|
170
|
+
name_order = OrderedDict.fromkeys(names).keys()
|
|
171
|
+
matchedList = [n for n in name_order if n in intersect]
|
|
172
|
+
|
|
173
|
+
# if both ForEach
|
|
174
|
+
for t2o in matchedList:
|
|
175
|
+
for pt in self.paramList:
|
|
176
|
+
if (pt in self.defaults) and (len(self.defaults[pt].PARNME) == 2):
|
|
177
|
+
# if set properly already (len=2), use the specified value
|
|
178
|
+
if isinstance(t2o, tuple):
|
|
179
|
+
nname = PestParamDataName().newName(self.defaults[pt].PARNME + private_cleanup_name(t2o[-1][:5]))
|
|
180
|
+
else:
|
|
181
|
+
nname = PestParamDataName().newName(self.defaults[pt].PARNME + private_cleanup_name(t2o))
|
|
182
|
+
else:
|
|
183
|
+
# use PARAM_ALIAS as name base if not set properly
|
|
184
|
+
if isinstance(t2o, tuple):
|
|
185
|
+
nname = PestParamDataName().newName(PARAM_ALIAS[pt] + private_cleanup_name(t2o[-1][:5]))
|
|
186
|
+
else:
|
|
187
|
+
nname = PestParamDataName().newName(PARAM_ALIAS[pt] + private_cleanup_name(t2o))
|
|
188
|
+
PestParamDataName().add(nname)
|
|
189
|
+
if self.defaults is not None:
|
|
190
|
+
if pt in self.defaults:
|
|
191
|
+
from copy import deepcopy
|
|
192
|
+
pd = deepcopy(self.defaults[pt])
|
|
193
|
+
else:
|
|
194
|
+
pd = PestParamData()
|
|
195
|
+
else:
|
|
196
|
+
pd = PestParamData()
|
|
197
|
+
pd.PARNME = nname
|
|
198
|
+
pd.PARVAL1 = par_getters[pt].get(dat, t2o)
|
|
199
|
+
self.paramData.append(pd)
|
|
200
|
+
theline = "$%-" + str(pd.TEMPLATEWIDTH) + 's$, %-20s, "%s"\n'
|
|
201
|
+
tpl.write(theline % (nname, ('"%s"' % pt), str([t2o])))
|
|
202
|
+
|
|
203
|
+
def readUserParameter(userListName, dat):
|
|
204
|
+
""" returns a list of UserEntryParam from reading the file with name
|
|
205
|
+
userListName """
|
|
206
|
+
userEntries = []
|
|
207
|
+
with open(userListName,'r') as f:
|
|
208
|
+
entryName, entry = readList(f)
|
|
209
|
+
# some defaults even if no sections exists:
|
|
210
|
+
parDefaults = {}
|
|
211
|
+
for i,en in enumerate(entryName):
|
|
212
|
+
if en == 'Defaults':
|
|
213
|
+
for line in entry[i]:
|
|
214
|
+
if ':' in line:
|
|
215
|
+
ptype = [s.strip() for s in line.split(':')[0].split(',')]
|
|
216
|
+
for p in ptype:
|
|
217
|
+
if p not in parDefaults: parDefaults[p] = PestParamData()
|
|
218
|
+
else:
|
|
219
|
+
for p in ptype:
|
|
220
|
+
updateObj(parDefaults[p],[line])
|
|
221
|
+
if en == 'Param':
|
|
222
|
+
if len(entry[i]) < 2: raise Exception
|
|
223
|
+
tmp1, tmp2 = entry[i][0].split(':')
|
|
224
|
+
paramListType = tmp1.strip()
|
|
225
|
+
paramList = [s.strip() for s in tmp2.split(',')]
|
|
226
|
+
tmp1, tmp2 = entry[i][1].split(':')
|
|
227
|
+
t2objListType = tmp1.strip()
|
|
228
|
+
t2objType = tmp2.strip()
|
|
229
|
+
t2objList = []
|
|
230
|
+
for line in entry[i][2:]:
|
|
231
|
+
t2objList.append(eval(line))
|
|
232
|
+
userEntries.append(UserEntryParam(paramListType,paramList,
|
|
233
|
+
t2objListType,t2objList,t2objType,dat,parDefaults))
|
|
234
|
+
return userEntries
|
|
235
|
+
|
|
236
|
+
def load_model_config(dat):
|
|
237
|
+
""" Return config dict loaded from .json file with same model base name.
|
|
238
|
+
"""
|
|
239
|
+
jname = splitext(dat.filename)[0] + '.json'
|
|
240
|
+
# print("*****", jname)
|
|
241
|
+
if isfile(jname):
|
|
242
|
+
with open(jname, 'rU') as jf:
|
|
243
|
+
return json.load(jf)
|
|
244
|
+
else:
|
|
245
|
+
return {}
|
|
246
|
+
|
|
247
|
+
def save_model_config(dat, config):
|
|
248
|
+
""" Saves config (dict) object into .json using same basename as t2data.
|
|
249
|
+
"""
|
|
250
|
+
jname = splitext(dat.filename)[0] + '.json'
|
|
251
|
+
with open(jname, 'w') as jf:
|
|
252
|
+
json.dump(config, jf, indent=4)
|
|
253
|
+
|
|
254
|
+
def generate_params_and_tpl(origInput, tplToWrite, par_data):
|
|
255
|
+
""" this reads goPESTpar.list and generate appropriate template file and
|
|
256
|
+
writes * parameter data lines into a file """
|
|
257
|
+
if INPUT_TYPE == 'aut2':
|
|
258
|
+
dat = t2data(origInput)
|
|
259
|
+
dat.config = load_model_config(dat)
|
|
260
|
+
elif INPUT_TYPE == 'waiwera':
|
|
261
|
+
with open(origInput, 'r') as f:
|
|
262
|
+
dat = json.load(f)
|
|
263
|
+
else:
|
|
264
|
+
raise Exception()
|
|
265
|
+
|
|
266
|
+
uentry = readUserParameter('goPESTpar.list', dat)
|
|
267
|
+
|
|
268
|
+
if par_data is not None:
|
|
269
|
+
parf = open(par_data, 'w')
|
|
270
|
+
else:
|
|
271
|
+
parf = None
|
|
272
|
+
tpl = open(tplToWrite, 'w')
|
|
273
|
+
tpl.write('ptf $\n')
|
|
274
|
+
for up in uentry:
|
|
275
|
+
up.makeParamData(dat,tpl)
|
|
276
|
+
for pp in up.paramData:
|
|
277
|
+
pp.write(parf)
|
|
278
|
+
tpl.close()
|
|
279
|
+
if parf is not None:
|
|
280
|
+
parf.close()
|
|
281
|
+
|
|
282
|
+
def generate_real_model(origInput, pestModel, realInput):
|
|
283
|
+
""" this reads PEST generated model file and create the real TOUGH2 model
|
|
284
|
+
"""
|
|
285
|
+
if INPUT_TYPE == 'aut2':
|
|
286
|
+
dat = t2data(origInput)
|
|
287
|
+
dat.config = load_model_config(dat)
|
|
288
|
+
elif INPUT_TYPE == 'waiwera':
|
|
289
|
+
with open(origInput, 'r') as f:
|
|
290
|
+
dat = json.load(f)
|
|
291
|
+
else:
|
|
292
|
+
raise Exception()
|
|
293
|
+
|
|
294
|
+
# reuse ParDef instances (used as getter/setter here) for param type
|
|
295
|
+
par_setters = {}
|
|
296
|
+
|
|
297
|
+
with open(pestModel,'r') as pmodel:
|
|
298
|
+
for line in pmodel.readlines():
|
|
299
|
+
vals = eval(line.strip())
|
|
300
|
+
pestValue, paramType, names = vals[0], vals[1], eval(vals[2])
|
|
301
|
+
if paramType not in par_setters:
|
|
302
|
+
par_setters[paramType] = par_classes[paramType](INPUT_TYPE)
|
|
303
|
+
par_setters[paramType].set(dat, names[0], pestValue)
|
|
304
|
+
|
|
305
|
+
if INPUT_TYPE == 'aut2':
|
|
306
|
+
dat.write(realInput, extra_precision=True, echo_extra_precision=True)
|
|
307
|
+
save_model_config(dat, dat.config)
|
|
308
|
+
elif INPUT_TYPE == 'waiwera':
|
|
309
|
+
with open(realInput, 'w') as f:
|
|
310
|
+
json.dump(dat, f, indent=4, sort_keys=True)
|
|
311
|
+
|
|
312
|
+
def goPESTpar(argv=[]):
|
|
313
|
+
userlistname = 'goPESTpar.list'
|
|
314
|
+
|
|
315
|
+
if len(argv) not in [3,4]:
|
|
316
|
+
print('to generate PEST .pst sections and .tpl (for once): ')
|
|
317
|
+
print(' gopest par origINPUT newPESTtpl')
|
|
318
|
+
print('to read PEST generated model file and create real INPUT for Tough2 (for each PEST forward run):')
|
|
319
|
+
print(' gopest par origINPUT pestINPUT realINPUT')
|
|
320
|
+
|
|
321
|
+
if len(argv) == 3:
|
|
322
|
+
origInput = argv[1]
|
|
323
|
+
tplToWrite = argv[2]
|
|
324
|
+
# write *param data lines to screen
|
|
325
|
+
generate_params_and_tpl(origInput, tplToWrite, None)
|
|
326
|
+
|
|
327
|
+
if len(argv) == 4:
|
|
328
|
+
origInput = argv[1]
|
|
329
|
+
pestModel = argv[2]
|
|
330
|
+
realInput = argv[3]
|
|
331
|
+
|
|
332
|
+
generate_real_model(origInput, pestModel, realInput)
|
gopest/par_def.py
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"""Definition file for parameter data types"""
|
|
2
|
+
#
|
|
3
|
+
# each function must accept three params: name,dat,val
|
|
4
|
+
# names: t2data object names, eg. block, gener etc, must be a list
|
|
5
|
+
# dat: your normal t2data object from PyTOUGH
|
|
6
|
+
# val: a number that is going to be assigned, when not exist value
|
|
7
|
+
# from dat will be returned, the first in the name list is used
|
|
8
|
+
#
|
|
9
|
+
# use existing entries as example to write new ones
|
|
10
|
+
# your new function name can then be used as 'param_type'
|
|
11
|
+
#
|
|
12
|
+
# the shortNames needs to be filled in, the right hand side
|
|
13
|
+
# string must be EXACTLY 3 characters wide, and NO SPACE
|
|
14
|
+
# these short names will be used as part of names in * parameter data
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
# TODO: consider using munch to allow access dictionary with object-oriented
|
|
18
|
+
# style? see:
|
|
19
|
+
# https://github.com/Infinidat/munch
|
|
20
|
+
# https://stackoverflow.com/questions/1305532/how-to-convert-a-nested-python-dict-to-object
|
|
21
|
+
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
from gopest.common import getFromDict, setInDict
|
|
25
|
+
|
|
26
|
+
class ParDef(object):
|
|
27
|
+
""" Base class for parameter, used to access model input parameters """
|
|
28
|
+
def __init__(self, simulator):
|
|
29
|
+
super(ParDef, self).__init__()
|
|
30
|
+
if simulator not in ['aut2', 'waiwera']:
|
|
31
|
+
raise Exception("simulator '%s' not supported." % simulator)
|
|
32
|
+
self.simulator = simulator
|
|
33
|
+
|
|
34
|
+
def get(self, dat, name):
|
|
35
|
+
_get = getattr(self, 'get_' + self.simulator)
|
|
36
|
+
return _get(dat, name)
|
|
37
|
+
def get_aut2(self, dat, name):
|
|
38
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
39
|
+
def get_waiwera(self, dat, name):
|
|
40
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
41
|
+
|
|
42
|
+
def set(self, dat, name, value):
|
|
43
|
+
_set = getattr(self, 'set_' + self.simulator)
|
|
44
|
+
return _set(dat, name, value)
|
|
45
|
+
def set_aut2(self, dat, name, value):
|
|
46
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
47
|
+
def set_waiwera(self, dat, name, value):
|
|
48
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
49
|
+
|
|
50
|
+
def find_names(self, dat, pattern):
|
|
51
|
+
_find_names = getattr(self, 'find_names_' + self.simulator)
|
|
52
|
+
return _find_names(dat, pattern)
|
|
53
|
+
def find_names_aut2(self, dat, pattern):
|
|
54
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
55
|
+
def find_names_waiwera(self, dat, pattern):
|
|
56
|
+
raise NotImplementedError(self.__class__.__name__)
|
|
57
|
+
|
|
58
|
+
class permeability_1_byrock(ParDef):
|
|
59
|
+
def get_aut2(self, dat, name):
|
|
60
|
+
return dat.grid.rocktype[name].permeability[0]
|
|
61
|
+
|
|
62
|
+
def set_aut2(self, dat, name, value):
|
|
63
|
+
dat.grid.rocktype[name].permeability[0] = value
|
|
64
|
+
|
|
65
|
+
def find_names_aut2(self, dat, pattern):
|
|
66
|
+
pattern = re.compile(pattern)
|
|
67
|
+
return [r.name for r in dat.grid.rocktypelist if pattern.match(r.name)]
|
|
68
|
+
|
|
69
|
+
def get_waiwera(self, dat, name):
|
|
70
|
+
for rock in dat['rock']['types']:
|
|
71
|
+
if rock['name'] == name:
|
|
72
|
+
return rock['permeability'][0]
|
|
73
|
+
|
|
74
|
+
def set_waiwera(self, dat, name, value):
|
|
75
|
+
for rock in dat['rock']['types']:
|
|
76
|
+
if rock['name'] == name:
|
|
77
|
+
rock['permeability'][0] = value
|
|
78
|
+
|
|
79
|
+
def find_names_waiwera(self, dat, pattern):
|
|
80
|
+
rex = re.compile(pattern)
|
|
81
|
+
return [r['name'] for r in dat['rock']['types'] if rex.match(r['name'])]
|
|
82
|
+
|
|
83
|
+
class permeability_2_byrock(ParDef):
|
|
84
|
+
def get_aut2(self, dat, name):
|
|
85
|
+
return dat.grid.rocktype[name].permeability[1]
|
|
86
|
+
|
|
87
|
+
def set_aut2(self, dat, name, value):
|
|
88
|
+
dat.grid.rocktype[name].permeability[1] = value
|
|
89
|
+
|
|
90
|
+
def find_names_aut2(self, dat, pattern):
|
|
91
|
+
pattern = re.compile(pattern)
|
|
92
|
+
return [r.name for r in dat.grid.rocktypelist if pattern.match(r.name)]
|
|
93
|
+
|
|
94
|
+
def get_waiwera(self, dat, name):
|
|
95
|
+
for rock in dat['rock']['types']:
|
|
96
|
+
if rock['name'] == name:
|
|
97
|
+
return rock['permeability'][1]
|
|
98
|
+
|
|
99
|
+
def set_waiwera(self, dat, name, value):
|
|
100
|
+
for rock in dat['rock']['types']:
|
|
101
|
+
if rock['name'] == name:
|
|
102
|
+
rock['permeability'][1] = value
|
|
103
|
+
|
|
104
|
+
def find_names_waiwera(self, dat, pattern):
|
|
105
|
+
rex = re.compile(pattern)
|
|
106
|
+
return [r['name'] for r in dat['rock']['types'] if rex.match(r['name'])]
|
|
107
|
+
|
|
108
|
+
class permeability_3_byrock(ParDef):
|
|
109
|
+
def get_aut2(self, dat, name):
|
|
110
|
+
return dat.grid.rocktype[name].permeability[2]
|
|
111
|
+
|
|
112
|
+
def set_aut2(self, dat, name, value):
|
|
113
|
+
dat.grid.rocktype[name].permeability[2] = value
|
|
114
|
+
|
|
115
|
+
def find_names_aut2(self, dat, pattern):
|
|
116
|
+
pattern = re.compile(pattern)
|
|
117
|
+
return [r.name for r in dat.grid.rocktypelist if pattern.match(r.name)]
|
|
118
|
+
|
|
119
|
+
def get_waiwera(self, dat, name):
|
|
120
|
+
for rock in dat['rock']['types']:
|
|
121
|
+
if rock['name'] == name:
|
|
122
|
+
return rock['permeability'][2]
|
|
123
|
+
|
|
124
|
+
def set_waiwera(self, dat, name, value):
|
|
125
|
+
for rock in dat['rock']['types']:
|
|
126
|
+
if rock['name'] == name:
|
|
127
|
+
rock['permeability'][2] = value
|
|
128
|
+
|
|
129
|
+
def find_names_waiwera(self, dat, pattern):
|
|
130
|
+
rex = re.compile(pattern)
|
|
131
|
+
return [r['name'] for r in dat['rock']['types'] if rex.match(r['name'])]
|
|
132
|
+
|
|
133
|
+
class porosity_byrock(ParDef):
|
|
134
|
+
def get_aut2(self, dat, name):
|
|
135
|
+
return dat.grid.rocktype[name].porosity
|
|
136
|
+
|
|
137
|
+
def set_aut2(self, dat, name, value):
|
|
138
|
+
dat.grid.rocktype[name].porosity = value
|
|
139
|
+
|
|
140
|
+
def find_names_aut2(self, dat, pattern):
|
|
141
|
+
pattern = re.compile(pattern)
|
|
142
|
+
return [r.name for r in dat.grid.rocktypelist if pattern.match(r.name)]
|
|
143
|
+
|
|
144
|
+
def get_waiwera(self, dat, name):
|
|
145
|
+
for rock in dat['rock']['types']:
|
|
146
|
+
if rock['name'] == name:
|
|
147
|
+
return rock['porosity']
|
|
148
|
+
|
|
149
|
+
def set_waiwera(self, dat, name, value):
|
|
150
|
+
for rock in dat['rock']['types']:
|
|
151
|
+
if rock['name'] == name:
|
|
152
|
+
rock['porosity'] = value
|
|
153
|
+
|
|
154
|
+
def find_names_waiwera(self, dat, pattern):
|
|
155
|
+
rex = re.compile(pattern)
|
|
156
|
+
return [r['name'] for r in dat['rock']['types'] if rex.match(r['name'])]
|
|
157
|
+
|
|
158
|
+
class massgener_rate(ParDef):
|
|
159
|
+
def get_aut2(self, dat, name):
|
|
160
|
+
for g in dat.generatorlist:
|
|
161
|
+
if g.name == name:
|
|
162
|
+
return g.gx
|
|
163
|
+
|
|
164
|
+
def set_aut2(self, dat, name, value):
|
|
165
|
+
for g in dat.generatorlist:
|
|
166
|
+
if g.name == name:
|
|
167
|
+
g.gx = value
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
def find_names_aut2(self, dat, pattern):
|
|
171
|
+
rex = re.compile(pattern)
|
|
172
|
+
return [g.name for g in dat.generatorlist if rex.match(g.name)]
|
|
173
|
+
|
|
174
|
+
def get_waiwera(self, dat, name):
|
|
175
|
+
for source in dat['source']:
|
|
176
|
+
if source['name'] == name:
|
|
177
|
+
return source['rate']
|
|
178
|
+
|
|
179
|
+
def set_waiwera(self, dat, name, value):
|
|
180
|
+
for source in dat['source']:
|
|
181
|
+
if source['name'] == name:
|
|
182
|
+
source['rate'] = value
|
|
183
|
+
|
|
184
|
+
def find_names_waiwera(self, dat, pattern):
|
|
185
|
+
rex = re.compile(pattern)
|
|
186
|
+
return [s['name'] for s in dat['source'] if rex.match(s['name'])]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class json_values(ParDef):
|
|
190
|
+
def get_aut2(self, dat, name):
|
|
191
|
+
""" expects name to be a tuple ([k1, k2, k3], last_key), where a list of
|
|
192
|
+
keys k1,k2,k3 (can use either str or int) leading up to just before the
|
|
193
|
+
last key.
|
|
194
|
+
"""
|
|
195
|
+
cfg = getFromDict(dat.config, name[0])
|
|
196
|
+
return cfg[name[1]]
|
|
197
|
+
|
|
198
|
+
def set_aut2(self, dat, name, value):
|
|
199
|
+
cfg = getFromDict(dat.config, name[0])
|
|
200
|
+
cfg[name[1]] = value
|
|
201
|
+
|
|
202
|
+
def find_names_aut2(self, dat, pattern):
|
|
203
|
+
rex = re.compile(name)
|
|
204
|
+
cfg = getFromDict(dat.config, name[0])
|
|
205
|
+
return [(name[0], z) for z in cfg.keys() if rex.match(z)]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
shortNames = {
|
|
209
|
+
'CJ' : 'json_values',
|
|
210
|
+
'HR' : 'heatgener_rate',
|
|
211
|
+
'SR' : 'massgener_rate',
|
|
212
|
+
'SE' : 'massgener_enth',
|
|
213
|
+
'IN' : 'infiltration',
|
|
214
|
+
'K1' : 'permeability_1',
|
|
215
|
+
'K2' : 'permeability_2',
|
|
216
|
+
'K3' : 'permeability_3',
|
|
217
|
+
'PO' : 'porosity',
|
|
218
|
+
'R1' : 'permeability_1_byrock',
|
|
219
|
+
'R2' : 'permeability_2_byrock',
|
|
220
|
+
'R3' : 'permeability_3_byrock',
|
|
221
|
+
'RA' : 'permeability_123_byrock', #tgra963
|
|
222
|
+
'RS' : 'permeability_12_byrock', #tgra963
|
|
223
|
+
'RP' : 'porosity_byrock',
|
|
224
|
+
'RE' : 'upflow_rech'
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def upflow_rech(names, dat, val=None):
|
|
229
|
+
if val is None:
|
|
230
|
+
return dat.config['RechCoefficients'][names[0]]
|
|
231
|
+
else:
|
|
232
|
+
dat.config['RechCoefficients'][names[0]] = val
|
|
233
|
+
|
|
234
|
+
def heatgener_rate(names,dat,val=None):
|
|
235
|
+
if val is None:
|
|
236
|
+
for g in dat.generatorlist:
|
|
237
|
+
if g.name in names:
|
|
238
|
+
return g.gx
|
|
239
|
+
else:
|
|
240
|
+
for g in dat.generatorlist:
|
|
241
|
+
if g.name in names:
|
|
242
|
+
g.gx = val
|
|
243
|
+
|
|
244
|
+
def massgener_enth(names,dat,val=None):
|
|
245
|
+
if val is None:
|
|
246
|
+
for g in dat.generatorlist:
|
|
247
|
+
if g.name in names:
|
|
248
|
+
return g.ex
|
|
249
|
+
else:
|
|
250
|
+
for g in dat.generatorlist:
|
|
251
|
+
if g.name in names:
|
|
252
|
+
g.ex = val
|
|
253
|
+
|
|
254
|
+
def infiltration(names,dat,val=None):
|
|
255
|
+
if val is None:
|
|
256
|
+
return 999 # yet to be done
|
|
257
|
+
else:
|
|
258
|
+
# doesn't care names
|
|
259
|
+
from make_rain import make_rain
|
|
260
|
+
cfg_name = 'make_rain.cfg'
|
|
261
|
+
cfg_name = os.getcwd() + os.path.sep + cfg_name
|
|
262
|
+
cfg = config(cfg_name)
|
|
263
|
+
[annualrain_const, annualrain_history,
|
|
264
|
+
infiltration, raintemp, newwell_label, tim2sec, cols] = make_rain_proc_cfg(cfg)
|
|
265
|
+
|
|
266
|
+
infiltration = val
|
|
267
|
+
|
|
268
|
+
total_rain = make_rain(geo,dat,annualrain_const,infiltration,raintemp,newwell_label,
|
|
269
|
+
60.0*60.0*24.0*365.25,cols)
|
|
270
|
+
|
|
271
|
+
def permeability_1(names,dat,val=None):
|
|
272
|
+
if val is None:
|
|
273
|
+
return dat.grid.block[names[0]].rocktype.permeability[0]
|
|
274
|
+
else:
|
|
275
|
+
from lib_rocktypes import update_rocktype_property_byblocks
|
|
276
|
+
update_rocktype_property_byblocks('permeability[0]',names,dat,val)
|
|
277
|
+
|
|
278
|
+
def permeability_2(names,dat,val=None):
|
|
279
|
+
if val is None:
|
|
280
|
+
return dat.grid.block[names[0]].rocktype.permeability[1]
|
|
281
|
+
else:
|
|
282
|
+
from lib_rocktypes import update_rocktype_property_byblocks
|
|
283
|
+
update_rocktype_property_byblocks('permeability[1]',names,dat,val)
|
|
284
|
+
|
|
285
|
+
def permeability_3(names,dat,val=None):
|
|
286
|
+
if val is None:
|
|
287
|
+
return dat.grid.block[names[0]].rocktype.permeability[2]
|
|
288
|
+
else:
|
|
289
|
+
from lib_rocktypes import update_rocktype_property_byblocks
|
|
290
|
+
update_rocktype_property_byblocks('permeability[2]',names,dat,val)
|
|
291
|
+
|
|
292
|
+
def porosity(names,dat,val=None):
|
|
293
|
+
if val is None:
|
|
294
|
+
return dat.grid.block[names[0]].rocktype.porosity
|
|
295
|
+
else:
|
|
296
|
+
from lib_rocktypes import update_rocktype_property_byblocks
|
|
297
|
+
update_rocktype_property_byblocks('porosity',names,dat,val)
|
|
298
|
+
|
|
299
|
+
def permeability_123_byrock(names,dat,val=None):
|
|
300
|
+
if val is None:
|
|
301
|
+
return dat.grid.rocktype[names[0]].permeability[0]
|
|
302
|
+
else:
|
|
303
|
+
dat.grid.rocktype[names[0]].permeability[0] = val
|
|
304
|
+
dat.grid.rocktype[names[0]].permeability[1] = val
|
|
305
|
+
dat.grid.rocktype[names[0]].permeability[2] = val
|
|
306
|
+
|
|
307
|
+
def permeability_12_byrock(names,dat,val=None):
|
|
308
|
+
if val is None:
|
|
309
|
+
return dat.grid.rocktype[names[0]].permeability[0]
|
|
310
|
+
else:
|
|
311
|
+
dat.grid.rocktype[names[0]].permeability[0] = val
|
|
312
|
+
dat.grid.rocktype[names[0]].permeability[1] = val
|
|
313
|
+
|