From b7d68fcff46e3ef672c82b30a691b3e8ab7af453 Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Thu, 21 Nov 2019 16:41:35 -0600 Subject: [PATCH 1/5] fix(mnw2): fix issues with files with empty lines Also contains fix for inconsistent wellid cases in dataset 2a and 4a --- flopy/modflow/mfmnw2.py | 44 ++++++++++++++++++++++------------------- flopy/utils/flopy_io.py | 23 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/flopy/modflow/mfmnw2.py b/flopy/modflow/mfmnw2.py index 2984f4513d..c3b674b73c 100644 --- a/flopy/modflow/mfmnw2.py +++ b/flopy/modflow/mfmnw2.py @@ -5,7 +5,7 @@ import numpy as np from .mfdis import get_layer from ..utils import check -from ..utils.flopy_io import line_parse, pop_item +from ..utils.flopy_io import line_parse, pop_item, get_next_line from ..utils import MfList from ..utils.recarray_utils import create_empty_recarray @@ -1213,7 +1213,7 @@ def load(f, model, nper=None, gwt=False, nsol=1, ext_unit_dict=None): # dataset 0 (header) while True: - line = next(f) + line = get_next_line(f) if line[0] != '#': break # dataset 1 @@ -1237,19 +1237,21 @@ def load(f, model, nper=None, gwt=False, nsol=1, ext_unit_dict=None): itmp = [] for per in range(0, nper): # dataset 3 - itmp_per = int(line_parse(next(f))[0]) + itmp_per = int(line_parse(get_next_line(f))[0]) # dataset4 # dict might be better here to only load submitted values if itmp_per > 0: current_4 = ModflowMnw2.get_empty_stress_period_data(itmp_per, aux_names=option) for i in range(itmp_per): - wellid, qdes, capmult, cprime, xyz = _parse_4a(next(f), - mnw, - gwt=gwt) + wellid, qdes, capmult, cprime, xyz = _parse_4a( + get_next_line(f), + mnw, + gwt=gwt) hlim, qcut, qfrcmn, qfrcmx = 0, 0, 0, 0 if mnw[wellid].qlimit < 0: - hlim, qcut, qfrcmn, qfrcmx = _parse_4b(next(f)) + hlim, qcut, qfrcmn, qfrcmx = _parse_4b( + get_next_line(f)) # update package stress period data table ndw = node_data[node_data.wellid == wellid] kij = [ndw.k[0], ndw.i[0], ndw.j[0]] @@ -1695,15 +1697,16 @@ def _parse_2(f): """ # dataset 2a - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) if len(line) > 2: - warnings.warn('MNW2: {}\nExtra items in Dataset 2a!' + \ - 'Check for WELLIDs with space but not enclosed in quotes.'.format( - line)) - wellid = pop_item(line) + warnings.warn('MNW2: {}\n'.format(line) + \ + 'Extra items in Dataset 2a!' + \ + 'Check for WELLIDs with space ' + \ + 'but not enclosed in quotes.') + wellid = pop_item(line).upper() nnodes = pop_item(line, int) # dataset 2b - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) losstype = pop_item(line) pumploc = pop_item(line, int) qlimit = pop_item(line, int) @@ -1719,14 +1722,15 @@ def _parse_2(f): zip(['rw', 'rskin', 'kskin', 'B', 'C', 'P', 'cwc'], [0] * 7)) if losstype.lower() != 'none': # update d2dw items - d2dw.update(_parse_2c(next(f), losstype)) # dict of values for well + d2dw.update( + _parse_2c(get_next_line(f), losstype)) # dict of values for well for k, v in d2dw.items(): if v > 0: d2d[k].append(v) # dataset 2d pp = 1 # partial penetration flag for i in range(np.abs(nnodes)): - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) if nnodes > 0: d2d['k'].append(pop_item(line, int) - 1) d2d['i'].append(pop_item(line, int) - 1) @@ -1752,7 +1756,7 @@ def _parse_2(f): pumpcol = None zpump = None if pumploc != 0: - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) if pumploc > 0: pumplay = pop_item(line, int) pumprow = pop_item(line, int) @@ -1767,7 +1771,7 @@ def _parse_2(f): if qlimit > 0: # Only specify dataset 2f if the value of Qlimit in dataset 2b is positive. # Do not enter fractions as percentages. - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) hlim = pop_item(line, float) qcut = pop_item(line, int) if qcut != 0: @@ -1781,7 +1785,7 @@ def _parse_2(f): if pumpcap > 0: # The number of additional data points on the curve (and lines in dataset 2h) # must correspond to the value of PUMPCAP for this well (where PUMPCAP <= 25). - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) hlift = pop_item(line, float) liftq0 = pop_item(line, float) liftqmax = pop_item(line, float) @@ -1796,7 +1800,7 @@ def _parse_2(f): # The discharge value for the last data point in the sequence # must be less than the value of LIFTqmax. for i in range(len(pumpcap)): - line = line_parse(next(f)) + line = line_parse(get_next_line(f)) liftn = pop_item(line, float) qn = pop_item(line, float) @@ -1875,7 +1879,7 @@ def _parse_4a(line, mnw, gwt=False): capmult = 0 cprime = 0 line = line_parse(line) - wellid = pop_item(line) + wellid = pop_item(line).upper() pumpcap = mnw[wellid].pumpcap qdes = pop_item(line, float) if pumpcap > 0: diff --git a/flopy/utils/flopy_io.py b/flopy/utils/flopy_io.py index 8712803e02..990608ace6 100755 --- a/flopy/utils/flopy_io.py +++ b/flopy/utils/flopy_io.py @@ -66,6 +66,29 @@ def line_strip(line): return line.replace(',', ' ') +def get_next_line(f): + """ + Get the next line from a file that is not a blank line + + Parameters + ---------- + f : filehandle + filehandle to a open file + + Returns + ------- + line : string + next non-empty line in a open file + + + """ + while True: + line = f.readline().rstrip() + if len(line) > 0: + break + return line + + def line_parse(line): """ Convert a line of text into to a list of values. This handles the From de5c12994d3c73b3461d7ceef362eb06fbae2ac4 Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Fri, 22 Nov 2019 10:49:16 -0600 Subject: [PATCH 2/5] fix(mnw2): fix issues with files with empty lines Also contains fix for inconsistent wellid cases in dataset 2a and 4a --- autotest/t027_test.py | 87 ++++++++++++++++++++++++++++++++++++++++- flopy/modflow/mfmnw2.py | 22 ++++++----- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/autotest/t027_test.py b/autotest/t027_test.py index cd035b91bc..7f9f23d90b 100644 --- a/autotest/t027_test.py +++ b/autotest/t027_test.py @@ -243,6 +243,88 @@ def test_export(): # need to add shapefile test +def test_blank_lines(): + mnw2str = """3 50 0 +EB-33 -3 +SKIN -1 0 0 0 +0.375 0.667 50 + 0 -1 1 1 +-1 -2 1 1 +-2 -3 1 1 +-3 +eb-35 3 +SKIN 0 0 0 0 +0.375 1.0 50 +1 1 1 83 24 +2 1 1 +3 1 1 + +EB-36 -2 +SKIN -1 0 0 0 +.375 1.0 50 + 0 -1 1 1 +-1 -2 1 1 +-2 + +3 +EB-33 -11229.2 +EB-35 -534.72 + +eb-36 -534.72 + +""" + fpth = os.path.join(cpth, 'mymnw2.mnw2') + f = open(fpth, 'w') + f.write(mnw2str) + f.close() + + disstr = """ 3 1 1 1 4 1 + 0 0 0 +constant 1 +constant 1 +constant 0 top of model +constant -1 bottom of layer 1 +constant -2 bottom of layer 2 +constant -3 bottom of layer 3 + 1. 1 1. Tr PERLEN NSTP TSMULT Ss/tr +""" + + fpth = os.path.join(cpth, 'mymnw2.dis') + f = open(fpth, 'w') + f.write(disstr) + f.close() + + namstr = """lst 101 mymnw2.lst +dis 102 mymnw2.dis +mnw2 103 mymnw2.mnw2""" + + fpth = os.path.join(cpth, 'mymnw2.nam') + f = open(fpth, 'w') + f.write(namstr) + f.close() + + m = flopy.modflow.Modflow.load('mymnw2.nam', model_ws=cpth, + verbose=True, check=False) + mnw2 = m.mnw2 + wellids = ['eb-33', 'eb-35', 'eb-36'] + rates = [np.float32(-11229.2), np.float32(-534.72), np.float32(-534.72)] + + emsg = 'incorrect keys returned from load mnw2' + assert list(mnw2.mnw.keys()) == wellids, emsg + + spd = mnw2.stress_period_data[0] + + wellids2 = list(spd['wellid']) + emsg = 'incorrect keys returned from load mnw2 stress period data' + assert wellids2 == wellids, emsg + + rates2 = list(spd['qdes']) + emsg = 'incorrect qdes rates returned from load mnw2 stress period data' + assert rates2 == rates, emsg + + return + + def test_checks(): """t027 test MNW2 Package checks in FloPy""" m = flopy.modflow.Modflow.load('MNW2-Fig28.nam', model_ws=mf2005pth, @@ -253,10 +335,13 @@ def test_checks(): chk.summary_array.desc) + + if __name__ == '__main__': #test_line_parse() #test_load() - #test_make_package() + test_blank_lines() + test_make_package() #test_export() #test_checks() test_mnw1_load_write() diff --git a/flopy/modflow/mfmnw2.py b/flopy/modflow/mfmnw2.py index c3b674b73c..af8dc01eb2 100644 --- a/flopy/modflow/mfmnw2.py +++ b/flopy/modflow/mfmnw2.py @@ -337,7 +337,7 @@ class Mnw(object): def __init__(self, wellid, nnodes=1, nper=1, - losstype="SKIN", pumploc=0, qlimit=0, ppflag=0, pumpcap=0, + losstype="skin", pumploc=0, qlimit=0, ppflag=0, pumpcap=0, rw=1, rskin=2, kskin=10, B=None, C=0, P=2., cwc=None, pp=1, k=0, i=0, j=0, ztop=0, zbotm=0, @@ -358,7 +358,7 @@ def __init__(self, wellid, self.wellid = wellid self.nnodes = nnodes # dataset 2b - self.losstype = losstype + self.losstype = losstype.lower() self.pumploc = pumploc self.qlimit = qlimit self.ppflag = ppflag @@ -416,6 +416,10 @@ def __init__(self, wellid, if node_data is not None: for n in node_data.dtype.names: self.node_data[n] = node_data[n] + # convert strings to lower case + if isinstance(n, str): + for idx, v in enumerate(self.node_data[n]): + self.node_data[n][idx] = self.node_data[n][idx] # build recarray of node data from MNW2 input file if node_data is None: @@ -527,7 +531,7 @@ def get_item2_names(mnw2obj=None, node_data=None): if node_data is not None: nnodes = Mnw.get_nnodes(node_data) - losstype = node_data.losstype[0] + losstype = node_data.losstype[0].lower() ppflag = node_data.ppflag[0] pumploc = node_data.pumploc[0] qlimit = node_data.qlimit[0] @@ -536,7 +540,7 @@ def get_item2_names(mnw2obj=None, node_data=None): # get names based on mnw2obj attribute values else: nnodes = mnw2obj.nnodes - losstype = mnw2obj.losstype + losstype = mnw2obj.losstype.lower() ppflag = mnw2obj.ppflag pumploc = mnw2obj.pumploc qlimit = mnw2obj.qlimit @@ -1699,11 +1703,11 @@ def _parse_2(f): # dataset 2a line = line_parse(get_next_line(f)) if len(line) > 2: - warnings.warn('MNW2: {}\n'.format(line) + \ - 'Extra items in Dataset 2a!' + \ - 'Check for WELLIDs with space ' + \ + warnings.warn('MNW2: {}\n'.format(line) + + 'Extra items in Dataset 2a!' + + 'Check for WELLIDs with space ' + 'but not enclosed in quotes.') - wellid = pop_item(line).upper() + wellid = pop_item(line).lower() nnodes = pop_item(line, int) # dataset 2b line = line_parse(get_next_line(f)) @@ -1879,7 +1883,7 @@ def _parse_4a(line, mnw, gwt=False): capmult = 0 cprime = 0 line = line_parse(line) - wellid = pop_item(line).upper() + wellid = pop_item(line).lower() pumpcap = mnw[wellid].pumpcap qdes = pop_item(line, float) if pumpcap > 0: From 415881f69e72000deedf075dc15351845cd8530b Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Fri, 22 Nov 2019 11:47:53 -0600 Subject: [PATCH 3/5] fix(mnw2): fix issues with files with empty lines Also contains fix for inconsistent wellid cases in dataset 2a and 4a --- .../flopy3_mnw2package_example.ipynb | 206 +++++++++--------- flopy/modflow/mfmnw2.py | 4 +- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/examples/Notebooks/flopy3_mnw2package_example.ipynb b/examples/Notebooks/flopy3_mnw2package_example.ipynb index 5ef1e24081..915eeb1d7d 100644 --- a/examples/Notebooks/flopy3_mnw2package_example.ipynb +++ b/examples/Notebooks/flopy3_mnw2package_example.ipynb @@ -23,7 +23,7 @@ "[Clang 4.0.1 (tags/RELEASE_401/final)]\n", "numpy version: 1.17.3\n", "pandas version: 0.25.2\n", - "flopy version: 3.2.13\n" + "flopy version: 3.3.0\n" ] } ], @@ -793,8 +793,8 @@ { "data": { "text/plain": [ - "{'well1': ,\n", - " 'well2': }" + "{'well1': ,\n", + " 'well2': }" ] }, "execution_count": 14, @@ -943,13 +943,13 @@ " gwt = False ('bool)\n", " ipakcb = 0 ('int)\n", " itmp (list, items = 3)\n", - " mnw = {'well1': , 'well2': } ('dict)\n", + " mnw = {'well1': , 'well2': } ('dict)\n", " mnwmax = 2 ('int)\n", " mnwprnt = 0 ('int)\n", " node_data (array, shape = 3,)\n", " nodtot = 3 ('int)\n", " nper = 3 ('int)\n", - " stress_period_data = ('flopy.utils.util_list.MfList)\n", + " stress_period_data = ('flopy.utils.util_list.MfList)\n", " structured = True ('bool)\n", " unit_number = 34, 'aux': [], 'wellid': 'well1', 'nnodes': -2, 'losstype': 'skin', 'pumploc': -1, 'qlimit': 0, 'ppflag': 0, 'pumpcap': 0, 'rw': [1.0,\n", " 0.5], 'rskin': [2.0, 2.0], 'kskin': [5.0,\n", @@ -1764,8 +1764,8 @@ " 40\n", " -5.0\n", " -65.0\n", - " Well-A\n", - " SKIN\n", + " well-a\n", + " skin\n", " 0\n", " 1\n", " 0\n", @@ -1788,7 +1788,7 @@ ], "text/plain": [ " k i j ztop zbotm wellid losstype pumploc qlimit ppflag ... \\\n", - "0 0 29 40 -5.0 -65.0 Well-A SKIN 0 1 0 ... \n", + "0 0 29 40 -5.0 -65.0 well-a skin 0 1 0 ... \n", "\n", " hlim qcut qfrcmn qfrcmx hlift liftq0 liftqmax hwtol liftn qn \n", "0 -7.5 -1 0.1 0.15 0.0 0.0 0.0 0.0 0.0 0.0 \n", @@ -1850,7 +1850,7 @@ " 0\n", " 29\n", " 40\n", - " Well-A\n", + " well-a\n", " 0.0\n", " 0\n", " 0.0\n", @@ -1865,7 +1865,7 @@ ], "text/plain": [ " k i j wellid qdes capmult cprime hlim qcut qfrcmn qfrcmx\n", - "0 0 29 40 Well-A 0.0 0 0.0 0.0 0 0.0 0.0" + "0 0 29 40 well-a 0.0 0 0.0 0.0 0 0.0 0.0" ] }, "execution_count": 29, @@ -1885,7 +1885,7 @@ { "data": { "text/plain": [ - "{'Well-A': }" + "{'well-a': }" ] }, "execution_count": 30, @@ -1996,7 +1996,7 @@ } ], "source": [ - "pd.DataFrame(mnw2.mnw['Well-A'].stress_period_data)" + "pd.DataFrame(mnw2.mnw['well-a'].stress_period_data)" ] }, { @@ -2057,8 +2057,8 @@ " 503\n", " 181.630005\n", " 161.630005\n", - " BR_Birch1\n", - " SKIN\n", + " br_birch1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2071,8 +2071,8 @@ " 503\n", " 179.119995\n", " 159.119995\n", - " BR_Birch2\n", - " SKIN\n", + " br_birch2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2081,31 +2081,31 @@ " \n", " \n", " 2\n", - " 174\n", + " 175\n", " 342\n", - " 399.119995\n", - " 312.119995\n", - " BR_DIaperville2\n", - " SKIN\n", + " 400.220001\n", + " 312.220001\n", + " br_diaperville1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", " 10.0\n", - " 313.119995\n", + " 313.220001\n", " \n", " \n", " 3\n", - " 175\n", + " 174\n", " 342\n", - " 400.220001\n", - " 312.220001\n", - " BR_Diaperville1\n", - " SKIN\n", + " 399.119995\n", + " 312.119995\n", + " br_diaperville2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", " 10.0\n", - " 313.220001\n", + " 313.119995\n", " \n", " \n", " 4\n", @@ -2113,8 +2113,8 @@ " 454\n", " 565.200012\n", " 555.200012\n", - " BR_Franks1\n", - " SKIN\n", + " br_franks1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2127,8 +2127,8 @@ " 453\n", " 564.419983\n", " 554.419983\n", - " BR_Franks2\n", - " SKIN\n", + " br_franks2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2141,8 +2141,8 @@ " 396\n", " 453.959991\n", " 447.959991\n", - " BR_Odanah1\n", - " SKIN\n", + " br_odanah1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2155,8 +2155,8 @@ " 395\n", " 450.559998\n", " 444.559998\n", - " BR_Odanah2\n", - " SKIN\n", + " br_odanah2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2169,8 +2169,8 @@ " 395\n", " 380.489990\n", " 371.489990\n", - " BR_Odanah3\n", - " SKIN\n", + " br_odanah3\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2183,8 +2183,8 @@ " 396\n", " 450.739990\n", " 444.739990\n", - " BR_Odanah4\n", - " SKIN\n", + " br_odanah4\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2197,8 +2197,8 @@ " 350\n", " 475.410004\n", " 472.410004\n", - " BR_OldSchool\n", - " SKIN\n", + " br_oldschool\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2211,8 +2211,8 @@ " 312\n", " 377.410004\n", " 348.410004\n", - " BR_recycle\n", - " SKIN\n", + " br_recycle\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2225,8 +2225,8 @@ " 412\n", " 562.200012\n", " 542.200012\n", - " BR_unspec\n", - " SKIN\n", + " br_unspec\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2239,8 +2239,8 @@ " 424\n", " 1079.910034\n", " 1072.910034\n", - " CFSP_ncp1\n", - " SKIN\n", + " cfsp_ncp1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2253,8 +2253,8 @@ " 424\n", " 1077.900024\n", " 1074.900024\n", - " CFSP_ncp2\n", - " SKIN\n", + " cfsp_ncp2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2267,8 +2267,8 @@ " 415\n", " 1093.010010\n", " 1003.010010\n", - " CFSP_of\n", - " SKIN\n", + " cfsp_of\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2281,8 +2281,8 @@ " 2\n", " 706.330017\n", " 699.330017\n", - " Hayward_bait_N\n", - " SKIN\n", + " hayward_bait_n\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2295,8 +2295,8 @@ " 6\n", " 705.289978\n", " 698.289978\n", - " Hayward_bait_NE\n", - " SKIN\n", + " hayward_bait_ne\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2309,8 +2309,8 @@ " 4\n", " 696.979980\n", " 689.979980\n", - " Hayward_bait_of\n", - " SKIN\n", + " hayward_bait_of\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2323,8 +2323,8 @@ " 699\n", " 1352.050049\n", " 1342.050049\n", - " IronBelt2\n", - " SKIN\n", + " ironbelt2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2337,8 +2337,8 @@ " 699\n", " 1350.439941\n", " 1343.439941\n", - " IronBelt3\n", - " SKIN\n", + " ironbelt3\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2351,8 +2351,8 @@ " 414\n", " 1198.839966\n", " 1188.839966\n", - " Mellen2\n", - " SKIN\n", + " mellen2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2365,8 +2365,8 @@ " 408\n", " 1151.599976\n", " 1131.599976\n", - " Mellen3\n", - " SKIN\n", + " mellen3\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2379,8 +2379,8 @@ " 149\n", " 622.179993\n", " 602.179993\n", - " Milestone\n", - " SKIN\n", + " milestone\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2393,8 +2393,8 @@ " 148\n", " 520.119995\n", " 500.119995\n", - " NSP\n", - " SKIN\n", + " nsp\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2407,8 +2407,8 @@ " 162\n", " 535.299988\n", " 30.299999\n", - " Washburn1\n", - " SKIN\n", + " washburn1\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2421,8 +2421,8 @@ " 143\n", " 541.280029\n", " -67.720001\n", - " Washburn2\n", - " SKIN\n", + " washburn2\n", + " skin\n", " -1\n", " 1.0\n", " 2.0\n", @@ -2435,39 +2435,39 @@ ], "text/plain": [ " i j ztop zbotm wellid losstype pumploc \\\n", - "0 294 503 181.630005 161.630005 BR_Birch1 SKIN -1 \n", - "1 295 503 179.119995 159.119995 BR_Birch2 SKIN -1 \n", - "2 174 342 399.119995 312.119995 BR_DIaperville2 SKIN -1 \n", - "3 175 342 400.220001 312.220001 BR_Diaperville1 SKIN -1 \n", - "4 248 454 565.200012 555.200012 BR_Franks1 SKIN -1 \n", - "5 249 453 564.419983 554.419983 BR_Franks2 SKIN -1 \n", - "6 180 396 453.959991 447.959991 BR_Odanah1 SKIN -1 \n", - "7 181 395 450.559998 444.559998 BR_Odanah2 SKIN -1 \n", - "8 181 395 380.489990 371.489990 BR_Odanah3 SKIN -1 \n", - "9 180 396 450.739990 444.739990 BR_Odanah4 SKIN -1 \n", - "10 170 350 475.410004 472.410004 BR_OldSchool SKIN -1 \n", - "11 172 312 377.410004 348.410004 BR_recycle SKIN -1 \n", - "12 216 412 562.200012 542.200012 BR_unspec SKIN -1 \n", - "13 516 424 1079.910034 1072.910034 CFSP_ncp1 SKIN -1 \n", - "14 515 424 1077.900024 1074.900024 CFSP_ncp2 SKIN -1 \n", - "15 539 415 1093.010010 1003.010010 CFSP_of SKIN -1 \n", - "16 360 2 706.330017 699.330017 Hayward_bait_N SKIN -1 \n", - "17 360 6 705.289978 698.289978 Hayward_bait_NE SKIN -1 \n", - "18 362 4 696.979980 689.979980 Hayward_bait_of SKIN -1 \n", - "19 456 699 1352.050049 1342.050049 IronBelt2 SKIN -1 \n", - "20 456 699 1350.439941 1343.439941 IronBelt3 SKIN -1 \n", - "21 599 414 1198.839966 1188.839966 Mellen2 SKIN -1 \n", - "22 576 408 1151.599976 1131.599976 Mellen3 SKIN -1 \n", - "23 253 149 622.179993 602.179993 Milestone SKIN -1 \n", - "24 208 148 520.119995 500.119995 NSP SKIN -1 \n", - "25 80 162 535.299988 30.299999 Washburn1 SKIN -1 \n", - "26 91 143 541.280029 -67.720001 Washburn2 SKIN -1 \n", + "0 294 503 181.630005 161.630005 br_birch1 skin -1 \n", + "1 295 503 179.119995 159.119995 br_birch2 skin -1 \n", + "2 175 342 400.220001 312.220001 br_diaperville1 skin -1 \n", + "3 174 342 399.119995 312.119995 br_diaperville2 skin -1 \n", + "4 248 454 565.200012 555.200012 br_franks1 skin -1 \n", + "5 249 453 564.419983 554.419983 br_franks2 skin -1 \n", + "6 180 396 453.959991 447.959991 br_odanah1 skin -1 \n", + "7 181 395 450.559998 444.559998 br_odanah2 skin -1 \n", + "8 181 395 380.489990 371.489990 br_odanah3 skin -1 \n", + "9 180 396 450.739990 444.739990 br_odanah4 skin -1 \n", + "10 170 350 475.410004 472.410004 br_oldschool skin -1 \n", + "11 172 312 377.410004 348.410004 br_recycle skin -1 \n", + "12 216 412 562.200012 542.200012 br_unspec skin -1 \n", + "13 516 424 1079.910034 1072.910034 cfsp_ncp1 skin -1 \n", + "14 515 424 1077.900024 1074.900024 cfsp_ncp2 skin -1 \n", + "15 539 415 1093.010010 1003.010010 cfsp_of skin -1 \n", + "16 360 2 706.330017 699.330017 hayward_bait_n skin -1 \n", + "17 360 6 705.289978 698.289978 hayward_bait_ne skin -1 \n", + "18 362 4 696.979980 689.979980 hayward_bait_of skin -1 \n", + "19 456 699 1352.050049 1342.050049 ironbelt2 skin -1 \n", + "20 456 699 1350.439941 1343.439941 ironbelt3 skin -1 \n", + "21 599 414 1198.839966 1188.839966 mellen2 skin -1 \n", + "22 576 408 1151.599976 1131.599976 mellen3 skin -1 \n", + "23 253 149 622.179993 602.179993 milestone skin -1 \n", + "24 208 148 520.119995 500.119995 nsp skin -1 \n", + "25 80 162 535.299988 30.299999 washburn1 skin -1 \n", + "26 91 143 541.280029 -67.720001 washburn2 skin -1 \n", "\n", " rw rskin kskin zpump \n", "0 1.0 2.0 10.0 162.630005 \n", "1 1.0 2.0 10.0 160.119995 \n", - "2 1.0 2.0 10.0 313.119995 \n", - "3 1.0 2.0 10.0 313.220001 \n", + "2 1.0 2.0 10.0 313.220001 \n", + "3 1.0 2.0 10.0 313.119995 \n", "4 1.0 2.0 10.0 556.200012 \n", "5 1.0 2.0 10.0 555.419983 \n", "6 1.0 2.0 10.0 448.959991 \n", diff --git a/flopy/modflow/mfmnw2.py b/flopy/modflow/mfmnw2.py index af8dc01eb2..56e1408a75 100644 --- a/flopy/modflow/mfmnw2.py +++ b/flopy/modflow/mfmnw2.py @@ -945,8 +945,8 @@ def __init__(self, model, mnwmax=0, nodtot=None, ipakcb=0, mnwprnt=0, ' {}, '.format(model.version_types[model.version]) + \ 'generated by Flopy.' # Dataset 1 - self.mnwmax = int( - mnwmax) # -maximum number of multi-node wells to be simulated + # maximum number of multi-node wells to be simulated + self.mnwmax = int(mnwmax) self.nodtot = nodtot # user-specified maximum number of nodes self.ipakcb = ipakcb self.mnwprnt = int(mnwprnt) # -verbosity flag From ecbdbd9232706a4d68ebf731b83da02760e9bb54 Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Fri, 22 Nov 2019 12:21:43 -0600 Subject: [PATCH 4/5] fix(mnw2): fix issues with files with empty lines Also contains fix for inconsistent wellid cases in dataset 2a and 4a --- autotest/t027_test.py | 69 ++++++++++++------- .../flopy3_mnw2package_example.ipynb | 10 +-- flopy/modflow/mfmnw2.py | 6 +- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/autotest/t027_test.py b/autotest/t027_test.py index 7f9f23d90b..9164fbf092 100644 --- a/autotest/t027_test.py +++ b/autotest/t027_test.py @@ -2,6 +2,7 @@ test MNW1 and MNW2 packages """ import sys + sys.path.insert(0, '..') import shutil import os @@ -16,6 +17,7 @@ mf2005pth = os.path.join('..', 'examples', 'data', 'mnw2_examples') mnw1_path = os.path.join('..', 'examples', 'data', 'mf2005_test') + def test_line_parse(): """t027 test line_parse method in MNW2 Package class""" # ensure that line_parse is working correctly @@ -50,6 +52,7 @@ def test_load(): mnw2_2.stress_period_data[0].qdes - mnw2_3.stress_period_data[ 0].qdes).min() < 0.01 + def test_mnw1_load_write(): m = flopy.modflow.Modflow.load('mnw1.nam', model_ws=mnw1_path, load_only=['mnw1'], @@ -66,11 +69,12 @@ def test_mnw1_load_write(): m.mnw1.fn_path = cpth + '/mnw1.mnw' m.mnw1.write_file() m2 = flopy.modflow.Modflow.load('mnw1.nam', model_ws=cpth, - load_only=['mnw1'], - verbose=True, forgive=False) + load_only=['mnw1'], + verbose=True, forgive=False) for k, v in m.mnw1.stress_period_data.data.items(): assert np.array_equal(v, m2.mnw1.stress_period_data[k]) + def test_make_package(): """t027 test make MNW2 Package""" m4 = flopy.modflow.Modflow('mnw2example', model_ws=cpth) @@ -82,7 +86,8 @@ def test_make_package(): [(0, 1, 1, 9.5, 7.1, 'well1', 'skin', -1, 0, 0, 0, 1.0, 2.0, 5.0, 6.2), (1, 1, 1, 7.1, 5.1, 'well1', 'skin', -1, 0, 0, 0, 0.5, 2.0, 5.0, 6.2), ( - 2, 3, 3, 9.1, 3.7, 'well2', 'skin', -1, 0, 0, 0, 1.0, 2.0, 5.0, 4.1)], + 2, 3, 3, 9.1, 3.7, 'well2', 'skin', -1, 0, 0, 0, 1.0, 2.0, 5.0, + 4.1)], dtype=[('index', ',\n", - " 'well2': }" + "{'well1': ,\n", + " 'well2': }" ] }, "execution_count": 14, @@ -943,13 +943,13 @@ " gwt = False ('bool)\n", " ipakcb = 0 ('int)\n", " itmp (list, items = 3)\n", - " mnw = {'well1': , 'well2': } ('dict)\n", + " mnw = {'well1': , 'well2': } ('dict)\n", " mnwmax = 2 ('int)\n", " mnwprnt = 0 ('int)\n", " node_data (array, shape = 3,)\n", " nodtot = 3 ('int)\n", " nper = 3 ('int)\n", - " stress_period_data = ('flopy.utils.util_list.MfList)\n", + " stress_period_data = ('flopy.utils.util_list.MfList)\n", " structured = True ('bool)\n", " unit_number = 34, 'aux': [], 'wellid': 'well1', 'nnodes': -2, 'losstype': 'skin', 'pumploc': -1, 'qlimit': 0, 'ppflag': 0, 'pumpcap': 0, 'rw': [1.0,\n", " 0.5], 'rskin': [2.0, 2.0], 'kskin': [5.0,\n", @@ -1885,7 +1885,7 @@ { "data": { "text/plain": [ - "{'well-a': }" + "{'well-a': }" ] }, "execution_count": 30, diff --git a/flopy/modflow/mfmnw2.py b/flopy/modflow/mfmnw2.py index 56e1408a75..21a33d9753 100644 --- a/flopy/modflow/mfmnw2.py +++ b/flopy/modflow/mfmnw2.py @@ -18,11 +18,11 @@ class Mnw(object): Parameters ---------- - wellid : int + wellid : str or int is the name of the well. This is a unique alphanumeric identification label for each well. The text string is limited to 20 alphanumeric characters. If the name of the well includes spaces, then enclose the - name in quotes. + name in quotes. Flopy converts wellid string to lower case. nnodes : int is the number of cells (nodes) associated with this well. NNODES normally is > 0, but for the case of a vertical borehole, @@ -355,6 +355,8 @@ def __init__(self, wellid, self.aux = None if mnwpackage is None else mnwpackage.aux # dataset 2a + if isinstance(wellid, str): + wellid = wellid.lower() self.wellid = wellid self.nnodes = nnodes # dataset 2b From 6791735877cdaf0d7dc017d4669a9126300003e8 Mon Sep 17 00:00:00 2001 From: jdhughes-usgs Date: Fri, 22 Nov 2019 13:08:54 -0600 Subject: [PATCH 5/5] fix(mnw2): fix issues with files with empty lines --- autotest/t027_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/autotest/t027_test.py b/autotest/t027_test.py index 9164fbf092..7af3d8ac69 100644 --- a/autotest/t027_test.py +++ b/autotest/t027_test.py @@ -325,10 +325,14 @@ def test_blank_lines(): wellids2 = list(spd['wellid']) emsg = 'incorrect keys returned from load mnw2 stress period data' + for wellid, wellid2 in zip(wellids, wellids2): + emsg += '\n {} -- {}'.format(wellid, wellid2) assert wellids2 == wellids, emsg rates2 = list(spd['qdes']) emsg = 'incorrect qdes rates returned from load mnw2 stress period data' + for rate, rate2 in zip(rates, rates2): + emsg += '\n {} -- {}'.format(rate, rate2) assert rates2 == rates, emsg return