gonna rewrite water a few times before its done. just getting a bunch of defaults right now.

This commit is contained in:
yggdrasil75
2025-11-23 08:23:34 -05:00
parent c4b6cd6c54
commit 6a05161b70
4 changed files with 601 additions and 1 deletions

172
util/simblocks/water.hpp Normal file
View File

@@ -0,0 +1,172 @@
#ifndef WATER_HPP
#define WATER_HPP
#include "../vectorlogic/vec2.hpp"
#include "../vectorlogic/vec3.hpp"
#include <cmath>
// Water constants (SI units: Kelvin, Pascals, Meters)
struct WaterConstants {
// Thermodynamic properties at STP (Standard Temperature and Pressure)
static constexpr float STANDARD_TEMPERATURE = 293.15f;
static constexpr float STANDARD_PRESSURE = 101325.0f;
static constexpr float FREEZING_POINT = 273.15f;
static constexpr float BOILING_POINT = 373.15f;
// Reference densities (kg/m³)
static constexpr float DENSITY_STP = 998.0f;
static constexpr float DENSITY_0C = 999.8f;
static constexpr float DENSITY_4C = 1000.0f;
// Viscosity reference values (Pa·s)
static constexpr float VISCOSITY_0C = 0.001792f;
static constexpr float VISCOSITY_20C = 0.001002f;
static constexpr float VISCOSITY_100C = 0.000282f;
// Thermal properties
static constexpr float SPECIFIC_HEAT_CAPACITY = 4182.0f;
static constexpr float THERMAL_CONDUCTIVITY = 0.598f;
static constexpr float LATENT_HEAT_VAPORIZATION = 2257000.0f;
static constexpr float LATENT_HEAT_FUSION = 334000.0f;
// Other physical constants
static constexpr float SURFACE_TENSION = 0.0728f;
static constexpr float SPEED_OF_SOUND = 1482.0f;
static constexpr float BULK_MODULUS = 2.15e9f;
};
class WaterThermodynamics {
public:
// Calculate density based on temperature (empirical relationship for 0-100°C)
static float calculateDensity(float temperature_K) {
// Empirical formula for pure water density vs temperature
float T = temperature_K - 273.15f; // Convert to Celsius for empirical formulas
if (T <= 0.0f) return WaterConstants::DENSITY_0C;
if (T >= 100.0f) return 958.4f; // Density at 100°C
// Polynomial approximation for 0-100°C range
return 1000.0f * (1.0f - (T + 288.9414f) * (T - 3.9863f) * (T - 3.9863f) /
(508929.2f * (T + 68.12963f)));
}
// Calculate dynamic viscosity based on temperature (using Vogel-Fulcher-Tammann equation)
static float calculateViscosity(float temperature_K) {
float T = temperature_K;
// Vogel-Fulcher-Tammann equation parameters for water
constexpr float A = -3.7188f;
constexpr float B = 578.919f;
constexpr float C = -137.546f;
return 0.001f * std::exp(A + B / (T - C)); // Returns in Pa·s
}
// Calculate viscosity using simpler Arrhenius-type equation (good for 0-100°C)
static float calculateViscositySimple(float temperature_K) {
float T = temperature_K - 273.15f; // Celsius
if (T <= 0.0f) return WaterConstants::VISCOSITY_0C;
if (T >= 100.0f) return WaterConstants::VISCOSITY_100C;
// Simple exponential decay model for 0-100°C range
return 0.001792f * std::exp(-0.024f * T);
}
// Calculate thermal conductivity (W/(m·K))
static float calculateThermalConductivity(float temperature_K) {
float T = temperature_K - 273.15f; // Celsius
// Linear approximation for 0-100°C
return 0.561f + 0.002f * T - 0.00001f * T * T;
}
// Calculate surface tension (N/m)
static float calculateSurfaceTension(float temperature_K) {
float T = temperature_K - 273.15f; // Celsius
// Linear decrease with temperature
return 0.07564f - 0.000141f * T - 0.00000025f * T * T;
}
// Calculate speed of sound in water (m/s)
static float calculateSpeedOfSound(float temperature_K, float pressure_Pa = WaterConstants::STANDARD_PRESSURE) {
float T = temperature_K - 273.15f; // Celsius
// Empirical formula for pure water
return 1402.5f + 5.0f * T - 0.055f * T * T + 0.0003f * T * T * T;
}
// Calculate bulk modulus (compressibility) in Pa
static float calculateBulkModulus(float temperature_K, float pressure_Pa = WaterConstants::STANDARD_PRESSURE) {
float T = temperature_K - 273.15f; // Celsius
// Approximation - decreases slightly with temperature
return WaterConstants::BULK_MODULUS * (1.0f - 0.0001f * T);
}
// Check if water should change phase
static bool isFrozen(float temperature_K, float pressure_Pa = WaterConstants::STANDARD_PRESSURE) {
return temperature_K <= WaterConstants::FREEZING_POINT;
}
static bool isBoiling(float temperature_K, float pressure_Pa = WaterConstants::STANDARD_PRESSURE) {
// Simple boiling point calculation (neglecting pressure effects for simplicity)
return temperature_K >= WaterConstants::BOILING_POINT;
}
};
struct WaterParticle {
Vec3 velocity;
Vec3 acceleration;
Vec3 force;
float temperature;
float pressure;
float density;
float mass;
float viscosity;
float volume;
float energy;
WaterParticle(float percent = 1.0f, float temp_K = WaterConstants::STANDARD_TEMPERATURE)
: velocity(0, 0, 0), acceleration(0, 0, 0), force(0, 0, 0),
temperature(temp_K), pressure(WaterConstants::STANDARD_PRESSURE),
volume(1.0f * percent) {
updateThermodynamicProperties();
// Mass is density × volume
mass = density * volume;
energy = mass * WaterConstants::SPECIFIC_HEAT_CAPACITY * temperature;
}
// Update all temperature-dependent properties
void updateThermodynamicProperties() {
density = WaterThermodynamics::calculateDensity(temperature);
viscosity = WaterThermodynamics::calculateViscosity(temperature);
// If we have a fixed mass, adjust volume for density changes
if (mass > 0.0f) {
volume = mass / density;
}
}
// Add thermal energy and update temperature
void addThermalEnergy(float energy_joules) {
energy += energy_joules;
temperature = energy / (mass * WaterConstants::SPECIFIC_HEAT_CAPACITY);
updateThermodynamicProperties();
}
// Set temperature directly
void setTemperature(float temp_K) {
temperature = temp_K;
energy = mass * WaterConstants::SPECIFIC_HEAT_CAPACITY * temperature;
updateThermodynamicProperties();
}
// Check phase state
bool isFrozen() const { return WaterThermodynamics::isFrozen(temperature, pressure); }
bool isBoiling() const { return WaterThermodynamics::isBoiling(temperature, pressure); }
bool isLiquid() const { return !isFrozen() && !isBoiling(); }
};
#endif