crunchflow 2.0.2__tar.gz → 2.0.3__tar.gz
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.
- {crunchflow-2.0.2 → crunchflow-2.0.3}/PKG-INFO +1 -1
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/input/blocks.py +38 -3
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/input/inputfile.py +35 -10
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/output/spatial.py +27 -4
- {crunchflow-2.0.2 → crunchflow-2.0.3}/pyproject.toml +1 -1
- {crunchflow-2.0.2 → crunchflow-2.0.3}/LICENSE +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/README.md +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/__init__.py +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/input/__init__.py +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/output/__init__.py +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/output/timeseries.py +0 -0
- {crunchflow-2.0.2 → crunchflow-2.0.3}/crunchflow/util.py +0 -0
|
@@ -476,7 +476,7 @@ class Gases(SpeciesBlock):
|
|
|
476
476
|
pass
|
|
477
477
|
|
|
478
478
|
|
|
479
|
-
class
|
|
479
|
+
class SurfaceComplexation(KeywordBlock):
|
|
480
480
|
def __init__(self):
|
|
481
481
|
super().__init__()
|
|
482
482
|
self.species = []
|
|
@@ -494,8 +494,43 @@ class KineticsBlock(KeywordBlock):
|
|
|
494
494
|
return "\n".join(result)
|
|
495
495
|
|
|
496
496
|
|
|
497
|
-
class
|
|
498
|
-
|
|
497
|
+
class KineticsBlock(KeywordBlock):
|
|
498
|
+
def __init__(self):
|
|
499
|
+
super().__init__()
|
|
500
|
+
self.species_dict = {}
|
|
501
|
+
self.species = []
|
|
502
|
+
|
|
503
|
+
def set_parameters(self, parameters):
|
|
504
|
+
for species, details in parameters.items():
|
|
505
|
+
label = details.pop('label', None)
|
|
506
|
+
if species not in self.species_dict:
|
|
507
|
+
self.species_dict[species] = {}
|
|
508
|
+
self.species.append(species)
|
|
509
|
+
if label:
|
|
510
|
+
self.species_dict[species][label] = details
|
|
511
|
+
else:
|
|
512
|
+
self.species_dict[species]['default'] = details
|
|
513
|
+
|
|
514
|
+
def update_parameters(self, species, label, new_details):
|
|
515
|
+
if species in self.species_dict and label in self.species_dict[species]:
|
|
516
|
+
self.species_dict[species][label].update(new_details)
|
|
517
|
+
else:
|
|
518
|
+
print(f"Species '{species}' with label '{label}' not found.")
|
|
519
|
+
|
|
520
|
+
def __str__(self):
|
|
521
|
+
result = []
|
|
522
|
+
for species, labels in self.species_dict.items():
|
|
523
|
+
if 'default' in labels and not labels['default']:
|
|
524
|
+
result.append(f"{species:<20}")
|
|
525
|
+
else:
|
|
526
|
+
for label, details in labels.items():
|
|
527
|
+
if label == 'default' and not details:
|
|
528
|
+
result.append(f"{species:<20}")
|
|
529
|
+
else:
|
|
530
|
+
details_str = ' '.join(f'-{k} {v}' for k, v in details.items())
|
|
531
|
+
label_str = f"-label {label} " if label != 'default' else ""
|
|
532
|
+
result.append(f"{species:<20} {label_str}{details_str}")
|
|
533
|
+
return "\n".join(result)
|
|
499
534
|
|
|
500
535
|
|
|
501
536
|
class Minerals(KineticsBlock):
|
|
@@ -63,7 +63,7 @@ class InputFile:
|
|
|
63
63
|
# Initialize other blocks as needed
|
|
64
64
|
|
|
65
65
|
def set_block(self, block_name, parameters):
|
|
66
|
-
"""Set the parameters
|
|
66
|
+
"""Set the parameters of a block in an InputFile instance.
|
|
67
67
|
|
|
68
68
|
Parameters
|
|
69
69
|
----------
|
|
@@ -93,11 +93,9 @@ class InputFile:
|
|
|
93
93
|
# Note that the "CONDITION <name>" is included in
|
|
94
94
|
# Condition.__str__ method, so it is omitted here
|
|
95
95
|
result.append(f"{str(condition)}\nEND")
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
# block_name = format_class_name(item.__class__.__name__)
|
|
100
|
-
# result.append(f"{block_name}\n{str(item)}\nEND")
|
|
96
|
+
|
|
97
|
+
# Otherwise, check if the block has any attributes set
|
|
98
|
+
# and if so, format the block name then print it
|
|
101
99
|
elif any(val for val in value.__dict__.values() if val):
|
|
102
100
|
block_name = format_class_name(value.__class__.__name__)
|
|
103
101
|
result.append(f"{block_name}\n{str(value)}\nEND")
|
|
@@ -114,7 +112,12 @@ class InputFile:
|
|
|
114
112
|
The path to the output file. Default is the current directory.
|
|
115
113
|
update_pestcontrol : bool, optional
|
|
116
114
|
Whether to update PestControl.ant with the name of the
|
|
117
|
-
CrunchFlow input file. Default is False.
|
|
115
|
+
CrunchFlow input file. Default is False.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
None
|
|
120
|
+
The CrunchFlow input file is saved to disk."""
|
|
118
121
|
|
|
119
122
|
full_path = os.path.join(path, filename)
|
|
120
123
|
with open(full_path, 'w') as file:
|
|
@@ -127,7 +130,7 @@ class InputFile:
|
|
|
127
130
|
if update_pestcontrol:
|
|
128
131
|
folder = os.path.dirname(full_path)
|
|
129
132
|
pestfile = os.path.join(folder, 'PestControl.ant')
|
|
130
|
-
with open(
|
|
133
|
+
with open(pestfile, 'w') as file:
|
|
131
134
|
file.write('%s \n' % os.path.basename(full_path))
|
|
132
135
|
|
|
133
136
|
@classmethod
|
|
@@ -160,7 +163,7 @@ class InputFile:
|
|
|
160
163
|
# Define attributes and blocks to be handled as special cases
|
|
161
164
|
# SpeciesBlock and KineticsBlock instances are handled differently below
|
|
162
165
|
species_blocks = ['primary_species', 'secondary_species', 'gases']
|
|
163
|
-
kinetics_blocks = ['minerals', 'aqueous_kinetics'
|
|
166
|
+
kinetics_blocks = ['minerals', 'aqueous_kinetics']
|
|
164
167
|
|
|
165
168
|
# Some attributes can be set multiple times within a single block
|
|
166
169
|
multiply_defined = ['time_series', 'pressure', 'mineral',
|
|
@@ -229,13 +232,35 @@ class InputFile:
|
|
|
229
232
|
parts = line.split()
|
|
230
233
|
current_block.species.append(parts[0])
|
|
231
234
|
|
|
232
|
-
elif current_block_name
|
|
235
|
+
elif current_block_name == 'surface_complexation':
|
|
233
236
|
parts = line.split()
|
|
234
237
|
species = parts[0]
|
|
235
238
|
details = " ".join(parts[1:]) if len(parts) > 1 else ""
|
|
236
239
|
current_block.species.append(species)
|
|
237
240
|
current_block.species_dict[species] = details
|
|
238
241
|
|
|
242
|
+
elif current_block_name in kinetics_blocks:
|
|
243
|
+
parts = line.split()
|
|
244
|
+
species = parts[0]
|
|
245
|
+
details = {}
|
|
246
|
+
|
|
247
|
+
# Assume the default label
|
|
248
|
+
# This will be updated below if it is included in details
|
|
249
|
+
label = 'default'
|
|
250
|
+
|
|
251
|
+
# If there are details associated with the species_dict, then parse them
|
|
252
|
+
if len(parts) > 1:
|
|
253
|
+
# Loop through kinetic options (e.g., -activation, -rate, etc.)
|
|
254
|
+
# and store this information in a dictionary
|
|
255
|
+
for i in range(1, len(parts), 2):
|
|
256
|
+
key = parts[i].lstrip('-')
|
|
257
|
+
value = parts[i+1] if (i+1) < len(parts) else None
|
|
258
|
+
if key == 'label':
|
|
259
|
+
label = value
|
|
260
|
+
else:
|
|
261
|
+
details[key] = value
|
|
262
|
+
current_block.set_parameters({species: {**details, 'label': label}})
|
|
263
|
+
|
|
239
264
|
# All other blocks, split on whitespace
|
|
240
265
|
else:
|
|
241
266
|
parts = line.split()
|
|
@@ -197,6 +197,29 @@ class SpatialProfile:
|
|
|
197
197
|
Get line segments that outline all the regions equal to
|
|
198
198
|
the provided value.
|
|
199
199
|
|
|
200
|
+
__init__(fileprefix, folder, output_times, suffix)
|
|
201
|
+
Read in and get basic info about all .tec files matching `fileprefix`.
|
|
202
|
+
For example, `tec('volume')` will read in all files matching
|
|
203
|
+
'volume[0-9]+.tec'
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
fileprefix : str
|
|
208
|
+
file prefix of the tec file to read in, without the timestep
|
|
209
|
+
number or ".tec" file ending. For example, if your files are
|
|
210
|
+
"volume1.tec", "volume2.tec", etc., then fileprefix should be
|
|
211
|
+
"volume".
|
|
212
|
+
folder : str, optional
|
|
213
|
+
folder in which the .tec files are located. The default is the
|
|
214
|
+
current directory
|
|
215
|
+
output_times : list of float, optional
|
|
216
|
+
list of the actual output times at which the .tec files were
|
|
217
|
+
output, in CrunchFlow time units
|
|
218
|
+
suffix : str, optional
|
|
219
|
+
file ending of the tec files to read in. This can vary depending on the
|
|
220
|
+
version of CrunchTope used. The default is '.tec', but '.out' is also
|
|
221
|
+
tried if '.tec' files are not found.
|
|
222
|
+
|
|
200
223
|
Examples
|
|
201
224
|
--------
|
|
202
225
|
>>> vol = SpatialProfile('volume')
|
|
@@ -207,7 +230,7 @@ class SpatialProfile:
|
|
|
207
230
|
|
|
208
231
|
def __init__(self, fileprefix, folder='.', output_times=None, suffix='.tec'):
|
|
209
232
|
"""Read in and get basic info about all .tec files matching `fileprefix`.
|
|
210
|
-
For example, `
|
|
233
|
+
For example, `SpatialProfile('volume')` will read in all files matching
|
|
211
234
|
'volume[0-9]+.tec'
|
|
212
235
|
|
|
213
236
|
Parameters
|
|
@@ -217,13 +240,13 @@ class SpatialProfile:
|
|
|
217
240
|
number or ".tec" file ending. For example, if your files are
|
|
218
241
|
"volume1.tec", "volume2.tec", etc., then fileprefix should be
|
|
219
242
|
"volume".
|
|
220
|
-
folder : str
|
|
243
|
+
folder : str, optional
|
|
221
244
|
folder in which the .tec files are located. The default is the
|
|
222
245
|
current directory
|
|
223
|
-
output_times : list of float
|
|
246
|
+
output_times : list of float, optional
|
|
224
247
|
list of the actual output times at which the .tec files were
|
|
225
248
|
output, in CrunchFlow time units
|
|
226
|
-
suffix : str
|
|
249
|
+
suffix : str, optional
|
|
227
250
|
file ending of the tec files to read in. This can vary depending on the
|
|
228
251
|
version of CrunchTope used. The default is '.tec', but '.out' is also
|
|
229
252
|
tried if '.tec' files are not found.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|