'''
MIT License
Copyright (c) [2022] [Temitope Ajayi]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
'''
import numpy as np
import os
import sys
from os.path import splitext, basename
from math import ceil
from os import devnull, remove
from subprocess import call
from copy import deepcopy
from t2grids import t2grid, rocktype
from t2data import t2data, trim_trailing_nones
from mulgrids import unfix_blockname, padstring
from fixed_format_file import fixed_format_file
from fixed_format_file import default_read_function
from pytoughreact.constants.format_specifications import t2bio_format_specification
from pytoughreact.constants.sections import t2bio_sections
from pytoughreact.constants.defaults_constants import DEFAULT_PARAMETERS
from pytoughreact.chemical.biomass_composition import BaseComponent, Gas, WaterBio, Biomass
from pytoughreact.chemical.bio_process_description import Process, BIODG
[docs]
class T2BioParser(fixed_format_file):
"""Class for parsing TMVOC data file."""
[docs]
def __init__(self, filename, mode, read_function=default_read_function):
super(T2BioParser, self).__init__(filename, mode,
t2bio_format_specification, read_function)
[docs]
def read_multi_value_line(self, variable, line_type):
""" Reads a line of parameter multi values from the file into a dictionary variable.
Null values are ignored.
Parameters
-----------
variable : str
variable to be read
line_type: str
type of line to be read
Returns
--------
"""
spec = self.specification[line_type]
vals = self.read_values(line_type)
if len(spec[0]) < 6:
for var, val in zip(spec[0], vals):
if val is not None:
variable[var] = val
else:
variable[line_type] = vals
[docs]
def read_params_value_line(self, variable, line_type):
""" Reads a line of parameter values from the file into a dictionary variable.
Null values are ignored.
Parameters
-----------
variable : str
variable to be read
line_type: str
type of line to be read
Returns
--------
"""
spec = self.specification[line_type]
vals = self.read_values(line_type)
if len(spec[0]) > 2:
for var, val in zip(spec[0], vals):
if val is not None:
variable[var] = val
else:
variable[line_type] = vals
[docs]
class T2Bio(t2data):
"""Class for TMVOC data."""
[docs]
def __init__(self, filename='', meshfilename='',
read_function=default_read_function):
super().__init__(filename='', meshfilename='', read_function=default_read_function)
self.filename = filename
self.meshfilename = meshfilename
self.title = ''
self.simulator = ''
self.parameter = deepcopy(DEFAULT_PARAMETERS)
self._more_option_str = '0' * 21,
self.more_option = np.zeros(22, int)
self.multi = {}
self.start = False
self.relative_permeability = {}
self.capillarity = {}
self.components = []
self.gas = []
self.biodg = []
self.solids = []
self.lineq = {}
self.output_times = {}
self.grid = t2grid()
self.generatorlist = []
self.generator = {}
self.short_output = {}
self.incon = {}
self.solver = {}
self.history_block = []
self.history_connection = []
self.history_generator = []
self.indom = {}
self.noversion = False
self.diffusion = []
self.selection = {}
self.meshmaker = []
self._sections = []
self.end_keyword = 'ENDCY'
self._extra_precision, self._echo_extra_precision = [], True
self.update_read_write_functions()
self.read_function = read_function
if self.filename:
self.read(filename, meshfilename)
[docs]
def update_read_write_functions(self):
"""Updates functions for reading and writing sections of data file."""
self.read_fn = dict(zip(
t2bio_sections,
[self.read_simulator,
self.read_rocktypes,
self.read_multi,
self.read_chem,
self.read_gas,
self.read_biodg,
self.read_solids,
self.read_parameters,
self.read_more_options,
self.read_start,
self.read_noversion,
self.read_rpcap,
self.read_lineq,
self.read_solver,
self.read_times,
self.read_selection,
self.read_diffusion,
self.read_blocks,
self.read_connections,
self.read_meshmaker,
self.read_generators,
self.read_short_output,
self.read_history_blocks,
self.read_history_connections,
self.read_history_generators,
self.read_incons,
self.read_indom]))
self.write_fn = dict(zip(
t2bio_sections,
[self.write_simulator,
self.write_rocktypes,
self.write_multi,
self.write_chem,
self.write_gas,
self.write_biodg,
self.write_solids,
self.write_parameters,
self.write_more_options,
self.write_start,
self.write_noversion,
self.write_rpcap,
self.write_lineq,
self.write_solver,
self.write_times,
self.write_selection,
self.write_diffusion,
self.write_blocks,
self.write_connections,
self.write_meshmaker,
self.write_generators,
self.write_short_output,
self.write_history_blocks,
self.write_history_connections,
self.write_history_generators,
self.write_incons,
self.write_indom]))
[docs]
def get_present_sections(self):
""" Returns a list of TOUGH2 section keywords for which there are
corresponding data in the t2bio object.
Parameters
-----------
Returns
--------
present_sections : list
Sections with corresponding data in the t2bio object
"""
data_present = dict(zip(
t2bio_sections,
[self.simulator,
self.grid and self.grid.rocktypelist,
self.multi,
self.components,
self.gas,
self.biodg,
self.solids,
self.parameter,
np.any(self.more_option),
self.start,
self.noversion,
self.relative_permeability or self.capillarity,
self.lineq,
self.solver,
self.output_times,
self.selection,
self.diffusion,
self.grid,
self.grid,
self.meshmaker,
self.generatorlist,
self.short_output,
self.history_block,
self.history_connection,
self.history_generator,
self.incon,
self.indom]))
return [keyword for keyword in t2bio_sections if data_present[keyword]]
present_sections = property(get_present_sections)
[docs]
def section_insertion_index(self, section):
""" Determines an appropriate position to insert the specified section
in the internal list of data file sections.
Parameters
-----------
section : list
list of sections
Returns
--------
parameter : int
Appropriate position to insert the specified section in the internal list of data file sections.
"""
try:
listindex = t2bio_sections.index(section)
if listindex == 0:
return 0 # SIMUL section
else:
# first look for sections above the one specified,
# and put new one just after the last found:
for i in reversed(range(listindex)):
try:
section_index = self._sections.index(t2bio_sections[i])
return section_index + 1
except ValueError:
pass
# look for sections below the one specified,
# and put new one just before the first found:
for i in range(listindex, len(t2bio_sections)):
try:
section_index = self._sections.index(t2bio_sections[i])
return section_index
except ValueError:
pass
return len(self._sections)
except ValueError:
return len(self._sections)
[docs]
def run(self, save_filename='', incon_filename='', runlocation='', simulator='AUTOUGH2_2',
silent=False, output_filename=''):
""" Runs simulation using TMVOC
Parameters
-----------
save_filename : str
filename of SAVE file
incon_filename : str
filename of INCON file
run_location : str
path to Executable and required files
simulator : str
simulator executable name
silent: boolean
if output messages should be written out
output_filename: str
name of output file
Returns
--------
"""
if runlocation:
os.chdir(os.path.dirname(os.path.realpath(__file__)))
print(os.path.dirname(os.path.realpath(__file__)))
# newPath = shutil.copy('tmvoc.exe', runlocation)
os.chdir(runlocation)
if self.filename:
datbase, ext = splitext(self.filename)
if (self.type == 'AUTOUGH2'):
if save_filename == '':
save_filename = datbase + '.save'
if incon_filename == '':
incon_filename = datbase + '.incon'
savebase, ext = splitext(save_filename)
inconbase, ext = splitext(incon_filename)
runfilename = datbase + '_' + basename(simulator) + '.in'
open(runfilename, 'w').write('\n'.join([savebase, inconbase, datbase]))
infile = open(runfilename, 'r')
cmd = [simulator]
if silent:
outfile = open(devnull, 'w')
else:
outfile = None
# run AUTOUGH2:
call(cmd, stdin=infile, stdout=outfile)
infile.close()
remove(runfilename)
else: # run TOUGH2 (need to specify simulator executable name)
if runlocation:
os.chdir(runlocation)
# if os.path.exists("GENER"): os.remove("GENER")
# if os.path.exists("OUTPUT_ELEME.csv"): os.remove("OUTPUT_ELEME.csv")
cmd = [simulator]
infile = open(self.filename, 'r')
if silent:
outfile = None
else:
if output_filename == '':
datbase = 'iter'
outfilename = datbase + '.out'
else:
outfilename = output_filename
outfile = open(outfilename, 'w')
call(cmd, stdin=infile, stdout=outfile)
[docs]
def read_rocktypes(self, infile):
""" Reads grid rock types
Parameters
-----------
infile : str
Input file processor
Returns
--------
rocktype: self
adds rocktype information to grid
"""
self.grid.rocktypelist = []
self.grid.rocktype = {}
line = padstring(infile.readline())
while line.strip():
[name, nad, density, porosity,
k1, k2, k3, conductivity, specific_heat] = infile.parse_string(line, 'rocks1')
self.grid.add_rocktype(rocktype(name, nad,
density, porosity,
[k1, k2, k3],
conductivity, specific_heat))
if nad is None:
nad = 0
if nad >= 1: # additional lines:
infile.read_multi_value_line2(self.grid.rocktype[name].__dict__, 'rocks1.1')
if nad >= 2:
vals = infile.read_values('rocks1.2')
self.grid.rocktype[name].relative_permeability['type'] = vals[0]
self.grid.rocktype[name].relative_permeability['parameters'] = vals[2: -1]
vals = infile.read_values('rocks1.3')
self.grid.rocktype[name].capillarity['type'] = vals[0]
self.grid.rocktype[name].capillarity['parameters'] = vals[2: -1]
line = padstring(infile.readline())
[docs]
def read_chem(self, infile):
""" Reads chemical components
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds components to grid
"""
params = infile.read_values('chemp')
all_comp = []
for i in range(int(params[0])):
comp_name = infile.read_values('chemp1')
first_line = infile.read_values('chemp1.1')
second_line = infile.read_values('chemp1.2')
third_line = infile.read_values('chemp1.3')
fourth_line = infile.read_values('chemp1.4')
fifth_line = infile.read_values('chemp1.5')
sixth_line = infile.read_values('chemp1.6')
seventh_line = infile.read_values('chemp1.7')
comp = BaseComponent(name=comp_name[0], critical_temperature=first_line[0], critical_pressure=first_line[1],
critical_compressibility=first_line[2],
acentric_factor=first_line[3], dipole_moment=first_line[4],
boiling_point=second_line[0], vapor_pressure_a=second_line[1],
vapor_pressure_b=second_line[2],
vapor_pressure_c=second_line[3], vapor_pressure_d=second_line[4],
molecular_weight=third_line[0], heat_capacity_constant_a=third_line[1],
heat_capacity_constant_b=third_line[2], heat_capacity_constant_c=third_line[3],
heat_capacity_constant_d=third_line[4],
liquid_density=fourth_line[0], reference_temp_for_density=fourth_line[1],
reference_binary_diffusivity=fourth_line[2],
reference_temperature_for_diffusivity=fourth_line[3],
exponent_chemical_diffusivity=fourth_line[4],
liquid_viscosity_constant_a=fifth_line[0], liquid_viscosity_constant_b=fifth_line[1],
liquid_viscosity_constant_c=fifth_line[2],
liquid_viscosity_constant_d=fifth_line[3], liquid_critical_volume=fifth_line[4],
liquid_chemical_solubility_a=sixth_line[0], liquid_chemical_solubility_b=sixth_line[1],
liquid_chemical_solubility_c=sixth_line[2],
liquid_chemical_solubility_d=sixth_line[3],
carbon_partition_coefficient=seventh_line[0],
fractional_organic_carbon=seventh_line[1],
decay_constant=seventh_line[2])
all_comp.append(comp)
self.components = all_comp
[docs]
def write_chem(self, outfile):
""" Writes chemical components
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
outfile.write('CHEMP\n')
vals = [len(self.components)]
outfile.write_values(vals, 'chemp')
for component in self.components:
vals = component.name
outfile.write(vals + '\n')
vals = component.get_first_set()
outfile.write_values(vals, 'chemp1.1')
vals = component.get_second_set()
outfile.write_values(vals, 'chemp1.2')
vals = component.get_third_set()
outfile.write_values(vals, 'chemp1.3')
vals = component.get_fourth_set()
outfile.write_values(vals, 'chemp1.4')
vals = component.get_fifth_set()
outfile.write_values(vals, 'chemp1.5')
vals = component.get_sixth_set()
outfile.write_values(vals, 'chemp1.6')
vals = component.get_seventh_set()
outfile.write_values(vals, 'chemp1.7')
# outfile.write(str(comp_total) + '\n')
pass
[docs]
def read_gas(self, infile):
""" Reads Gases
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds gases to grid
"""
params = infile.read_values('ncgas')
all_comp = []
for i in range(int(params[0])):
first_line = infile.read_values('ncgas1')
comp = Gas(name=first_line[0], index=i + 2)
all_comp.append(comp)
self.gas = all_comp
[docs]
def write_gas(self, outfile):
""" Writes Gases
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
outfile.write('NCGAS\n')
vals = [len(self.gas)]
outfile.write_values(vals, 'ncgas')
for i in range(len(self.gas)):
vals = self.gas[i].name
outfile.write(vals + '\n')
[docs]
def reset_bio_dicta(self, all_components):
""" Resets the BIO dictionary
Parameters
-----------
all_components : list
all components present
Returns
--------
empty_list: list
empty list containing no parameters
"""
empty_list = []
for i in range(len(all_components)):
dicta = {}
dicta[all_components[i]] = []
empty_list.append(dicta)
return empty_list
[docs]
def read_biodg(self, infile):
""" Reads Biodegradation Block
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds biodegradation block to grid
"""
params = infile.read_values('biodg')
number_of_processes = int(infile.read_values('biodg1')[0])
process_details = []
for i in range(number_of_processes):
first_line = infile.read_values('biodg1.1')
second_line = infile.read_values('biodg1.1.1')
third_line = infile.read_values('biodg1.1.2')
fourth_line = infile.read_values('biodg1.1.3')
fifth_line = infile.read_values('biodg1.1.4')
sixth_line = infile.read_values('biodg1.1.5')
comp = [first_line, second_line, third_line, fourth_line, fifth_line, sixth_line]
process_details.append(comp)
number_of_biomass = int(infile.read_values('biodg2')[0])
biomass_details = []
for i in range(number_of_biomass):
biomass_1 = infile.read_values('biodg2.1')
biomass_class = Biomass(index=i + 1, name='biom' + str(i), init_conc=biomass_1[0], min_conc=biomass_1[1],
max_temp=biomass_1[2], death_rate=biomass_1[3], inhibition_constant=biomass_1[4])
biomass_details.append(biomass_class)
water_component = [WaterBio('H2O')]
all_components = water_component + self.gas + self.components
dicta_all = []
# for i in range(len(all_components)):
# dicta = {}
# dicta[all_components[i]] = []
# dicta_all.append(dicta)
all_processes = []
for i in range(len(process_details)):
dicta_all = self.reset_bio_dicta(all_components)
process = Process(biomass=biomass_details[process_details[i][0][1] - 1],
number_of_components=process_details[i][0][0],
mumax=process_details[i][0][2], yield_mass=process_details[i][0][3],
number_competiting=process_details[i][0][4],
number_of_non_competiting=process_details[i][0][5],
number_of_haldane=process_details[i][0][6], enthalpy=process_details[i][0][7])
for j in range(len(all_components)):
dicta_all[j][all_components[j]].append(process_details[i][5][j])
for k in range(len(process_details[i][1])):
if process_details[i][1][k] == j + 1:
dicta_all[j][all_components[j]].append(process_details[i][1][k + 1])
if len(dicta_all[j][all_components[j]]) == 1:
all_components[j].add_to_process(process, dicta_all[j][all_components[j]][0])
elif len(dicta_all[j][all_components[j]]) == 2:
all_components[j].add_to_process(process, dicta_all[j][all_components[j]][0],
dicta_all[j][all_components[j]][1])
elif len(dicta_all[j][all_components[j]]) == 3:
all_components[j].add_to_process(process, dicta_all[j][all_components[j]][0],
dicta_all[j][all_components[j]][1],
dicta_all[j][all_components[j]][2])
elif len(dicta_all[j][all_components[j]]) == 4:
all_components[j].add_to_process(process, dicta_all[j][all_components[j]][0],
dicta_all[j][all_components[j]][1],
dicta_all[j][all_components[j]][2],
dicta_all[j][all_components[j]][3])
elif len(dicta_all[j][all_components[j]]) == 5:
all_components[j].add_to_process(process, dicta_all[j][all_components[j]][0],
dicta_all[j][all_components[j]][1],
dicta_all[j][all_components[j]][2],
dicta_all[j][all_components[j]][3],
dicta_all[j][all_components[j]][4])
all_processes.append(process)
biodegradation = BIODG(imonod=params[0], bfac=params[2], sw1=params[4], sw2=params[5], wea=params[6],
wsub=params[7],
processes=all_processes, biomass=biomass_details, icflag=params[1])
self.biodg.append(biodegradation)
[docs]
def write_biodg(self, outfile):
""" Writes Biodegradation Block
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
outfile.write('BIODG\n')
value = self.biodg[0]
vals = value.get_first_set()
# numberOfBiomass = value.getNumberOfBiomasses()
outfile.write_values(vals, 'biodg')
vals = [len(value.processes)]
outfile.write_values(vals, 'biodg1')
for i in range(len(value.processes)):
sub_degrade = value.processes[i].get_ks()
comp_degrade = value.processes[i].get_kc()
ncomp_degrade = value.processes[i].get_knc()
h_degrade = value.processes[i].get_kh()
uptake = value.processes[i].get_uptake()
vals = [len(sub_degrade), value.processes[i].biomass.index, value.processes[i].mumax,
value.processes[i].yield_mass,
value.processes[i].number_competiting, value.processes[i].number_of_non_competiting,
value.processes[i].number_of_haldane, value.processes[i].enthalpy]
outfile.write_values(vals, 'biodg1.1')
vals = []
for j in sub_degrade:
component = list(j.keys())[0]
vals.append(component)
value1 = list(j.values())[0]
vals.append(value1)
outfile.write_values(vals, 'biodg1.1.1')
vals = []
if len(comp_degrade) != 0:
for j in comp_degrade:
component = list(j.keys())[0]
vals.append(component)
value1 = list(j.values())[0]
vals.append(value1)
else:
vals = [0]
outfile.write_values(vals, 'biodg1.1.2')
vals = []
if len(ncomp_degrade) != 0:
for j in ncomp_degrade:
component = list(j.keys())[0]
vals.append(component)
value1 = list(j.values())[0]
vals.append(value1)
else:
vals = [0]
outfile.write_values(vals, 'biodg1.1.3')
vals = []
if len(h_degrade) != 0:
for j in h_degrade:
component = list(j.keys())[0]
vals.append(component)
value1 = list(j.values())[0]
vals.append(value1)
else:
vals = [0]
outfile.write_values(vals, 'biodg1.1.4')
vals = uptake
outfile.write_values(vals, 'biodg1.1.5')
vals = [len(value.biomass)]
outfile.write_values(vals, 'biodg2')
for i in range(len(value.biomass)):
vals = [value.biomass[i].init_conc, value.biomass[i].min_conc, value.biomass[i].max_temp,
value.biomass[i].death_rate, value.biomass[i].inhibition_constant]
outfile.write_values(vals, 'biodg2.1')
[docs]
def read_solids(self, infile):
""" Reads Solids Block
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds solid block to grid
"""
pass
[docs]
def write_solids(self, outfile):
""" Writes Solid Block
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
outfile.write('SOLIDS\n')
outfile.write_values(len(self.solids), 'solids1')
for i in range(len(self.solids)):
value = self.solids[i]
vals = value.getFirstSet()
outfile.write_values(vals, 'solids2')
[docs]
def read_parameters(self, infile):
""" Reads Parameters Block
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds parameters block to grid
"""
spec = ['param1', 'param1_autough2'][self.type == 'AUTOUGH2']
# infile.read_value_line(self.parameter, spec)
infile.read_params_value_line(self.parameter, spec)
mops = self.parameter['_option_str'].rstrip().ljust(24).replace(' ', '0')
self.parameter['option'] = np.array([0] + [int(mop) for mop in mops], int)
# infile.read_value_line(self.parameter, 'param2')
infile.read_params_value_line(self.parameter, 'param2')
if (self.parameter['print_block'] is not None) and \
(self.parameter['print_block'].strip() == ''):
self.parameter['print_block'] = None
self.read_timesteps(infile)
# infile.read_value_line(self.parameter, 'param3')
infile.read_params_value_line(self.parameter, 'param3')
infile.read_value_line(self.parameter, 'param4')
for val in infile.read_values('default_incons'):
self.parameter['default_incons'].append(val)
self.parameter['default_incons'] = trim_trailing_nones(self.parameter['default_incons'])
# read any additional lines of default incons:
more = True
while more:
line = padstring(infile.readline())
if line.strip():
section = any([line.startswith(keyword) for keyword in t2bio_sections])
if section:
more = False
else:
more_incons = infile.parse_string(line, 'default_incons')
more_incons = trim_trailing_nones(more_incons)
self.parameter['default_incons'] += more_incons
else:
more, line = False, None
return line
[docs]
def write_parameters(self, outfile):
""" Writes Parameters Block
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
outfile.write('PARAM\n')
from copy import copy
paramw = copy(self.parameter)
if paramw['print_block'] is not None:
paramw['print_block'] = unfix_blockname(paramw['print_block'])
self.parameter['_option_str'] = ''.join([str(m) for m in self.parameter['option'][1:]])
spec = ['param1', 'param1_autough2'][self.type == 'AUTOUGH2']
outfile.write_value_line(self.parameter, spec)
outfile.write_value_line(paramw, 'param2')
self.write_timesteps(outfile)
outfile.write_value_line(self.parameter, 'param3')
outfile.write_value_line(self.parameter, 'param4')
num_vars = len(self.parameter['default_incons'])
if num_vars > 0:
nlines = int(ceil(num_vars / 4.))
for i in range(nlines):
i1, i2 = i * 4, min((i + 1) * 4, num_vars)
vals = list(self.parameter['default_incons'][i1: i2])
if len(vals) < 4:
vals += [None] * (4 - len(vals))
outfile.write_values(vals, 'default_incons')
else:
outfile.write('\n')
[docs]
def read_more_options(self, infile):
""" Reads additional parameter options
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds more_options block to grid
"""
infile.read_value_line(self.__dict__, '_more_option_str')
momops = self._more_option_str.rstrip().ljust(21).replace(' ', '0')
self.more_option = np.array([0] + [int(mop) for mop in momops], int)
[docs]
def read_multi(self, infile):
""" Reads EOS parameters
Parameters
-----------
infile : str
Input file processor
Returns
--------
components: self
adds multi block to grid
"""
spec = ['multi', 'multi_autough2'][self.type == 'AUTOUGH2']
# spec = self.specification[spec]
# vals = infile.read_values('multi')
# for var, val in zip(spec[0], vals):
# if val is not None: self.multi[var] = val
infile.read_multi_value_line(self.multi, spec)
if 'eos' in self.multi:
self.multi['eos'] = self.multi['eos'].strip()
[docs]
def write_start(self, outfile):
""" Writes Start Block
Parameters
-----------
outfile : str
output file processor
Returns
--------
"""
if self.start:
outfile.write('START\n')
[docs]
def read(self, filename='', meshfilename='', runlocation=''):
""" Reads data from file. Mesh data can optionally be read from an
auxiliary file. Extra precision data will also be read from
an associated '.pdat' file, if it exists.
Parameters
-----------
filename : str
file to read
meshfilename : str
Mesh file to read
runlocation : str
Path containing executables
Returns
--------
"""
if runlocation:
if not os.path.isdir(runlocation):
os.mkdir(runlocation)
os.chdir(runlocation)
if filename:
self.filename = filename
mode = 'r' if sys.version_info > (3,) else 'rU'
infile = T2BioParser(self.filename, mode, read_function=self.read_function)
self.read_title(infile)
self._sections = []
more = True
next_line = None
while more:
if next_line:
line = next_line
else:
line = infile.readline()
if line:
keyword = line[0: 5].strip()
if keyword in ['ENDCY', 'ENDFI']:
more = False
self.end_keyword = keyword
elif keyword in t2bio_sections:
fn = self.read_fn[keyword]
next_line = None
if keyword == 'SHORT':
fn(infile, line)
elif keyword == 'PARAM':
next_line = fn(infile)
else:
fn(infile)
self._sections.append(keyword)
else:
more = False
infile.close()
if meshfilename and (self.grid.num_blocks == 0):
self.meshfilename = meshfilename
if isinstance(meshfilename, str):
mode = 'r' if sys.version_info > (3,) else 'rU'
meshfile = T2BioParser(self.meshfilename, mode, read_function=self.read_function)
self.read_meshfile(meshfile)
meshfile.close()
elif isinstance(meshfilename, (list, tuple)):
if len(meshfilename) == 2:
self.read_binary_meshfiles()
else:
print('Mesh filename must be either a string or a two-element tuple or list.')
self.status = 'successful'
return self
[docs]
def write(self, filename='', meshfilename='', run_location='',
extra_precision=None, echo_extra_precision=None):
""" Writes data to file. Mesh data can optionally be written to an
auxiliary file. For AUTOUGH2, if extra_precision is True or a
list of section names, the corresponding data sections will be
written to an extra precision file; otherwise, the same
sections (if any) that were read in as extra precision will
also be written out as extra precision. If
echo_extra_precision is True, the extra precision sections
will also be written to the main data file.
Parameters
-----------
filename : str
file to read
meshfilename : str
Mesh file to read
runlocation : str
Path containing executables
extra_precision: boolean
Required for AUTOUGH from PYTOUGH
echo_extra_precision: boolean
Required for AUTOUGH from PYTOUGH
Returns
--------
"""
if run_location:
if not os.path.isdir(run_location):
os.mkdir(run_location)
os.chdir(run_location)
if filename:
self.filename = filename
if self.filename == '':
self.filename = 't2bio.dat'
self.update_sections()
mesh_sections = []
if meshfilename:
self.meshfilename = meshfilename
if self.meshfilename:
if isinstance(self.meshfilename, str):
meshfile = T2BioParser(self.meshfilename, 'w')
self.write_blocks(meshfile)
self.write_connections(meshfile)
meshfile.close()
mesh_sections = ['ELEME', 'CONNE']
elif isinstance(self.meshfilename, (list, tuple)):
if len(self.meshfilename) == 2:
self.write_binary_meshfiles()
mesh_sections = ['ELEME', 'CONNE']
if self.type == 'AUTOUGH2':
self.write_extra_precision(extra_precision, echo_extra_precision)
outfile = T2BioParser(self.filename, 'w')
self.write_title(outfile)
for keyword in self._sections:
if (keyword not in mesh_sections) and \
((keyword not in self.extra_precision) or (keyword in self.extra_precision and
self.echo_extra_precision)):
self.write_fn[keyword](outfile)
outfile.write(self.end_keyword + '\n')
self.status = 'successful'
outfile.close()