From 73ac70ad6d738476f7739600b673e69770a679d9 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber <tomas.oberhuber@fjfi.cvut.cz> Date: Sun, 2 Nov 2014 18:42:50 +0100 Subject: [PATCH] Debuging the heat equation EOC test. --- TODO | 16 ++++ examples/heat-equation/tnl-heat-equation.cpp | 9 ++- .../functions/tnlSinWaveFunction_impl.h | 4 +- .../matrices/tnlMatrixSetter_impl.h | 4 +- .../mesh/tnlTraversal_Grid1D_impl.h | 19 +++-- .../mesh/tnlTraversal_Grid2D_impl.h | 31 ++++++-- .../mesh/tnlTraversal_Grid3D_impl.h | 37 +++++++++- .../diffusion/tnlLinearDiffusion_impl.h | 36 +++++---- .../tnlDirichletBoundaryConditions_impl.h | 2 +- .../pde/tnlSemiImplicitTimeStepper_impl.h | 9 +++ src/matrices/tnlMatrixSetter.h | 12 +-- .../tnlDirichletBoundaryConditions.h | 1 + .../matrices/tnlSparseMatrixTester.h | 40 +++++----- .../diffusion/tnlLinearDiffusionTest.cpp | 32 +++++++- .../operators/tnlPDEOperatorEocTestResult.h | 1 + .../operators/tnlPDEOperatorEocTestSetter.h | 7 ++ .../operators/tnlPDEOperatorEocTester.h | 14 ++-- tests/unit-tests/tnlApproximationError.h | 60 ++++++++++++++- tests/unit-tests/tnlApproximationError_impl.h | 74 ++++++++++++++++++- 19 files changed, 335 insertions(+), 73 deletions(-) diff --git a/TODO b/TODO index 601def17fe..333e2c0927 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,20 @@ +TODO: test aproximace pro implicitni schemata +TODO: pokusit se napsat test explicitni aproximace podobne jako implicinit bez specializace pro grid +TODO: doladit semi-implicitni resic +TODO: opravit argumenty metod v heat equation - nekde se nepredavaji dofy a pomocne dofy +TODO: doresit okrajove podminky v heat equation - nacitani ze souboru + => soucasne Dir. a Neum. okrajove podminky prejmenovat asi tnlAnalytic... a zavest nove tnlDirichlet... a tnlNeumann... + ktere budou mit sve hodnoty ulozene ve vektoru TODO: neumanovy okrajove podminky +TODO: doladit vse s CUDA +TODO: doplnit mesh travelsals pro jine mesh entity nez cell +TODO: implementace maticovych resicu + * Gaussova eliminace + * SOR metoda + * Jacobiho metoda + * TFQMR metoda + * IDR metody + TODO: implementovat tridu tnlFileName pro generovani jmen souboru diff --git a/examples/heat-equation/tnl-heat-equation.cpp b/examples/heat-equation/tnl-heat-equation.cpp index 449eb20a30..d74f517f68 100644 --- a/examples/heat-equation/tnl-heat-equation.cpp +++ b/examples/heat-equation/tnl-heat-equation.cpp @@ -32,8 +32,13 @@ class heatEquationConfig public: static void configSetup( tnlConfigDescription& config ) { - //config.addDelimiter( "Heat equation settings:" ); - } + config.addDelimiter( "Heat equation settings:" ); + config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< tnlString >( "dirichlet" ); + config.addEntryEnum< tnlString >( "neumann" ); + config.addEntry< tnlString >( "boundary-conditions", "File with the values of the boundary conditions.", "boundary.tnl" ); + config.addEntry< tnlString >( "initial-condition", "File with the initial condition.", "initial.tnl"); + }; }; template< typename Real, diff --git a/src/implementation/functions/tnlSinWaveFunction_impl.h b/src/implementation/functions/tnlSinWaveFunction_impl.h index 10f0afea48..90f6f003cd 100644 --- a/src/implementation/functions/tnlSinWaveFunction_impl.h +++ b/src/implementation/functions/tnlSinWaveFunction_impl.h @@ -129,11 +129,11 @@ getValue( const Vertex& v, if( XDiffOrder == 1 && YDiffOrder == 0 ) return 2.0 * M_PI * x / ( this->waveLength * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); if( XDiffOrder == 2 && YDiffOrder == 0 ) - return 2.0 * M_PI * y * y / ( this->waveLength * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) - 4.0 * M_PI * M_PI * x * x / ( this->waveLength * this->waveLength * ( x * x + y * y ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); + return 2.0 * M_PI * x * x / ( this->waveLength * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) - 4.0 * M_PI * M_PI * x * x / ( this->waveLength * this->waveLength * ( x * x + y * y ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); if( XDiffOrder == 0 && YDiffOrder == 1 ) return 2.0 * M_PI * y / ( this->waveLength * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); if( XDiffOrder == 0 && YDiffOrder == 2 ) - return 2.0 * M_PI * x * x / ( this->waveLength * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) - 4.0 * M_PI * M_PI * y * y / ( this->waveLength * this->waveLength * ( x * x + y * y ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); + return 2.0 * M_PI * y * y / ( this->waveLength * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) * sqrt( x * x + y * y ) ) * this->amplitude * cos( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ) - 4.0 * M_PI * M_PI * y * y / ( this->waveLength * this->waveLength * ( x * x + y * y ) ) * this->amplitude * sin( this->phase + 2.0 * M_PI * sqrt( x * x + y * y ) / this->waveLength ); return 0.0; } diff --git a/src/implementation/matrices/tnlMatrixSetter_impl.h b/src/implementation/matrices/tnlMatrixSetter_impl.h index b8a808013f..d1e310eea6 100644 --- a/src/implementation/matrices/tnlMatrixSetter_impl.h +++ b/src/implementation/matrices/tnlMatrixSetter_impl.h @@ -54,8 +54,8 @@ template< int Dimensions, void tnlMatrixSetter< tnlGrid< Dimensions, Real, Device, Index >, DifferentialOperator, BoundaryConditions, RowLengthsVector >:: getRowLengths( const MeshType& mesh, - DifferentialOperator& differentialOperator, - BoundaryConditions& boundaryConditions, + const DifferentialOperator& differentialOperator, + const BoundaryConditions& boundaryConditions, RowLengthsVector& rowLengths ) const { TraversalUserData userData( differentialOperator, boundaryConditions, rowLengths ); diff --git a/src/implementation/mesh/tnlTraversal_Grid1D_impl.h b/src/implementation/mesh/tnlTraversal_Grid1D_impl.h index 99259fa78e..b17f5133d4 100644 --- a/src/implementation/mesh/tnlTraversal_Grid1D_impl.h +++ b/src/implementation/mesh/tnlTraversal_Grid1D_impl.h @@ -35,13 +35,22 @@ processEntities( const GridType& grid, */ CoordinatesType coordinates; const IndexType& xSize = grid.getDimensions().x(); - for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) + + /**** + * Boundary conditions + */ + coordinates.x() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, 0, coordinates ); + coordinates.x() = xSize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, xSize - 1, coordinates ); + + /**** + * Interior cells + */ + for( coordinates.x() = 1; coordinates.x() < xSize-1; coordinates.x() ++ ) { const IndexType index = grid.getCellIndex( coordinates ); - if( grid.isBoundaryCell( coordinates ) ) - boundaryEntitiesProcessor.template processCell( grid, userData, index, coordinates ); - else - interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); + interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); } } diff --git a/src/implementation/mesh/tnlTraversal_Grid2D_impl.h b/src/implementation/mesh/tnlTraversal_Grid2D_impl.h index 2f1bb1ee02..a5e6f34609 100644 --- a/src/implementation/mesh/tnlTraversal_Grid2D_impl.h +++ b/src/implementation/mesh/tnlTraversal_Grid2D_impl.h @@ -37,17 +37,36 @@ processEntities( const GridType& grid, CoordinatesType coordinates; const IndexType& xSize = grid.getDimensions().x(); const IndexType& ySize = grid.getDimensions().y(); + + /**** + * Boundary conditions + */ + for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) + { + coordinates.y() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + coordinates.y() = ySize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + } + for( coordinates.y() = 1; coordinates.y() < ySize - 1; coordinates.y() ++ ) + { + coordinates.x() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + coordinates.x() = xSize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + } + + /**** + * Interior cells + */ #ifdef HAVE_OPENMP //#pragma omp parallel for #endif - for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ ) - for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) + for( coordinates.y() = 1; coordinates.y() < ySize - 1; coordinates.y() ++ ) + for( coordinates.x() = 1; coordinates.x() < xSize - 1; coordinates.x() ++ ) { const IndexType index = grid.getCellIndex( coordinates ); - if( grid.isBoundaryCell( coordinates ) ) - boundaryEntitiesProcessor.template processCell( grid, userData, index, coordinates ); - else - interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); + interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); } } diff --git a/src/implementation/mesh/tnlTraversal_Grid3D_impl.h b/src/implementation/mesh/tnlTraversal_Grid3D_impl.h index d0f21814f6..e64353b0f0 100644 --- a/src/implementation/mesh/tnlTraversal_Grid3D_impl.h +++ b/src/implementation/mesh/tnlTraversal_Grid3D_impl.h @@ -37,6 +37,38 @@ processEntities( const GridType& grid, const IndexType& xSize = grid.getDimensions().x(); const IndexType& ySize = grid.getDimensions().y(); const IndexType& zSize = grid.getDimensions().z(); + + /**** + * Boundary conditions + */ + for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ ) + for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) + { + coordinates.z() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + coordinates.z() = zSize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + } + + for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ ) + for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) + { + coordinates.y() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + coordinates.y() = ySize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + } + + for( coordinates.z() = 0; coordinates.z() < zSize; coordinates.z() ++ ) + for( coordinates.y() = 0; coordinates.y() < ySize; coordinates.y() ++ ) + { + coordinates.x() = 0; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + coordinates.x() = xSize - 1; + boundaryEntitiesProcessor.template processCell( grid, userData, grid.getCellIndex( coordinates ), coordinates ); + } + + #ifdef HAVE_OPENMP //#pragma omp parallel for #endif @@ -45,10 +77,7 @@ processEntities( const GridType& grid, for( coordinates.x() = 0; coordinates.x() < xSize; coordinates.x() ++ ) { const IndexType index = grid.getCellIndex( coordinates ); - if( grid.isBoundaryCell( coordinates ) ) - boundaryEntitiesProcessor.template processCell( grid, userData, index, coordinates ); - else - interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); + interiorEntitiesProcessor.template processCell( grid, userData, index, coordinates ); } } diff --git a/src/implementation/operators/diffusion/tnlLinearDiffusion_impl.h b/src/implementation/operators/diffusion/tnlLinearDiffusion_impl.h index 2acc343c26..05ade1d5db 100644 --- a/src/implementation/operators/diffusion/tnlLinearDiffusion_impl.h +++ b/src/implementation/operators/diffusion/tnlLinearDiffusion_impl.h @@ -81,12 +81,13 @@ updateLinearSystem( const RealType& time, RealType* values, IndexType& rowLength ) const { + const RealType lambdaX = tau * mesh.getHxSquareInverse(); columns[ 0 ] = mesh.getCellXPredecessor( index ); columns[ 1 ] = index; columns[ 2 ] = mesh.getCellXSuccessor( index ); - values[ 0 ] = -tau; - values[ 1 ] = 1.0 + 2.0 * tau; - values[ 2 ] = -tau; + values[ 0 ] = -lambdaX; + values[ 1 ] = 1.0 + 2.0 * lambdaX; + values[ 2 ] = -lambdaX; rowLength = 3; } @@ -170,16 +171,18 @@ updateLinearSystem( const RealType& time, RealType* values, IndexType& rowLength ) const { + const RealType lambdaX = tau * mesh.getHxSquareInverse(); + const RealType lambdaY = tau * mesh.getHySquareInverse(); columns[ 0 ] = mesh.getCellYPredecessor( index ); columns[ 1 ] = mesh.getCellXPredecessor( index ); columns[ 2 ] = index; columns[ 3 ] = mesh.getCellXSuccessor( index ); columns[ 4 ] = mesh.getCellYSuccessor( index ); - values[ 0 ] = -tau; - values[ 1 ] = -tau; - values[ 2 ] = 1.0 + 4.0 * tau; - values[ 3 ] = -tau; - values[ 4 ] = -tau; + values[ 0 ] = -lambdaY; + values[ 1 ] = -lambdaX; + values[ 2 ] = 1.0 + 2.0 * ( lambdaX + lambdaY ); + values[ 3 ] = -lambdaX; + values[ 4 ] = -lambdaY; rowLength = 5; } @@ -266,6 +269,9 @@ updateLinearSystem( const RealType& time, RealType* values, IndexType& rowLength ) const { + const RealType lambdaX = tau * mesh.getHxSquareInverse(); + const RealType lambdaY = tau * mesh.getHySquareInverse(); + const RealType lambdaZ = tau * mesh.getHzSquareInverse(); columns[ 0 ] = mesh.getCellZPredecessor( index ); columns[ 1 ] = mesh.getCellYPredecessor( index ); columns[ 2 ] = mesh.getCellXPredecessor( index ); @@ -273,13 +279,13 @@ updateLinearSystem( const RealType& time, columns[ 4 ] = mesh.getCellXSuccessor( index ); columns[ 5 ] = mesh.getCellYSuccessor( index ); columns[ 6 ] = mesh.getCellZSuccessor( index ); - values[ 0 ] = -tau; - values[ 1 ] = -tau; - values[ 2 ] = -tau; - values[ 3 ] = 1.0 + 6.0 * tau; - values[ 4 ] = -tau; - values[ 5 ] = -tau; - values[ 6 ] = -tau; + values[ 0 ] = -lambdaZ; + values[ 1 ] = -lambdaY; + values[ 2 ] = -lambdaX; + values[ 3 ] = 1.0 + 2.0 * ( lambdaX + lambdaY + lambdaZ ); + values[ 4 ] = -lambdaX; + values[ 5 ] = -lambdaY; + values[ 6 ] = -lambdaZ; rowLength = 7; } diff --git a/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h b/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h index 6c781e00db..a00a250c79 100644 --- a/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h +++ b/src/implementation/operators/tnlDirichletBoundaryConditions_impl.h @@ -11,7 +11,7 @@ template< typename MeshReal, bool tnlDirichletBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >:: setup( const tnlParameterContainer& parameters, - const tnlString& prefix ) + const tnlString& prefix ) { return function.setup( parameters, prefix ); } diff --git a/src/implementation/solvers/pde/tnlSemiImplicitTimeStepper_impl.h b/src/implementation/solvers/pde/tnlSemiImplicitTimeStepper_impl.h index 91f775f6e7..8f44de2620 100644 --- a/src/implementation/solvers/pde/tnlSemiImplicitTimeStepper_impl.h +++ b/src/implementation/solvers/pde/tnlSemiImplicitTimeStepper_impl.h @@ -147,6 +147,8 @@ solve( const RealType& time, dofVector, this->matrix, this->rightHandSide ); + cout << "u = " << dofVector << endl; + cout << "b = " << this->rightHandSide << endl; if( verbose ) cout << " Solving the linear system for time " << t << " \r" << flush; if( ! this->linearSystemSolver->solve( this->rightHandSide, dofVector ) ) @@ -154,6 +156,13 @@ solve( const RealType& time, cerr << "The linear system solver did not converge." << endl; return false; } + DofVectorType aux; + aux.setLike( dofVector ); + this->matrix.vectorProduct( dofVector, aux ); + cout << "tau = " << currentTau << endl; + cout << "u = " << dofVector << endl; + cout << "Ax = " << aux << endl; + cout << "b = " << this->rightHandSide << endl; t += currentTau; } return true; diff --git a/src/matrices/tnlMatrixSetter.h b/src/matrices/tnlMatrixSetter.h index cf04a6e2b3..01448ea314 100644 --- a/src/matrices/tnlMatrixSetter.h +++ b/src/matrices/tnlMatrixSetter.h @@ -25,14 +25,14 @@ class tnlMatrixSetterTraversalUserData { public: - DifferentialOperator& differentialOperator; + const DifferentialOperator& differentialOperator; - BoundaryConditions& boundaryConditions; + const BoundaryConditions& boundaryConditions; RowLengthsVector& rowLengths; - tnlMatrixSetterTraversalUserData( DifferentialOperator& differentialOperator, - BoundaryConditions& boundaryConditions, + tnlMatrixSetterTraversalUserData( const DifferentialOperator& differentialOperator, + const BoundaryConditions& boundaryConditions, RowLengthsVector& rowLengths ) : differentialOperator( differentialOperator ), boundaryConditions( boundaryConditions ), @@ -117,8 +117,8 @@ class tnlMatrixSetter< tnlGrid< Dimensions, Real, Device, Index >, template< int EntityDimensions > void getRowLengths( const MeshType& mesh, - DifferentialOperator& differentialOperator, - BoundaryConditions& boundaryConditions, + const DifferentialOperator& differentialOperator, + const BoundaryConditions& boundaryConditions, RowLengthsVector& rowLengths ) const; diff --git a/src/operators/tnlDirichletBoundaryConditions.h b/src/operators/tnlDirichletBoundaryConditions.h index b631df7c3d..24c9a7379b 100644 --- a/src/operators/tnlDirichletBoundaryConditions.h +++ b/src/operators/tnlDirichletBoundaryConditions.h @@ -4,6 +4,7 @@ #include <core/vectors/tnlStaticVector.h> #include <config/tnlParameterContainer.h> #include <functions/tnlConstantFunction.h> +#include <core/vectors/tnlSharedVector.h> template< typename Mesh, typename Function = tnlConstantFunction< Mesh::Dimensions, diff --git a/tests/unit-tests/matrices/tnlSparseMatrixTester.h b/tests/unit-tests/matrices/tnlSparseMatrixTester.h index 2b25a67d4d..5d12983eb8 100644 --- a/tests/unit-tests/matrices/tnlSparseMatrixTester.h +++ b/tests/unit-tests/matrices/tnlSparseMatrixTester.h @@ -259,12 +259,12 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase rowLengths.setValue( 7 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 0; i < 10; i++ ) m.setElementFast( i, i, i ); } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -340,7 +340,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase rowLengths.setValue( 10 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 0; i < 10; i++ ) m.setElementFast( i, i, i ); @@ -348,7 +348,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase for( int j = 0; j < 10; j++ ) m.addElementFast( i, j, 1, 0.5 ); } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -377,13 +377,13 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.reset(); m.setDimensions( 10, 10 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 9; i >= 0; i-- ) for( int j = 9; j >= 0; j-- ) m.setElementFast( i, j, i+j ); } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -456,13 +456,13 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase rowLengths.setElement( i, i+1 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 0; i < 10; i++ ) for( int j = 0; j <= i; j++ ) m.setElementFast( i, j, i + j ); } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -491,13 +491,13 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.reset(); m.setDimensions( 10, 10 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 9; i >= 0; i-- ) for( int j = i; j >= 0; j-- ) m.setElementFast( i, j, i + j ); } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -597,7 +597,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { RealType values[ 1 ]; IndexType columnIndexes[ 1 ]; @@ -608,7 +608,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowFast( i, columnIndexes, values, 1 ); } } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -702,7 +702,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase for( int i = 0; i < 10; i++ ) columnIndexes[ i ] = i; - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 0; i < 10; i++ ) { @@ -715,7 +715,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowFast( i, columnIndexes, values, 10 ); } } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -746,7 +746,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setDimensions( 10, 10 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 9; i >= 0; i-- ) { @@ -755,7 +755,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowFast( i, columnIndexes, values, 10 ); } } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -847,7 +847,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase for( int i = 0; i < 10; i++ ) columnIndexes[ i ] = i; - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 0; i < 10; i++ ) { @@ -856,7 +856,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowFast( i, columnIndexes, values, i + 1 ); } } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); @@ -887,7 +887,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setDimensions( 10, 10 ); m.setRowLengths( rowLengths ); - if( DeviceType::DeviceType == tnlHostDevice ) + if( DeviceType::DeviceType == ( int ) tnlHostDevice ) { for( int i = 9; i >= 0; i-- ) { @@ -896,7 +896,7 @@ class tnlSparseMatrixTester : public CppUnit :: TestCase m.setRowFast( i, columnIndexes, values, i + 1 ); } } - if( DeviceType::DeviceType == tnlCudaDevice ) + if( DeviceType::DeviceType == ( int ) tnlCudaDevice ) { #ifdef HAVE_CUDA MatrixType* kernel_matrix = tnlCuda::passToDevice( m ); diff --git a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp index 525725954c..ddffcf8229 100644 --- a/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp +++ b/tests/unit-tests/operators/diffusion/tnlLinearDiffusionTest.cpp @@ -31,8 +31,10 @@ template< int Dimensions, typename Real, typename Device, typename Index, - typename TestFunction > + typename TestFunction, + typename ApproximationMethod > class tnlPDEOperatorEocTestResult< tnlLinearDiffusion< tnlGrid< Dimensions, Real, Device, Index >, Real, Index >, + ApproximationMethod, TestFunction > { public: @@ -52,19 +54,47 @@ int main( int argc, char* argv[] ) const bool verbose( true ); const int MeshSize( 32 ); #ifdef HAVE_CPPUNIT + /**** + * Explicit approximation + */ if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >, tnlExactLinearDiffusion< 1 >, tnlExpBumpFunction< 1, double >, + tnlExplicitApproximation, MeshSize, verbose > >() || ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >, tnlExactLinearDiffusion< 2 >, tnlExpBumpFunction< 2, double >, + tnlExplicitApproximation, MeshSize, verbose > >() || ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >, tnlExactLinearDiffusion< 3 >, tnlExpBumpFunction< 3, double >, + tnlExplicitApproximation, + MeshSize, + verbose > >() ) + return EXIT_FAILURE; + /**** + * Implicit (matrix) approximation + */ + if( ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 1, double, tnlHost, int >, double, int >, + tnlExactLinearDiffusion< 1 >, + tnlExpBumpFunction< 1, double >, + tnlImplicitApproximation, + MeshSize, + verbose > >() || + ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 2, double, tnlHost, int >, double, int >, + tnlExactLinearDiffusion< 2 >, + tnlExpBumpFunction< 2, double >, + tnlImplicitApproximation, + MeshSize, + verbose > >() || + ! tnlUnitTestStarter :: run< tnlPDEOperatorEocTester< tnlLinearDiffusion< tnlGrid< 3, double, tnlHost, int >, double, int >, + tnlExactLinearDiffusion< 3 >, + tnlExpBumpFunction< 3, double >, + tnlImplicitApproximation, MeshSize, verbose > >() ) diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h index 0214a086e0..7e1954dcf2 100644 --- a/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h +++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestResult.h @@ -19,6 +19,7 @@ #define TNLPDEOPERATOREOCTESTRESULT_H_ template< typename ApproximateOperator, + typename ApproximationMethod, typename TestFunction > class tnlPDEOperatorEocTestResult { diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h index 2ed0ce0a0e..16542c201d 100644 --- a/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h +++ b/tests/unit-tests/operators/tnlPDEOperatorEocTestSetter.h @@ -23,6 +23,7 @@ template< typename ApproximateOperator, typename ExactOperator, + typename ApproximationMethod, typename Mesh, typename TestFunction > class tnlPDEOperatorEocTestSetter @@ -31,11 +32,13 @@ class tnlPDEOperatorEocTestSetter template< typename ApproximateOperator, typename ExactOperator, + typename ApproximationMethod, typename Real, typename Device, typename Index > class tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, + ApproximationMethod, tnlGrid< 1, Real, Device, Index >, tnlExpBumpFunction< 1, Real > > { @@ -72,11 +75,13 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator, template< typename ApproximateOperator, typename ExactOperator, + typename ApproximationMethod, typename Real, typename Device, typename Index > class tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, + ApproximationMethod, tnlGrid< 2, Real, Device, Index >, tnlExpBumpFunction< 2, Real > > { @@ -116,11 +121,13 @@ class tnlPDEOperatorEocTestSetter< ApproximateOperator, template< typename ApproximateOperator, typename ExactOperator, + typename ApproximationMethod, typename Real, typename Device, typename Index > class tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, + ApproximationMethod, tnlGrid< 3, Real, Device, Index >, tnlExpBumpFunction< 3, Real > > { diff --git a/tests/unit-tests/operators/tnlPDEOperatorEocTester.h b/tests/unit-tests/operators/tnlPDEOperatorEocTester.h index 9e1b50ff54..97381cf3ec 100644 --- a/tests/unit-tests/operators/tnlPDEOperatorEocTester.h +++ b/tests/unit-tests/operators/tnlPDEOperatorEocTester.h @@ -31,18 +31,19 @@ template< typename ApproximateOperator, typename ExactOperator, typename TestFunction, + typename ApproximationMethod, int MeshSize, bool verbose = false > class tnlPDEOperatorEocTester : public CppUnit :: TestCase { public: - typedef tnlPDEOperatorEocTester< ApproximateOperator, ExactOperator, TestFunction, MeshSize, verbose > TesterType; + typedef tnlPDEOperatorEocTester< ApproximateOperator, ExactOperator, TestFunction, ApproximationMethod, MeshSize, verbose > TesterType; typedef typename CppUnit::TestCaller< TesterType > TestCallerType; typedef typename ApproximateOperator::MeshType MeshType; typedef typename ApproximateOperator::RealType RealType; typedef typename ApproximateOperator::IndexType IndexType; - typedef tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, MeshType, TestFunction > TestSetter; - typedef tnlPDEOperatorEocTestResult< ApproximateOperator, TestFunction > TestResult; + typedef tnlPDEOperatorEocTestSetter< ApproximateOperator, ExactOperator, ApproximationMethod, MeshType, TestFunction > TestSetter; + typedef tnlPDEOperatorEocTestResult< ApproximateOperator, ApproximationMethod, TestFunction > TestResult; tnlPDEOperatorEocTester(){}; @@ -55,6 +56,7 @@ class tnlPDEOperatorEocTester : public CppUnit :: TestCase ApproximateOperator::getType() + ", " + ExactOperator::getType() + ", " + TestFunction::getType() + ", " + + ApproximationMethod::getType() + ", " + tnlString( MeshSize ) + ", " + tnlString( verbose ) + " >"; CppUnit :: TestSuite* suiteOfTests = new CppUnit :: TestSuite( testName.getString() ); @@ -80,7 +82,8 @@ class tnlPDEOperatorEocTester : public CppUnit :: TestCase tnlApproximationError< MeshType, ExactOperator, ApproximateOperator, - TestFunction > + TestFunction, + ApproximationMethod > ::getError( mesh, exactOperator, approximateOperator, @@ -94,7 +97,8 @@ class tnlPDEOperatorEocTester : public CppUnit :: TestCase tnlApproximationError< MeshType, ExactOperator, ApproximateOperator, - TestFunction > + TestFunction, + ApproximationMethod > ::getError( mesh, exactOperator, approximateOperator, diff --git a/tests/unit-tests/tnlApproximationError.h b/tests/unit-tests/tnlApproximationError.h index 47ad750ceb..fed513b22c 100644 --- a/tests/unit-tests/tnlApproximationError.h +++ b/tests/unit-tests/tnlApproximationError.h @@ -19,12 +19,43 @@ #define TNLAPPROXIMATIONERROR_H_ #include <mesh/tnlGrid.h> +#include <functions/tnlConstantFunction.h> +#include <operators/tnlDirichletBoundaryConditions.h> + +class tnlExplicitApproximation +{ + public: + + static tnlString getType() + { + return tnlString( "tnlExplicitApproximation" ); + }; +}; + +class tnlImplicitApproximation +{ + public: + + static tnlString getType() + { + return tnlString( "tnlImplicitApproximation" ); + }; +}; template< typename Mesh, typename ExactOperator, typename ApproximateOperator, - typename Function > + typename Function, + typename ApproximationMethod > class tnlApproximationError +{ +}; + +template< typename Mesh, + typename ExactOperator, + typename ApproximateOperator, + typename Function > +class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation > { public: @@ -33,6 +64,8 @@ class tnlApproximationError typedef typename MeshType::DeviceType DeviceType; typedef typename MeshType::IndexType IndexType; typedef typename MeshType::VertexType VertexType; + typedef tnlConstantFunction< MeshType::Dimensions, RealType > ConstantFunctionType; + typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunctionType > BoundaryConditionsType; static void getError( const Mesh& mesh, const ExactOperator& exactOperator, @@ -50,7 +83,7 @@ template< int Dimensions, typename ExactOperator, typename ApproximateOperator, typename Function > -class tnlApproximationError< tnlGrid< Dimensions, Real, Device, Index >, ExactOperator, ApproximateOperator, Function > +class tnlApproximationError< tnlGrid< Dimensions, Real, Device, Index >, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation > { public: @@ -70,7 +103,30 @@ class tnlApproximationError< tnlGrid< Dimensions, Real, Device, Index >, ExactOp RealType& maxErr ); }; +template< typename Mesh, + typename ExactOperator, + typename ApproximateOperator, + typename Function > +class tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlImplicitApproximation > +{ + public: + + typedef typename ApproximateOperator::RealType RealType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + typedef typename MeshType::VertexType VertexType; + typedef tnlConstantFunction< MeshType::Dimensions, RealType > ConstantFunctionType; + typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunctionType > BoundaryConditionsType; + static void getError( const Mesh& mesh, + const ExactOperator& exactOperator, + const ApproximateOperator& approximateOperator, + const Function& function, + RealType& l1Err, + RealType& l2Err, + RealType& maxErr ); +}; #include "tnlApproximationError_impl.h" diff --git a/tests/unit-tests/tnlApproximationError_impl.h b/tests/unit-tests/tnlApproximationError_impl.h index f1c8fc1ab8..4b41d873a3 100644 --- a/tests/unit-tests/tnlApproximationError_impl.h +++ b/tests/unit-tests/tnlApproximationError_impl.h @@ -21,13 +21,16 @@ #include <mesh/tnlTraversal.h> #include <core/vectors/tnlVector.h> #include <functions/tnlFunctionDiscretizer.h> +#include <matrices/tnlCSRMatrix.h> +#include <matrices/tnlMatrixSetter.h> +#include <solvers/pde/tnlLinearSystemAssembler.h> template< typename Mesh, typename ExactOperator, typename ApproximateOperator, typename Function > void -tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function >:: +tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation >:: getError( const Mesh& mesh, const ExactOperator& exactOperator, const ApproximateOperator& approximateOperator, @@ -77,7 +80,7 @@ template< int Dimensions, typename ApproximateOperator, typename Function > void -tnlApproximationError< tnlGrid< Dimensions, Real, Device, Index >, ExactOperator, ApproximateOperator, Function >:: +tnlApproximationError< tnlGrid< Dimensions, Real, Device, Index >, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation >:: getError( const MeshType& mesh, const ExactOperator& exactOperator, const ApproximateOperator& approximateOperator, @@ -120,5 +123,72 @@ getError( const MeshType& mesh, maxErr = mesh.getDifferenceAbsMax( exactData, approximateData ); } +/**** + * Implicit (matrix) approximation + */ + +template< typename Mesh, + typename ExactOperator, + typename ApproximateOperator, + typename Function > +void +tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlImplicitApproximation >:: +getError( const Mesh& mesh, + const ExactOperator& exactOperator, + const ApproximateOperator& approximateOperator, + const Function& function, + RealType& l1Err, + RealType& l2Err, + RealType& maxErr ) +{ + typedef tnlVector< RealType, DeviceType, IndexType > Vector; + typedef tnlCSRMatrix< RealType, DeviceType, IndexType > MatrixType; + typedef typename MatrixType::RowLengthsVector RowLengthsVectorType; + Vector functionData, exactData, approximateData; + MatrixType matrix; + RowLengthsVectorType rowLengths; + BoundaryConditionsType boundaryConditions; + ConstantFunctionType zeroFunction; + + const IndexType entities = mesh.getNumberOfCells(); + + if( ! functionData.setSize( entities ) || + ! exactData.setSize( entities ) || + ! approximateData.setSize( entities ) || + ! rowLengths.setSize( entities ) ) + return; + + tnlFunctionDiscretizer< Mesh, Function, Vector >::template discretize< 0, 0, 0 >( mesh, function, functionData ); + + tnlMatrixSetter< MeshType, ApproximateOperator, BoundaryConditionsType, RowLengthsVectorType > matrixSetter; + matrixSetter.template getRowLengths< Mesh::Dimensions >( mesh, + approximateOperator, + boundaryConditions, + rowLengths ); + matrix.setDimensions( entities, entities ); + if( ! matrix.setRowLengths( rowLengths ) ) + return; + + tnlLinearSystemAssembler< Mesh, Vector, ApproximateOperator, BoundaryConditionsType, ConstantFunctionType, MatrixType > systemAssembler; + systemAssembler.template assembly< Mesh::Dimensions >( 0.0, // time + 0.0, // tau + mesh, + approximateOperator, + boundaryConditions, + zeroFunction, + functionData, + matrix, + approximateData // this has no meaning here + ); + + matrix.vectorProduct( functionData, approximateData ); + for( IndexType i = 0; i < entities; i++ ) + if( mesh.isBoundaryCell( i ) ) + approximateData.setElement( i, exactData.getElement( i ) ); + + l1Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 1.0 ); + l2Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 2.0 ); + maxErr = mesh.getDifferenceAbsMax( exactData, approximateData ); +} #endif /* TNLAPPROXIMATIONERROR_IMPL_H_ */ -- GitLab