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.
@@ -0,0 +1,587 @@
1
+ """
2
+ Copyright 2013, 2014 University of Auckland.
3
+
4
+ This file is part of TIM (Tim Isn't Mulgraph).
5
+
6
+ TIM is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ TIM is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with TIM. If not, see <http://www.gnu.org/licenses/>.
18
+ """
19
+
20
+ """
21
+ Wrap Waiwera's hdf5 output as t2listing
22
+ """
23
+
24
+ import h5py
25
+ import numpy as np
26
+
27
+ from mulgrids import mulgrid
28
+ from t2listing import listingtable
29
+
30
+ import json
31
+ import time
32
+ import unittest
33
+ from pprint import pprint as pp
34
+
35
+ class wlisting(object):
36
+ def __init__(self, filename=None, geo=None, fjson=None, size_check=True):
37
+ """ Waiwera h5 output pretending to be t2listing
38
+
39
+ If corresponding geo is supplied, wlisting can behave more like
40
+ t2listing, which includes atmosphere blocks
41
+
42
+ If Waiwera input json is provided, then .generation has .row_name using
43
+ (t2 block name, source name) instead of (cell index, source index).
44
+ """
45
+ self._table = {}
46
+ if isinstance(geo, str):
47
+ self.geo = mulgrid(geo)
48
+ else:
49
+ self.geo = geo
50
+ if self.geo is not None:
51
+ if self.geo.block_order != 'dmplex':
52
+ raise Exception("wlisting loading Waiwera output file requires a geometry with .block_order = 'dmplex'")
53
+ if isinstance(fjson, str):
54
+ with open(fjson, 'r') as f:
55
+ self.wjson = json.load(f)
56
+ else:
57
+ self.wjson = fjson
58
+ self._h5 = h5py.File(filename, 'r')
59
+ self.filename = filename
60
+ self.simulator = 'waiwera'
61
+ self.size_check = size_check # raise Exception if number of block does not match geo
62
+ self.setup()
63
+
64
+ def close(self):
65
+ self._h5.close()
66
+
67
+ def setup(self):
68
+ self.cell_idx = self._h5['cell_index'][:,0]
69
+ self.fulltimes = self._h5['time'][:,0]
70
+ self.num_fulltimes = len(self.fulltimes)
71
+ self._index = 0
72
+ ### checks:
73
+ nh5 = len(self.cell_idx)
74
+ if self.geo is not None:
75
+ print('wlisting.element: uses mulgrid block name (str) as key.')
76
+ nb = self.geo.num_blocks - self.geo.num_atmosphere_blocks
77
+ if self.size_check and nh5 != nb:
78
+ msg = 'HDF5 result %s has %i cells different from geometry %s (%i excl. atmosphere blocks)' % (
79
+ self.filename, nh5, self.geo.filename, nb)
80
+ raise Exception(msg)
81
+ if nh5 < nb:
82
+ msg = 'HDF5 result %s has %i cells less than from geometry %s (%i excl. atmosphere blocks)' % (
83
+ self.filename, nh5, self.geo.filename, nb)
84
+ raise Exception(msg)
85
+ # blocks is seen by TIM/geo, w_blocks is used by waiwera-h5/json
86
+ blocks = self.geo.block_name_list
87
+ w_blocks = self.geo.block_name_list[self.geo.num_atmosphere_blocks:]
88
+ if nh5 > nb:
89
+ # assumes they are MINC blocks
90
+ blocks += [' '+str(i) for i in range(nh5 - nb)]
91
+ w_blocks += [' '+str(i) for i in range(nh5 - nb)]
92
+ else:
93
+ print('wlisting.element: uses waiwera natural index (as str) as key.')
94
+ blocks = [str(i) for i in range(nh5)]
95
+ w_blocks = blocks
96
+ ### element table
97
+ if 'cell_fields' in self._h5:
98
+ cols = sorted([c for c in self._h5['cell_fields'].keys() if c.startswith('fluid_')])
99
+ table = listingtable(cols, blocks, num_keys=1)
100
+ self._table['element'] = table
101
+ ### connection table
102
+ if 'face_fields' in self._h5:
103
+ cid1 = self._h5['face_cell_1'][:,0]
104
+ cid2 = self._h5['face_cell_2'][:,0]
105
+ # .face_idx equivalent to .cell_idx and .source_idx, which maps waiwera h5 table into
106
+ # geo/mulgrid order, there is no "natural order" of faces in waiwera, so we have to
107
+ # build one here
108
+ self.face_idx = []
109
+ self.face_idx_dir = []
110
+ if self.geo is not None:
111
+ print('wlisting.connection: tuple of mulgrid block names (str, str) as key.')
112
+ face_keys = self.geo.block_connection_name_list
113
+ # w_boundary is a list of dict, in the order of wjson boundaries, each dict has key
114
+ # of block1, gives name of b2.
115
+ w_boundary = []
116
+ if self.wjson is not None and 'boundaries' in self.wjson:
117
+ for bd in self.wjson['boundaries']:
118
+ b2_names = {}
119
+ for i1 in bd['faces']['cells']:
120
+ b1 = w_blocks[i1]
121
+ b2 = ' ' # default empty , overwritten if atmosphere
122
+ if bd['faces']['normal'] == [0.0, 0.0, 1.0]:
123
+ # if connect upwards, assume atmospheric, use mulgrid atm block names
124
+ b1_col = self.geo.column[self.geo.column_name(b1)]
125
+ b1_lay = self.geo.layer[self.geo.layer_name(b1)]
126
+ if self.geo.column_surface_layer(b1_col).name == b1_lay.name:
127
+ if self.geo.atmosphere_type == 0:
128
+ b2 = self.geo.block_name_list[0]
129
+ elif self.geo.atmosphere_type == 1:
130
+ b2 = self.geo.block_name(self.geo.layerlist[0].name, b1_col.name)
131
+ b2_names[b1] = b2
132
+ w_boundary.append(b2_names)
133
+ # this translate waiwera cell ids in (face_cell_1, face_cell_2) into block names
134
+ # w_connection_name_index has keys of (b1 name, b2 name), value is waiwera face index
135
+ # ordered as in h5 file
136
+ w_connection_name_index = {}
137
+ self.w_connection_index_index = {} # useful if given two waiwera cell indices
138
+ for i,(c1,c2) in enumerate(zip(cid1, cid2)):
139
+ self.w_connection_index_index[(c1,c2)] = i
140
+ b1 = w_blocks[c1]
141
+ if c2 < 0:
142
+ if w_boundary:
143
+ # face_cell_2 contains the negative of the (1-based) index of the boundaries
144
+ # specified in json
145
+ b2 = w_boundary[-c2-1][b1]
146
+ else:
147
+ # either wai JSON not loaded OR none are standard atm conne
148
+ b2 = ' '
149
+ # simply assumes atm conne if top of the model
150
+ b1_col = self.geo.column[self.geo.column_name(b1)]
151
+ b1_lay = self.geo.layer[self.geo.layer_name(b1)]
152
+ if self.geo.column_surface_layer(b1_col).name == b1_lay.name:
153
+ if self.geo.atmosphere_type == 0:
154
+ b2 = self.geo.block_name_list[0]
155
+ elif self.geo.atmosphere_type == 1:
156
+ b2 = self.geo.block_name(self.geo.layerlist[0].name, b1_col.name)
157
+ else:
158
+ b2 = w_blocks[c2]
159
+ w_connection_name_index[(b1,b2)] = i
160
+ for c in self.geo.block_connection_name_list:
161
+ # (cell1, cell2) positive means cell1 -> cell2
162
+ # NOTE this is opposite to T2/AUT2's result convention!
163
+ if c in w_connection_name_index:
164
+ self.face_idx.append(w_connection_name_index[c])
165
+ self.face_idx_dir.append(-1.0)
166
+ elif c[::-1] in w_connection_name_index:
167
+ self.face_idx.append(w_connection_name_index[c[::-1]])
168
+ self.face_idx_dir.append(1.0)
169
+ else:
170
+ debugxx = []
171
+ for key in w_connection_name_index:
172
+ if c[0] in key:
173
+ debugxx.append(key)
174
+ msg = str(debugxx)
175
+ msg += '\nMulgrid connection name %s not found in Waiwera H5 output.' % str(c)
176
+ raise Exception(msg)
177
+ else:
178
+ print('wlisting.connection: tuple of natural cell indices (as str, as str) as key.')
179
+ # keeps whatever order is in h5, NOTE the order is unpredictable
180
+ face_keys = [(str(i), str(j)) for i,j in zip(cid1, cid2)]
181
+ self.face_idx = list(range(len(cid1)))
182
+ self.face_idx_dir = [-1.0] * len(cid1)
183
+
184
+ self.face_idx_dir = np.array(self.face_idx_dir)
185
+ cols = sorted([c for c in self._h5['face_fields'].keys() if c.startswith('flux_')])
186
+ table = listingtable(cols, face_keys, num_keys=2, allow_reverse_keys=True)
187
+ self._table['connection'] = table
188
+ ### gener table
189
+ if 'source_fields' in self._h5:
190
+ self.source_name_index = {} # allows either source name or (block name, gener name) as key
191
+ skip_cols = ['source_' + n for n in ['source_index', 'local_source_index', 'natural_cell_index', 'local_cell_index']]
192
+ cols = sorted([c for c in self._h5['source_fields'].keys() if c.startswith('source_') and c not in skip_cols])
193
+ self.source_idx = self._h5['source_index'][:,0]
194
+ source_keys = None
195
+ if self.geo is not None and self.wjson is not None:
196
+ if 'source' in self.wjson and len(self.wjson['source']) == len(self.source_idx):
197
+ if all(['name' in s for s in self.wjson['source']]) and all(['cell' in s for s in self.wjson['source']]):
198
+ # each source has a name, each source has a single cell
199
+ print('wlisting.generation: detects matching Waiwera input JSON and HDF5 source_fields, use (block name, source name) as key.')
200
+ cid = [w_blocks[s['cell']] for s in self.wjson['source']]
201
+ gid = [str(s['name']) for s in self.wjson['source']]
202
+ source_keys = list(zip(cid, gid))
203
+ for i,gk in enumerate(source_keys):
204
+ self.source_name_index[gk] = i
205
+ for i,s in enumerate(self.wjson['source']):
206
+ if 'name' in s:
207
+ self.source_name_index[s['name']] = i
208
+ if source_keys is None:
209
+ print('wlisting.generation: use source index (as str) as key.')
210
+ # use source index (as str) as key
211
+ source_keys = [str(i) for i in range(len(self.source_idx))]
212
+ table = listingtable(cols, source_keys, num_keys=1)
213
+ else:
214
+ # source_keys is (bname, gname) as in original t2listing
215
+ table = listingtable(cols, list(zip(cid, gid)), num_keys=2)
216
+ self._table['generation'] = table
217
+ # makes tables in self._table accessible as attributes
218
+ for key,table in self._table.items():
219
+ setattr(self, key, table)
220
+ # have to be get first table ready
221
+ self.index = 0
222
+
223
+ def history(self, selection, short=False, start_datetime=None):
224
+ """ Returns time histories for specified selection of table type, names
225
+ (or indices) and column names. This is implemented to be similar to
226
+ t2listing's .history().
227
+
228
+ ('e', block name/index, column name)
229
+ for cell_fields, cell can be specified as Waiwera natural cell index
230
+ (int) or mulgrid's block name (str)
231
+
232
+ ('c', (c1, c2), column name)
233
+ for face_fields, a face/connection can be specified by a tuple of
234
+ Waiwera's natural cell index (int, int) or mulgrid's block names
235
+ (str, str).
236
+
237
+ ('g', g, column name) OR ('g', (b,g), column name)
238
+ for source_fields, a gener/source can be specified by an index
239
+ (int), a source name (str), or a tuple of (block name, source name)
240
+ ((str, str)). The tuple option is only available if each source has
241
+ a name and each source has a single cell in the Waiwera JSON input.
242
+
243
+ short and start_datetime are not implemented at the moment
244
+ """
245
+ if short is True: raise Exception('.history() short=True not implemented yet')
246
+ if start_datetime is not None: raise Exception('.history() start_datetime not implemented yet')
247
+ if isinstance(selection, tuple):
248
+ selection = [selection]
249
+ results = []
250
+ for tbl,b,cname in selection:
251
+ if tbl == 'e':
252
+ if isinstance(b, str):
253
+ bi = self.geo.block_name_index[b]
254
+ elif isinstance(b, int):
255
+ bi = b
256
+ else:
257
+ raise Exception('.history() block must be an int or str: %s (%s)' % (str(b),str(type(b))))
258
+ if bi < 0:
259
+ bi = self.geo.num_blocks + bi
260
+ if bi < self.geo.num_atmosphere_blocks:
261
+ raise Exception('.history() does not support extracting results for atmosphere blocks')
262
+ ### important to convert cell index
263
+ bbi = self.cell_idx[bi-self.geo.num_atmosphere_blocks]
264
+ ys = self._h5['cell_fields'][cname][:,bbi]
265
+ results.append((self.fulltimes, ys))
266
+ elif tbl == 'c':
267
+ if isinstance(b[0], int):
268
+ # (i1, i2) assume both are integer cell index in Waiwera sense
269
+ cci = self.w_connection_index_index[b]
270
+ elif isinstance(b[0], str):
271
+ # (b1, b2) assume both are string block names in mulgrid
272
+ if self.geo is None:
273
+ raise Exception('Mulgrid geometry is required if connection tuple is specified by block names.')
274
+ ci = self.geo.block_connection_name_index[b]
275
+ cci = self.face_idx[ci]
276
+ ys = self._h5['face_fields'][cname][:,cci]
277
+ results.append((self.fulltimes, ys))
278
+ elif tbl == 'g':
279
+ if isinstance(b, tuple):
280
+ # (block name, source name) both str
281
+ gi = self.source_name_index[b]
282
+ elif isinstance(b, str):
283
+ # single natural source index !! diff from TOUGH2
284
+ gi = self.source_name_index[b]
285
+ if isinstance(b, int):
286
+ # directly as source index
287
+ gi = b
288
+ ggi = self.source_idx[gi]
289
+ ys = self._h5['source_fields'][cname][:,ggi]
290
+ results.append((self.fulltimes, ys))
291
+ else:
292
+ raise Exception('Unsupported .history() selection table type: %s' % tbl)
293
+ if len(results) == 1: results = results[0]
294
+ return results
295
+
296
+ def read_tables(self):
297
+ """ copy values from h5 into listingtables, with slicing """
298
+ if 'element' in self.table_names:
299
+ nh5 = len(self.cell_idx)
300
+ for i,cname in enumerate(self.element.column_name):
301
+ self.element._data[-nh5:,i] = self._h5['cell_fields'][cname][self._index][self.cell_idx]
302
+ if 'connection' in self.table_names:
303
+ for i,cname in enumerate(self.connection.column_name):
304
+ # re-order as geo.block_connection_name_list and reverse values if required
305
+ self.connection._data[:,i] = self._h5['face_fields'][cname][self._index][self.face_idx] * self.face_idx_dir
306
+ if 'generation' in self.table_names:
307
+ for i,cname in enumerate(self.generation.column_name):
308
+ self.generation._data[:,i] = self._h5['source_fields'][cname][self._index][self.source_idx]
309
+
310
+ def get_index(self): return self._index
311
+ def set_index(self, i):
312
+ self._index = i
313
+ if self._index < 0: self._index += self.num_fulltimes
314
+ self.read_tables()
315
+ index = property(get_index, set_index)
316
+
317
+ def first(self): self.index = 0
318
+ def last(self): self.index = -1
319
+ def next(self):
320
+ """Find and read next set of results; returns false if at end of listing"""
321
+ more = self.index < self.num_fulltimes - 1
322
+ if more: self.index += 1
323
+ return more
324
+ def prev(self):
325
+ """Find and read previous set of results; returns false if at start of listing"""
326
+ more = self.index > 0
327
+ if more: self.index -= 1
328
+ return more
329
+
330
+ def get_table_names(self):
331
+ return sorted(self._table.keys())
332
+ table_names = property(get_table_names)
333
+
334
+ def get_time(self): return self.fulltimes[self.index]
335
+ def set_time(self, t):
336
+ if t < self.fulltimes[0]: self.index = 0
337
+ elif t > self.fulltimes[-1]: self.index = -1
338
+ else:
339
+ dt = np.abs(self.fulltimes - t)
340
+ self.index = np.argmin(dt)
341
+ time = property(get_time, set_time)
342
+
343
+
344
+ class test_medium(unittest.TestCase):
345
+ def setUp(self):
346
+ from mulgrids import mulgrid
347
+ self.geo = mulgrid('g2medium.dat')
348
+ self.lst = wlisting('2DM002.h5', self.geo)
349
+
350
+ def test_atm_blocks(self):
351
+ self.assertEqual(len(self.lst.element.row_name), self.geo.num_blocks)
352
+ # atmosphere blocks should be zero
353
+ self.assertEqual(
354
+ list(self.lst.element['fluid_temperature'][:self.geo.num_atmosphere_blocks]),
355
+ [0.0] * self.geo.num_atmosphere_blocks)
356
+ # even after change index
357
+ self.index = 1
358
+ self.assertEqual(
359
+ list(self.lst.element['fluid_temperature'][:self.geo.num_atmosphere_blocks]),
360
+ [0.0] * self.geo.num_atmosphere_blocks)
361
+
362
+ def test_tables(self):
363
+ self.assertEqual(self.lst.table_names, ['element', 'generation'])
364
+ cols = [
365
+ 'fluid_liquid_capillary_pressure',
366
+ 'fluid_liquid_density',
367
+ 'fluid_liquid_internal_energy',
368
+ 'fluid_liquid_relative_permeability',
369
+ 'fluid_liquid_saturation',
370
+ 'fluid_liquid_specific_enthalpy',
371
+ 'fluid_liquid_viscosity',
372
+ 'fluid_liquid_water_mass_fraction',
373
+ 'fluid_phases',
374
+ 'fluid_pressure',
375
+ 'fluid_region',
376
+ 'fluid_temperature',
377
+ 'fluid_vapour_capillary_pressure',
378
+ 'fluid_vapour_density',
379
+ 'fluid_vapour_internal_energy',
380
+ 'fluid_vapour_relative_permeability',
381
+ 'fluid_vapour_saturation',
382
+ 'fluid_vapour_specific_enthalpy',
383
+ 'fluid_vapour_viscosity',
384
+ 'fluid_vapour_water_mass_fraction',
385
+ 'fluid_water_partial_pressure']
386
+ self.assertEqual(sorted(self.lst.element.column_name), sorted(cols))
387
+ cols = [
388
+ 'source_component',
389
+ 'source_enthalpy',
390
+ 'source_rate',
391
+ ]
392
+ self.assertEqual(sorted(self.lst.generation.column_name), sorted(cols))
393
+
394
+ def test_basic_properties(self):
395
+ self.assertEqual(self.lst.num_fulltimes, 2)
396
+ np.testing.assert_almost_equal(
397
+ self.lst.fulltimes,
398
+ [0.0, 1.0E16],
399
+ decimal=7)
400
+
401
+ def test_index(self):
402
+ self.assertEqual(self.lst.index, 0)
403
+ self.assertAlmostEqual(self.lst.time, 0.0)
404
+ np.testing.assert_almost_equal(
405
+ self.lst.element['fluid_temperature'][-5:],
406
+ [15.0, 15.0, 15.0, 15.0, 15.0]
407
+ )
408
+
409
+ self.lst.index = 1
410
+ self.lst.index = 1
411
+ self.assertEqual(self.lst.index, 1)
412
+ self.assertAlmostEqual(self.lst.time, 1.0E16)
413
+ np.testing.assert_almost_equal(
414
+ self.lst.element['fluid_temperature'][-5:],
415
+ [235.7365710, 234.266913, 233.142164, 232.376319, 231.98525],
416
+ decimal=4
417
+ )
418
+
419
+ self.lst.index = 0
420
+ self.assertEqual(self.lst.index, 0)
421
+ self.assertAlmostEqual(self.lst.time, 0.0)
422
+ np.testing.assert_almost_equal(
423
+ self.lst.element['fluid_temperature'][-5:],
424
+ [15.0, 15.0, 15.0, 15.0, 15.0]
425
+ )
426
+
427
+ self.lst.index = -1
428
+ self.assertEqual(self.lst.index, 1)
429
+ self.assertAlmostEqual(self.lst.time, 1.0E16)
430
+ np.testing.assert_almost_equal(
431
+ self.lst.element['fluid_temperature'][-5:],
432
+ [235.7365710, 234.266913, 233.142164, 232.376319, 231.98525],
433
+ decimal=4
434
+ )
435
+
436
+ ### generation
437
+ np.testing.assert_almost_equal(
438
+ self.lst.generation['source_rate'][:3],
439
+ [0.075, 0.075, 160.0],
440
+ decimal=4
441
+ )
442
+ np.testing.assert_almost_equal(
443
+ self.lst.generation['source_enthalpy'][:3],
444
+ [1200000.0, 1200000.0, 0.0],
445
+ decimal=4
446
+ )
447
+ np.testing.assert_almost_equal(
448
+ self.lst.generation['source_component'][:3],
449
+ [1.0, 1.0, 2.0],
450
+ decimal=4
451
+ )
452
+
453
+ def test_time(self):
454
+ self.lst.time = self.lst.fulltimes[1] - 100.0
455
+ self.assertEqual(self.lst.index, 1)
456
+ self.lst.time = 1.0e19
457
+ self.assertEqual(self.lst.index, 1)
458
+ self.lst.time = 0.0
459
+ self.assertEqual(self.lst.index, 0)
460
+ self.lst.time = 100.0
461
+ self.assertEqual(self.lst.index, 0)
462
+
463
+ def test_history(self):
464
+ # use relative tolerance, expect minor diff with different num of cpus
465
+ rtol = 1e-10
466
+ xs, ys = self.lst.history(('e', -1, 'fluid_pressure'))
467
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
468
+ np.testing.assert_allclose(ys, [101350.0, 1.3010923804323431E7], rtol=rtol)
469
+ xs, ys = self.lst.history(('e', 339, 'fluid_pressure'))
470
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
471
+ np.testing.assert_allclose(ys, [101350.0, 1.3010923804323431E7], rtol=rtol)
472
+ xs, ys = self.lst.history(('e', ' t16', 'fluid_pressure'))
473
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
474
+ np.testing.assert_allclose(ys, [101350.0, 1.3010923804323431E7], rtol=rtol)
475
+ xs, ys = self.lst.history(('e', 338, 'fluid_temperature'))
476
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
477
+ np.testing.assert_allclose(ys, [15.0, 232.3763193900396], rtol=rtol)
478
+ # cell index doesn't matter in generation
479
+ xs, ys = self.lst.history(('g', (999, 0), 'source_enthalpy'))
480
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
481
+ np.testing.assert_allclose(ys, [1200e3, 1200e3], rtol=rtol)
482
+ # also accepts single gener index int
483
+ xs, ys = self.lst.history(('g', 0, 'source_enthalpy'))
484
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
485
+ np.testing.assert_allclose(ys, [1200e3, 1200e3], rtol=rtol)
486
+ # also accepts gener index as str
487
+ xs, ys = self.lst.history(('g', '0', 'source_enthalpy'))
488
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
489
+ np.testing.assert_allclose(ys, [1200e3, 1200e3], rtol=rtol)
490
+ # cell index doesn't matter in generation
491
+ xs, ys = self.lst.history(('g', (999, '0'), 'source_enthalpy'))
492
+ np.testing.assert_allclose(xs, [0, 1.0e16], rtol=rtol)
493
+ np.testing.assert_allclose(ys, [1200e3, 1200e3], rtol=rtol)
494
+ tbl = self.lst.history([
495
+ ('e', -1, 'fluid_pressure'),
496
+ ('e', 339, 'fluid_pressure'),
497
+ ('e', ' t16', 'fluid_pressure'),
498
+ ('e', 338, 'fluid_temperature'),
499
+ ('g', (999, 0), 'source_enthalpy'),
500
+ ])
501
+ np.testing.assert_allclose(tbl[0][0], [0, 1.0e16], rtol=rtol)
502
+ np.testing.assert_allclose(tbl[0][1], [101350.0, 1.3010923804323431E7], rtol=rtol)
503
+ np.testing.assert_allclose(tbl[1][1], [101350.0, 1.3010923804323431E7], rtol=rtol)
504
+ np.testing.assert_allclose(tbl[2][1], [101350.0, 1.3010923804323431E7], rtol=rtol)
505
+ np.testing.assert_allclose(tbl[3][1], [15.0, 232.3763193900396], rtol=rtol)
506
+ np.testing.assert_allclose(tbl[4][1], [1200e3, 1200e3], rtol=rtol)
507
+
508
+ # should spit out an exception about not supporting atmosphere blocks
509
+ self.assertRaises(Exception, self.lst.history, ('e', 0, 'fluid_temperature'))
510
+ self.assertRaisesRegex(Exception, 'atmosphere', self.lst.history, ('e', 0, 'fluid_temperature'))
511
+
512
+ class test_medium_multiple_cpu(test_medium):
513
+ def setUp(self):
514
+ from mulgrids import mulgrid
515
+ self.geo = mulgrid('g2medium.dat')
516
+ self.lst = wlisting('2DM002a.h5', self.geo)
517
+
518
+ class test_compare(unittest.TestCase):
519
+ def setUp(self):
520
+ from mulgrids import mulgrid
521
+ self.geo = mulgrid('g2medium.dat')
522
+ self.lst1 = wlisting('2DM002.h5', self.geo)
523
+ self.lst2 = wlisting('2DM002a.h5', self.geo)
524
+
525
+ def test_table(self):
526
+ self.lst1.index = 1
527
+ self.lst2.index = 1
528
+ self.assertAlmostEqual(self.lst1.time, 1.0E16)
529
+ self.assertAlmostEqual(self.lst2.time, 1.0E16)
530
+ np.testing.assert_allclose(
531
+ self.lst1.element['fluid_temperature'],
532
+ self.lst2.element['fluid_temperature'],
533
+ rtol=1e-10,
534
+ equal_nan=True
535
+ )
536
+ np.testing.assert_allclose(
537
+ self.lst1.element['fluid_pressure'],
538
+ self.lst2.element['fluid_pressure'],
539
+ rtol=1e-10,
540
+ equal_nan=True
541
+ )
542
+
543
+ def test_history(self):
544
+ np.testing.assert_allclose(
545
+ self.lst1.history(('e', -1, 'fluid_pressure'))[1],
546
+ self.lst2.history(('e', -1, 'fluid_pressure'))[1],
547
+ rtol=1e-10,
548
+ )
549
+ np.testing.assert_allclose(
550
+ self.lst1.history(('e', 128, 'fluid_temperature'))[1],
551
+ self.lst2.history(('e', 128, 'fluid_temperature'))[1],
552
+ rtol=1e-10,
553
+ )
554
+
555
+ # check for false positive, this should be different
556
+ self.assertRaises(
557
+ AssertionError,
558
+ np.testing.assert_allclose,
559
+ self.lst1.history(('e', 123, 'fluid_pressure'))[1],
560
+ self.lst2.history(('e', 78, 'fluid_pressure'))[1],
561
+ rtol=1e-10,
562
+ )
563
+ self.assertRaises(
564
+ AssertionError,
565
+ np.testing.assert_allclose,
566
+ self.lst1.history(('e', 127, 'fluid_temperature'))[1],
567
+ self.lst2.history(('e', 128, 'fluid_temperature'))[1],
568
+ rtol=1e-10,
569
+ )
570
+
571
+
572
+
573
+ if __name__ == '__main__':
574
+ unittest.main(verbosity=2)
575
+
576
+ # import time
577
+ # from mulgrids import mulgrid
578
+ # geo = mulgrid('gLihir_v7_NS.dat')
579
+ # init_time = time.time()
580
+ # lst = wlisting('Lihir_v7_SP_NS_060_wai.h5', geo)
581
+ # print('%.2f sec' % (time.time() - init_time))
582
+ # init_time = time.time()
583
+ # lst.index = 1
584
+ # print('%.2f sec' % (time.time() - init_time))
585
+
586
+
587
+