Commit f3ce970e authored by jannick.wolters's avatar jannick.wolters
Browse files

closed #22 by adding tests for mesh class; updated #24 by adding tests for...

closed #22 by adding tests for mesh class; updated #24 by adding tests for academic lattice/checkboard testcases
parent d5ad7d35
......@@ -126,6 +126,7 @@ set( CORE_LIBRARIES ${LAPACK_LIBRARIES} ${MPI_LIBRARIES} ${VTK_LIBRARIES} parmet
target_link_libraries( ${CMAKE_PROJECT_NAME} ${CORE_LIBRARIES} )
if( BUILD_TESTING )
add_compile_definitions( BUILD_TESTING=1 )
add_subdirectory( ${CMAKE_SOURCE_DIR}/ext/Catch2 )
include_directories( ${CMAKE_SOURCE_DIR}/ext/Catch2/single_include/catch2 )
file( GLOB_RECURSE TEST_SRCS RELATIVE ${CMAKE_SOURCE_DIR} "tests/*.cpp" )
......
unsigned int Factorial( unsigned int number );
......@@ -19,7 +19,6 @@
#include <vtkSmartPointer.h>
#include <vtkTriangle.h>
#include <vtkUnstructuredGrid.h>
#include <vtkUnstructuredGridReader.h>
#include <vtkUnstructuredGridWriter.h>
#include "mesh.h"
......@@ -31,7 +30,6 @@ using vtkTriangleSP = vtkSmartPointer<vtkTriangle>;
using vtkCellArraySP = vtkSmartPointer<vtkCellArray>;
using vtkDoubleArraySP = vtkSmartPointer<vtkDoubleArray>;
using vtkUnstructuredGridWriterSP = vtkSmartPointer<vtkUnstructuredGridWriter>;
using vtkUnstructuredGridReaderSP = vtkSmartPointer<vtkUnstructuredGridReader>;
using vtkCellDataToPointDataSP = vtkSmartPointer<vtkCellDataToPointData>;
using vtkPointDataToCellDataSP = vtkSmartPointer<vtkPointDataToCellData>;
......
#include "factorialexample.h"
unsigned int Factorial( unsigned int number ) { return number > 1 ? Factorial( number - 1 ) * number : 1; }
......@@ -70,30 +70,6 @@ void ExportVTK( const std::string fileName,
cellData->InsertNextValue( results[i][0][j] );
}
break;
case 2:
cellData = vtkDoubleArraySP::New();
cellData->SetName( "E(ρU)" );
cellData->SetNumberOfComponents( 3 );
cellData->SetComponentName( 0, "x" );
cellData->SetComponentName( 1, "y" );
cellData->SetComponentName( 2, "z" );
cellData->SetNumberOfTuples( numCells );
for( unsigned j = 0; j < numCells; j++ ) {
cellData->SetTuple3( i, results[i][0][j], results[i][1][j], 0.0 );
}
break;
case 3:
cellData = vtkDoubleArraySP::New();
cellData->SetName( "E(ρU)" );
cellData->SetNumberOfComponents( 3 );
cellData->SetComponentName( 0, "x" );
cellData->SetComponentName( 1, "y" );
cellData->SetComponentName( 2, "z" );
cellData->SetNumberOfTuples( numCells );
for( unsigned j = 0; j < numCells; j++ ) {
cellData->SetTuple3( i, results[i][0][j], results[i][1][j], results[i][2][j] );
}
break;
default:
auto log = spdlog::get( "event" );
log->error( "[ERROR][IO::ExportVTK] Invalid dimension" );
......
......@@ -165,7 +165,7 @@ void Mesh::ComputeCellMidpoints() {
for( unsigned l = 0; l < _cells[j].size(); ++l ) {
_cellMidPoints[j] = _cellMidPoints[j] + _nodes[_cells[j][l]];
}
_cellMidPoints[j] = _cellMidPoints[j] / double( _cells[j].size() );
_cellMidPoints[j] = _cellMidPoints[j] / static_cast<double>( _cells[j].size() );
}
}
......
......@@ -312,8 +312,12 @@ void Config::SetPostprocessing() {
// create directories if they dont exist
if( !std::filesystem::exists( _outputDir ) ) std::filesystem::create_directory( _outputDir );
// init logger
// init logger
#ifdef BUILD_TESTING
InitLogger( spdlog::level::off, spdlog::level::off );
#else
InitLogger( spdlog::level::info, spdlog::level::info );
#endif
// Check if there are contradictive or false options set.
......@@ -491,55 +495,57 @@ void Config::InitLogger( spdlog::level::level_enum terminalLogLvl, spdlog::level
std::filesystem::create_directory( _logDir );
}
// create sinks if level is not off
std::vector<spdlog::sink_ptr> sinks;
if( terminalLogLvl != spdlog::level::off ) {
// create spdlog terminal sink
auto terminalSink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
terminalSink->set_level( terminalLogLvl );
terminalSink->set_pattern( "%v" );
sinks.push_back( terminalSink );
}
if( fileLogLvl != spdlog::level::off ) {
// define filename on root
int pe;
MPI_Comm_rank( MPI_COMM_WORLD, &pe );
char cfilename[1024];
if( pe == 0 ) {
// get date and time
time_t now = time( nullptr );
struct tm tstruct;
char buf[80];
tstruct = *localtime( &now );
strftime( buf, sizeof( buf ), "%Y-%m-%d_%X", &tstruct );
// set filename to date and time
std::string filename = buf;
// in case of existing files append '_#'
int ctr = 0;
if( std::filesystem::exists( _logDir + filename ) ) {
filename += "_" + std::to_string( ++ctr );
}
while( std::filesystem::exists( _logDir + filename ) ) {
filename.pop_back();
filename += std::to_string( ++ctr );
if( spdlog::get( "event" ) == nullptr ) {
// create sinks if level is not off
std::vector<spdlog::sink_ptr> sinks;
if( terminalLogLvl != spdlog::level::off ) {
// create spdlog terminal sink
auto terminalSink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
terminalSink->set_level( terminalLogLvl );
terminalSink->set_pattern( "%v" );
sinks.push_back( terminalSink );
}
if( fileLogLvl != spdlog::level::off ) {
// define filename on root
int pe;
MPI_Comm_rank( MPI_COMM_WORLD, &pe );
char cfilename[1024];
if( pe == 0 ) {
// get date and time
time_t now = time( nullptr );
struct tm tstruct;
char buf[80];
tstruct = *localtime( &now );
strftime( buf, sizeof( buf ), "%Y-%m-%d_%X", &tstruct );
// set filename to date and time
std::string filename = buf;
// in case of existing files append '_#'
int ctr = 0;
if( std::filesystem::exists( _logDir + filename ) ) {
filename += "_" + std::to_string( ++ctr );
}
while( std::filesystem::exists( _logDir + filename ) ) {
filename.pop_back();
filename += std::to_string( ++ctr );
}
strncpy( cfilename, filename.c_str(), sizeof( cfilename ) );
cfilename[sizeof( cfilename ) - 1] = 0;
}
strncpy( cfilename, filename.c_str(), sizeof( cfilename ) );
cfilename[sizeof( cfilename ) - 1] = 0;
MPI_Bcast( &cfilename, sizeof( cfilename ), MPI_CHAR, 0, MPI_COMM_WORLD );
MPI_Barrier( MPI_COMM_WORLD );
// create spdlog file sink
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>( _logDir + cfilename );
fileSink->set_level( fileLogLvl );
fileSink->set_pattern( "%Y-%m-%d %H:%M:%S.%f | %v" );
sinks.push_back( fileSink );
}
MPI_Bcast( &cfilename, sizeof( cfilename ), MPI_CHAR, 0, MPI_COMM_WORLD );
MPI_Barrier( MPI_COMM_WORLD );
// create spdlog file sink
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>( _logDir + cfilename );
fileSink->set_level( fileLogLvl );
fileSink->set_pattern( "%Y-%m-%d %H:%M:%S.%f | %v" );
sinks.push_back( fileSink );
}
// register all sinks
auto event_logger = std::make_shared<spdlog::logger>( "event", begin( sinks ), end( sinks ) );
spdlog::register_logger( event_logger );
spdlog::flush_every( std::chrono::seconds( 5 ) );
// register all sinks
auto event_logger = std::make_shared<spdlog::logger>( "event", begin( sinks ), end( sinks ) );
spdlog::register_logger( event_logger );
spdlog::flush_every( std::chrono::seconds( 5 ) );
}
}
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include <mpi.h>
int main( int argc, char** argv ) {
MPI_Init( &argc, &argv );
const int result = Catch::Session().run( argc, argv );
MPI_Finalize();
return result;
}
#include "catch.hpp"
#include "factorialexample.h"
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( Factorial( 0 ) == 1 );
REQUIRE( Factorial( 1 ) == 1 );
REQUIRE( Factorial( 2 ) == 2 );
REQUIRE( Factorial( 3 ) == 6 );
REQUIRE( Factorial( 10 ) == 3628800 );
}
% ---- File specifications ----
OUTPUT_DIR = ../../result
OUTPUT_FILE = rtsn_test_checkerboard
LOG_DIR = ../../result/logs
MESH_FILE = checkerboard.su2
% ---- Solver specifications ----
CFL_NUMBER = 0.5
TIME_FINAL = 3.2
PROBLEM = CHECKERBOARD
% ---- Boundary Conditions ----
BC_NEUMANN = ( void )
QUAD_TYPE = LEBEDEV
QUAD_ORDER = 15
import pygmsh as pg
import numpy as np
import itertools
import os
def add_block(x0,y0,length,char_length,geom):
coords = np.array([
[x0, y0, 0.0],
[x0+length, y0, 0.0],
[x0+length, y0+length, 0.0],
[x0, y0+length, 0.0]
])
return geom.add_polygon(coords, char_length)
char_length = 0.125
geom = pg.opencascade.Geometry()
domain = add_block(0, 0, 7, char_length, geom)
xpos = ypos = [1, 2, 3, 4, 5]
pattern = list(itertools.product(xpos, ypos))[::2]
pattern.pop(7)
boxes = [domain]
for pos in pattern:
boxes.append(add_block(pos[0], pos[1], 1, char_length, geom))
geom.boolean_fragments(boxes,[])
geom.add_physical(domain.lines, label="void")
mesh_code = geom.get_code()
with open("checkerboard.geo","w") as mesh_file:
mesh_file.write(mesh_code)
os.system('gmsh checkerboard.geo -2 -format su2 -save_all')
os.system('rm checkerboard.geo')
This diff is collapsed.
This diff is collapsed.
% ---- File specifications ----
OUTPUT_DIR = ../../result
OUTPUT_FILE = rtsn_test_linesource
LOG_DIR = ../../result/logs
MESH_FILE = linesource.su2
% ---- Solver specifications ----
CFL_NUMBER = 0.5
TIME_FINAL = 0.5
PROBLEM = LINESOURCE
% ---- Boundary Conditions ----
BC_NEUMANN = ( void )
QUAD_TYPE = LEBEDEV
QUAD_ORDER = 15
import pygmsh as pg
import numpy as np
import itertools
import os
def add_block(x0,y0,length,char_length,geom):
coords = np.array([
[x0, y0, 0.0],
[x0+length, y0, 0.0],
[x0+length, y0+length, 0.0],
[x0, y0+length, 0.0]
])
return geom.add_polygon(coords, char_length)
char_length = 0.02
geom = pg.opencascade.Geometry()
domain = add_block(-0.6, -0.6, 1.2, char_length, geom)
geom.add_raw_code('psource = newp;\nPoint(psource) = {0.0, 0.0, 0.0, '+str(char_length)+'};\nPoint{psource} In Surface{'+domain.id+'};')
geom.add_physical(domain.lines, label="void")
mesh_code = geom.get_code()
with open("linesource.geo","w") as mesh_file:
mesh_file.write(mesh_code)
os.system('gmsh linesource.geo -2 -format su2 -save_all')
os.system('rm linesource.geo')
This diff is collapsed.
This diff is collapsed.
% ---- File specifications ----
OUTPUT_DIR = ../../result
OUTPUT_FILE = rtsn_test_unit
LOG_DIR = ../../result/logs
MESH_FILE = unit.su2
% ---- Solver specifications ----
CFL_NUMBER = 0.5
TIME_FINAL = 0.0
PROBLEM = ELECTRONRT
% ---- Boundary Conditions ----
BC_DIRICHLET = ( void )
QUAD_TYPE = MONTE_CARLO
QUAD_ORDER = 1
import pygmsh as pg
import numpy as np
import itertools
import os
def add_block(x0,y0,length,char_length,geom):
coords = np.array([
[x0, y0, 0.0],
[x0+length, y0, 0.0],
[x0+length, y0+length, 0.0],
[x0, y0+length, 0.0]
])
return geom.add_polygon(coords, char_length)
char_length = 0.5
geom = pg.opencascade.Geometry()
domain = add_block(0.0, 0.0, 1.0, char_length, geom)
geom.add_physical(domain.lines, label="void")
mesh_code = geom.get_code()
with open("unit.geo","w") as mesh_file:
mesh_file.write(mesh_code)
os.system('gmsh unit.geo -2 -format su2 -save_all')
os.system('rm unit.geo')
NDIME= 2
NELEM= 14
5 1 9 4 0
5 5 9 1 1
5 3 11 6 2
5 7 11 3 3
5 2 10 5 4
5 6 10 2 5
5 4 8 0 6
5 0 8 7 7
5 9 11 8 8
5 8 11 7 9
5 4 9 8 10
5 10 11 9 11
5 6 11 10 12
5 5 10 9 13
NPOIN= 12
0 0 0
1 0 1
1 1 2
0 1 3
0.5 0 4
1 0.5 5
0.5 1 6
0 0.5 7
0.25 0.25 8
0.625 0.3750000000000001 9
0.71875 0.7187500000000001 10
0.345703125 0.654296875 11
NMARK= 1
MARKER_TAG= void
MARKER_ELEMS= 8
3 0 4
3 4 1
3 1 5
3 5 2
3 2 6
3 6 3
3 3 7
3 7 0
Supports Markdown
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