我有一个名为plate2.odb的.odb文件,我想从中提取应变数据。为此,我构建了下面的简单代码,循环遍历每个元素的字段输出E(应变)并将其保存到列表中。
from odbAccess import openOdb
import pickle as pickle
# import database
odbname = 'plate2'
path = './'
myodbpath = path + odbname + '.odb'
odb = openOdb(myodbpath)
# load the strain values into a list
E = []
for i in range(1000):
E.append(odb.steps['Step-1'].frames[0].fieldOutputs['E'].values[i].data)
# save the data
with open("mises.pickle", "wb") as input_file:
pickle.dump(E, input_file)
odb.close()
问题是将应变值加载到列表中的for循环需要很长时间(1000个元素需要35秒)。按此速率(0.035查询/秒),我需要2个小时才能为我的模型提取200,000个元素的数据。这为什么需要这么长时间?我怎样才能加速这个?
如果我在任何Python lool之外执行单个应变查询需要0.04秒,所以我知道这不是Python循环的问题。
答案 0 :(得分:2)
我发现每次我想要一个应变时,我不得不重新打开odb字典中的子目录。因此,为了解决这个问题,我将odb对象保存为一个较小的对象。我需要一小段时间才能解决的更新代码如下。
from odbAccess import openOdb
import pickle as pickle
# import database
odbname = 'plate2'
path = './'
myodbpath = path + odbname + '.odb'
odb = openOdb(myodbpath)
# load the strain values into a list
E = []
EE = odb.steps['Step-1'].frames[0].fieldOutputs['E']
for i in range(1000):
E.append(EE.values[i].data)
# save the data
with open("mises.pickle", "wb") as input_file:
pickle.dump(E, input_file)
odb.close()
答案 1 :(得分:2)
我会在这里使用bulkDataBlocks。这比使用value方法快得多。使用泡菜通常也很慢,没有必要。请查看FieldBulkData对象的C ++手册http://abaqus.software.polimi.it/v6.14/books/ker/default.htm。 Python方法是相同的,但至少在Abaqus 6.14中没有记录在Python-Scripting-Reference中(从6.13开始提供)。
例如:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
请注意,如果您有多个元素类型,则可能有多个bulkDataBlock。
答案 2 :(得分:1)
派对迟到了,但我觉得在这种情况下使用operator.attrgetter
比for
循环或列表理解要快得多
而不是@AustinDowney
E = []
EE = odb.steps['Step-1'].frames[0].fieldOutputs['E']
for i in range(1000):
E.append(EE.values[i].data)
这样做:
from operator import attrgetter
EE = odb.steps['Step-1'].frames[0].fieldOutputs['E']
E = map(attrgetter('data'), EE.values)
这与列表理解大致相同,但如果您想要一次提取多个属性(例如coordinates
或elementId
)