Simplify scenario visualisation

parent f64a14ed
......@@ -24,7 +24,7 @@
#include "../opengl/visualization.h"
#include "../opengl/controller.h"
#include "../scenarios/SWE_Scenario.h"
#include "../scenarios/SWE_simple_scenarios_vis.h"
#include "../scenarios/SWE_simple_scenarios.h"
#include "../scenarios/SWE_VtkScenarioVisInfo.h"
#include "../SWE_BlockCUDA.hh"
// #include "../SWE_RusanovBlockCUDA.hh"
......@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
if (scene == NULL) {
// ... if VTK file not specified (or was not read successfully)
// use splashing pool scenario ...
SWE_SplashingPoolScenarioVisInfo* newScene = new SWE_SplashingPoolScenarioVisInfo();
SWE_SplashingPoolScenario* newScene = new SWE_SplashingPoolScenario();
scene = newScene;
};
......
......@@ -19,6 +19,7 @@
// =====================================================================
#include "controller.h"
#include "../scenarios/SWE_simple_scenarios.h"
#include "../scenarios/SWE_simple_scenarios_vis.h"
#ifdef ASAGI
#include "../scenarios/SWE_AsagiScenario.hpp"
......@@ -41,13 +42,16 @@ Controller::Controller(Simulation* sim, Visualization* vis) {
// No scenario loaded
memset(scenarios, 0, SCENARIO_COUNT*sizeof(SWE_Scenario*));
memset(visInfos, 0, SCENARIO_COUNT*sizeof(SWE_VisInfo*));
}
Controller::~Controller()
{
// Delete scenarios
for (int i = 0; i < SCENARIO_COUNT; i++)
for (int i = 0; i < SCENARIO_COUNT; i++) {
delete scenarios[i];
delete visInfos[i];
}
}
/**
......@@ -174,7 +178,7 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
allowStep = paused;
if (scenarios[0] == 0)
scenarios[0] = new SWE_RadialDamBreakScenario();
scenarios[0] = new SWE_RadialDamBreakScenario;
SWE_Scenario* newScene = scenarios[0];
......@@ -192,8 +196,10 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
{
allowStep = paused;
if (scenarios[1] == 0)
if (scenarios[1] == 0) {
scenarios[1] = new SWE_BathymetryDamBreakScenario();
visInfos[1] = new SWE_BathymetryDamBreakVisInfo();
}
SWE_Scenario* newScene = scenarios[1];
......@@ -202,7 +208,7 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
simulation->loadNewScenario(newScene, visInfos[1]);
visualization->updateBathymetryVBO(simulation);
}
break;
......@@ -212,7 +218,7 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
allowStep = paused;
if (scenarios[2] == 0)
scenarios[2] = new SWE_SplashingPoolScenarioVisInfo();
scenarios[2] = new SWE_SplashingPoolScenario();
SWE_Scenario* newScene = scenarios[2];
......
......@@ -50,7 +50,9 @@ private:
Simulation* simulation;
Visualization* visualization;
/** Store scenarios, thus we only have to create them once */
SWE_Scenario *scenarios[SCENARIO_COUNT];
SWE_VisInfo *visInfos[SCENARIO_COUNT];
// Handle keyboard events
bool handleKeyPress( SDL_keysym *keysym);
......
......@@ -21,6 +21,10 @@
#include <stdlib.h>
#include "../SWE_BlockCUDA.hh"
// Taken form FWaveCuda.h
// TODO: Put it in a common header file
const float dryTol = 100.;
/**
Constructor.
Initializes SWE_BlockCUDA and creates a new instance of it.
......@@ -35,32 +39,16 @@
Simulation::Simulation (int nx, int ny, float dx, float dy,
SWE_Scenario* scene, SWE_VisInfo* visInfo,
SWE_BlockCUDA* _splash)
: myScenario(scene),
maxDim( (nx > ny) ? nx : ny ),
: maxDim( (nx > ny) ? nx : ny ),
maxCellSize( (dx > dy) ? dx : dy ),
splash(_splash),
curTime(0.0f),
isFirstStep(1),
fileNumber(0),
useFileInput(false)
fileNumber(0)
{
Simulation::initBoundaries(myScenario);
if (visInfo != NULL) {
wAverage = visInfo->waterHeightAtRest();
wScale = visInfo->waterVerticalScaling()*(maxDim/20.0f);
wOffset = visInfo->waterDistanceFromGround()*(maxDim/20.0f);
bAverage = visInfo->bathyVerticalCenter();
bScale = visInfo->bathyVerticalScaling()*(maxDim/20.0f);
bOffset = visInfo->bathyDistanceFromGround()*(maxDim/20.0f);
} else {
getScalingApproximation(splash->getWaterHeight(), splash->getBathymetry());
}
loadNewScenario(scene, visInfo);
}
/**
Destructor.
Delete current SWE_BlockCUDA and SWE_Scenario instance.
Destructor.
*/
Simulation::~Simulation () {
}
......@@ -72,12 +60,9 @@ void Simulation::loadNewScenario(SWE_Scenario* scene, SWE_VisInfo* visInfo) {
useFileInput = false;
Simulation::initBoundaries(myScenario);
if (visInfo != NULL) {
wAverage = visInfo->waterHeightAtRest();
wScale = visInfo->waterVerticalScaling()*(maxDim/20.0f);
wOffset = visInfo->waterDistanceFromGround()*(maxDim/20.0f);
bAverage = visInfo->bathyVerticalCenter();
bScale = visInfo->bathyVerticalScaling()*(maxDim/20.0f);
bOffset = visInfo->bathyDistanceFromGround()*(maxDim/20.0f);
wScale = visInfo->waterVerticalScaling();
bScale = visInfo->bathyVerticalScaling();
bOffset = visInfo->bathyVerticalOffset();
} else {
getScalingApproximation(splash->getWaterHeight(), splash->getBathymetry());
}
......@@ -162,8 +147,6 @@ void Simulation::restart() {
@param bath float array in which computed values will be stored
*/
void Simulation::setBathBuffer(float* bath) {
// splash->setBathBuffer(output, bAverage, bScale, bOffset);
const Float2D& b = splash->getBathymetry();
int nx = b.getRows()-2;
int ny = b.getCols()-2;
......@@ -172,8 +155,7 @@ void Simulation::setBathBuffer(float* bath) {
for (int j=0; j<ny+1;j++) {
for (int i=0;i<nx+1;i++) {
bath[(j*(ny+1) + i)*6] = (float) i;
bath[(j*(ny+1) + i)*6 + 1]= scaleFunction(0.25f*(b[i][j]+b[i+1][j]+b[i][j+1]+b[i+1][j+1]),
bAverage, bScale, bOffset);
bath[(j*(ny+1) + i)*6 + 1]= bScale * 0.25f * (b[i][j]+b[i+1][j]+b[i][j+1]+b[i+1][j+1]) + bOffset;
bath[(j*(ny+1) + i)*6 + 2] = (float) j;
bath[(j*(ny+1) + i)*6 + 3] = 0.0f;
bath[(j*(ny+1) + i)*6 + 4] = 0.0f;
......@@ -269,9 +251,8 @@ void Simulation::calculateWaterSurface(float3* destBuffer) {
@param h Fload2D array that holds water height
@param b Fload2D array that holds bathymetry data
*/
void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b) {
// Averages of B and (B + H)
float avgB, avgH;
void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b)
{
// Minimum values
float minB, minH;
// Maximum values
......@@ -281,8 +262,6 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b) {
int ny = h.getCols()-2;
int maxDim = (nx > ny) ? nx : ny;
avgH = 0.0f;
avgB = 0.0f;
minB = b[1][1];
minH = h[1][1];
maxB = b[1][1];
......@@ -290,9 +269,6 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b) {
for(int i=1; i<=nx; i++) {
for(int j=1; j<=ny; j++) {
// Update averages
avgH += (h[i][j] + b[i][j])/(nx*ny);
avgB += b[i][j]/(nx*ny);
// Update minima
if ((h[i][j] + b[i][j]) < minH)
minH = (h[i][j] + b[i][j]);
......@@ -305,22 +281,10 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b) {
maxB = b[i][j];
}
}
// cout << "max and min bathymetry: " << maxB << " ; " << minB << endl;
// bAverage = avgB;
bAverage = (maxB+minB)/2;
cout << "Average bathymetry: " << bAverage << endl;
if (abs(maxB - minB) > 0.0001f) {
bScale = (maxDim/20.0f)/(maxB - minB);
} else {
bScale = (maxDim/20.0f);
}
bOffset = 0; // This should be !=0 only in some artificial scenarios
bScale = -50/minB;
cout << "Scaling of bathymetry: " << bScale << endl;
bOffset = bScale*(avgB - minB) + maxDim/15.0f;
// bOffset = minB+100;
cout << "bathymetry offset: " << bOffset << endl;
wAverage = avgH;
cout << "Average water height: " << avgH << endl;
if ((maxH - minH) < 0.0001f) {
wScale = 1.0f/(maxH- minH);
} else {
......@@ -328,8 +292,6 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b) {
}
wScale = (maxDim/40.0)*wScale;
cout << "Scaling of water level: " << wScale << endl;
wOffset = bOffset + (maxDim/5.0f);
cout << "water level offset: " << wOffset << endl;
}
......@@ -361,8 +323,8 @@ void Simulation::calculateNormal(float fVert1[], float fVert2[],
Scale function used for visualization
*/
__device__ __host__
float scaleFunction(float val, float average, float scale, float offset) {
return (val - average)*scale + offset;
float scaleFunction(float val, float scale) {
return val * scale;
}
// /**
......@@ -391,20 +353,25 @@ float scaleFunction(float val, float average, float scale, float offset) {
*/
__global__
void kernelCalcVisBuffer(float3* visBuffer, const float* hd, const float* bd,
int nx, int ny, float average, float scale, float offset)
int nx, int ny, float scale)
{
int i = TILE_SIZE*blockIdx.x + threadIdx.x;
int j = TILE_SIZE*blockIdx.y + threadIdx.y;
if ((i <= nx) && (j <= ny)) {
int index = i*(nx+2) + j;
int index2 = (i+1)*(nx+2) + j;
visBuffer[j*(ny+1) + i] = make_float3(
i,
scaleFunction(0.25*(
hd[index]+hd[index + 1]+ hd[index2] + hd[index2 + 1] +
bd[index]+bd[index + 1]+ bd[index2] + bd[index2 + 1])
, average, scale, offset),
j);
if (hd[index] <= dryTol
|| hd[index+1] <= dryTol
|| hd[index2] <= dryTol
|| hd[index2+1] <= dryTol)
visBuffer[j*(ny+1)+i] = make_float3(i, 0, j);
else
visBuffer[j*(ny+1) + i] = make_float3(
i,
scale * 0.25 * (
hd[index]+hd[index + 1]+ hd[index2] + hd[index2 + 1] +
bd[index]+bd[index + 1]+ bd[index2] + bd[index2 + 1]),
j);
}
//Corresponding C-Code:
// for (int j=0; j<ny+1;j++)
......@@ -430,8 +397,7 @@ void Simulation::updateVisBuffer(float3* _visBuffer) {
// Interpolate cell centered h-values
dim3 dimBlock(TILE_SIZE,TILE_SIZE);
dim3 dimGrid((nx+TILE_SIZE)/TILE_SIZE,(ny+TILE_SIZE)/TILE_SIZE);
kernelCalcVisBuffer<<<dimGrid,dimBlock>>>(_visBuffer, hd, bd, nx, ny,
wAverage, wScale, wOffset);
kernelCalcVisBuffer<<<dimGrid,dimBlock>>>(_visBuffer, hd, bd, nx, ny, wScale);
}
/**
Function used for debugging. Outputs the current visBuffer
......
......@@ -4,6 +4,7 @@
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Michael Bader, Kaveh Rahnema, Tobias Schnabel
// Copyright (C) 2012 Sebastian Rettenberger
//
// SWE_CUDA is free software: you can redristribute it and/or modify
// it under the terms of the GNU General Public License as published by
......@@ -63,10 +64,10 @@ class Simulation {
// Maximum of cell sizes
float maxCellSize;
// Scaling factors used by visualization
float bOffset, bScale, wOffset, wScale, bAverage, wAverage;
// Initalize boundaries defined by the scene
float bScale, bOffset, wScale;
// Initialize boundaries defined by the scene
void initBoundaries(SWE_Scenario* scene);
// Initalize boundaries defined by an input file
// Initialize boundaries defined by an input file
int fileNumber;
// Use file input as boundary data
......@@ -83,14 +84,6 @@ class Simulation {
void updateVisBuffer(float3* _visBuffer);
void debugVisBuffer(float3* _visBuffer);
/**
Scale function used for visualization
*/
__device__ __host__
static float scaleFunction(float val, float average, float scale, float offset) {
return (val - average)*scale + offset;
}
static void calculateNormal(float fVert1[], float fVert2[],
float fVert3[], float fNormal[]);
......
......@@ -91,7 +91,7 @@ void Visualization::renderDisplay() {
camera->setCamera();
// Draw Scene
DrawBottom();
//DrawBottom();
DrawBathymetry(vboBathymetry, verticesIndex);
// Shaded pass
......
......@@ -4,6 +4,7 @@
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Michael Bader, Kaveh Rahnema, Tobias Schnabel
// Copyright (C) 2012 Sebastian Rettenberger
//
// SWE_CUDA is free software: you can redristribute it and/or modify
// it under the terms of the GNU General Public License as published by
......@@ -19,6 +20,8 @@
// along with SWE_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include "SWE_Scenario.h"
/**
* SWE_VisInfo defines an interface that can be used for online
* visualisation of a shallow water simulation.
......@@ -28,14 +31,14 @@
class SWE_VisInfo {
public:
/**
* Empty virtual destructor
*/
virtual ~SWE_VisInfo() {};
// Scaling factors for custom visualization
// virtual bool useCustomScaling() { return false; };
virtual float waterHeightAtRest() { return 10.0f; };
virtual float waterDistanceFromGround() { return 10.0f; };
virtual float waterVerticalScaling() { return 10.0f; };
virtual float bathyVerticalCenter() { return 0.0f; };
virtual float bathyDistanceFromGround() { return 0.0f; };
virtual float bathyVerticalOffset() { return 0.0f; };
virtual float bathyVerticalScaling() { return 10.0f; };
};
......
......@@ -103,10 +103,10 @@ SWE_VtkScenarioVisInfo* SWE_VtkScenarioVisInfo::readVtkFile(char const * filenam
dimx = atoi(values[1].c_str());
dimy = atoi(values[2].c_str());
scene = new SWE_VtkScenarioVisInfo(dimx,dimy);
h = scene->h.elemVector();
u = scene->u.elemVector();
v = scene->v.elemVector();
b = scene->b.elemVector();
h = scene->h.elemVector();
u = scene->u.elemVector();
v = scene->v.elemVector();
b = scene->b.elemVector();
state = 5;
}
}
......
......@@ -46,7 +46,7 @@ class SWE_RadialDamBreakScenario : public SWE_Scenario {
};
float getWaterHeight(float x, float y) {
return ( sqrt( (x-500.f)*(x-500.f) + (y-500.f)*(y-500.f) ) < 100.f ) ? 265.f: 260.0f;
return ( sqrt( (x-500.f)*(x-500.f) + (y-500.f)*(y-500.f) ) < 100.f ) ? 253.f: 250.0f;
};
virtual float endSimulation() { return (float) 15; };
......@@ -111,7 +111,7 @@ class SWE_BathymetryDamBreakScenario : public SWE_Scenario {
*/
float getWaterHeight( float i_positionX,
float i_positionY ) {
return (float) 270;
return (float) 260;
}
};
......
......@@ -4,6 +4,7 @@
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Michael Bader, Kaveh Rahnema, Tobias Schnabel
// Copyright (C) 2012 Sebastian Rettenberger
//
// SWE_CUDA is free software: you can redristribute it and/or modify
// it under the terms of the GNU General Public License as published by
......@@ -19,44 +20,15 @@
// along with SWE_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <math.h>
#include "SWE_simple_scenarios.h"
#include "SWE_VisInfo.h"
/**
* Scenario "Radial Dam Break":
* elevated water in the center of the domain
* VisInfo "Bathymetry Dam Break":
* uniform water depth, but elevated bathymetry in the center of the domain
* Set bathymetry offset hence it is visible in the screen
*/
class SWE_RadialDamBreakScenarioVisInfo
: public SWE_RadialDamBreakScenario,
public SWE_VisInfo {
virtual float waterVerticalScaling() { return 5.0f; };
/* use inherited default implementations */
class SWE_BathymetryDamBreakVisInfo : public SWE_VisInfo {
float bathyVerticalOffset() { return 2500.0f; };
};
/**
* Scenario "Splashing Pool with custom scaling":
* intial water surface has a fixed slope (diagonal to x,y)
* shows how to use custom scaling to enhance visualization
* results
*/
class SWE_SplashingPoolScenarioVisInfo
: public SWE_SplashingPoolScenario,
public SWE_VisInfo {
public:
float waterDistanceFromGround() { return 9.0f; };
float waterVerticalScaling() { return 5.0f; };
float bathyVerticalCenter() { return 0.0f; };
float bathyDistanceFromGround() { return 0.0f; };
float bathyVerticalScaling() { return 0.0f; };
virtual BoundaryType getBoundaryType(BoundaryEdge edge) { return OUTFLOW; };
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment