Skip to content

Commit

Permalink
Fix Issue 2820 (#2827)
Browse files Browse the repository at this point in the history
* WIP: issue 2820

* fix #2820

* clang-format

* minor

* clang-format

* fix #2828

Co-authored-by: Samuel Li <shaomeng@cisl-vapor>
  • Loading branch information
shaomeng and Samuel Li committed Jul 27, 2021
1 parent d613051 commit 8ba376e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 36 deletions.
18 changes: 6 additions & 12 deletions include/vapor/FlowRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
#define FLOWRENDERER_H

#include "vapor/glutil.h"
#ifndef WIN32
#include <sys/time.h>
#endif

#include "vapor/Renderer.h"
#include "vapor/FlowParams.h"
#include "vapor/GLManager.h"
Expand Down Expand Up @@ -98,11 +94,10 @@ class RENDER_API FlowRenderer final : public Renderer {
//
// Member functions
//
void _printFlowStatus(const std::string &prefix, FlowStatus stat) const;
int _genSeedsRakeUniform(std::vector<flow::Particle> &seeds) const;
int _genSeedsRakeRandom(std::vector<flow::Particle> &seeds) const;
int _genSeedsRakeRandomBiased(std::vector<flow::Particle> &seeds) const;
int _genSeedsFromList(std::vector<flow::Particle> &seeds) const;
int _genSeedsRakeUniform(std::vector<flow::Particle> &seeds) const;
int _genSeedsRakeRandom(std::vector<flow::Particle> &seeds) const;
int _genSeedsRakeRandomBiased(std::vector<flow::Particle> &seeds) const;
int _genSeedsFromList(std::vector<flow::Particle> &seeds) const;

int _renderFromAnAdvectionLegacy(const flow::Advection *, FlowParams *, bool fast);
int _renderAdvection(const flow::Advection *adv);
Expand All @@ -124,9 +119,8 @@ class RENDER_API FlowRenderer final : public Renderer {
size_t firstN, // First N particles to duplicate
double newTime) const; // New time to assign to particles

#ifndef WIN32
double _getElapsedSeconds(const struct timeval *begin, const struct timeval *end) const;
#endif
// Print return code if it's non-zero and compiled in debug mode.
void _printNonZero(int rtn, const char *file, const char *func, int line);

}; // End of class FlowRenderer

Expand Down
23 changes: 17 additions & 6 deletions lib/flow/Advection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,15 @@ int Advection::AdvectTillTime(Field *velocity, double startT, double deltaT, dou

bool happened = false;
size_t streamIdx = 0;
size_t maxSteps = 10000;
for (auto &s : _streams) // Process one stream at a time
{
Particle p0 = s.back(); // Start from the last particle in this stream
if (p0.time < startT) // Skip this stream if it didn't advance to startT
continue;

size_t thisStep = 0;

while (p0.time < targetT) {
// Check if the particle is inside of the volume.
// Wrap it along periodic dimensions if applicable.
Expand Down Expand Up @@ -239,20 +242,28 @@ int Advection::AdvectTillTime(Field *velocity, double startT, double deltaT, dou
case ADVECTION_METHOD::EULER: rv = _advectEuler(velocity, p0, dt, p1); break;
case ADVECTION_METHOD::RK4: rv = _advectRK4(velocity, p0, dt, p1); break;
}
if (rv != 0) // Advection wasn't successful for some reason...
{
if (rv != 0) { // Advection wasn't successful for some reason...
break;
} else // Advection successful, keep the new particle.
{
} else { // Advection successful, keep the new particle.
happened = true;
s.push_back(p1);
p0 = std::move(p1);
}
} // Finish the while loop to advect one particle to a time

// Another termination criterion: when advecting at least 10,000 steps and
// more than 10X more than the previous max num of steps.
//
if (++thisStep == maxSteps) {
thisStep = maxSteps / 10;
break;
}
} // Finish advecting one particle

maxSteps = std::max(maxSteps, thisStep * 10);

streamIdx++;

} // Finish the for loop to advect all particles to a time
} // Finish advecting all particles

if (happened)
return ADVECT_HAPPENED;
Expand Down
44 changes: 26 additions & 18 deletions lib/render/FlowRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,13 @@ int FlowRenderer::_paintGL(bool fast)
if (params->GetNeedFlowlineOutput()) {
rv = _outputFlowLines();
params->SetNeedFlowlineOutput(false);
_printNonZero(rv, __FILE__, __func__, __LINE__);
if (rv != 0) return rv;
}

if (_updateFlowCacheAndStates(params) != 0) {
rv = _updateFlowCacheAndStates(params);
if (rv != 0) {
_printNonZero(rv, __FILE__, __func__, __LINE__);
MyBase::SetErrMsg("Parameters not ready!");
return flow::PARAMS_ERROR;
}
Expand All @@ -197,9 +200,10 @@ int FlowRenderer::_paintGL(bool fast)
// First step is to re-calculate deltaT
rv = _velocityField.CalcDeltaTFromCurrentTimeStep(_cache_deltaT);
if (rv == flow::FIELD_ALL_ZERO) {
MyBase::SetErrMsg("The velocity field seems to contain only invalid values!");
MyBase::SetErrMsg("The velocity field seems to contain only zero values!");
return flow::PARAMS_ERROR;
} else if (rv != 0) {
_printNonZero(rv, __FILE__, __func__, __LINE__);
MyBase::SetErrMsg("Update deltaT failed!");
return rv;
}
Expand All @@ -216,6 +220,7 @@ int FlowRenderer::_paintGL(bool fast)
rv = _genSeedsFromList(seeds);

if (rv != 0) {
_printNonZero(rv, __FILE__, __func__, __LINE__);
MyBase::SetErrMsg("Generating seeds failed!");
return flow::NO_SEED_PARTICLE_YET;
}
Expand All @@ -226,6 +231,7 @@ int FlowRenderer::_paintGL(bool fast)
_advection.UseSeedParticles(seeds);
rv = _updateAdvectionPeriodicity(&_advection);
if (rv != 0) {
_printNonZero(rv, __FILE__, __func__, __LINE__);
MyBase::SetErrMsg("Update Advection Periodicity failed!");
return flow::GRID_ERROR;
}
Expand All @@ -234,6 +240,7 @@ int FlowRenderer::_paintGL(bool fast)
_2ndAdvection->UseSeedParticles(seeds);
rv = _updateAdvectionPeriodicity(_2ndAdvection.get());
if (rv != 0) {
_printNonZero(rv, __FILE__, __func__, __LINE__);
MyBase::SetErrMsg("Update Advection Periodicity failed!");
return flow::GRID_ERROR;
}
Expand Down Expand Up @@ -288,16 +295,21 @@ int FlowRenderer::_paintGL(bool fast)
// Advection scheme 2: advect to a certain timestamp.
// This scheme is used for unsteady flow
else {
for (int i = 1; i <= _cache_currentTS; i++) { rv = _advection.AdvectTillTime(&_velocityField, _timestamps.at(i - 1), deltaT, _timestamps.at(i)); }
for (int i = 1; i <= _cache_currentTS; i++) {
rv = _advection.AdvectTillTime(&_velocityField, _timestamps.at(i - 1), deltaT, _timestamps.at(i));
_printNonZero(rv, __FILE__, __func__, __LINE__);
}
}

_advectionComplete = true;
}

if (!_coloringComplete) {
rv = _advection.CalculateParticleValues(&_colorField, true);
_printNonZero(rv, __FILE__, __func__, __LINE__);
if (_2ndAdvection) // bi-directional advection
rv = _2ndAdvection->CalculateParticleValues(&_colorField, true);
_printNonZero(rv, __FILE__, __func__, __LINE__);
_coloringComplete = true;
}

Expand All @@ -310,8 +322,9 @@ int FlowRenderer::_paintGL(bool fast)

if (params->GetValueLong("old_render", 0)) {
_renderFromAnAdvectionLegacy(&_advection, params, fast);
/* If the advection is bi-directional */
if (_2ndAdvection) _renderFromAnAdvectionLegacy(_2ndAdvection.get(), params, fast);
if (_2ndAdvection) { // If the advection is bi-directional
_renderFromAnAdvectionLegacy(_2ndAdvection.get(), params, fast);
}
} else {
// Workaround for how bi-directional was implemented.
// The rendering caches the flow data on the GPU however it
Expand All @@ -321,10 +334,12 @@ int FlowRenderer::_paintGL(bool fast)
if (_2ndAdvection) _renderStatus = FlowStatus::SIMPLE_OUTOFDATE;

rv |= _renderAdvection(&_advection);
_printNonZero(rv, __FILE__, __func__, __LINE__);
/* If the advection is bi-directional */
if (_2ndAdvection) {
_renderStatus = FlowStatus::SIMPLE_OUTOFDATE;
rv |= _renderAdvection(_2ndAdvection.get());
_printNonZero(rv, __FILE__, __func__, __LINE__);
}
}

Expand Down Expand Up @@ -1213,18 +1228,11 @@ int FlowRenderer::_updateAdvectionPeriodicity(flow::Advection *advc)
return 0;
}

void FlowRenderer::_printFlowStatus(const std::string &prefix, FlowStatus stat) const
void FlowRenderer::_printNonZero(int rtn, const char *file, const char *func, int line)
{
std::cout << prefix << " : ";
if (stat == FlowStatus::SIMPLE_OUTOFDATE)
std::cout << "simple out-of-date";
else if (stat == FlowStatus::TIME_STEP_OOD)
std::cout << "time step out-of-date";
else if (stat == FlowStatus::UPTODATE)
std::cout << "up to date";
std::cout << std::endl;
}

#ifndef WIN32
double FlowRenderer::_getElapsedSeconds(const struct timeval *begin, const struct timeval *end) const { return (end->tv_sec - begin->tv_sec) + ((end->tv_usec - begin->tv_usec) / 1000000.0); }
#ifndef NDEBUG
if (rtn != 0) { // only print non-zero values
printf("Rtn == %d: %s:(%s):%d\n", rtn, file, func, line);
}
#endif
}

0 comments on commit 8ba376e

Please sign in to comment.