pushing this home. its working better now.
This commit is contained in:
@@ -286,7 +286,7 @@ void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//expandPixel(grid,config,seeds);
|
//expandPixel(grid,config,seeds);
|
||||||
grid.diffuseTempsOptimized(100);
|
grid.diffuseTemps(100);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(state.mutex);
|
std::lock_guard<std::mutex> lock(state.mutex);
|
||||||
state.grid = grid;
|
state.grid = grid;
|
||||||
|
|||||||
@@ -977,25 +977,25 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void diffuseTemps(int timestep) {
|
// void diffuseTemps(int timestep) {
|
||||||
TIME_FUNCTION;
|
// TIME_FUNCTION;
|
||||||
std::cout << "diffusing temps with a timestep of " << timestep << std::endl;
|
// std::cout << "diffusing temps with a timestep of " << timestep << std::endl;
|
||||||
if (tempMap.empty() || timestep < 1) return;
|
// if (tempMap.empty() || timestep < 1) return;
|
||||||
#pragma omp parallel for
|
// #pragma omp parallel for
|
||||||
for (const auto& [id, pos] : Positions) {
|
// for (const auto& [id, pos] : Positions) {
|
||||||
auto tempIT = tempMap.find(id);
|
// auto tempIT = tempMap.find(id);
|
||||||
if (tempIT != tempMap.end()) {
|
// if (tempIT != tempMap.end()) {
|
||||||
Temp oldtemp = tempIT->second;
|
// Temp oldtemp = tempIT->second;
|
||||||
tempMap.erase(id);
|
// tempMap.erase(id);
|
||||||
float newtemp = Temp::calGrad(pos, getTemps(id));
|
// float newtemp = Temp::calGrad(pos, getTemps(id));
|
||||||
float newtempMult = (newtemp-oldtemp.temp) * timestep;
|
// float newtempMult = (newtemp-oldtemp.temp) * timestep;
|
||||||
oldtemp.temp = newtempMult;
|
// oldtemp.temp = newtempMult;
|
||||||
tempMap.emplace(id, oldtemp);
|
// tempMap.emplace(id, oldtemp);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void diffuseTempsOptimized(float deltaTime) {
|
void diffuseTemps(float deltaTime) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
if (tempMap.empty() || deltaTime <= 0) return;
|
if (tempMap.empty() || deltaTime <= 0) return;
|
||||||
|
|
||||||
@@ -1003,33 +1003,27 @@ public:
|
|||||||
tempUpdates.reserve(tempMap.size());
|
tempUpdates.reserve(tempMap.size());
|
||||||
|
|
||||||
// Process in spatial order for better cache performance
|
// Process in spatial order for better cache performance
|
||||||
for (const auto& [id, tempObj] : tempMap) {
|
for (auto& [id, tempObj] : tempMap) {
|
||||||
Vec2 pos = Positions.at(id);
|
Vec2 pos = Positions.at(id);
|
||||||
|
float oldtemp = tempObj.temp;
|
||||||
// Use smaller query radius for diffusion
|
// Use smaller query radius for diffusion
|
||||||
auto nearbyIds = spatialGrid.queryRange(pos, neighborRadius * tempObj.conductivity);
|
auto nearbyIds = spatialGrid.queryRange(pos, neighborRadius * tempObj.conductivity);
|
||||||
|
|
||||||
float heatTransfer = 0.0f;
|
float heatTransfer = 0.0f;
|
||||||
int validNeighbors = 0;
|
int validNeighbors = 0;
|
||||||
|
std::unordered_map<Vec2, Temp> neighborTemps;
|
||||||
for (size_t neighborId : nearbyIds) {
|
for (size_t neighborId : nearbyIds) {
|
||||||
if (neighborId != id && tempMap.find(neighborId) != tempMap.end()) {
|
if (neighborId != id && tempMap.find(neighborId) != tempMap.end()) {
|
||||||
float tempDiff = tempMap.at(neighborId).temp - tempObj.temp;
|
neighborTemps.emplace(Positions.at(neighborId), tempMap.at(neighborId));
|
||||||
float distance = pos.distance(Positions.at(neighborId));
|
|
||||||
|
|
||||||
if (distance > EPSILON) {
|
|
||||||
// Basic heat conduction formula
|
|
||||||
float conductivity = tempObj.conductivity * (tempObj.diffusivity + tempMap.at(neighborId).diffusivity);
|
|
||||||
heatTransfer += conductivity * tempDiff / distance;
|
|
||||||
validNeighbors++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
tempObj.calGrad(pos, neighborTemps);
|
||||||
|
float newtemp = tempObj.temp;
|
||||||
if (validNeighbors > 0) {
|
float tempdiff = (oldtemp - newtemp) * (deltaTime / 1000);
|
||||||
float newTemp = tempObj.temp + heatTransfer * deltaTime / validNeighbors;
|
// if (std::abs(newtemp) < EPSILON) {
|
||||||
tempUpdates.emplace_back(id, newTemp);
|
// std::cout << "new temp is: " << newtemp << " old temp is: " << oldtemp << " diff*delta: " << tempdiff << std::endl;
|
||||||
}
|
// }
|
||||||
|
tempObj.temp = oldtemp - tempdiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch update temperatures
|
// Batch update temperatures
|
||||||
|
|||||||
@@ -78,46 +78,52 @@ public:
|
|||||||
return num / den;
|
return num / den;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float calGrad(const Vec2& testPos, const std::unordered_map<Vec2, Temp>& others) {
|
void calGrad(const Vec2& testPos, const std::unordered_map<Vec2, Temp>& others) {
|
||||||
|
int meh;
|
||||||
|
//std::cout << meh++ << std::endl;
|
||||||
std::vector<std::pair<Vec2, float>> nearbyPoints;
|
std::vector<std::pair<Vec2, float>> nearbyPoints;
|
||||||
for (const auto& [point, temp] : others) {
|
for (const auto& [point, ctemp] : others) {
|
||||||
if (point.distance(testPos) <= 25) {
|
if (point.distance(testPos) <= 25) {
|
||||||
nearbyPoints.emplace_back(point, temp.temp);
|
nearbyPoints.emplace_back(point, ctemp.temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float sumX, sumY, sumT, sumX2, sumY2, sumXY, sumXT, sumYT = 0;
|
//std::cout << meh++ << std::endl;
|
||||||
|
float sumX = 0,sumY = 0,sumT = 0,sumX2 = 0,sumY2 = 0,sumXY = 0,sumXT = 0, sumYT = 0;
|
||||||
int n = nearbyPoints.size();
|
int n = nearbyPoints.size();
|
||||||
for (const auto& [point, temp] : nearbyPoints) {
|
//std::cout << meh++ << std::endl;
|
||||||
|
for (const auto& [point, ctemp] : nearbyPoints) {
|
||||||
float x = point.x - testPos.x;
|
float x = point.x - testPos.x;
|
||||||
float y = point.y - testPos.y;
|
float y = point.y - testPos.y;
|
||||||
|
|
||||||
sumX += x;
|
sumX += x;
|
||||||
sumY += y;
|
sumY += y;
|
||||||
sumT += temp;
|
sumT += ctemp;
|
||||||
sumX2 += x * x;
|
sumX2 += x * x;
|
||||||
sumY2 += y * y;
|
sumY2 += y * y;
|
||||||
sumXY += x * y;
|
sumXY += x * y;
|
||||||
sumXT += x * temp;
|
sumXT += x * ctemp;
|
||||||
sumYT += y * temp;
|
sumYT += y * ctemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//std::cout << meh++ << std::endl;
|
||||||
float det = sumX2 * sumY2 - sumXY * sumXY;
|
float det = sumX2 * sumY2 - sumXY * sumXY;
|
||||||
|
|
||||||
|
Vec2 calpoint;
|
||||||
if (std::abs(det) < 1e-10) {
|
if (std::abs(det) < 1e-10) {
|
||||||
Vec2 calpoint = Vec2(0, 0); // Singular matrix, cannot solve
|
calpoint = Vec2(0, 0); // Singular matrix, cannot solve
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
float a = (sumXT * sumY2 - sumYT * sumXY) / det;
|
float a = (sumXT * sumY2 - sumYT * sumXY) / det;
|
||||||
float b = (sumX2 * sumYT - sumXY * sumXT) / det;
|
float b = (sumX2 * sumYT - sumXY * sumXT) / det;
|
||||||
|
calpoint = Vec2(a, b); // ∇T = (∂T/∂x, ∂T/∂y)
|
||||||
Vec2 calpoint = Vec2(a, b); // ∇T = (∂T/∂x, ∂T/∂y)
|
}
|
||||||
|
//std::cout << meh++ << std::endl;
|
||||||
Vec2 closest = findClosestPoint(testPos, others);
|
Vec2 closest = findClosestPoint(testPos, others);
|
||||||
Vec2 displacement = testPos - closest;
|
Vec2 displacement = testPos - closest;
|
||||||
|
|
||||||
float refTemp = others.at(closest).temp;
|
float estimatedTemp = temp + (calpoint.x * displacement.x + calpoint.y * displacement.y);
|
||||||
float estimatedTemp = refTemp + (calpoint.x * displacement.x + calpoint.y * displacement.y);
|
temp = estimatedTemp;
|
||||||
return estimatedTemp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user