#include #include #include "fiko/dokum/hava_analiz.hpp" #include "fiko_test.hpp" using namespace fiko; using namespace fiko::dokum; namespace { VoxelKafes kafesYap(u32 n) { VoxelKafes k; Aabbd s; s.genislet({-1, -1, -1}); s.genislet({1, 1, 1}); k.kur(s, n, 0.0, 1.0); for (auto& t : k.tip) t = HucreTip::Dis; return k; } DolumSonuc dolumYap(const VoxelKafes& k) { DolumSonuc d; d.varisZamani.assign(k.hucreSayi(), -1.0); d.hazir = true; return d; } } // namespace FIKO_TEST(hava_kapali_cep_ve_vent) { // Dik şaft alttan yukarı dolar; yandaki kör cep hiç dolmaz, üstü kalıp → // kaçış yok → hapsolmuş hava + vent önerisi cebin TEPESİNDE. VoxelKafes k = kafesYap(8); DolumSonuc d = dolumYap(k); for (u32 kk = 0; kk <= 6; ++kk) { const u32 idx = k.indeks(2, 4, kk); k.tip[idx] = HucreTip::Ic; d.varisZamani[idx] = kk * 1.0; } const u32 kol = k.indeks(3, 4, 3); k.tip[kol] = HucreTip::Ic; d.varisZamani[kol] = 3.5; k.tip[k.indeks(4, 4, 2)] = HucreTip::Ic; k.tip[k.indeks(4, 4, 3)] = HucreTip::Ic; d.toplamSure = 6.0; const HavaAnalizSonuc s = havaAnaliz(k, d, {}); FIKO_KONTROL(s.hazir); FIKO_KONTROL(s.cepler.size() == 1); FIKO_KONTROL(s.cepler[0].kapali); FIKO_KONTROL(s.cepler[0].hucreSayi == 2); FIKO_KONTROL(s.cepler[0].ventHucre == k.indeks(4, 4, 3)); FIKO_KONTROL(s.kapaliCepSayi >= 1); FIKO_KONTROL(!s.ventOnerileri.empty()); FIKO_KONTROL(s.lastAir[k.indeks(4, 4, 2)] > 0.99f); // Şaftın tepesi (son dolan) açık üst hücre → kapalı DEĞİL. FIKO_KONTROL(s.sonHavaBolgeleri.size() == 1); FIKO_KONTROL(!s.sonHavaBolgeleri[0].kapali); } FIKO_TEST(hava_cephe_bulusma_riski) { // İki uçtan dolan yatay kanal: cepheler ortada çarpışır → buluşma hücresi // varış-zamanı yerel maksimumu + Campbell hız aşımı → risk > 0. VoxelKafes k = kafesYap(8); DolumSonuc d = dolumYap(k); for (u32 i = 0; i < 8; ++i) { const u32 idx = k.indeks(i, 4, 4); k.tip[idx] = HucreTip::Ic; d.varisZamani[idx] = std::min(i * 1.0, (7.0 - i) * 1.1); } d.toplamSure = 3.3; const HavaAnalizSonuc s = havaAnaliz(k, d, {}); FIKO_KONTROL(s.hazir); FIKO_KONTROL(s.kabarcikRisk[k.indeks(4, 4, 4)] > 0.3f); // buluşma hücresi FIKO_KONTROL(s.kabarcikRisk[k.indeks(1, 4, 4)] < 0.05f); // düz akış hücresi FIKO_KONTROL(s.azamiCepheHiz > 0.5); // buluşmada hız Campbell eşiğini aşar FIKO_KONTROL(s.riskliHucre >= 1); } FIKO_TEST(hava_duz_dolum_dusuk_risk) { // Tek girişli yavaş düz dolum: risk ~0, son hava en uzak uçta, cep yok. VoxelKafes k = kafesYap(8); DolumSonuc d = dolumYap(k); for (u32 i = 0; i < 8; ++i) { const u32 idx = k.indeks(i, 4, 4); k.tip[idx] = HucreTip::Ic; d.varisZamani[idx] = i * 1.0; // v = 0.25 m/s < 0.5 (kritik altı) } d.toplamSure = 7.0; const HavaAnalizSonuc s = havaAnaliz(k, d, {}); FIKO_KONTROL(s.hazir); f32 azamiRisk = 0; for (f32 r : s.kabarcikRisk) azamiRisk = std::max(azamiRisk, r); FIKO_KONTROL(azamiRisk < 0.05f); FIKO_KONTROL(s.cepler.empty()); FIKO_KONTROL(s.sonHavaBolgeleri.size() == 1); FIKO_KONTROL(s.sonHavaBolgeleri[0].merkez.x > 0.8f); // en uzak köşe FIKO_KONTROL(s.lastAir[k.indeks(7, 4, 4)] > 0.99f); FIKO_KONTROL(s.lastAir[k.indeks(0, 4, 4)] < 1e-6f); } FIKO_TEST(hava_gercek_cep_basinci) { // Dolum hava geri-basıncı modeli alanları (cepBasinc + hapsoldu) varsa // HavaCebi vekil skor yerine GERÇEK basıncı taşır: sonBasinc + kritikAsti; // kritik aşım cebi kaçış-testinden bağımsız KAPALI işaretler. VoxelKafes k = kafesYap(8); DolumSonuc d = dolumYap(k); for (u32 kk = 0; kk <= 6; ++kk) { const u32 idx = k.indeks(2, 4, kk); k.tip[idx] = HucreTip::Ic; d.varisZamani[idx] = kk * 1.0; } const u32 kol = k.indeks(3, 4, 3); k.tip[kol] = HucreTip::Ic; d.varisZamani[kol] = 3.5; const u32 cepA = k.indeks(4, 4, 2), cepB = k.indeks(4, 4, 3); k.tip[cepA] = HucreTip::Ic; k.tip[cepB] = HucreTip::Ic; d.toplamSure = 6.0; d.cepBasinc.assign(k.hucreSayi(), 0.0f); d.hapsoldu.assign(k.hucreSayi(), 0); d.cepBasinc[cepA] = 180000.0f; // sıkışmış gaz ~1.78 atm d.cepBasinc[cepB] = 180000.0f; d.hapsoldu[cepA] = 1; d.hapsoldu[cepB] = 1; d.maksCepBasinc = 180000.0; const HavaAnalizSonuc s = havaAnaliz(k, d, {}); FIKO_KONTROL(s.hazir); FIKO_KONTROL(s.gercekBasinc); FIKO_KONTROL(s.cepler.size() == 1); FIKO_YAKIN(s.cepler[0].sonBasinc, 180000.0, 1.0); FIKO_KONTROL(s.cepler[0].kritikAsti); FIKO_KONTROL(s.cepler[0].kapali); FIKO_YAKIN(s.maksCepBasinc, 180000.0, 1e-6); // Model alanları YOKKEN (eski DolumSonuc) geriye uyum: basınç 0, bayrak yok. DolumSonuc eski = d; eski.cepBasinc.clear(); eski.hapsoldu.clear(); eski.maksCepBasinc = 0; const HavaAnalizSonuc s2 = havaAnaliz(k, eski, {}); FIKO_KONTROL(s2.hazir && !s2.gercekBasinc); FIKO_KONTROL(s2.cepler.size() == 1); FIKO_YAKIN(s2.cepler[0].sonBasinc, 0.0, 1e-30); FIKO_KONTROL(!s2.cepler[0].kritikAsti); } FIKO_TEST(hava_bos_ve_dolmamis_cokme_yok) { VoxelKafes bos; const HavaAnalizSonuc s0 = havaAnaliz(bos, {}, {}); FIKO_KONTROL(!s0.hazir); VoxelKafes k = kafesYap(8); DolumSonuc hazirDegil; hazirDegil.varisZamani.assign(k.hucreSayi(), -1.0); const HavaAnalizSonuc s1 = havaAnaliz(k, hazirDegil, {}); FIKO_KONTROL(!s1.hazir); DolumSonuc yanlisBoy; yanlisBoy.hazir = true; yanlisBoy.varisZamani.assign(3, 0.0); const HavaAnalizSonuc s2 = havaAnaliz(k, yanlisBoy, {}); FIKO_KONTROL(!s2.hazir); // Tümü metal ama HİÇ dolmamış (misrun): çökme yok, alan boyutları doğru. for (auto& t : k.tip) t = HucreTip::Ic; DolumSonuc d = dolumYap(k); const HavaAnalizSonuc s3 = havaAnaliz(k, d, {}); FIKO_KONTROL(s3.hazir); FIKO_KONTROL(s3.lastAir.size() == k.hucreSayi()); FIKO_KONTROL(s3.kabarcikRisk.size() == k.hucreSayi()); FIKO_KONTROL(s3.cepler.size() == 1); FIKO_KONTROL(!s3.cepler[0].kapali); // blok üst yüzeye açık → misrun, hapis değil }