Issue with writing SSM file #2071
-
Hi all. I'm having a problem with editing the first entry in the stress_period_data dictionary used to generate the SSM file for MT3D-USGS. For some reason it does not seem to behave like a normal Python dictionary. After I set up the dictionary using the time period (in years) as a key, if I want to edit a single array at a particular year, it changes the value of that array for every year. I cannot reproduce this problem with an arbitrary dictionary. This isn't a huge issue, but I would like to know what I am doing wrong, as this would be faster than manually editing the SSM file for certain years. Here is the code: nper=80
nrow=64
ncol=203
nlay=38
ssm_data = [[1, 33, 179, 1344, 15, 1344, 0, 0]] # plume source
for k in range(nlay):
for i in range(nrow):
ssm_data.append((k, i, ncol, -1, itype['CHD'], -1, 9.28, 105))
ssm_data = {time: ssm_data for time in range(nper)}
# I want to change the source concentration at year 70, but it does it for every single year!
ssm_data[70][0] = [1, 33, 179, 0, 15, 0, 0, 0]
ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=ssm_data, mxss=100000, crch=crch, crch2=crch2, crch3=crch3) Any help would be greatly appreciated. Edit: I can do this in the WEL package and there is no problem. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
The dict comprehension line with Here is what type(ssm_data) # dict
len(ssm_data) # 80
len(ssm_data[0]) # 2433 == nlay * nrow
ssm_data[0] is ssm_data[1] # True; first and second are the same
all(ssm_data[0] is ssm_data[key] for key in ssm_data.keys()) # True; all items are the same and since they are all the same, then modifying one will modify them all. This is a common Python "gotcha" that most users run into from time-to-time. To avoid creating multiple references, make "deep copies" instead. Also, it is a really good idea to give the different object a different name: import copy
# After creating the original ssm_data object
spd = {sp: copy.deepcopy(ssm_data) for sp in range(nper)}
spd[0] is spd[70] # False
spd[0][0] is spd[70][0] # False
# modify spd[70][0]
ssm = flopy.mt3d.Mt3dSsm(mt, stress_period_data=spd, ...) Using the |
Beta Was this translation helpful? Give feedback.
-
Thanks a lot! Very well explained and helplful. |
Beta Was this translation helpful? Give feedback.
The dict comprehension line with
{time: ssm_data for time in range(nper)}
is suspect, because it references the same object 80 times without a copy. Also, depending on where you read the code,ssm_data
is either a list with 2433 items, or it is a dict with 80 items.Here is what
ssm_data
looks like after the dict comprehension line, which shows that all the items in the dict are the same object:and since they are all the same, then modifying one will…