#pragma once #include "FluidSim/Component.hpp" #include "FluidSim/Engine.hpp" #include namespace fluidsim::port { class Crankcase final : public Component { public: Crankcase(Crankshaft& crankshaft, float crank_radius, float connecting_rod_length, float bore, float clearance_volume, float initial_pressure = 101325.0f, float initial_temperature = 300.0f); Port intake_port{}, transfer_port{}; float pressure() const { return pressure_; } float temperature() const { return temperature_; } float density() const { return mass_ / (volume_ > 1e-12f ? volume_ : 1e-12f); } float volume() const { return volume_; } float geometry_work() const { return geometry_work_; } // J delivered by gas during the latest geometry step. float mass() const { return mass_; } float air_fraction() const { return air_fraction_; } float fuel_fraction() const { return fuel_fraction_; } float fuel_mass() const { return mass_ * fuel_fraction_; } void initialize_mixture(float afr) { fuel_fraction_ = 1.0f / (1.0f + afr); air_fraction_ = 1.0f - fuel_fraction_; sync_ports(); } std::vector ports() override { return {&intake_port, &transfer_port}; } void pre_step(float dt); void update_state(float dt) override; private: Crankshaft& crankshaft_; float crank_radius_{}, connecting_rod_length_{}, piston_area_{}; float clearance_volume_{}, obliquity_{}; float geometry_work_{}; float mass_{}, energy_{}, air_fraction_{1.0f}, fuel_fraction_{}; float pressure_{101325.0f}, temperature_{300.0f}, volume_{}, previous_volume_{}; void sync_ports(); }; } // namespace fluidsim::port