我正在設計一個有限元庫的過程。對於給定的問題,所使用的有限元網格可以具有不同尺寸的元素(例如四面體和三角形),並且可以組合相同尺寸的不同元素(例如四面體和六面體)。因此,我需要一個存儲有限元素信息的數據結構。最基本的信息是元素的連通性(定義元素的節點ID)。例如,我需要以某種方式存儲該三角形元素4連接到節點5,6和10.設計複雜的數據結構的依賴關係
我的第一個嘗試是創建一個索引是維度(0,1,2或3)的列表和即存儲字典。這些字典有字符串鍵(標識符),值是numpy數組(每行代表一個元素的連通性)。我需要這樣做,因爲根據字符串標識符,給定尺寸的numpy數組具有不同的形狀。
這是類:
import os
from collections import OrderedDict
import numpy.ma as ma
flatten = lambda l: [item for sublist in l for item in sublist]
class ElementData(list):
def __init__(self, *args, **kwargs):
self.reset()
super(ElementData, self).__init__(*args, **kwargs)
def __iter__(self):
for k, v in self[self.idx].items():
for i, e in enumerate(v):
yield (k,i,e) if not ma.is_masked(e) else (k,i, None)
self.reset()
def __call__(self, idx):
self.idx = idx-1
return self
def __getitem__(self, index):
if index >= len(self):
self.expand(index)
return super(ElementData, self).__getitem__(index)
def __setitem__(self, index, value):
if index >= len(self):
self.expand(index)
list.__setitem__(self, index, value)
def __str__(self):
return "Element dimensions present: {}\n".format([i for i in range(len(self)) if self[i]]) + super(ElementData, self).__str__()
def keys(self):
return flatten([list(self[i].keys()) for i in range(len(self))])
def reset(self):
self.idx = -1
self.d = -1
def expand(self, index):
self.d = max(index, self.d)
for i in range(index + 1 - len(self)):
self.append(OrderedDict())
def strip(self, value=None):
if not callable(value):
saved_value, value = value, lambda k,v: saved_value
return ElementData([OrderedDict({k:value(k, v) for k,v in i.items()}) for i in super(ElementData, self).__iter__()])
def numElements(self, d):
def elementsOfDimension(d):
# loop over etypes
nelems = 0
for v in self[d].values():
nelems += v.shape[0] if not isinstance(v, ma.MaskedArray) else v.shape[0] - v.mask.any(axis=1).sum()
return nelems
# compute the number of all elements
if d == -1:
nelems = 0
for i in range(self.d+1):
nelems += elementsOfDimension(i)
return nelems
else: # of specific dimension only
return elementsOfDimension(d)
類工作得很好,它讓我無縫循環通過特定維度的所有項目。但是,還有其他數據與單獨存儲的每個元素相關聯,例如其材料。因此,我決定使用相同的數據結構來引用其他屬性。爲此,我使用該類的strip
函數,將整個結構返回給我,而不使用numpy數組。
問題是我原來的數據結構是動態的,如果我改變它,我不得不修改所有依賴它的其他結構。我真的認爲我在設計這門課的時候走錯了方向。也許有更簡單的方法來解決這個問題?我想在numpy數組旁邊存儲額外的信息(例如元組),但我不知道這是否好。設計軟件時所做的選擇可能會讓我們的生活過得更悲慘,現在我開始意識到這一點。
UPDATE
使用上述類,一個示例可以是如下:其中,所述數據結構已經被用來存儲0(節點)的元素,1(行)
Element dimensions present: [0, 1, 2]
[OrderedDict([('n1', array([[0],
[1],
[3]]))]), OrderedDict([('l2', array([[1, 2]]))]), OrderedDict([('q4', array([[0, 1, 5, 4],
[5, 1, 2, 6],
[6, 2, 3, 7],
[7, 3, 0, 4],
[4, 5, 6, 7]]))])]
和2(四邊形)尺寸。
可能有助於理解你爲什麼最初設計了這樣的數據結構。你解決什麼問題? – plalx
我正在創建一個有限元素庫。這些numpy數組中的每一行都是元素連接(定義元素的節點ID)。對於一個給定的問題,所使用的有限元網格可以具有不同尺寸的元素(例如四面體和三角形),並且可以組合相同維度的不同元素(適用於例如四面體和六面體)。但是,該第一數據結構僅處理元素的連接性,每個元素也被分配一個材料屬性(爲此我需要另一個數據結構來存儲材料),其他數據也是一樣的 – aaragon
請提供一些數據給你的問題,顯示**變化**,一個它與給定的'class'一起工作,其中一個不適合我的第一次嘗試失敗,因爲缺少'ma.MaskedArray',它出現在哪裏。 – stovfl