From a92f742c66b7248658912ac10ddc73977c1430cd Mon Sep 17 00:00:00 2001 From: Saveliy Skresanov Date: Tue, 30 Apr 2024 23:16:19 +0700 Subject: [PATCH] Improve heat convection in ambient heat. --- src/simulation/Air.cpp | 89 ++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/src/simulation/Air.cpp b/src/simulation/Air.cpp index 4b905c704..3c4bbaece 100644 --- a/src/simulation/Air.cpp +++ b/src/simulation/Air.cpp @@ -38,23 +38,26 @@ void Air::ClearAirH() std::fill(&hv[0][0], &hv[0][0]+NCELL, ambientAirTemp); } +// Used when updating temp or velocity from far away +const float advDistanceMult = 0.7f; + void Air::update_airh(void) { - for (auto i=0; i0 && y+j0 && x+i0 && y+j0 && x+i1.0f || dy*advDistanceMult>1.0f) && (tx>=2 && tx=2 && tystd::abs(dy)) + { + stepX = (dx<0.0f) ? 1.f : -1.f; + stepY = -dy/fabsf(dx); + stepLimit = (int)(fabsf(dx*advDistanceMult)); + } + else + { + stepY = (dy<0.0f) ? 1.f : -1.f; + stepX = -dx/fabsf(dy); + stepLimit = (int)(fabsf(dy*advDistanceMult)); + } + tx = float(x); + ty = float(y); + auto step = 0; + for (; step=2 && i=2 && j=2 && i<=XCELLS-3 && j>=2 && j<=YCELLS-3) { auto odh = dh; dh *= 1.0f - AIR_VADV; @@ -99,17 +140,27 @@ void Air::update_airh(void) dh += AIR_VADV*tx*ty*((bmap_blockairh[j+1][i+1]&0x8) ? odh : hv[j+1][i+1]); } ohv[y][x] = dh; + + // Air convection. + // We use the Boussinesq approximation, i.e. we assume density to be nonconstant only + // near the gravity term of the fluid equation, and we suppose that it depends linearly on the + // difference between the current temperature (hv[y][x]) and some "stationary" temperature (ambientAirTemp). if (x>=2 && x=2 && y 0 && !(bmap_blockairh[y-1][x]&0x8)) - { - vx[y][x] += weight * convGravX; - vy[y][x] += weight * convGravY; - } + auto weight = (hv[y][x] - ambientAirTemp) / 10000.0f; + + // Our approximation works best when the temperature difference is small, so we cap it from above. + if (weight > 0.1f) weight = 0.1f; + + vx[y][x] += weight * convGravX; + vy[y][x] += weight * convGravY; } + + // Temp caps + if (hv[y][x] > MAX_TEMP) hv[y][x] = MAX_TEMP; + if (hv[y][x] < MIN_TEMP) hv[y][x] = MIN_TEMP; } } memcpy(hv, ohv, sizeof(hv)); @@ -117,8 +168,6 @@ void Air::update_airh(void) void Air::update_air(void) { - const float advDistanceMult = 0.7f; - if (airMode != AIR_NOUPDATE) //airMode 4 is no air/pressure update { for (auto i=0; i1.0f || dy*advDistanceMult>1.0f) && (tx>=2 && tx=2 && tystd::abs(dy)) @@ -273,8 +323,7 @@ void Air::update_air(void) auto j = (int)ty; tx -= i; ty -= j; - if (!bmap_blockair[y][x] && i>=2 && i<=XCELLS-3 && - j>=2 && j<=YCELLS-3) + if (!bmap_blockair[y][x] && i>=2 && i<=XCELLS-3 && j>=2 && j<=YCELLS-3) { dx *= 1.0f - AIR_VADV; dy *= 1.0f - AIR_VADV;