Sonlu elemanlar kütüphanesi tasarlama aşamasındayım. Belirli bir problem için, kullanılan sonlu eleman örgüsü farklı boyutlarda elemanlara sahip olabilir (örneğin tetrahedra ve üçgenler) ve aynı boyuttaki farklı unsurları birleştirmek de mümkündür (örneğin tetrahedra ve hexahedra). Bu nedenle, sonlu elemanların bilgilerini saklayan bir veri yapısına ihtiyacım var. En temel bilgi, elemanların bağlantısıdır (elemanı tanımlayan düğüm kimlikleri). Örneğin, üçgen elemanın (4) düğümlerin 5, 6 ve 10'a bağlı olduğunu bir şekilde kaydetmem gerekiyor.Karmaşık veri yapısının bağımlılıklarını tasarlama
İlk denemem indeksi boyutu (0,1,2 veya 3) olan bir liste oluşturmaktı. sözlükleri depolar. Bu sözlüklerin dize anahtarları (tanımlayıcıları) vardır ve değerler, saydam dizilerdir (her satır bir eleman bağlantısını temsil eder). Bunu yapmak zorundayım çünkü belirli bir boyut için numol dizileri dize tanımlayıcılarına bağlı olarak farklı şekillere sahiptir.
Bu
sınıftır: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)
sınıf güzel çalışıyor ve sorunsuz belirli boyutun tüm öğeleri döngü beni tanır. Bununla birlikte, ayrı olarak depolanan her öğe ile ilişkili başka veriler de vardır, örneğin onun malzemesi. Bu nedenle, diğer veriye başvurmak için aynı veri yapısını kullanmaya karar verdim. Bu amaçla, tüm yapıyı numpy dizileri olmadan geri döndürmek için sınıfın strip
işlevini kullanıyorum.
Asıl veri yapısının dinamik olduğu ve değiştirdiğimde sorun, ona bağlı olan diğer tüm yapıları değiştirmem gerekiyor. Gerçekten bu sınıfı tasarlarken yanlış yöne gittiğimi düşünüyorum. Belki de bu probleme yaklaşmanın daha basit bir yolu var mı? Numune dizilerinin yanında ek bilgi saklamayı düşündüm (örnek olarak), ama bunun iyi olup olmadığını bilmiyorum. Yazılım tasarlarken yapılan seçimler hayatımızı daha sonra sefil hale getirebilir ve şimdi bunu anlamaya başlıyorum. Yukarıdaki sınıfını kullanma
UPDATE
, bir örnek aşağıdaki gibi olabilir: veri yapısı 0 (düğüm) elemanlarını, 1 (hat) depolamak için kullanılmaktadırElement 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]]))])]
ve 2 (dörtgen) boyutlar.
Bu veri yapısını neden ilk başta böyle tasarladığınızı anlamanıza yardımcı olabilir. Hangi problemi çözüyorsun? – plalx
Sonlu eleman kitaplığı oluşturuyorum. Bu numol dizilerindeki her satır, bir eleman bağlantısıdır (öğeyi tanımlayan düğüm kimlikleri). Belirli bir problem için, kullanılan sonlu eleman örgüsü farklı boyutlarda elemanlara sahip olabilir (örneğin, tetrahedra ve üçgenler) ve aynı boyuttaki farklı unsurları birleştirmek de mümkündür (örnek olarak tetrahedra ve hexahedra'ya uyar. Fakat bu ilk veri yapısı sadece elementlerin bağlanabilirlikleri: Her elemanın aynı zamanda bir malzeme özelliği (malzemelerin depolanması için başka bir veri yapısına ihtiyacım var) ve diğer veriler için de aynı şekilde atanır. – aaragon
Lütfen sorunuza ** değişimini gösteren bir miktar veri verin **, bir Bu verilen "class" ile çalışır ve biri uymayan değişti. İlk denemem başarısız oldu ma.MaskedArray', nerede geldi? – stovfl