Commit 5c22fe66 authored by bader's avatar bader

Merge branch 'master' of https://github.com/TUM-I5/SWE

parents 99f0a72a 018806e2
...@@ -37,8 +37,8 @@ print ' Department of Informatics' ...@@ -37,8 +37,8 @@ print ' Department of Informatics'
print ' Chair of Scientific Computing' print ' Chair of Scientific Computing'
print ' http://www5.in.tum.de/SWE' print ' http://www5.in.tum.de/SWE'
print '' print ''
print 'This program comes with ABSOLUTELY NO WARRANTY.' print 'SWE comes with ABSOLUTELY NO WARRANTY.'
print 'This is free software, and you are welcome to redistribute it' print 'SWE free software, and you are welcome to redistribute it'
print 'under certain conditions.' print 'under certain conditions.'
print 'Details can be found in the file \'gpl.txt\'.' print 'Details can be found in the file \'gpl.txt\'.'
print '' print ''
...@@ -48,10 +48,16 @@ print '' ...@@ -48,10 +48,16 @@ print ''
# #
vars = Variables() vars = Variables()
# SWE specific variables # read parameters from a file if given
vars.AddVariables( vars.AddVariables(
PathVariable( 'xmlFile', 'location of the xml-file, which contains compile parameters', None, PathVariable.PathIsFile ), PathVariable( 'buildVariablesFile', 'location of the python file, which contains the build variables', None, PathVariable.PathIsFile )
)
env = Environment(variables=vars)
if 'buildVariablesFile' in env:
vars = Variables(env['buildVariablesFile'])
# SWE specific variables
vars.AddVariables(
PathVariable( 'buildDir', 'where to build the code', 'build', PathVariable.PathIsDirCreate ), PathVariable( 'buildDir', 'where to build the code', 'build', PathVariable.PathIsDirCreate ),
EnumVariable( 'compiler', 'used compiler', 'gnu', EnumVariable( 'compiler', 'used compiler', 'gnu',
...@@ -83,6 +89,8 @@ vars.AddVariables( ...@@ -83,6 +89,8 @@ vars.AddVariables(
# external variables # external variables
vars.AddVariables( vars.AddVariables(
PathVariable( 'compilerPath', 'location of the C++ compiler', None, PathVariable.PathIsFile ),
PathVariable( 'linkerPath', 'location of the C++ linker', None, PathVariable.PathIsFile ),
PathVariable( 'cudaToolkitDir', 'location of the CUDA toolkit', None ), PathVariable( 'cudaToolkitDir', 'location of the CUDA toolkit', None ),
PathVariable( 'cudaSDKDir', 'location of the CUDA SDK', None), PathVariable( 'cudaSDKDir', 'location of the CUDA SDK', None),
PathVariable( 'netCDFDir', 'location of netCDF', None), PathVariable( 'netCDFDir', 'location of netCDF', None),
...@@ -98,6 +106,12 @@ Help(vars.GenerateHelpText(env)) ...@@ -98,6 +106,12 @@ Help(vars.GenerateHelpText(env))
# handle unknown, maybe misspelled variables # handle unknown, maybe misspelled variables
unknownVariables = vars.UnknownVariables() unknownVariables = vars.UnknownVariables()
# remove the buildVariablesFile from the list of unknown variables (used before)
if 'buildVariablesFile' in unknownVariables:
unknownVariables.pop('buildVariablesFile')
# exit in the case of unknown variables
if unknownVariables: if unknownVariables:
print "*** The following build variables are unknown:", unknownVariables.keys() print "*** The following build variables are unknown:", unknownVariables.keys()
Exit(1) Exit(1)
...@@ -174,12 +188,18 @@ if env['parallelization'] in ['mpi_with_cuda']: ...@@ -174,12 +188,18 @@ if env['parallelization'] in ['mpi_with_cuda']:
# set the precompiler flags for MPI (C++) # set the precompiler flags for MPI (C++)
if env['parallelization'] in ['mpi_with_cuda', 'mpi']: if env['parallelization'] in ['mpi_with_cuda', 'mpi']:
env.Append(CPPDEFINES=['USEMPI']) env.Append(CPPDEFINES=['USEMPI'])
env['CXX'] = 'mpiCC.openmpi' if 'compilerPath' in env:
env['LINKERFORPROGRAMS'] = 'mpiCC.openmpi' env['CXX'] = env['compilerPath']
else:
env['CXX'] = 'mpiCC'
if 'linkerPath' in env:
env['LINKERFORPROGRAMS'] = env['linkerPath']
env['LINKERFORPROGRAMS'] = 'mpiCC'
# set the precompiler flags and includes for netCDF # set the precompiler flags and includes for netCDF
if env['writeNetCDF'] == True: if env['writeNetCDF'] == True:
env.Append(CPPDEFINES=['WRITENETCDF']) env.Append(CPPDEFINES=['WRITENETCDF'])
env.Append(LIBS=['netcdf','netcdf_c++'])
# set netCDF location # set netCDF location
if 'netCDFDir' in env: if 'netCDFDir' in env:
env.Append(CPPPATH=[env['netCDFDir']+'/include']) env.Append(CPPPATH=[env['netCDFDir']+'/include'])
...@@ -193,7 +213,7 @@ if env['asagi'] == True: ...@@ -193,7 +213,7 @@ if env['asagi'] == True:
env.Append(LIBS=['asagi']) env.Append(LIBS=['asagi'])
if 'asagiDir' in env: if 'asagiDir' in env:
env.Append(CPPPATH=[env['asagiDir']+'/include']) env.Append(CPPPATH=[env['asagiDir']+'/include'])
env.Append(LIBPATH=[env['asagiDir']]) env.Append(LIBPATH=[env['asagiDir']+'/lib'])
if 'netCDFDir' in env: if 'netCDFDir' in env:
env.Append(LIBPATH=[env['netCDFDir']+'/lib']) env.Append(LIBPATH=[env['netCDFDir']+'/lib'])
......
#! /usr/bin/python
# @file
# This file is part of SWE.
#
# @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
#
# @section LICENSE
#
# SWE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SWE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SWE. If not, see <http://www.gnu.org/licenses/>.
#
#
# @section DESCRIPTION
#
# Example build parameters a "gnu, cuda, asagi" setting.
#
#build options
parallelization='cuda'
computeCapability='sm_21'
solver='fwave'
asagi='yes'
# libraries (machine dependent)
cudaToolkitDir='/work/breuera/software/cuda'
cudaSDKDir='/work/breuera/workspace/NVIDIA_GPU_Computing_SDK'
asagiDir='/work/breuera/software/asagi_nompi'
netCDFDir='/home_local/breuera/software/netcdf/netcdf-4.1.3'
#! /usr/bin/python
# @file
# This file is part of SWE.
#
# @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
#
# @section LICENSE
#
# SWE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SWE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SWE. If not, see <http://www.gnu.org/licenses/>.
#
#
# @section DESCRIPTION
#
# Example build parameters a "gnu, mpi_with_cuda, asagi" setting.
#
#build options
parallelization='mpi_with_cuda'
computeCapability='sm_21'
solver='fwave'
asagi='yes'
writeNetCDF='yes'
# libraries (machine dependent)
cudaToolkitDir='/work/breuera/software/cuda'
cudaSDKDir='/work/breuera/workspace/NVIDIA_GPU_Computing_SDK'
asagiDir='/work/breuera/software/asagi_nompi'
netCDFDir='/home_local/breuera/software/netcdf/netcdf-4.1.3/'
#! /usr/bin/python
# @file
# This file is part of SWE.
#
# @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
#
# @section LICENSE
#
# SWE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SWE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SWE. If not, see <http://www.gnu.org/licenses/>.
#
#
# @section DESCRIPTION
#
# Example build parameters for the NPS GPU-cluster.
#
#build options
parallelization='mpi_with_cuda'
computeCapability='sm_20'
solver='fwave'
asagi='yes'
writeNetCDF='yes'
# libraries (machine dependent)
compilerPath='/usr/lib64/openmpi/bin/mpiCC'
linkerPath='/usr/lib64/openmpi/bin/mpiCC'
cudaSDKDir='/'
asagiDir='/home/prof2/software/asagi/mpi'
netCDFDir='/home/prof2/software/netcdf'
...@@ -57,7 +57,7 @@ sourceFiles = ['SWE_Block.cpp'] ...@@ -57,7 +57,7 @@ sourceFiles = ['SWE_Block.cpp']
# netCDF writer # netCDF writer
if env['writeNetCDF'] == True: if env['writeNetCDF'] == True:
sourceFiles.append( ['io/NetCdfWriter.cpp'] ) sourceFiles.append( ['tools/NetCdfWriter.cpp'] )
# xml reader # xml reader
if env['xmlRuntime'] == True: if env['xmlRuntime'] == True:
......
...@@ -61,7 +61,7 @@ SWE_Block::SWE_Block(float _offsetX, float _offsetY) ...@@ -61,7 +61,7 @@ SWE_Block::SWE_Block(float _offsetX, float _offsetY)
{ {
// set WALL as default boundary condition // set WALL as default boundary condition
for(int i=0; i<4;i++) { for(int i=0; i<4;i++) {
boundary[i] = WALL; boundary[i] = PASSIVE;
neighbour[i] = NULL; neighbour[i] = NULL;
}; };
...@@ -80,53 +80,44 @@ SWE_Block::~SWE_Block() { ...@@ -80,53 +80,44 @@ SWE_Block::~SWE_Block() {
//================================================================== //==================================================================
/** /**
* Initialise unknowns and bathymetry in all grid cells * Initializes the unknowns and bathymetry in all grid cells according to the given SWE_Scenario.
* according to the specified SWE_Scenario *
* Note: unknowns hu and hv represent momentum, while parameters u and v are velocities! * In the case of multiple SWE_Blocks at this point, it is not clear how the boundary conditions
* should be set. This is because an isolated SWE_Block doesn't have any in information about the grid.
* Therefore the calling routine, which has the information about multiple blocks, has to take care about setting
* the right boundary conditions.
* *
* @param i_scenario scenario, which is used during the setup.
* @param i_multipleBlocks are the multiple SWE_blocks?
*/ */
void SWE_Block::initScenario(SWE_Scenario &scene) { void SWE_Block::initScenario( SWE_Scenario &i_scenario,
const bool i_multipleBlocks ) {
// initialize water height and discharge // initialize water height and discharge
for(int i=1; i<=nx; i++) for(int i=1; i<=nx; i++)
for(int j=1; j<=ny; j++) { for(int j=1; j<=ny; j++) {
float x = offsetX + (i-0.5f)*dx; float x = offsetX + (i-0.5f)*dx;
float y = offsetY + (j-0.5f)*dy; float y = offsetY + (j-0.5f)*dy;
h[i][j] = scene.getWaterHeight(x,y); h[i][j] = i_scenario.getWaterHeight(x,y);
hu[i][j] = scene.getVeloc_u(x,y) * h[i][j]; hu[i][j] = i_scenario.getVeloc_u(x,y) * h[i][j];
hv[i][j] = scene.getVeloc_v(x,y) * h[i][j]; hv[i][j] = i_scenario.getVeloc_v(x,y) * h[i][j];
}; };
// initialise bathymetry // initialize bathymetry
for(int i=0; i<=nx+1; i++) { for(int i=0; i<=nx+1; i++) {
for(int j=0; j<=ny+1; j++) { for(int j=0; j<=ny+1; j++) {
b[i][j] = scene.getBathymetry(offsetX + (i-0.5f)*dx, b[i][j] = i_scenario.getBathymetry( offsetX + (i-0.5f)*dx,
offsetY + (j-0.5f)*dy ); offsetY + (j-0.5f)*dy );
} }
} }
// obtain boundary conditions for all four edges from scenario // in the case of multiple blocks the calling routine takes care about proper boundary conditions.
boundary[BND_LEFT] = scene.getBoundaryType(BND_LEFT); if( i_multipleBlocks == false ) {
boundary[BND_RIGHT] = scene.getBoundaryType(BND_RIGHT); // obtain boundary conditions for all four edges from scenario
boundary[BND_BOTTOM] = scene.getBoundaryType(BND_BOTTOM); setBoundaryType(BND_LEFT, i_scenario.getBoundaryType(BND_LEFT));
boundary[BND_TOP] = scene.getBoundaryType(BND_TOP); setBoundaryType(BND_RIGHT, i_scenario.getBoundaryType(BND_RIGHT));
setBoundaryType(BND_BOTTOM, i_scenario.getBoundaryType(BND_BOTTOM));
// set bathymetry values in the ghost layer, if necessary setBoundaryType(BND_TOP, i_scenario.getBoundaryType(BND_TOP));
for(int j=0; j<=ny+1; j++) {
if( boundary[BND_LEFT] == OUTFLOW || boundary[BND_LEFT] == WALL ) {
b[0][j] = b[1][j];
}
if( boundary[BND_RIGHT] == OUTFLOW || boundary[BND_RIGHT] == WALL ) {
b[nx+1][j] = b[nx][j];
}
}
for(int i=0; i<=nx+1; i++) {
if( boundary[BND_BOTTOM] == OUTFLOW || boundary[BND_BOTTOM] == WALL ) {
b[i][0] = b[i][1];
}
if( boundary[BND_TOP] == OUTFLOW || boundary[BND_TOP] == WALL ) {
b[i][ny+1] = b[i][ny];
}
} }
// perform update after external write to variables // perform update after external write to variables
...@@ -339,16 +330,38 @@ void SWE_Block::setOutflowBoundaries() { ...@@ -339,16 +330,38 @@ void SWE_Block::setOutflowBoundaries() {
} }
/** /**
* set boundary type for a specific block boundary * Set the boundary type for specific block boundary.
* @param edge specifies boundary (LEFT, RIGHT, BOTTOM, TOP) *
* @param boundtype type of boundary condition * @param i_edge location of the edge relative to the SWE_block.
* @param inflow pointer to an SWE_block1D that specifies * @param i_boundaryType type of the boundary condition.
* inflow (should be NULL for WALL or OUTFLOW boundary) * @param i_inflow pointer to an SWE_Block1D, which specifies the inflow (should be NULL for WALL or OUTFLOW boundary)
*/ */
void SWE_Block::setBoundaryType(BoundaryEdge edge, BoundaryType boundtype, void SWE_Block::setBoundaryType( const BoundaryEdge i_edge,
const SWE_Block1D* inflow) { const BoundaryType i_boundaryType,
boundary[edge] = boundtype; const SWE_Block1D* i_inflow) {
neighbour[edge] = inflow; boundary[i_edge] = i_boundaryType;
neighbour[i_edge] = i_inflow;
// set bathymetry values in the ghost layer, if necessary
for(int j=0; j<=ny+1; j++) {
if( boundary[BND_LEFT] == OUTFLOW || boundary[BND_LEFT] == WALL ) {
b[0][j] = b[1][j];
}
if( boundary[BND_RIGHT] == OUTFLOW || boundary[BND_RIGHT] == WALL ) {
b[nx+1][j] = b[nx][j];
}
}
for(int i=0; i<=nx+1; i++) {
if( boundary[BND_BOTTOM] == OUTFLOW || boundary[BND_BOTTOM] == WALL ) {
b[i][0] = b[i][1];
}
if( boundary[BND_TOP] == OUTFLOW || boundary[BND_TOP] == WALL ) {
b[i][ny+1] = b[i][ny];
}
}
// synchronize after an external update of the bathymetry
synchBathymetryAfterWrite();
} }
// /** // /**
...@@ -529,7 +542,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -529,7 +542,6 @@ void SWE_Block::setBoundaryConditions() {
h[0][j] = h[1][j]; h[0][j] = h[1][j];
hu[0][j] = -hu[1][j]; hu[0][j] = -hu[1][j];
hv[0][j] = hv[1][j]; hv[0][j] = hv[1][j];
b[0][j] = b[1][j];
}; };
break; break;
} }
...@@ -539,7 +551,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -539,7 +551,6 @@ void SWE_Block::setBoundaryConditions() {
h[0][j] = h[1][j]; h[0][j] = h[1][j];
hu[0][j] = hu[1][j]; hu[0][j] = hu[1][j];
hv[0][j] = hv[1][j]; hv[0][j] = hv[1][j];
b[0][j] = b[1][j];
}; };
break; break;
} }
...@@ -559,7 +570,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -559,7 +570,6 @@ void SWE_Block::setBoundaryConditions() {
h[nx+1][j] = h[nx][j]; h[nx+1][j] = h[nx][j];
hu[nx+1][j] = -hu[nx][j]; hu[nx+1][j] = -hu[nx][j];
hv[nx+1][j] = hv[nx][j]; hv[nx+1][j] = hv[nx][j];
b[nx+1][j] = b[nx][j];
}; };
break; break;
} }
...@@ -569,7 +579,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -569,7 +579,6 @@ void SWE_Block::setBoundaryConditions() {
h[nx+1][j] = h[nx][j]; h[nx+1][j] = h[nx][j];
hu[nx+1][j] = hu[nx][j]; hu[nx+1][j] = hu[nx][j];
hv[nx+1][j] = hv[nx][j]; hv[nx+1][j] = hv[nx][j];
b[nx+1][j] = b[nx][j];
}; };
break; break;
} }
...@@ -589,7 +598,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -589,7 +598,6 @@ void SWE_Block::setBoundaryConditions() {
h[i][0] = h[i][1]; h[i][0] = h[i][1];
hu[i][0] = hu[i][1]; hu[i][0] = hu[i][1];
hv[i][0] = -hv[i][1]; hv[i][0] = -hv[i][1];
b[i][0] = b[i][1];
}; };
break; break;
} }
...@@ -599,7 +607,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -599,7 +607,6 @@ void SWE_Block::setBoundaryConditions() {
h[i][0] = h[i][1]; h[i][0] = h[i][1];
hu[i][0] = hu[i][1]; hu[i][0] = hu[i][1];
hv[i][0] = hv[i][1]; hv[i][0] = hv[i][1];
b[i][0] = b[i][1];
}; };
break; break;
} }
...@@ -619,7 +626,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -619,7 +626,6 @@ void SWE_Block::setBoundaryConditions() {
h[i][ny+1] = h[i][ny]; h[i][ny+1] = h[i][ny];
hu[i][ny+1] = hu[i][ny]; hu[i][ny+1] = hu[i][ny];
hv[i][ny+1] = -hv[i][ny]; hv[i][ny+1] = -hv[i][ny];
b[i][ny+1] = b[i][ny];
}; };
break; break;
} }
...@@ -629,7 +635,6 @@ void SWE_Block::setBoundaryConditions() { ...@@ -629,7 +635,6 @@ void SWE_Block::setBoundaryConditions() {
h[i][ny+1] = h[i][ny]; h[i][ny+1] = h[i][ny];
hu[i][ny+1] = hu[i][ny]; hu[i][ny+1] = hu[i][ny];
hv[i][ny+1] = hv[i][ny]; hv[i][ny+1] = hv[i][ny];
b[i][ny+1] = b[i][ny];
}; };
break; break;
} }
......
...@@ -118,7 +118,7 @@ class SWE_Block { ...@@ -118,7 +118,7 @@ class SWE_Block {
public: public:
// object methods // object methods
/// initialise unknowns to a specific scenario: /// initialise unknowns to a specific scenario:
void initScenario(SWE_Scenario &scene); void initScenario(SWE_Scenario &i_scenario, const bool i_multipleBlocks = false );
// set unknowns // set unknowns
/// set the water height to a uniform value /// set the water height to a uniform value
void setWaterHeight(float _h); void setWaterHeight(float _h);
......
...@@ -23,21 +23,34 @@ ...@@ -23,21 +23,34 @@
* *
* @section DESCRIPTION * @section DESCRIPTION
* *
* Very basic setting of SWE, which uses a wave propagation solver and an artificial scenario on a single block. * Setting of SWE, which uses a wave propagation solver and an artificial or ASAGI scenario on multiple blocks.
*/ */
#include <mpi.h> #include <mpi.h>
#include "../tools/help.hh" #include <cassert>
#include <cmath>
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include "../tools/help.hh"
#include "../SWE_Block.hh" #include "../SWE_Block.hh"
#ifndef CUDA #ifndef CUDA
#include "../SWE_WavePropagationBlock.hh" #include "../SWE_WavePropagationBlock.hh"
#else #else
#include "../SWE_WavePropagationBlockCuda.hh" #include "../SWE_WavePropagationBlockCuda.hh"
#endif #endif
#ifdef WRITENETCDF
#include "../tools/NetCdfWriter.hh"
#endif
#ifdef ASAGI
#include "../scenarios/SWE_AsagiScenario.hpp"
#else
#include "../scenarios/SWE_simple_scenarios.h" #include "../scenarios/SWE_simple_scenarios.h"
#endif
#ifdef READXML #ifdef READXML
#include "../tools/CXMLConfig.hpp" #include "../tools/CXMLConfig.hpp"
...@@ -136,6 +149,7 @@ int main( int argc, char** argv ) { ...@@ -136,6 +149,7 @@ int main( int argc, char** argv ) {
// read xml file // read xml file
#ifdef READXML #ifdef READXML
assert(false); //TODO: not implemented.
if(argc != 2) { if(argc != 2) {
l_sweLogger.printString("Aborting. Please provide a proper input file."); l_sweLogger.printString("Aborting. Please provide a proper input file.");
l_sweLogger.printString("Example: ./SWE_gnu_debug_none_augrie config.xml"); l_sweLogger.printString("Example: ./SWE_gnu_debug_none_augrie config.xml");
...@@ -169,8 +183,34 @@ int main( int argc, char** argv ) { ...@@ -169,8 +183,34 @@ int main( int argc, char** argv ) {
l_blockPositionX = l_mpiRank / l_blocksY; l_blockPositionX = l_mpiRank / l_blocksY;
l_blockPositionY = l_mpiRank % l_blocksY; l_blockPositionY = l_mpiRank % l_blocksY;
#ifdef ASAGI
/*
* Pixel node registration used [Cartesian grid]
* Grid file format: nf = GMT netCDF format (float) (COARDS-compliant)
* x_min: -500000 x_max: 6500000 x_inc: 500 name: x nx: 14000
* y_min: -2500000 y_max: 1500000 y_inc: 500 name: y ny: 8000
* z_min: -6.48760175705 z_max: 16.1780223846 name: z
* scale_factor: 1 add_offset: 0
* mean: 0.00217145586762 stdev: 0.245563641735 rms: 0.245573241263
*/
//simulation area
float simulationArea[4];
simulationArea[0] = -450000;
simulationArea[1] = 6450000;
simulationArea[2] = -2450000;
simulationArea[3] = 1450000;
// scenarios::Asagi scene( "/naslx/ptmp/2/di56dok/data/tohoku_gebco_ucsb3_500m_hawaii_bath.nc",
// "/naslx/ptmp/2/di56dok/data/tohoku_gebco_ucsb3_500m_hawaii_displ.nc",
// (float) 300., simulationArea);
SWE_AsagiScenario l_scenario( "/work/breuera/workspace/geo_information/output/tohoku_gebco_ucsb3_500m_hawaii_bath.nc",
"/work/breuera/workspace/geo_information/output/tohoku_gebco_ucsb3_500m_hawaii_displ.nc",
(float) 14400., simulationArea, true);
#else
// create a simple artificial scenario // create a simple artificial scenario
SWE_BathymetryDamBreakScenario l_scenario; SWE_BathymetryDamBreakScenario l_scenario;
#endif
//! number of checkpoints for visualization (at each checkpoint in time, an output file is written). //! number of checkpoints for visualization (at each checkpoint in time, an output file is written).
int l_numberOfCheckPoints = 40; int l_numberOfCheckPoints = 40;
...@@ -218,7 +258,7 @@ int main( int argc, char** argv ) { ...@@ -218,7 +258,7 @@ int main( int argc, char** argv ) {
#endif #endif
// initialize the wave propgation block // initialize the wave propgation block
l_wavePropgationBlock.initScenario(l_scenario); l_wavePropgationBlock.initScenario( l_scenario, true );
//! time when the simulation ends. //! time when the simulation ends.
float l_endSimulation = l_scenario.endSimulation(); float l_endSimulation = l_scenario.endSimulation();
...@@ -330,8 +370,27 @@ int main( int argc, char** argv ) { ...@@ -330,8 +370,27 @@ int main( int argc, char** argv ) {
// write the output at time zero // write the output at time zero
l_sweLogger.printOutputTime(0); l_sweLogger.printOutputTime(0);
#ifdef WRITENETCDF
//boundary size of the ghost layers
int l_boundarySize[4];
l_boundarySize[0] = l_boundarySize[1] = l_boundarySize[2] = l_boundarySize[3] = 1;
//construct a NetCdfWriter
std::string l_fileName = generateFileName(l_baseName,l_blockPositionX,l_blockPositionY);
io::NetCdfWriter l_netCdfWriter( l_fileName, l_nXLocal, l_nYLocal );
//create the netCDF-file
l_netCdfWriter.createNetCdfFile( l_dX, l_dY,
l_originX, l_originY );
l_netCdfWriter.writeBathymetry( l_wavePropgationBlock.getBathymetry(),
l_boundarySize );
l_netCdfWriter.writeUnknowns( l_wavePropgationBlock.getWaterHeight(),
l_wavePropgationBlock.getDischarge_hu(),
l_wavePropgationBlock.getDischarge_hv(),
l_boundarySize, (float) 0.);
#else
l_wavePropgationBlock.writeVTKFileXML( generateFileName(l_baseName,0,l_blockPositionX,l_blockPositionY), l_wavePropgationBlock.writeVTKFileXML( generateFileName(l_baseName,0,l_blockPositionX,l_blockPositionY),
l_nXLocal*l_blockPositionX, l_nYLocal*l_blockPositionY); l_nXLocal*l_blockPositionX, l_nYLocal*l_blockPositionY);
#endif
/** /**
...@@ -352,7 +411,6 @@ int main( int argc, char** argv ) { ...@@ -352,7 +411,6 @@ int main( int argc, char** argv ) {
// do time steps until next checkpoint is reached // do time steps until next checkpoint is reached
while( l_t < l_checkPoints[c] ) { while( l_t < l_checkPoints[c] ) {
// exchange ghost and copy layers // exchange ghost and copy layers
l_sweLogger.printString("Exchanging ghost and copy layers.");
exchangeLeftRightGhostLayers( l_leftNeighborRank, l_leftInflow, l_leftOutflow, exchangeLeftRightGhostLayers( l_leftNeighborRank, l_leftInflow, l_leftOutflow,
l_rightNeighborRank, l_rightInflow, l_rightOutflow, l_rightNeighborRank, l_rightInflow, l_rightOutflow,
l_mpiCol ); l_mpiCol );
...@@ -364,7 +422,7 @@ int main( int argc, char** argv ) { ...@@ -364,7 +422,7 @@ int main( int argc, char** argv ) {
// reset the cpu clock // reset the cpu clock
l_sweLogger.resetCpuClockToCurrentTime(); l_sweLogger.resetCpuClockToCurrentTime();
// set values in ghost cells: // set values in ghost cells
l_wavePropgationBlock.setGhostLayer(); l_wavePropgationBlock.setGhostLayer();
// compute numerical flux on each edge // compute numerical flux on each edge
...@@ -396,9 +454,16 @@ int main( int argc, char** argv ) { ...@@ -396,9 +454,16 @@ int main( int argc, char** argv ) {
// print current simulation time // print current simulation time
l_sweLogger.printOutputTime(l_t); l_sweLogger.printOutputTime(l_t);
// write vtk output // write output
#ifdef WRITENETCDF
l_netCdfWriter.writeUnknowns( l_wavePropgationBlock.getWaterHeight(),
l_wavePropgationBlock.getDischarge_hu(),
l_wavePropgationBlock.getDischarge_hv(),
l_boundarySize, l_t);
#else
l_wavePropgationBlock.writeVTKFileXML( generateFileName(l_baseName,c,l_blockPositionX,l_blockPositionY), l_wavePropgationBlock.writeVTKFileXML( generateFileName(l_baseName,c,l_blockPositionX,l_blockPositionY),
l_blockPositionX*l_nXLocal, l_blockPositionY*l_nYLocal); l_blockPositionX*l_nXLocal, l_blockPositionY*l_nYLocal);
#endif
} }
/** /**
......
...@@ -23,21 +23,35 @@ ...@@ -23,21 +23,35 @@
* *
* @section DESCRIPTION * @section DESCRIPTION
* *
* Very basic setting of SWE, which uses a wave propagation solver and an artificial scenario on a single block. * Basic setting of SWE, which uses a wave propagation solver and an artificial or ASAGI scenario on a single block.
*/ */
#include "../tools/help.hh" #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include "../tools/help.hh"
#include "../SWE_Block.hh" #include "../SWE_Block.hh"
#ifndef CUDA #ifndef CUDA
#include "../SWE_WavePropagationBlock.hh" #include "../SWE_WavePropagationBlock.hh"
#else #else
#include "../SWE_WavePropagationBlockCuda.hh" #include "../SWE_WavePropagationBlockCuda.hh"
#endif #endif
#ifdef WRITENETCDF
#include "../tools/NetCdfWriter.hh"
#endif
#ifdef ASAGI
#include "../scenarios/SWE_AsagiScenario.hpp"
#else
#include "../scenarios/SWE_simple_scenarios.h" #include "../scenarios/SWE_simple_scenarios.h"
#include "../tools/Logger.hpp" #endif
#ifdef READXML
#include "../tools/CXMLConfig.hpp"
#endif
#ifndef STATICLOGGER #ifndef STATICLOGGER
#define STATICLOGGER #define STATICLOGGER
...@@ -53,12 +67,14 @@ int main( int argc, char** argv ) { ...@@ -53,12 +67,14 @@ int main( int argc, char** argv ) {
* Initialization. * Initialization.
*/ */
// check if the necessary command line input parameters are given // check if the necessary command line input parameters are given
#ifndef READXML
if(argc != 4) { if(argc != 4) {
std::cout << "Aborting ... please provide proper input parameters." << std::endl std::cout << "Aborting ... please provide proper input parameters." << std::endl
<< "Example: ./SWE_parallel 200 300 /work/openmp_out" << std::endl << "Example: ./SWE_parallel 200 300 /work/openmp_out" << std::endl
<< "\tfor a single block of size 200 * 300" << std::endl; << "\tfor a single block of size 200 * 300" << std::endl;
return 1; return 1;
} }
#endif
//! number of grid cells in x- and y-direction. //! number of grid cells in x- and y-direction.
int l_nX, l_nY; int l_nX, l_nY;
...@@ -67,15 +83,58 @@ int main( int argc, char** argv ) { ...@@ -67,15 +83,58 @@ int main( int argc, char** argv ) {
std::string l_baseName; std::string l_baseName;
// read command line parameters // read command line parameters
#ifndef READXML
l_nY = l_nX = atoi(argv[1]); l_nY = l_nX = atoi(argv[1]);
l_nY = atoi(argv[2]); l_nY = atoi(argv[2]);
l_baseName = std::string(argv[3]); l_baseName = std::string(argv[3]);
#endif
//create a simple artificial scenario // read xml file
#ifdef READXML
assert(false); //TODO: not implemented.
if(argc != 2) {
s_sweLogger.printString("Aborting. Please provide a proper input file.");
s_sweLogger.printString("Example: ./SWE_gnu_debug_none_augrie config.xml");
return 1;
}
s_sweLogger.printString("Reading xml-file.");
std::string l_xmlFile = std::string(argv[1]);
s_sweLogger.printString(l_xmlFile);
CXMLConfig l_xmlConfig;
l_xmlConfig.loadConfig(l_xmlFile.c_str());
#endif
#ifdef ASAGI
/* Information about the example bathymetry grid (tohoku_gebco_ucsb3_500m_hawaii_bath.nc):
*
* Pixel node registration used [Cartesian grid]
* Grid file format: nf = GMT netCDF format (float) (COARDS-compliant)
* x_min: -500000 x_max: 6500000 x_inc: 500 name: x nx: 14000
* y_min: -2500000 y_max: 1500000 y_inc: 500 name: y ny: 8000
* z_min: -6.48760175705 z_max: 16.1780223846 name: z
* scale_factor: 1 add_offset: 0
* mean: 0.00217145586762 stdev: 0.245563641735 rms: 0.245573241263
*/
//simulation area
float simulationArea[4];
simulationArea[0] = -450000;
simulationArea[1] = 6450000;
simulationArea[2] = -2450000;
simulationArea[3] = 1450000;
SWE_AsagiScenario l_scenario( "/work/breuera/workspace/geo_information/output/tohoku_gebco_ucsb3_500m_hawaii_bath.nc",
"/work/breuera/workspace/geo_information/output/tohoku_gebco_ucsb3_500m_hawaii_displ.nc",
(float) 28800., simulationArea, true);
#else
// create a simple artificial scenario
SWE_BathymetryDamBreakScenario l_scenario; SWE_BathymetryDamBreakScenario l_scenario;
#endif
//! number of checkpoints for visualization (at each checkpoint in time, an output file is written). //! number of checkpoints for visualization (at each checkpoint in time, an output file is written).
int l_numberOfCheckPoints = 40; int l_numberOfCheckPoints = 20;
//! size of a single cell in x- and y-direction //! size of a single cell in x- and y-direction
float l_dX, l_dY; float l_dX, l_dY;
...@@ -116,8 +175,27 @@ int main( int argc, char** argv ) { ...@@ -116,8 +175,27 @@ int main( int argc, char** argv ) {
l_checkPoints[cp] = cp*(l_endSimulation/l_numberOfCheckPoints); l_checkPoints[cp] = cp*(l_endSimulation/l_numberOfCheckPoints);
} }
// write the output at time zero // write the output at time zero
s_sweLogger.printOutputTime((float) 0.);
#ifdef WRITENETCDF
//boundary size of the ghost layers
int l_boundarySize[4];
l_boundarySize[0] = l_boundarySize[1] = l_boundarySize[2] = l_boundarySize[3] = 1;
//construct a NetCdfWriter
std::string l_fileName = l_baseName;
io::NetCdfWriter l_netCdfWriter( l_fileName, l_nX, l_nY );
//create the netCDF-file
l_netCdfWriter.createNetCdfFile(l_dX, l_dY, l_originX, l_originY);
l_netCdfWriter.writeBathymetry(l_wavePropgationBlock.getBathymetry(), l_boundarySize);
l_netCdfWriter.writeUnknowns( l_wavePropgationBlock.getWaterHeight(),
l_wavePropgationBlock.getDischarge_hu(),
l_wavePropgationBlock.getDischarge_hv(),
l_boundarySize, (float) 0.);
#else
l_wavePropgationBlock.writeVTKFileXML(generateFileName(l_baseName,0,0,0), l_nX, l_nY); l_wavePropgationBlock.writeVTKFileXML(generateFileName(l_baseName,0,0,0), l_nX, l_nY);
#endif
/** /**
...@@ -159,11 +237,18 @@ int main( int argc, char** argv ) { ...@@ -159,11 +237,18 @@ int main( int argc, char** argv ) {
// update the cpu time in the logger // update the cpu time in the logger
s_sweLogger.updateCpuTime(); s_sweLogger.updateCpuTime();
// print current simulation time // print current simulation time of the output
s_sweLogger.printOutputTime(l_t); s_sweLogger.printOutputTime(l_t);
// write vtk output // write output
#ifdef WRITENETCDF
l_netCdfWriter.writeUnknowns( l_wavePropgationBlock.getWaterHeight(),
l_wavePropgationBlock.getDischarge_hu(),
l_wavePropgationBlock.getDischarge_hv(),
l_boundarySize, l_t);
#else
l_wavePropgationBlock.writeVTKFileXML(generateFileName(l_baseName,c,0,0), l_nX, l_nY); l_wavePropgationBlock.writeVTKFileXML(generateFileName(l_baseName,c,0,0), l_nX, l_nY);
#endif
} }
/** /**
...@@ -173,7 +258,7 @@ int main( int argc, char** argv ) { ...@@ -173,7 +258,7 @@ int main( int argc, char** argv ) {
s_sweLogger.printStatisticsMessage(); s_sweLogger.printStatisticsMessage();
// print the cpu time // print the cpu time
s_sweLogger.printCpuTime("CPU/GPU time"); s_sweLogger.printCpuTime();
// print the wall clock time (includes plotting) // print the wall clock time (includes plotting)
s_sweLogger.printWallClockTime(time(NULL)); s_sweLogger.printWallClockTime(time(NULL));
......
...@@ -25,19 +25,15 @@ ...@@ -25,19 +25,15 @@
* Access to bathymetry and displacement files with ASAGI. * Access to bathymetry and displacement files with ASAGI.
*/ */
#ifndef ASAGI_HPP_ #ifndef SWEASAGISCENARIO_HPP_
#define ASAGI_HPP_ #define SWEASAGISCENARIO_HPP_
#include <cassert> #include <cassert>
#include <string> #include <string>
#include <asagi.h> #include <asagi.h>
#include "SWE_Scenario.h" #include "SWE_Scenario.h"
namespace scenarios { class SWE_AsagiScenario: public SWE_Scenario {
class Asagi;
}
class scenarios::Asagi: public SWE_Scenario {
//private: //private:
//! pointer to the Asagi bathymetry grid //! pointer to the Asagi bathymetry grid
asagi::Grid* bathymetryGrid; asagi::Grid* bathymetryGrid;
...@@ -75,17 +71,17 @@ class scenarios::Asagi: public SWE_Scenario { ...@@ -75,17 +71,17 @@ class scenarios::Asagi: public SWE_Scenario {
* @param i_displacementFile path to the netCDF-displacement file * @param i_displacementFile path to the netCDF-displacement file
* @param i_duration time the simulation runs (in seconds) * @param i_duration time the simulation runs (in seconds)
*/ */
Asagi ( const std::string i_bathymetryFile, SWE_AsagiScenario ( const std::string i_bathymetryFile,
const std::string i_displacementFile, const std::string i_displacementFile,
const float i_duration, const float i_duration,
const float i_simulationArea[4], const float i_simulationArea[4],
const bool i_dynamicDisplacement = false ): const bool i_dynamicDisplacement = false ):
dynamicDisplacement(i_dynamicDisplacement), dynamicDisplacement(i_dynamicDisplacement),
duration(i_duration) { duration(i_duration) {
//create the bathymetry grid //create the bathymetry grid
bathymetryGrid = asagi::Grid::create( asagi::Grid::FLOAT ); bathymetryGrid = asagi::Grid::create( asagi::Grid::FLOAT );
//create the displacement grid //create the displacement grid
displacementGrid = asagi::Grid::create( asagi::Grid::FLOAT ); displacementGrid = asagi::Grid::create( asagi::Grid::FLOAT );
int l_asagiOpen = bathymetryGrid->open(i_bathymetryFile.c_str()); int l_asagiOpen = bathymetryGrid->open(i_bathymetryFile.c_str());
//open the bathymetry grid //open the bathymetry grid
...@@ -154,7 +150,7 @@ class scenarios::Asagi: public SWE_Scenario { ...@@ -154,7 +150,7 @@ class scenarios::Asagi: public SWE_Scenario {
} }
virtual ~Asagi() { virtual ~SWE_AsagiScenario() {
} }
void deleteGrids() { void deleteGrids() {
...@@ -287,4 +283,4 @@ class scenarios::Asagi: public SWE_Scenario { ...@@ -287,4 +283,4 @@ class scenarios::Asagi: public SWE_Scenario {
}; };
}; };
#endif /* ASAGI_HPP_ */ #endif /* SWEASAGISCENARIO_HPP_ */
...@@ -72,6 +72,9 @@ class tools::Logger { ...@@ -72,6 +72,9 @@ class tools::Logger {
//! definition of the welcome message //! definition of the welcome message
const std::string welcomeMessage; const std::string welcomeMessage;
//! definition of the copyrights
const std::string copyRights;
//! definition of the finish message //! definition of the finish message
const std::string finishMessage; const std::string finishMessage;
...@@ -150,15 +153,26 @@ class tools::Logger { ...@@ -150,15 +153,26 @@ class tools::Logger {
* @param i_indentation definition of the indentation (used in all messages, except welcome, start and finish). * @param i_indentation definition of the indentation (used in all messages, except welcome, start and finish).
*/ */
Logger( const int i_processRank = 0, Logger( const int i_processRank = 0,
const std::string i_programName = "SWE teaching code", const std::string i_programName = "SWE",
const std::string i_welcomeMessage = "Welcome to the", const std::string i_welcomeMessage = "Welcome to",
const std::string i_copyRights = "\n\nSWE Copyright (C) 2012\n"
" Technische Universitaet Muenchen\n"
" Department of Informatics\n"
" Chair of Scientific Computing\n"
" http://www5.in.tum.de/SWE\n"
"\n"
"SWE comes with ABSOLUTELY NO WARRANTY.\n"
"SWE is free software, and you are welcome to redistribute it\n"
"under certain conditions.\n"
"Details can be found in the file \'gpl.txt\'.",
const std::string i_finishMessage = "finished successfully.", const std::string i_finishMessage = "finished successfully.",
const std::string i_midDelimiter = "\n------------------------------------------------------------------\n", const std::string i_midDelimiter = "\n------------------------------------------------------------------\n",
const std::string i_largeDelimiter = "\n****************************************\n", const std::string i_largeDelimiter = "\n*************************************************************\n",
const std::string i_indentation = "\t" ): const std::string i_indentation = "\t" ):
processRank(i_processRank), processRank(i_processRank),
programName(i_programName), programName(i_programName),
welcomeMessage(i_welcomeMessage), welcomeMessage(i_welcomeMessage),
copyRights(i_copyRights),
finishMessage(i_finishMessage), finishMessage(i_finishMessage),
midDelimiter(i_midDelimiter), midDelimiter(i_midDelimiter),
largeDelimiter(i_largeDelimiter), largeDelimiter(i_largeDelimiter),
...@@ -190,6 +204,7 @@ class tools::Logger { ...@@ -190,6 +204,7 @@ class tools::Logger {
std::cout << largeDelimiter std::cout << largeDelimiter
<< welcomeMessage << " " << welcomeMessage << " "
<< programName << programName
<< copyRights
<< largeDelimiter; << largeDelimiter;
} }
} }
......
...@@ -151,6 +151,25 @@ inline std::string generateFileName(std::string baseName, int timeStep) { ...@@ -151,6 +151,25 @@ inline std::string generateFileName(std::string baseName, int timeStep) {
return FileName.str(); return FileName.str();
}; };
/**
* Generates an output file name for a multiple SWE_Block version based on the ordering of the blocks.
*
* @param i_baseName base name of the output.
* @param i_blockPositionX position of the SWE_Block in x-direction.
* @param i_blockPositionY position of the SWE_Block in y-direction.
* @param i_fileExtension file extension of the output file.
* @return
*/
inline std::string generateFileName( std::string i_baseName,
int i_blockPositionX, int i_blockPositionY,
std::string i_fileExtension=".nc" ) {
std::ostringstream l_fileName;
l_fileName << i_baseName << "_" << i_blockPositionX << i_blockPositionY << i_fileExtension;
return l_fileName.str();
};
/** /**
* generate output filename for the multiple-SWE_Block version * generate output filename for the multiple-SWE_Block version
* (for serial and parallel (OpenMP and MPI) versions that use * (for serial and parallel (OpenMP and MPI) versions that use
......
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