2017-10-04 25 views
1

我有一个.odb文件,名为plate2.odb,我想从中提取应变数据。为此,我构建了下面的简单代码,通过每个元素的字段输出E(应变)循环并将其保存到列表中。加速Abaqus-python代码中的缓慢循环以从.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 = [] 
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个小时才能提取20万个元素的模型数据。为什么这需要这么长时间?我怎样才能加速这个?

如果我在任何Python lool之外进行单个应变查询,它需要0.04秒,所以我知道这不是Python循环的问题。

回答

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() 
+2

请注意,您可以使用列表理解'E = [v.v.data for v in EE.values]'(也许性能也有所提高) – agentp

+1

不错。顺便说一句,这种技术(在Abaqus脚本用户手册的“创建保存临时变量的对象”一节中也提到过)可用于任何Python脚本中,您希望避免重复重建一系列对象。 –

2

我会在这里使用bulkDataBlocks。这比使用值方法快得多。也使用酸菜通常是缓慢的,没有必要。查看FieldBulkData对象的C++手册http://abaqus.software.polimi.it/v6.14/books/ker/default.htm。 Python方法是相同的,但至少在Abaqus 6.14中,它没有在Python-Scripting-Reference(它自6.13开始可用)中记录。

例如:

from odbAccess import openOdb 
import numpy as np 

# import database 
odbname = 'plate2' 
path = './' 
myodbpath = path + odbname + '.odb' 
odb = openOdb(myodbpath) 

# load the strain values into a numpy array 
EE = odb.steps['Step-1'].frames[0].fieldOutputs['E'] 

# get a numpy array with your data 
# Not using np.copy here may work also, but sometimes I encountered some weird bugs 
Strains=np.copy(EE.bulkDataBlocks[0].data) 

# save the data 
np.save('OutputPath',Strains) 

odb.close() 

请记住,如果你有多个单元类型可能有不止一个bulkDataBlock。

+0

我也遇到过'bulkDataBlacks'的奇怪表现,我会看看'np.copy'是否改善了一些事情。 –

+0

使用bulkDataBlocks方法时,我遇到没有性能问题。它应该比价值法快得多。当我重塑或切片bulkDataBlocks方法返回的numpy数组时,我遇到了问题。但与copiing阵列一切都应该没问题。 – max9111

+0

我的意思是操纵'bulkDataBlocks'的随机结果。我没有想过只是在内存中的其他地方复制块。 –

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) 

这与列表理解的速度大致相同,但如果您有多个属性需要extrac (例如coordinateselementId