Sonlu hacim kodu için veri yapıları: Diziler ve Sınıflar


11

Manyetohidrodinamik (MHD) için sonlu bir hacim kodu yazmam gerekiyor. Daha önce sayısal kod yazmıştım ama bu ölçekte değil. Ben sadece hangi iyi bir seçim olacağını sormak istedim, sınıfları ile bir veri yapısı (nesne yönelimli yaklaşım) kullanarak veya sadece hız, ölçeklenebilirlik vb açısından farklı özellikler için birden çok dizi kullanarak. Python kod yazmayı planlıyorum ve sayısal olarak yoğun kısım için fortran kullanın.

Python'daki sınıf için bir örnek

class Cell:
   def __init__(self, x, y, z, U):

Diziler basitçe şu şekilde tanımlanabilir:

x[nx][ny][nz]
y[nx][ny][nz]
z[nx][ny][nz]
U[nx][ny][nz]

vb.

Yanıtlar:


9

Basit cevap: Modern python'da her veri türü bir sınıftır, bu nedenle resmi olarak önerdiğiniz iki çözüm arasında bir fark yoktur. (Lütfen yeni stil sınıfları kullanmayı unutmayın: klasik sınıflar kullanılmıyor! Bkz. Http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes )

Şimdi soru şu olmalıdır: Python'da verimli bir veri yapısını nasıl düzenleyebilirim? Kuşkusuz, hücreleri bir dizi class Cellörnek olarak organize etme fikri çok verimsizdir. Karmaşık bir bağlantılı liste gibi düzenlenmiş işaretçiler ve bitişik olmayan verilerle sonuçlanacaksınız. Elbette listenize kolayca yeni hücreler ekleme olanağınız var: ama bu özelliğe ihtiyacınız var mı? Aksine bitişik olmayan veri depolamanız olacaktır ve her hücreye farklı dolaylı düzeylerde erişmeniz gerekir.

Verilerinizi bu şekilde düzenlerseniz, veriler numpy.ndarraybellek bitişiktir ve farklı hücrelere erişim basitçe bellek bloğunuz üzerinden geçilir: alandan tasarruf sağlar (işaretçiler için bellek kaybı olmaz) ve hızlıdır .

Ethan'ın işaret ettiği gibi, OO kavramları kullanılmalıdır, ancak daha yüksek seviyede, genellikle düşük verimli bir veri yapısı uygulandığında numpy.ndarray.

OO programlama, verilerin kendisinde daha yüksek soyutlama düzeyinde çalışan yöntemlere bağlanması anlamına gelir. (Bir örnek: Sertlik matrisinin seyrek süper nodal koleski çarpanlarına ayırma yöntemi olan bir sınıf olarak tanımlandığı bir FEM kodu uyguladım. İlk uygulama çekirdekti: çekirdek dışı bir uygulamaya ihtiyaç duyulduğunda, bu kalıtım ve alt çizgi veri depolamasında minimum ayarlamalarla elde edilmiştir . Süper düğümlü kolesky kodunun neredeyse% 100'ü tekrar kullanılmıştır.)

Son bir yorum, ama çok önemli: verimli bir sayısal prosedür, bir algoritmanın ve bir veri yapısının hedef hesaplama mimarinize akıllı bir şekilde eşlenmesinin sonucudur. Yanlış veri yapısıyla başlarsanız , tam bir yeniden yazma olmadan verimliliği kurtarmanın bir yolu yoktur .


@EthanCoon Diğer cevaba yaptığınız yorum için teşekkür ederim, bu da kendi cevabımı yazmama neden oldu.
Stefano M

10

Bunu birkaç gün önce (Python'da da) düşünüyordum. Şahsen, nesne yönelimli programlamanın her zaman sayısal programlama için uygun olduğunu düşünmüyorum. Sadece denklemleri çözmek yerine sınıfları tasarlarken dikkatinizi dağıtabilirsiniz. Basit fonksiyonlarla kalmayı tercih ediyorum ve numpy ile denklemlerinizin vektörlenmesini sağlayabilirsiniz, böylece ihtiyacınız olan hat sayısı çok azdır. Numpy oldukça hızlıdır çünkü gerçek hesaplamalar bir C (veya FORTRAN?) Arka ucu ile yapılır.

Ne yapmanızı öneririm,

  1. Numpy ile işlevsel bir yaklaşım kullanarak probleminizin mümkün olan en basit sürümünü çözen bir Python betiği yazın . Örneğin, her şeyi rastgele bir ünitede bulundurun ve sadece 1D (veya 2D) deneyin. Kodun dağınık olması durumunda bu aşamada gayet iyi. Önemli olan, projenizle birlikte ilerlemeniz.
  2. Bir kez çalışan bir şey var. Kodun ayrıntılı ve refrakter nerede olduğunu belirleyin. Bu aşamada, kodunuzu nasıl basitleştireceğiniz konusunda farklı fikirlerle oynayabilirsiniz. Belki kendinizi tekrarladığınızı fark ettiğiniz fonksiyonları tanıtın. Orijinal sürümle karşılaştırabilirsiniz, böylece hataları tanımadığınızı bilirsiniz.
  3. Nesneye yönelik yaklaşımın kodun karmaşıklığını daha da azaltacağına karar verin.

Ana mesaj, problemi mümkün olan en basit şekilde çözene kadar sınıf yazmaya başlamamaktır. Sadece problem çözme deneyimini kazanarak, nesne yönelimli arayüzünüzü nasıl tanımlayacağınızı bileceksiniz. Bunu elden önce yaparsanız, sadece yolunuza çıkması muhtemeldir.


3
OO'nun sayısal programlama için iyi bir uyum olmadığı, ancak iyi bir uyumun olduğu yerlerde çok daha yüksek olduğu ifadesine kesinlikle katılmıyorum. OO, fizik modelleri, ağlar, çözücüler, vb.Gibi şeyler için çok yararlıdır, ancak hücre düzeyinde neredeyse her zaman uygun değildir.
Ethan Coon

Mesajda, özellikle bir başlangıçta, sayısal kodun "erken nesnelleştirilmesi" potansiyel çukur düşüşleri hakkında uyarmak istedim. Nesneleri kullanmak konusunda olumsuz değilim, üçüncü noktama bakın: nesneler karmaşıklığı azaltabilirse iyi bir fikirdir. Alıntı yaptığınız örneklerin iyi kullanımlar olduğuna katılıyorum, ancak o noktaya gelmek deneyim gerektiriyor.
boyfarrell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.