#include "fiko/dokum/methoding.hpp" #include #include #include "fiko/dokum/voxel_kafes.hpp" namespace fiko::dokum { namespace { constexpr f64 kPi = 3.14159265358979323846; } // ---- Parça modülü: voxel'den V/A ------------------------------------------- // V = metal (Ic+Sinir) hücre hacmi. A = metal hücrenin metal-olmayan (Dis) ya // da grid-sınırı komşusuna bakan yüz alanı (soğuyan yüzey). h() FİZİK (m) → // mesh birimine (mm) ölçekle: metre yüzü m²; mesh çıktısı için h_mesh kullan. ParcaModul parcaModulu(const VoxelKafes& kafes) { ParcaModul r; if (!kafes.gecerliMi() || kafes.tip.empty()) return r; const u32 nx = kafes.nx(), ny = kafes.ny(), nz = kafes.nz(); // Hücre kenarı mesh biriminde (merkez() ile tutarlı): iki komşu merkez farkı. const f64 h = (nx > 1) ? std::abs(kafes.merkez(1, 0, 0).x - kafes.merkez(0, 0, 0).x) : std::abs(kafes.merkez(0, 0, 0).x) * 2.0; if (!(h > 0)) return r; const f64 hucreHacim = h * h * h; const f64 yuzAlan = h * h; auto metalMi = [&](i64 i, i64 j, i64 k) -> bool { if (i < 0 || j < 0 || k < 0 || i >= (i64)nx || j >= (i64)ny || k >= (i64)nz) return false; const HucreTip t = kafes.tip[kafes.indeks((u32)i, (u32)j, (u32)k)]; return t == HucreTip::Ic || t == HucreTip::Sinir; }; u64 metalHucre = 0, acikYuz = 0; const i64 komsu[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}}; for (u32 k = 0; k < nz; ++k) for (u32 j = 0; j < ny; ++j) for (u32 i = 0; i < nx; ++i) { if (!metalMi(i, j, k)) continue; ++metalHucre; for (auto& d : komsu) if (!metalMi((i64)i + d[0], (i64)j + d[1], (i64)k + d[2])) ++acikYuz; } if (metalHucre == 0 || acikYuz == 0) return r; r.hacim = (f64)metalHucre * hucreHacim; r.yuzeyAlan = (f64)acikYuz * yuzAlan; r.modul = r.hacim / r.yuzeyAlan; // Kesit kalınlık T tahmini: her z-diliminde metal hücrelerin en dar süreklilik // yönü ≈ 2·M yaklaşıklığı yerine, modülden T≈6·M (küp kesit) kaba tahmini // KULLANMA — bunun yerine metal hücre başına ort. yüzey/hacimden efektif // kalınlık: T_ef = 2·V/A_yalnız-yanal ≈ 2·M (plaka için modül = T/2). Plaka // modülü M=T/2 ⇒ T≈2·M pratik besleme-mesafesi girdisi (döküm literatürü). r.kesitKalinlik = 2.0 * r.modul; r.gecerli = true; return r; } // ---- Analitik silindir ------------------------------------------------------ f64 silindirHacim(f64 capMm, f64 yukseklikMm) { const f64 rr = capMm * 0.5; return kPi * rr * rr * yukseklikMm; } f64 silindirModul(f64 capMm, f64 yukseklikMm) { const f64 d = capMm, h = yukseklikMm, rr = d * 0.5; if (d <= 0 || h <= 0) return 0; const f64 V = kPi * rr * rr * h; const f64 A = kPi * d * h + kPi * rr * rr; // yan + üst (alt = beslenen yüz) return A > 0 ? V / A : 0; } // ---- Besleyici öneri -------------------------------------------------------- // h = kOran·d sabitlenirse silindir modülü M(d) = d·kOran/(4·kOran+1) (kapalı-form, // A = πd h + πr²; türetme methoding.hpp yorumunda). Hedef M_r için: // d = M_r·(4·kOran+1)/kOran , h = kOran·d. BesleyiciOneri besleyiciOner(const ParcaModul& parca, Vec3d hotSpotKonum, f64 carpan, f64 hDoranYuk) { BesleyiciOneri o; o.konum = hotSpotKonum; if (!parca.gecerli || parca.modul <= 0) return o; const f64 kOran = (hDoranYuk > 0) ? hDoranYuk : 1.5; o.hedefModul = carpan * parca.modul; o.capMm = o.hedefModul * (4.0 * kOran + 1.0) / kOran; o.yukseklikMm = kOran * o.capMm; o.modul = silindirModul(o.capMm, o.yukseklikMm); o.hacimMm3 = silindirHacim(o.capMm, o.yukseklikMm); o.modulYeterli = o.modul >= o.hedefModul - 1e-6; // 4.5T besleme mesafesi kuralı: besleyici, T kalınlık kesitte en fazla ~4.5·T // uzağa besler. Besleyici tabanı hot-spot üstüne konduğundan erişim koşulu // trivial sağlanır (mesafe≈0); yine de kuralı raporla (kullanıcı yerini kaydırırsa). o.beslemeMesafe = 4.5 * parca.kesitKalinlik; o.mesafeYeterli = o.beslemeMesafe > 0; o.gecerli = true; return o; } f64 besleyiciVerim(f64 parcaHacimMm3, f64 besleyiciHacimMm3) { const f64 toplam = parcaHacimMm3 + besleyiciHacimMm3; return toplam > 0 ? (parcaHacimMm3 / toplam) * 100.0 : 0; } } // namespace fiko::dokum