/*************************************************************************** tnlApproximationError_impl.h - description ------------------- begin : Aug 8, 2014 copyright : (C) 2014 by Tomas Oberhuber email : tomas.oberhuber@fjfi.cvut.cz ***************************************************************************/ /*************************************************************************** * * * This program 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 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TNLAPPROXIMATIONERROR_IMPL_H_ #define TNLAPPROXIMATIONERROR_IMPL_H_ #include <mesh/tnlTraverser.h> #include <core/vectors/tnlVector.h> #include <functions/tnlFunctionDiscretizer.h> #include <matrices/tnlCSRMatrix.h> #include <matrices/tnlMatrixSetter.h> #include <solvers/pde/tnlLinearSystemAssembler.h> #include <solvers/pde/tnlNoTimeDiscretisation.h> #include <operators/tnlExactOperatorEvaluator.h> template< typename Mesh, typename ExactOperator, typename ApproximateOperator, typename Function > void tnlApproximationError< Mesh, ExactOperator, ApproximateOperator, Function, tnlExplicitApproximation >:: 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; Vector functionData, exactData, approximateData, aux; const IndexType entities = mesh.template getEntitiesCount< typename Mesh::Cell >(); BoundaryConditionsType boundaryConditions; boundaryConditions.setFunction( function ); ConstantFunctionType zeroFunction; if( ! functionData.setSize( entities ) || ! exactData.setSize( entities ) || ! approximateData.setSize( entities ) || ! aux.setSize( entities) ) return; tnlFunctionDiscretizer< Mesh, Function, Vector >::template discretize< 0, 0, 0 >( mesh, function, functionData ); tnlExplicitUpdater< Mesh, Vector, ApproximateOperator, BoundaryConditionsType, ConstantFunctionType > explicitUpdater; explicitUpdater.template update< typename Mesh::Cell >( 0.0, mesh, approximateOperator, boundaryConditions, zeroFunction, functionData, approximateData ); tnlExactOperatorEvaluator< Mesh, Vector, ExactOperator, Function, BoundaryConditionsType > operatorEvaluator; operatorEvaluator.template evaluate< typename Mesh::Cell >( 0.0, mesh, exactOperator, function, boundaryConditions, exactData ); typename Mesh::Cell cell( mesh ); for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < entities; cell.getCoordinates().x()++ ) { //cell.setIndex( mesh.getEntityIndex( cell ) ); cell.refresh(); if( cell.isBoundaryEntity() ) approximateData.setElement( cell.getIndex(), exactData.getElement( cell.getIndex() ) ); } l1Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 1.0 ); l2Err = mesh.getDifferenceLpNorm( exactData, approximateData, ( RealType ) 2.0 ); 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::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; Vector functionData, exactData, approximateData; MatrixType matrix; CompressedRowsLengthsVectorType rowLengths; BoundaryConditionsType boundaryConditions; boundaryConditions.setFunction( function ); ConstantFunctionType zeroFunction; const IndexType entities = mesh.template getEntitiesCount< typename Mesh::Cell >(); 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, CompressedRowsLengthsVectorType > matrixSetter; matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, approximateOperator, boundaryConditions, rowLengths ); matrix.setDimensions( entities, entities ); if( ! matrix.setCompressedRowsLengths( rowLengths ) ) return; tnlLinearSystemAssembler< Mesh, Vector, ApproximateOperator, BoundaryConditionsType, ConstantFunctionType, tnlNoTimeDiscretisation, MatrixType > systemAssembler; systemAssembler.template assembly< typename Mesh::Cell >( 0.0, // time 1.0, // tau mesh, approximateOperator, boundaryConditions, zeroFunction, functionData, matrix, approximateData // this has no meaning here ); tnlExactOperatorEvaluator< Mesh, Vector, ExactOperator, Function, BoundaryConditionsType > operatorEvaluator; operatorEvaluator.template evaluate< typename Mesh::Cell >( 0.0, mesh, exactOperator, function, boundaryConditions, exactData ); typename Mesh::Cell cell( mesh ); for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < entities; cell.getCoordinates().x()++ ) { IndexType i = mesh.getEntityIndex( cell ); if( ! cell.isBoundaryEntity() ) matrix.setElement( i, i, matrix.getElement( i, i ) - 1.0 ); } matrix.vectorProduct( functionData, approximateData ); // TODO: replace this when matrix.vectorProduct has multiplicator parameter for( IndexType i = 0; i < entities; i++ ) approximateData.setElement( i, -1.0 * approximateData.getElement( i ) ); for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < entities; cell.getCoordinates().x()++ ) { IndexType i = mesh.getEntityIndex( cell ); if( cell.isBoundaryEntity() ) 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_ */