From 0b3e87ab4c55865a3bedefcdd645d49f2974e362 Mon Sep 17 00:00:00 2001 From: fencl Date: Sat, 25 Nov 2017 12:48:46 +0100 Subject: [PATCH 01/28] zmena inicializace v tnlDirectEikonalMethodsBase_impl.h --- .../tnlDirectEikonalMethodsBase_impl.h | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index b924f7233..88ed4ddf4 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -31,15 +31,38 @@ initInterface( const MeshFunctionType& input, if( ! cell.isBoundaryEntity() ) { const auto& neighbors = cell.getNeighborEntities(); + const RealType& h = mesh.getSpaceSteps().x(); //const IndexType& c = cell.getIndex(); const IndexType e = neighbors.template getEntityIndex< 1 >(); const IndexType w = neighbors.template getEntityIndex< -1 >(); - if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ) + /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ) { output[ cell.getIndex() ] = c; interfaceMap[ cell.getIndex() ] = true; continue; + }*/ + if( c * input[ e ] <=0 ) + { + /*if( c >= 0 ) + { + output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ); + } + else + { + output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); + }*/ + c >= 0 ? output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ) : + output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); + interfaceMap[ cell.getIndex() ] = true; + continue; + } + else if( c * input[ w ] <=0 ) + { + c <= 0 ? output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ) : + output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); + interfaceMap[ cell.getIndex() ] = true; + continue; } } output[ cell.getIndex() ] = @@ -85,6 +108,9 @@ initInterface( const MeshFunctionType& input, if( ! cell.isBoundaryEntity() ) { auto neighbors = cell.getNeighborEntities(); + //const RealType& hx = mesh.getSpaceSteps().x(); + //const RealType& hy = mesh.getSpaceSteps().y(); + //const RealType& pom; const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); const IndexType w = neighbors.template getEntityIndex< -1, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); @@ -92,7 +118,7 @@ initInterface( const MeshFunctionType& input, if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || c * input[ n ] <= 0 || c * input[ s ] <= 0 ) { - output[ cell.getIndex() ] = c; + output[ cell.getIndex() ] = tnlTypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = true; continue; } -- GitLab From 1c287e95fdad52f8ed165ffb935931c551d3791d Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 27 Nov 2017 11:52:53 +0100 Subject: [PATCH 02/28] "Fixed" tnl-run-fsm-eoc-test. --- .../Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test | 4 ++-- .../hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test index 6d997ce23..57a40528b 100755 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test @@ -172,8 +172,8 @@ runTest() echo "=========================================================================" echo "=== STARTING THE SOLVER ===" echo "=========================================================================" - solve explicit merson - #solve semi-implicit gmres + #solve explicit merson + solve semi-implicit cg mv computation-in-progress computation-done fi echo "=========================================================================" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 904253116..414a2135c 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -117,7 +117,7 @@ initInterface( const MeshFunctionType& input, if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || c * input[ n ] <= 0 || c * input[ s ] <= 0 ) { - output[ cell.getIndex() ] = tnlTypeInfo< RealType >::getMaxValue(); + output[ cell.getIndex() ] = TypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = true; continue; } -- GitLab From e7de9a4d04ce2cc59f7be35e0a34fd1048117555 Mon Sep 17 00:00:00 2001 From: fencl Date: Mon, 27 Nov 2017 18:55:03 +0100 Subject: [PATCH 03/28] finall change of inicialization for 2D --- .../tnlDirectEikonalMethodsBase_impl.h | 82 ++++++++++++++++--- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 904253116..c76d988c3 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -51,21 +51,23 @@ initInterface( const MeshFunctionType& input, { output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); }*/ - c >= 0 ? output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ) : - output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); + output[ cell.getIndex() ] = + c >= 0 ? ( h * c )/( c - input[ e ] ) : + - ( h * c )/( c - input[ e ] ); interfaceMap[ cell.getIndex() ] = true; continue; } - else if( c * input[ w ] <=0 ) + if( c * input[ w ] <=0 ) { - c <= 0 ? output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ) : - output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); + output[ cell.getIndex() ] = + c >= 0 ? ( h * c )/( c - input[ w ] ) : + - ( h * c )/( c - input[ w ] ); interfaceMap[ cell.getIndex() ] = true; continue; } } output[ cell.getIndex() ] = - c > 0 ? TypeInfo< RealType >::getMaxValue() : + c > 0 ? TNL::TypeInfo< RealType >::getMaxValue() : -TypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = false; } @@ -95,6 +97,16 @@ initInterface( const MeshFunctionType& input, const MeshType& mesh = input.getMesh(); typedef typename MeshType::Cell Cell; Cell cell( mesh ); + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + for( cell.getCoordinates().y() = 0; cell.getCoordinates().y() < mesh.getDimensions().y(); cell.getCoordinates().y() ++ ) @@ -107,19 +119,65 @@ initInterface( const MeshFunctionType& input, if( ! cell.isBoundaryEntity() ) { auto neighbors = cell.getNeighborEntities(); - //const RealType& hx = mesh.getSpaceSteps().x(); - //const RealType& hy = mesh.getSpaceSteps().y(); - //const RealType& pom; + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + Real pom = 0; const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); - const IndexType w = neighbors.template getEntityIndex< -1, 0 >(); + //const IndexType w = neighbors.template getEntityIndex< -1, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); - const IndexType s = neighbors.template getEntityIndex< 0, -1 >(); - if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || + //const IndexType s = neighbors.template getEntityIndex< 0, -1 >(); + /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || c * input[ n ] <= 0 || c * input[ s ] <= 0 ) { output[ cell.getIndex() ] = tnlTypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = true; continue; + }*/ + if( c * input[ n ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + output[ n ] = ( hy * c )/( c - input[ n ]) - hy; + }else + { + pom = - ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + output[ n ] = hy - ( hy * c )/( c - input[ n ]); + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; + continue; + } + if( c * input[ e ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hx * c )/( c - input[ e ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( output[ e ] != 0 && output[ e ] >= pom ) + output[ e ] = pom; + }else + { + pom = - (hx * c)/( c - input[ e ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ e ] < pom ) + output[ e ] = pom; + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + continue; } } output[ cell.getIndex() ] = -- GitLab From f575dd05e9e95af16c4ef3923352ec4c7e374a90 Mon Sep 17 00:00:00 2001 From: fencl Date: Mon, 4 Dec 2017 12:21:21 +0100 Subject: [PATCH 04/28] Implementation of 2D FSM updateCell --- .../tnlDirectEikonalMethodsBase_impl.h | 65 +++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 65f4d0ffe..00b61d2d5 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -187,7 +187,7 @@ initInterface( const MeshFunctionType& input, } } -template< typename Real, +/*template< typename Real, typename Device, typename Index > template< typename MeshEntity > @@ -230,7 +230,7 @@ updateCell( MeshFunctionType& u, fabs( b ) == TypeInfo< Real >::getMaxValue() || fabs( a - b ) >= h ) { - tmp = argAbsMin( a, b ) + sign( value ) * h; + tmp = argAbsMin( a, b ) + sign( value ) * h;*/ /* std::cerr << "a = " << a << " b = " << b << " h = " << h << " ArgAbsMin( a, b ) = " << ArgAbsMin( a, b ) << " sign( value ) = " << sign( value ) << " sign( value ) * h = " << sign( value ) * h @@ -243,14 +243,71 @@ updateCell( MeshFunctionType& u, std::cerr << " tmp = " << tmp << std::endl; std::cerr << " res = " << res << std::endl;*/ - } + /*} else tmp = 0.5 * ( a + b + sign( value ) * sqrt( 2.0 * h * h - ( a - b ) * ( a - b ) ) ); u[ cell.getIndex() ] = argAbsMin( value, tmp ); //std::cerr << ArgAbsMin( value, tmp ) << " "; -} +}*/ +template< typename Real, + typename Device, + typename Index > + template< typename MeshEntity > +void +tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: +updateCell( MeshFunctionType& u, + const MeshEntity& cell) + //MeshFunctionType& v +{ + const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); + const MeshType& mesh = cell.getMesh(); + + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + const RealType value = u( cell ); + //const RealType permeability = v( cell ); + Real a, b, tmp; + + if( cell.getCoordinates().x() == 0 ) + a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + a = u[ neighborEntities.template getEntityIndex< -1, 0 >() ]; + else + { + a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0 >() ], + u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); + } + + if( cell.getCoordinates().y() == 0 ) + b = u[ neighborEntities.template getEntityIndex< 0, 1 >()]; + else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 ) + b = u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; + else + { + b = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, -1 >() ], + u[ neighborEntities.template getEntityIndex< 0, 1 >() ] ); + } + if( fabs( a ) == TypeInfo< Real >::getMaxValue() && + fabs( b ) == TypeInfo< Real >::getMaxValue() ) + return; + if( fabs( a ) == TypeInfo< Real >::getMaxValue() || + fabs( b ) == TypeInfo< Real >::getMaxValue() || + fabs( a - b ) >= TNL::sqrt( (hx * hx + hy * hy)/1 ) ) //permeability ) ) + { + tmp = + fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : + a + TNL::sign( value ) * hx; + } + else + tmp = ( hx * hx * a + hy * hy * b + + sign( value ) * hx * hy * sqrt( ( hx * hx + hy * hy )/1 - + ( a - b ) * ( a - b ) ) )/( hx * hx + hy * hy ); //permeability + + + u[ cell.getIndex() ] = argAbsMin( value, tmp ); +} template< typename Real, typename Device, -- GitLab From 1b4d886525908c612240d1b2f3ecb04d3481f533 Mon Sep 17 00:00:00 2001 From: fencl Date: Sun, 17 Dec 2017 17:46:30 +0100 Subject: [PATCH 05/28] remade initialization in 3D and made updateCell for 3D --- .../tnlDirectEikonalMethodsBase.h | 19 +- .../tnlDirectEikonalMethodsBase_impl.h | 388 ++++++++++++------ 2 files changed, 278 insertions(+), 129 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index c6385f64a..1182ac574 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -37,7 +37,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, - const MeshEntity& cell ); + const MeshEntity& cell); }; @@ -62,7 +62,8 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, - const MeshEntity& cell ); + const MeshEntity& cell, + double velocity = 1.0 ); }; template< typename Real, @@ -85,7 +86,19 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, - const MeshEntity& cell ); + const MeshEntity& cell, + double velocity = 1.0); + + Real sort( Real a, Real b, Real c, + const RealType& ha, + const RealType& hb, + const RealType& hc ); }; +template < typename T1, typename T2 > +T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double v = 1); + +template < typename T1 > +T1 sortMinims( T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc); + #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 00b61d2d5..7456a2fa1 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -34,23 +34,8 @@ initInterface( const MeshFunctionType& input, //const IndexType& c = cell.getIndex(); const IndexType e = neighbors.template getEntityIndex< 1 >(); const IndexType w = neighbors.template getEntityIndex< -1 >(); - - /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ) - { - output[ cell.getIndex() ] = c; - interfaceMap[ cell.getIndex() ] = true; - continue; - }*/ if( c * input[ e ] <=0 ) { - /*if( c >= 0 ) - { - output[ cell.getIndex() ] = ( h * c )/( c - input[ e ] ); - } - else - { - output[ cell.getIndex() ] = - ( h * c )/( c - input[ e ] ); - }*/ output[ cell.getIndex() ] = c >= 0 ? ( h * c )/( c - input[ e ] ) : - ( h * c )/( c - input[ e ] ); @@ -94,19 +79,21 @@ initInterface( const MeshFunctionType& input, MeshFunctionType& output, InterfaceMapType& interfaceMap ) { - const MeshType& mesh = input.getMesh(); - typedef typename MeshType::Cell Cell; - Cell cell( mesh ); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh.getDimensions().y(); - cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh.getDimensions().x(); - cell.getCoordinates().x() ++ ) - output[ cell.getIndex() ] = - input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - TypeInfo< RealType >::getMaxValue(); + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); for( cell.getCoordinates().y() = 0; cell.getCoordinates().y() < mesh.getDimensions().y(); cell.getCoordinates().y() ++ ) @@ -119,20 +106,9 @@ initInterface( const MeshFunctionType& input, if( ! cell.isBoundaryEntity() ) { auto neighbors = cell.getNeighborEntities(); - const RealType& hx = mesh.getSpaceSteps().x(); - const RealType& hy = mesh.getSpaceSteps().y(); Real pom = 0; const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); - //const IndexType w = neighbors.template getEntityIndex< -1, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); - //const IndexType s = neighbors.template getEntityIndex< 0, -1 >(); - /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || - c * input[ n ] <= 0 || c * input[ s ] <= 0 ) - { - output[ cell.getIndex() ] = TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = true; - continue; - }*/ if( c * input[ n ] <= 0 ) { if( c >= 0 ) @@ -152,7 +128,6 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ n ] = true; - continue; } if( c * input[ e ] <= 0 ) { @@ -163,7 +138,7 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ e ] != 0 && output[ e ] >= pom ) + if( output[ e ] >= pom ) output[ e ] = pom; }else { @@ -177,8 +152,8 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ e ] = true; - continue; } + continue; } output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : @@ -187,70 +162,6 @@ initInterface( const MeshFunctionType& input, } } -/*template< typename Real, - typename Device, - typename Index > - template< typename MeshEntity > -void -tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: -updateCell( MeshFunctionType& u, - const MeshEntity& cell ) -{ - const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); - const MeshType& mesh = cell.getMesh(); - - const RealType& h = mesh.getSpaceSteps().x(); - const RealType value = u( cell ); - Real a, b, tmp; - - if( cell.getCoordinates().x() == 0 ) - a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; - else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) - a = u[ neighborEntities.template getEntityIndex< -1, 0 >() ]; - else - { - a = argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0 >() ], - u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); - } - - if( cell.getCoordinates().y() == 0 ) - b = u[ neighborEntities.template getEntityIndex< 0, 1 >()]; - else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 ) - b = u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; - else - { - b = argAbsMin( u[ neighborEntities.template getEntityIndex< 0, -1 >() ], - u[ neighborEntities.template getEntityIndex< 0, 1 >() ] ); - } - - if( fabs( a ) == TypeInfo< Real >::getMaxValue() && - fabs( b ) == TypeInfo< Real >::getMaxValue() ) - return; - if( fabs( a ) == TypeInfo< Real >::getMaxValue() || - fabs( b ) == TypeInfo< Real >::getMaxValue() || - fabs( a - b ) >= h ) - { - tmp = argAbsMin( a, b ) + sign( value ) * h;*/ - /* std::cerr << "a = " << a << " b = " << b << " h = " << h - << " ArgAbsMin( a, b ) = " << ArgAbsMin( a, b ) << " sign( value ) = " << sign( value ) - << " sign( value ) * h = " << sign( value ) * h - << " ArgAbsMin( a, b ) + sign( value ) * h = " << ArgAbsMin( a, b ) + sign( value ) * h - << " tmp = " << tmp << std::endl; - tmp = ArgAbsMin( a, b ) + sign( value ) * h; - tmp = ArgAbsMin( a, b ) + sign( value ) * h; - tmp = ArgAbsMin( a, b ) + sign( value ) * h; - res = ArgAbsMin( a, b ) + sign( value ) * h; - std::cerr << " tmp = " << tmp << std::endl; - std::cerr << " res = " << res << std::endl;*/ - - /*} - else - tmp = 0.5 * ( a + b + sign( value ) * sqrt( 2.0 * h * h - ( a - b ) * ( a - b ) ) ); - - u[ cell.getIndex() ] = argAbsMin( value, tmp ); - //std::cerr << ArgAbsMin( value, tmp ) << " "; -}*/ - template< typename Real, typename Device, typename Index > @@ -258,8 +169,8 @@ template< typename Real, void tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: updateCell( MeshFunctionType& u, - const MeshEntity& cell) - //MeshFunctionType& v + const MeshEntity& cell, + double v) { const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); const MeshType& mesh = cell.getMesh(); @@ -267,7 +178,6 @@ updateCell( MeshFunctionType& u, const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType value = u( cell ); - //const RealType permeability = v( cell ); Real a, b, tmp; if( cell.getCoordinates().x() == 0 ) @@ -292,18 +202,19 @@ updateCell( MeshFunctionType& u, if( fabs( a ) == TypeInfo< Real >::getMaxValue() && fabs( b ) == TypeInfo< Real >::getMaxValue() ) return; - if( fabs( a ) == TypeInfo< Real >::getMaxValue() || + /*if( fabs( a ) == TypeInfo< Real >::getMaxValue() || fabs( b ) == TypeInfo< Real >::getMaxValue() || - fabs( a - b ) >= TNL::sqrt( (hx * hx + hy * hy)/1 ) ) //permeability ) ) + fabs( a - b ) >= TNL::sqrt( (hx * hx + hy * hy)/v ) ) { tmp = fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : a + TNL::sign( value ) * hx; - } - else - tmp = ( hx * hx * a + hy * hy * b + - sign( value ) * hx * hy * sqrt( ( hx * hx + hy * hy )/1 - - ( a - b ) * ( a - b ) ) )/( hx * hx + hy * hy ); //permeability + }*/ + tmp = meet2DCondition( a, b, hx, hy, value); + if( tmp == 0 ) + tmp = + fabs( a ) >= fabs( b ) ? fabs( b ) + TNL::sign( value ) * hy : + fabs( a ) + TNL::sign( value ) * hx; u[ cell.getIndex() ] = argAbsMin( value, tmp ); @@ -321,14 +232,30 @@ initInterface( const MeshFunctionType& input, const MeshType& mesh = input.getMesh(); typedef typename MeshType::Cell Cell; Cell cell( mesh ); - for( cell.getCoordinates().z() = 1; - cell.getCoordinates().z() < mesh.getDimensions().z() - 1; + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh.getDimensions().z(); + cell.getCoordinates().z() ++ ) + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + const RealType& hz = mesh.getSpaceSteps().z(); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh.getDimensions().z(); cell.getCoordinates().z() ++ ) - for( cell.getCoordinates().y() = 1; - cell.getCoordinates().y() < mesh.getDimensions().y() - 1; + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 1; - cell.getCoordinates().x() < mesh.getDimensions().x() - 1; + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); cell.getCoordinates().x() ++ ) { cell.refresh(); @@ -336,27 +263,98 @@ initInterface( const MeshFunctionType& input, if( ! cell.isBoundaryEntity() ) { auto neighbors = cell.getNeighborEntities(); + Real pom = 0; //const IndexType& c = cell.getIndex(); const IndexType e = neighbors.template getEntityIndex< 1, 0, 0 >(); - const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); + //const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1, 0 >(); - const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); + //const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); const IndexType t = neighbors.template getEntityIndex< 0, 0, 1 >(); - const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); - - if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || + //const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); + /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || c * input[ n ] <= 0 || c * input[ s ] <= 0 || c * input[ t ] <= 0 || c * input[ b ] <= 0 ) { output[ cell.getIndex() ] = c; interfaceMap[ cell.getIndex() ] = true; continue; + }*/ + if( c * input[ n ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + output[ n ] = ( hy * c )/( c - input[ n ]) - hy; + }else + { + pom = - ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + output[ n ] = hy - ( hy * c )/( c - input[ n ]); + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; + continue; } + if( c * input[ e ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hx * c )/( c - input[ e ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( output[ e ] >= pom ) + output[ e ] = pom; + }else + { + pom = - (hx * c)/( c - input[ e ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ e ] < pom ) + output[ e ] = pom; + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + continue; + } + if( c * input[ t ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hz * c )/( c - input[ t ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + pom = pom - hz; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( output[ t ] >= pom ) + output[ t ] = pom; + }else + { + pom = - (hz * c)/( c - input[ t ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hz; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ t ] < pom ) + output[ t ] = pom; + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ t ] = true; + continue; } output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : -TypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = false; + } } } @@ -367,7 +365,145 @@ template< typename Real, void tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >:: updateCell( MeshFunctionType& u, - const MeshEntity& cell ) + const MeshEntity& cell, + double v ) { + const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); + const MeshType& mesh = cell.getMesh(); + + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + const RealType& hz = mesh.getSpaceSteps().z(); + const RealType value = u( cell ); + Real a, b, c, tmp = 0; + if( cell.getCoordinates().x() == 0 ) + a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + a = u[ neighborEntities.template getEntityIndex< -1, 0 >() ]; + else + { + a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0 >() ], + u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); + } + + if( cell.getCoordinates().x() == 0 ) + a = u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + a = u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + else + { + a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ], + u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] ); + } + if( cell.getCoordinates().x() == 0 ) + b = u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + b = u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ]; + else + { + b = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ], + u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] ); + }if( cell.getCoordinates().x() == 0 ) + c = u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + c = u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ]; + else + { + c = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ], + u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] ); + } + if( fabs( a ) == TypeInfo< Real >::getMaxValue() && + fabs( b ) == TypeInfo< Real >::getMaxValue() && + fabs( c ) == TypeInfo< Real >::getMaxValue() ) + return; + if( fabs( a ) == TypeInfo< Real >::getMaxValue() || + fabs( b ) == TypeInfo< Real >::getMaxValue() || + fabs( c ) == TypeInfo< Real >::getMaxValue() || + hz * hz * fabs( a - b ) * fabs( a - b ) + hy * hy * fabs( a - c ) * fabs( a - c ) + + hx * hx * fabs( b - c ) * fabs( b - c ) >= ( hx * hx * hy * hy + hx * hx * hz * hz + hy * hy * hz * hz )/v ) + { + /*if( fabs( a ) != TypeInfo< Real >::getMaxValue() && + fabs( b ) != TypeInfo< Real >::getMaxValue() && + fabs( a - b ) >= TNL::sqrt( (hx * hx + hy * hy)/v ) ) + { + tmp = ( hx * hx * a + hy * hy * b + + sign( value ) * hx * hy * sqrt( ( hx * hx + hy * hy )/v - + ( a - b ) * ( a - b ) ) )/( hx * hx + hy * hy ); + } + if( fabs( a ) != TypeInfo< Real >::getMaxValue() && + fabs( c ) != TypeInfo< Real >::getMaxValue() && + fabs( a - c ) >= TNL::sqrt( (hx * hx + hz * hz)/v ) ) + { + tmp = ( hx * hx * a + hz * hz * c + + sign( value ) * hx * hz * sqrt( ( hx * hx + hz * hz )/v - + ( a - c ) * ( a - c ) ) )/( hx * hx + hz * hz ); + } + if( fabs( b ) != TypeInfo< Real >::getMaxValue() && + fabs( c ) != TypeInfo< Real >::getMaxValue() && + fabs( b - c ) >= TNL::sqrt( (hy * hy + hz * hz)/v ) ) + { + tmp = ( hy * hy * b + hz * hz * c + + sign( value ) * hy * hz * sqrt( ( hy * hy + hz * hz )/v - + ( b - c ) * ( b - c ) ) )/( hy * hy + hz * hz ); + }*/ + Real pom = sortMinims( a, b, c, (Real)hx, (Real)hy, (Real)hz); + tmp = meet2DCondition( pom[0], pom[1], pom[3], pom[4]); + + if( tmp == 0 ) + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]; + + } + else + tmp = ( hx * hx * a + hy * hy * b + hz * hz * c + + sign( value ) * hx * hy * hz * sqrt( ( hx * hx + hy * hy + hz * hz)/v - + hz * hz * ( a - b ) * ( a - b ) + hy * hy * ( a - c ) * ( a - c ) + + hx * hx * ( b - c ) * ( b - c ) ) )/( hx * hx + hy * hy + hz * hz ); + + + u[ cell.getIndex() ] = argAbsMin( value, tmp ); +} + +template < typename T1, typename T2 > +T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double v) +{ + T1 tmp; + if( fabs( a ) == TypeInfo< T1 >::getMaxValue() && + fabs( b ) == TypeInfo< T1 >::getMaxValue() && + fabs( a - b ) <= TNL::sqrt( (ha * ha + hb * hb)/v ) ) + { + tmp = ( ha * ha * a + hb * hb * b + + sign( value ) * hb * hb * sqrt( ( ha * ha + hb * hb )/v - + ( a - b ) * ( a - b ) ) )/( ha * ha + hb * hb ); + } + else + tmp = 0; + + return tmp; } + +template < typename T1 > +T1 sortMinims( T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc) +{ + T1 tmp[6]; + if( a <= b && b <= c){ + tmp = {a,b,c,ha,hb,hc}; + } + else if( a <= c && c <= b ){ + tmp = {a,c,b,ha,hc,hb}; + } + else if( b<=a && a<=c ){ + tmp = {b,a,c,hb,ha,hc}; + } + else if( b <= c && c <= a ){ + tmp = {b,c,a,hb,hc,ha}; + } + else if( c <= a && a <= b ){ + tmp = {c,a,b,hc,ha,hb}; + } + else if( c <=b && b <= a ){ + tmp = {c,b,a,hc,hb,ha}; + } + + return tmp; +} \ No newline at end of file -- GitLab From 0577cc48dbc00a774e46e88c0a3c1e93734703c2 Mon Sep 17 00:00:00 2001 From: fencl Date: Tue, 20 Feb 2018 18:47:13 +0100 Subject: [PATCH 06/28] removed some mistakes in methods 2D and 3D --- .../tnlDirectEikonalMethodsBase_impl.h | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 7456a2fa1..461c70f55 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -40,7 +40,6 @@ initInterface( const MeshFunctionType& input, c >= 0 ? ( h * c )/( c - input[ e ] ) : - ( h * c )/( c - input[ e ] ); interfaceMap[ cell.getIndex() ] = true; - continue; } if( c * input[ w ] <=0 ) { @@ -48,7 +47,6 @@ initInterface( const MeshFunctionType& input, c >= 0 ? ( h * c )/( c - input[ w ] ) : - ( h * c )/( c - input[ w ] ); interfaceMap[ cell.getIndex() ] = true; - continue; } } output[ cell.getIndex() ] = @@ -88,9 +86,12 @@ initInterface( const MeshFunctionType& input, for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < mesh.getDimensions().x(); cell.getCoordinates().x() ++ ) + { output[ cell.getIndex() ] = input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); @@ -153,12 +154,11 @@ initInterface( const MeshFunctionType& input, interfaceMap[ cell.getIndex() ] = true; interfaceMap[ e ] = true; } - continue; } - output[ cell.getIndex() ] = + /*output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : - -TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; + -TypeInfo< RealType >::getMaxValue();*/ + //interfaceMap[ cell.getIndex() ] = false; //is on line 90 } } @@ -210,7 +210,7 @@ updateCell( MeshFunctionType& u, fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : a + TNL::sign( value ) * hx; }*/ - tmp = meet2DCondition( a, b, hx, hy, value); + tmp = meet2DCondition( a, b, hx, hy, value, v); if( tmp == 0 ) tmp = fabs( a ) >= fabs( b ) ? fabs( b ) + TNL::sign( value ) * hy : @@ -241,9 +241,12 @@ initInterface( const MeshFunctionType& input, for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < mesh.getDimensions().x(); cell.getCoordinates().x() ++ ) - output[ cell.getIndex() ] = - input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - - TypeInfo< RealType >::getMaxValue(); + { + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); @@ -298,7 +301,6 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ n ] = true; - continue; } if( c * input[ e ] <= 0 ) { @@ -323,7 +325,6 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ e ] = true; - continue; } if( c * input[ t ] <= 0 ) { @@ -348,13 +349,12 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ t ] = true; - continue; + } } - output[ cell.getIndex() ] = + /*output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : -TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; - } + interfaceMap[ cell.getIndex() ] = false;*/ //is on line 245 } } @@ -448,7 +448,7 @@ updateCell( MeshFunctionType& u, ( b - c ) * ( b - c ) ) )/( hy * hy + hz * hz ); }*/ Real pom = sortMinims( a, b, c, (Real)hx, (Real)hy, (Real)hz); - tmp = meet2DCondition( pom[0], pom[1], pom[3], pom[4]); + tmp = meet2DCondition( pom[0], pom[1], pom[3], pom[4], value, v); if( tmp == 0 ) tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]; @@ -468,8 +468,8 @@ template < typename T1, typename T2 > T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double v) { T1 tmp; - if( fabs( a ) == TypeInfo< T1 >::getMaxValue() && - fabs( b ) == TypeInfo< T1 >::getMaxValue() && + if( fabs( a ) != TypeInfo< T1 >::getMaxValue() && + fabs( b ) != TypeInfo< T1 >::getMaxValue() && fabs( a - b ) <= TNL::sqrt( (ha * ha + hb * hb)/v ) ) { tmp = ( ha * ha * a + hb * hb * b + -- GitLab From 53db9650839998c21f68f7f9631d414803ceb29b Mon Sep 17 00:00:00 2001 From: fencl Date: Tue, 27 Feb 2018 17:10:22 +0100 Subject: [PATCH 07/28] tnl-run-fsm-eoc-test: Change of the final file for computeError tnlDirectEikonalMethodsBase_impl.h: 2D method repaired, 3D method ready for debug tnlDirectEikonalMethod2D_impl.h: Added save of aux-* as results from computation tnlDirectEikonalMethod3D_impl.h: Implemented all sweaps and saving results from computation --- .../hamilton-jacobi/tnl-run-fsm-eoc-test | 11 +- .../tnlDirectEikonalMethodsBase.h | 2 +- .../tnlDirectEikonalMethodsBase_impl.h | 143 ++++++++------ .../tnlFastSweepingMethod2D_impl.h | 11 +- .../tnlFastSweepingMethod3D_impl.h | 175 ++++++++++++++++++ 5 files changed, 274 insertions(+), 68 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test index 57a40528b..0dc50246f 100755 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test @@ -2,7 +2,7 @@ device="host" dimensions="2D 3D" -dimensions="2D" +#dimensions="3D" sizes1D="16 32 64 128 256 512 1024 2048 4096" #sizes1D="256" sizes2D="16 32 64 128 256 512 1024" @@ -12,7 +12,7 @@ testFunctions="paraboloid" snapshotPeriod=0.1 finalTime=1.5 solverName="tnl-direct-eikonal-solver" -#solverName="gdb --args tnl-direct-eikonal-solver-dbg" +#solverName="gdb --args tnl-direct-eikonal-solver-dbg --catch-exceptions no" # setupTestFunction() @@ -59,7 +59,7 @@ setupGrid() setInitialCondition() { testFunction=$1 - tnl-init --test-function ${testFunction}-sdf \ + tnl-init --test-function ${testFunction} \ --output-file initial-u.tnl \ --amplitude ${amplitude} \ --wave-length ${waveLength} \ @@ -78,7 +78,7 @@ setInitialCondition() --radius ${radius} tnl-init --test-function ${testFunction}-sdf \ - --output-file final-u.tnl \ + --output-file exact-u.tnl \ --amplitude ${amplitude} \ --wave-length ${waveLength} \ --wave-length-x ${waveLengthX} \ @@ -108,7 +108,6 @@ solve() --time-step 10 \ --time-step-order 2 \ --discrete-solver ${discreteSolver} \ - --merson-adaptivity 1.0e-5 \ --min-iterations 20 \ --convergence-residue 1.0e-12 \ --snapshot-period ${snapshotPeriod} \ @@ -118,7 +117,7 @@ solve() computeError() { tnl-diff --mesh mesh.tnl \ - --input-files final-u.tnl u-*.tnl \ + --input-files aux-final.tnl exact-u.tnl \ --mode sequence \ --snapshot-period ${snapshotPeriod} \ --output-file errors.txt \ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 1182ac574..a4a46396c 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -99,6 +99,6 @@ template < typename T1, typename T2 > T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double v = 1); template < typename T1 > -T1 sortMinims( T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc); +void sortMinims( T1 pom[] ); #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 461c70f55..4cb8327a1 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -86,12 +86,13 @@ initInterface( const MeshFunctionType& input, for( cell.getCoordinates().x() = 0; cell.getCoordinates().x() < mesh.getDimensions().x(); cell.getCoordinates().x() ++ ) - { - output[ cell.getIndex() ] = + { + cell.refresh(); + output[ cell.getIndex() ] = input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; - } + interfaceMap[ cell.getIndex() ] = false; + } const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); @@ -117,15 +118,15 @@ initInterface( const MeshFunctionType& input, pom = ( hy * c )/( c - input[ n ]); if( output[ cell.getIndex() ] > pom ) output[ cell.getIndex() ] = pom; - - output[ n ] = ( hy * c )/( c - input[ n ]) - hy; + if( output[ n ] < pom-hx ) + output[ n ] = pom - hy; //( hy * c )/( c - input[ n ]) - hy; }else { pom = - ( hy * c )/( c - input[ n ]); if( output[ cell.getIndex() ] < pom ) output[ cell.getIndex() ] = pom; - - output[ n ] = hy - ( hy * c )/( c - input[ n ]); + if( output[ n ] > hy + pom ) + output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ n ] = true; @@ -139,7 +140,7 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ e ] >= pom ) + if( output[ e ] < pom ) output[ e ] = pom; }else { @@ -148,7 +149,7 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ e ] < pom ) + if( output[ e ] > pom ) output[ e ] = pom; } interfaceMap[ cell.getIndex() ] = true; @@ -157,7 +158,7 @@ initInterface( const MeshFunctionType& input, } /*output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : - -TypeInfo< RealType >::getMaxValue();*/ + -TypeInfo< RealType >::getMaxValue(); */ //interfaceMap[ cell.getIndex() ] = false; //is on line 90 } } @@ -178,7 +179,7 @@ updateCell( MeshFunctionType& u, const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType value = u( cell ); - Real a, b, tmp; + Real a, b, tmp = TypeInfo< Real >::getMaxValue(); if( cell.getCoordinates().x() == 0 ) a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; @@ -211,10 +212,10 @@ updateCell( MeshFunctionType& u, a + TNL::sign( value ) * hx; }*/ tmp = meet2DCondition( a, b, hx, hy, value, v); - if( tmp == 0 ) + if( tmp == TypeInfo< Real >::getMaxValue() ) tmp = - fabs( a ) >= fabs( b ) ? fabs( b ) + TNL::sign( value ) * hy : - fabs( a ) + TNL::sign( value ) * hx; + fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : + a + TNL::sign( value ) * hx; u[ cell.getIndex() ] = argAbsMin( value, tmp ); @@ -242,6 +243,7 @@ initInterface( const MeshFunctionType& input, cell.getCoordinates().x() < mesh.getDimensions().x(); cell.getCoordinates().x() ++ ) { + cell.refresh(); output[ cell.getIndex() ] = input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - TypeInfo< RealType >::getMaxValue(); @@ -288,16 +290,19 @@ initInterface( const MeshFunctionType& input, { pom = ( hy * c )/( c - input[ n ]); if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; + output[ cell.getIndex() ] = pom; - output[ n ] = ( hy * c )/( c - input[ n ]) - hy; + if ( output[ n ] < pom - hy) + output[ n ] = pom - hy; // ( hy * c )/( c - input[ n ]) - hy; + }else { pom = - ( hy * c )/( c - input[ n ]); if( output[ cell.getIndex() ] < pom ) output[ cell.getIndex() ] = pom; - - output[ n ] = hy - ( hy * c )/( c - input[ n ]); + if( output[ n ] > hy + pom ) + output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); + } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ n ] = true; @@ -308,11 +313,12 @@ initInterface( const MeshFunctionType& input, { pom = ( hx * c )/( c - input[ e ]); if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; + output[ cell.getIndex() ] = pom; pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ e ] >= pom ) - output[ e ] = pom; + if( output[ e ] < pom ) + output[ e ] = pom; + }else { pom = - (hx * c)/( c - input[ e ]); @@ -320,7 +326,7 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ e ] < pom ) + if( output[ e ] > pom ) output[ e ] = pom; } interfaceMap[ cell.getIndex() ] = true; @@ -335,8 +341,9 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom - hz; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ t ] >= pom ) - output[ t ] = pom; + if( output[ t ] < pom ) + output[ t ] = pom; + }else { pom = - (hz * c)/( c - input[ t ]); @@ -344,8 +351,9 @@ initInterface( const MeshFunctionType& input, output[ cell.getIndex() ] = pom; pom = pom + hz; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ t ] < pom ) + if( output[ t ] > pom ) output[ t ] = pom; + } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ t ] = true; @@ -368,24 +376,15 @@ updateCell( MeshFunctionType& u, const MeshEntity& cell, double v ) { - const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); + const auto& neighborEntities = cell.template getNeighborEntities< 3 >(); const MeshType& mesh = cell.getMesh(); const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType& hz = mesh.getSpaceSteps().z(); const RealType value = u( cell ); - Real a, b, c, tmp = 0; + Real a, b, c, tmp = TypeInfo< Real >::getMaxValue(); - if( cell.getCoordinates().x() == 0 ) - a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; - else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) - a = u[ neighborEntities.template getEntityIndex< -1, 0 >() ]; - else - { - a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0 >() ], - u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); - } if( cell.getCoordinates().x() == 0 ) a = u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ]; @@ -396,17 +395,17 @@ updateCell( MeshFunctionType& u, a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ], u[ neighborEntities.template getEntityIndex< 1, 0, 0 >() ] ); } - if( cell.getCoordinates().x() == 0 ) + if( cell.getCoordinates().y() == 0 ) b = u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ]; - else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 ) b = u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ]; else { b = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, -1, 0 >() ], u[ neighborEntities.template getEntityIndex< 0, 1, 0 >() ] ); - }if( cell.getCoordinates().x() == 0 ) + }if( cell.getCoordinates().z() == 0 ) c = u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ]; - else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + else if( cell.getCoordinates().z() == mesh.getDimensions().z() - 1 ) c = u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ]; else { @@ -447,11 +446,12 @@ updateCell( MeshFunctionType& u, sign( value ) * hy * hz * sqrt( ( hy * hy + hz * hz )/v - ( b - c ) * ( b - c ) ) )/( hy * hy + hz * hz ); }*/ - Real pom = sortMinims( a, b, c, (Real)hx, (Real)hy, (Real)hz); - tmp = meet2DCondition( pom[0], pom[1], pom[3], pom[4], value, v); + Real pom[6] = { a, b, c, (Real)hx, (Real)hy, (Real)hz}; + sortMinims( pom ); + tmp = meet2DCondition( pom[0], pom[1], pom[2], pom[3], value, v); - if( tmp == 0 ) - tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]; + if( tmp == TypeInfo< Real >::getMaxValue() ) + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 2 ]; } else @@ -477,33 +477,64 @@ T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double ( a - b ) * ( a - b ) ) )/( ha * ha + hb * hb ); } else - tmp = 0; + { + tmp = TypeInfo< T1 >::getMaxValue(); + } return tmp; } template < typename T1 > -T1 sortMinims( T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc) +void sortMinims( T1 pom[]) +{ + T1 tmp[6]; + if( pom[0] <= pom[1] && pom[1] <= pom[2]){ + tmp[0] = pom[0]; tmp[1] = pom[1]; tmp[2] = pom[3]; tmp[3] = pom[4]; + } + else if( pom[0] <= pom[2] && pom[2] <= pom[1] ){ + tmp[0] = pom[0]; tmp[1] = pom[2]; tmp[2] = pom[3]; tmp[3] = pom[5]; + } + else if( pom[1]<=pom[0] && pom[0] <= pom[2] ){ + tmp[0] = pom[1]; tmp[1] = pom[0]; tmp[2] = pom[4]; tmp[3] = pom[3]; + } + else if( pom[1] <= pom[2] && pom[2] <= pom[0] ){ + tmp[0] = pom[1]; tmp[1] = pom[2]; tmp[2] = pom[4]; tmp[3] = pom[5]; + } + else if( pom[2] <= pom[0] && pom[0] <= pom[1] ){ + tmp[0] = pom[2]; tmp[1] = pom[0]; tmp[2] = pom[5]; tmp[3] = pom[3]; + } + else if( pom[2] <= pom[1] && pom[1] <= pom[0] ){ + tmp[0] = pom[2]; tmp[1] = pom[1]; tmp[2] = pom[5]; tmp[3] = pom[4]; + } + for( int i = 0; i < 6; i++ ) + pom[ i ] = tmp[ i ]; + +} + +/*template < typename T1 > +T1* sortMinims( T1 pom[], T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc) { - T1 tmp[6]; + T1 tmp[6] = pom; if( a <= b && b <= c){ - tmp = {a,b,c,ha,hb,hc}; + tmp[0] = a; tmp[1] = b; tmp[2] = ha; tmp[3] = hb; } else if( a <= c && c <= b ){ - tmp = {a,c,b,ha,hc,hb}; + tmp[0] = a; tmp[1] = c; tmp[2] = ha; tmp[3] = hc; } else if( b<=a && a<=c ){ - tmp = {b,a,c,hb,ha,hc}; + tmp[0] = b; tmp[1] = a; tmp[2] = hb; tmp[3] = ha; } else if( b <= c && c <= a ){ - tmp = {b,c,a,hb,hc,ha}; + tmp[0] = b; tmp[1] = c; tmp[2] = hb; tmp[3] = hc; } else if( c <= a && a <= b ){ - tmp = {c,a,b,hc,ha,hb}; + tmp[0] = c; tmp[1] = a; tmp[2] = hc; tmp[3] = ha; } else if( c <=b && b <= a ){ - tmp = {c,b,a,hc,hb,ha}; + tmp[0] = c; tmp[1] = b; tmp[2] = hc; tmp[3] = hb; } + for( int i = 0; i < 6; i++ ) + pom[ i ] = tmp[ i ]; - return tmp; -} \ No newline at end of file + return pom; +}*/ \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 13e5c8249..bb1d4a018 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -64,7 +64,7 @@ solve( const MeshPointer& mesh, interfaceMap.setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, aux, interfaceMap ); - //aux.save( "aux-ini.tnl" ); + aux.save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); @@ -85,7 +85,7 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - //aux.save( "aux-1.tnl" ); + aux.save( "aux-1.tnl" ); for( cell.getCoordinates().y() = 0; cell.getCoordinates().y() < mesh->getDimensions().y(); @@ -101,7 +101,7 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - //aux.save( "aux-2.tnl" ); + aux.save( "aux-2.tnl" ); for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; cell.getCoordinates().y() >= 0 ; @@ -117,7 +117,7 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - //aux.save( "aux-3.tnl" ); + aux.save( "aux-3.tnl" ); for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; @@ -134,8 +134,9 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - //aux.save( "aux-4.tnl" ); + aux.save( "aux-4.tnl" ); iteration++; } + aux.save("aux-final.tnl"); } diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 6fad87c7e..2c281617f 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -65,5 +65,180 @@ solve( const MeshPointer& mesh, std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, aux, interfaceMap ); aux.save( "aux-ini.tnl" ); + + typename MeshType::Cell cell( *mesh ); + + IndexType iteration( 0 ); + while( iteration < this->maxIterations ) + { + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-1.tnl" ); + + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-2.tnl" ); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-3.tnl" ); + + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-4.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "5 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-5.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "6 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-6.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "7 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-7.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "8 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + aux.save( "aux-8.tnl" ); + iteration++; + + } + aux.save("aux-final.tnl"); } -- GitLab From 9b293e449f94ce30a4c48325ca5ff9849473d346 Mon Sep 17 00:00:00 2001 From: fencl Date: Sun, 4 Mar 2018 08:31:43 +0100 Subject: [PATCH 08/28] final changes in 3D updateCell --- .../tnlDirectEikonalMethodsBase_impl.h | 56 +++++-------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 4cb8327a1..42a1eed11 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -1,4 +1,4 @@ -/* + /* * File: tnlDirectEikonalMethodsBase_impl.h * Author: oberhuber * @@ -118,7 +118,7 @@ initInterface( const MeshFunctionType& input, pom = ( hy * c )/( c - input[ n ]); if( output[ cell.getIndex() ] > pom ) output[ cell.getIndex() ] = pom; - if( output[ n ] < pom-hx ) + if( output[ n ] < pom - hy ) output[ n ] = pom - hy; //( hy * c )/( c - input[ n ]) - hy; }else { @@ -214,8 +214,8 @@ updateCell( MeshFunctionType& u, tmp = meet2DCondition( a, b, hx, hy, value, v); if( tmp == TypeInfo< Real >::getMaxValue() ) tmp = - fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : - a + TNL::sign( value ) * hx; + fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy/v : + a + TNL::sign( value ) * hx/v; u[ cell.getIndex() ] = argAbsMin( value, tmp ); @@ -357,7 +357,7 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ t ] = true; - } + } } /*output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : @@ -383,7 +383,7 @@ updateCell( MeshFunctionType& u, const RealType& hy = mesh.getSpaceSteps().y(); const RealType& hz = mesh.getSpaceSteps().z(); const RealType value = u( cell ); - Real a, b, c, tmp = TypeInfo< Real >::getMaxValue(); + Real a, b, c, tmp = TypeInfo< RealType >::getMaxValue(); if( cell.getCoordinates().x() == 0 ) @@ -451,7 +451,7 @@ updateCell( MeshFunctionType& u, tmp = meet2DCondition( pom[0], pom[1], pom[2], pom[3], value, v); if( tmp == TypeInfo< Real >::getMaxValue() ) - tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 2 ]; + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 2 ]/v; } else @@ -488,53 +488,25 @@ template < typename T1 > void sortMinims( T1 pom[]) { T1 tmp[6]; - if( pom[0] <= pom[1] && pom[1] <= pom[2]){ + if( fabs(pom[0]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[2])){ tmp[0] = pom[0]; tmp[1] = pom[1]; tmp[2] = pom[3]; tmp[3] = pom[4]; } - else if( pom[0] <= pom[2] && pom[2] <= pom[1] ){ + else if( fabs(pom[0]) <= fabs(pom[2]) && fabs(pom[2]) <= fabs(pom[1]) ){ tmp[0] = pom[0]; tmp[1] = pom[2]; tmp[2] = pom[3]; tmp[3] = pom[5]; } - else if( pom[1]<=pom[0] && pom[0] <= pom[2] ){ + else if( fabs(pom[1]) <= fabs(pom[0]) && fabs(pom[0]) <= fabs(pom[2]) ){ tmp[0] = pom[1]; tmp[1] = pom[0]; tmp[2] = pom[4]; tmp[3] = pom[3]; } - else if( pom[1] <= pom[2] && pom[2] <= pom[0] ){ + else if( fabs(pom[1]) <= fabs(pom[2]) && fabs(pom[2]) <= fabs(pom[0]) ){ tmp[0] = pom[1]; tmp[1] = pom[2]; tmp[2] = pom[4]; tmp[3] = pom[5]; } - else if( pom[2] <= pom[0] && pom[0] <= pom[1] ){ + else if( fabs(pom[2]) <= fabs(pom[0]) && fabs(pom[0]) <= fabs(pom[1]) ){ tmp[0] = pom[2]; tmp[1] = pom[0]; tmp[2] = pom[5]; tmp[3] = pom[3]; } - else if( pom[2] <= pom[1] && pom[1] <= pom[0] ){ + else if( fabs(pom[2]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[0]) ){ tmp[0] = pom[2]; tmp[1] = pom[1]; tmp[2] = pom[5]; tmp[3] = pom[4]; } for( int i = 0; i < 6; i++ ) pom[ i ] = tmp[ i ]; -} - -/*template < typename T1 > -T1* sortMinims( T1 pom[], T1 a, T1 b, T1 c, T1 ha, T1 hb, T1 hc) -{ - T1 tmp[6] = pom; - if( a <= b && b <= c){ - tmp[0] = a; tmp[1] = b; tmp[2] = ha; tmp[3] = hb; - } - else if( a <= c && c <= b ){ - tmp[0] = a; tmp[1] = c; tmp[2] = ha; tmp[3] = hc; - } - else if( b<=a && a<=c ){ - tmp[0] = b; tmp[1] = a; tmp[2] = hb; tmp[3] = ha; - } - else if( b <= c && c <= a ){ - tmp[0] = b; tmp[1] = c; tmp[2] = hb; tmp[3] = hc; - } - else if( c <= a && a <= b ){ - tmp[0] = c; tmp[1] = a; tmp[2] = hc; tmp[3] = ha; - } - else if( c <=b && b <= a ){ - tmp[0] = c; tmp[1] = b; tmp[2] = hc; tmp[3] = hb; - } - for( int i = 0; i < 6; i++ ) - pom[ i ] = tmp[ i ]; - - return pom; -}*/ \ No newline at end of file +} \ No newline at end of file -- GitLab From 7d7e266ec1467f761c1f3a6fd11a3e7b85f9b22b Mon Sep 17 00:00:00 2001 From: fencl Date: Wed, 28 Mar 2018 16:06:09 +0200 Subject: [PATCH 09/28] final changes in algorithms of FastSweepingMethod (Zhao) --- .../tnlDirectEikonalMethodsBase.h | 10 +- .../tnlDirectEikonalMethodsBase_impl.h | 198 ++++++++++++------ .../tnlFastSweepingMethod2D_impl.h | 82 +++++++- .../tnlFastSweepingMethod3D_impl.h | 16 +- 4 files changed, 218 insertions(+), 88 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index a4a46396c..4dc8e9228 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -37,7 +37,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, - const MeshEntity& cell); + const MeshEntity& cell ); }; @@ -63,7 +63,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, const MeshEntity& cell, - double velocity = 1.0 ); + const RealType velocity = 1.0 ); }; template< typename Real, @@ -87,12 +87,12 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > template< typename MeshEntity > void updateCell( MeshFunctionType& u, const MeshEntity& cell, - double velocity = 1.0); + const RealType velocity = 1.0); - Real sort( Real a, Real b, Real c, + /*Real sort( Real a, Real b, Real c, const RealType& ha, const RealType& hb, - const RealType& hc ); + const RealType& hc ); */ }; template < typename T1, typename T2 > diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 42a1eed11..caa2f533f 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -8,7 +8,7 @@ #pragma once #include - +#include template< typename Real, typename Device, typename Index > @@ -111,7 +111,22 @@ initInterface( const MeshFunctionType& input, Real pom = 0; const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); + //Try init with exact data: if( c * input[ n ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ n ] = input[ n ]; + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; + } + if( c * input[ e ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ e ] = input[ e ]; + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + } + /*if( c * input[ n ] <= 0 ) { if( c >= 0 ) { @@ -154,12 +169,8 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ e ] = true; - } + }*/ } - /*output[ cell.getIndex() ] = - c > 0 ? TypeInfo< RealType >::getMaxValue() : - -TypeInfo< RealType >::getMaxValue(); */ - //interfaceMap[ cell.getIndex() ] = false; //is on line 90 } } @@ -170,8 +181,8 @@ template< typename Real, void tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: updateCell( MeshFunctionType& u, - const MeshEntity& cell, - double v) + const MeshEntity& cell, + const RealType v) { const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); const MeshType& mesh = cell.getMesh(); @@ -179,7 +190,7 @@ updateCell( MeshFunctionType& u, const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType value = u( cell ); - Real a, b, tmp = TypeInfo< Real >::getMaxValue(); + RealType a, b, tmp1, tmp = TypeInfo< RealType >::getMaxValue(); if( cell.getCoordinates().x() == 0 ) a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; @@ -188,7 +199,7 @@ updateCell( MeshFunctionType& u, else { a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1, 0 >() ], - u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); + u[ neighborEntities.template getEntityIndex< 1, 0 >() ] ); } if( cell.getCoordinates().y() == 0 ) @@ -198,10 +209,10 @@ updateCell( MeshFunctionType& u, else { b = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, -1 >() ], - u[ neighborEntities.template getEntityIndex< 0, 1 >() ] ); + u[ neighborEntities.template getEntityIndex< 0, 1 >() ] ); } - if( fabs( a ) == TypeInfo< Real >::getMaxValue() && - fabs( b ) == TypeInfo< Real >::getMaxValue() ) + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && + fabs( b ) == TypeInfo< RealType >::getMaxValue() ) return; /*if( fabs( a ) == TypeInfo< Real >::getMaxValue() || fabs( b ) == TypeInfo< Real >::getMaxValue() || @@ -211,14 +222,37 @@ updateCell( MeshFunctionType& u, fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy : a + TNL::sign( value ) * hx; }*/ - tmp = meet2DCondition( a, b, hx, hy, value, v); - if( tmp == TypeInfo< Real >::getMaxValue() ) - tmp = - fabs( a ) >= fabs( b ) ? b + TNL::sign( value ) * hy/v : + /*if( fabs( a ) != TypeInfo< Real >::getMaxValue() && + fabs( b ) != TypeInfo< Real >::getMaxValue() && + fabs( a - b ) < TNL::sqrt( (hx * hx + hy * hy)/v ) ) + { + tmp = ( hx * hx * b + hy * hy * a + + sign( value ) * hx * hy * TNL::sqrt( ( hx * hx + hy * hy )/v - + ( a - b ) * ( a - b ) ) )/( hx * hx + hy * hy ); + u[ cell.getIndex() ] = tmp; + } + else + { + tmp = + fabs( a ) > fabs( b ) ? b + TNL::sign( value ) * hy/v : a + TNL::sign( value ) * hx/v; - - - u[ cell.getIndex() ] = argAbsMin( value, tmp ); + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + //tmp = TypeInfo< RealType >::getMaxValue(); + }*/ + RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, 0.0 }; + sortMinims( pom ); + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]/v; + + + if( fabs( tmp ) < fabs( pom[ 1 ] ) ) + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + else + { + tmp = ( pom[ 3 ] * pom[ 3 ] * pom[ 1 ] + pom[ 4 ] * pom[ 4 ] * pom[ 0 ] + + TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - + ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + } } template< typename Real, @@ -245,7 +279,7 @@ initInterface( const MeshFunctionType& input, { cell.refresh(); output[ cell.getIndex() ] = - input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + input( cell ) > 0 ? TypeInfo< RealType >::getMaxValue() : - TypeInfo< RealType >::getMaxValue(); interfaceMap[ cell.getIndex() ] = false; } @@ -269,20 +303,33 @@ initInterface( const MeshFunctionType& input, { auto neighbors = cell.getNeighborEntities(); Real pom = 0; - //const IndexType& c = cell.getIndex(); const IndexType e = neighbors.template getEntityIndex< 1, 0, 0 >(); - //const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); const IndexType n = neighbors.template getEntityIndex< 0, 1, 0 >(); - //const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); const IndexType t = neighbors.template getEntityIndex< 0, 0, 1 >(); - //const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); - /*if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || - c * input[ n ] <= 0 || c * input[ s ] <= 0 || - c * input[ t ] <= 0 || c * input[ b ] <= 0 ) + //Try exact initiation + /*const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); + const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); + const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); + if( c * input[ e ] <= 0 ) { output[ cell.getIndex() ] = c; + output[ e ] = input[ e ]; + interfaceMap[ e ] = true; + interfaceMap[ cell.getIndex() ] = true; + } + else if( c * input[ n ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ n ] = input[ n ]; + interfaceMap[ n ] = true; + interfaceMap[ cell.getIndex() ] = true; + } + else if( c * input[ t ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ t ] = input[ t ]; + interfaceMap[ t ] = true; interfaceMap[ cell.getIndex() ] = true; - continue; }*/ if( c * input[ n ] <= 0 ) { @@ -357,7 +404,7 @@ initInterface( const MeshFunctionType& input, } interfaceMap[ cell.getIndex() ] = true; interfaceMap[ t ] = true; - } + } } /*output[ cell.getIndex() ] = c > 0 ? TypeInfo< RealType >::getMaxValue() : @@ -374,7 +421,7 @@ void tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >:: updateCell( MeshFunctionType& u, const MeshEntity& cell, - double v ) + const RealType v ) { const auto& neighborEntities = cell.template getNeighborEntities< 3 >(); const MeshType& mesh = cell.getMesh(); @@ -383,7 +430,8 @@ updateCell( MeshFunctionType& u, const RealType& hy = mesh.getSpaceSteps().y(); const RealType& hz = mesh.getSpaceSteps().z(); const RealType value = u( cell ); - Real a, b, c, tmp = TypeInfo< RealType >::getMaxValue(); + //std::cout << value << std::endl; + RealType a, b, c, tmp = TypeInfo< RealType >::getMaxValue(); if( cell.getCoordinates().x() == 0 ) @@ -412,16 +460,12 @@ updateCell( MeshFunctionType& u, c = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< 0, 0, -1 >() ], u[ neighborEntities.template getEntityIndex< 0, 0, 1 >() ] ); } - if( fabs( a ) == TypeInfo< Real >::getMaxValue() && - fabs( b ) == TypeInfo< Real >::getMaxValue() && - fabs( c ) == TypeInfo< Real >::getMaxValue() ) + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && + fabs( b ) == TypeInfo< RealType >::getMaxValue() && + fabs( c ) == TypeInfo< RealType >::getMaxValue() ) return; - if( fabs( a ) == TypeInfo< Real >::getMaxValue() || - fabs( b ) == TypeInfo< Real >::getMaxValue() || - fabs( c ) == TypeInfo< Real >::getMaxValue() || - hz * hz * fabs( a - b ) * fabs( a - b ) + hy * hy * fabs( a - c ) * fabs( a - c ) + - hx * hx * fabs( b - c ) * fabs( b - c ) >= ( hx * hx * hy * hy + hx * hx * hz * hz + hy * hy * hz * hz )/v ) - { + + /*if( fabs( a ) != TypeInfo< Real >::getMaxValue() && fabs( b ) != TypeInfo< Real >::getMaxValue() && fabs( a - b ) >= TNL::sqrt( (hx * hx + hy * hy)/v ) ) @@ -446,22 +490,31 @@ updateCell( MeshFunctionType& u, sign( value ) * hy * hz * sqrt( ( hy * hy + hz * hz )/v - ( b - c ) * ( b - c ) ) )/( hy * hy + hz * hz ); }*/ - Real pom[6] = { a, b, c, (Real)hx, (Real)hy, (Real)hz}; - sortMinims( pom ); - tmp = meet2DCondition( pom[0], pom[1], pom[2], pom[3], value, v); - - if( tmp == TypeInfo< Real >::getMaxValue() ) - tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 2 ]/v; - - } - else - tmp = ( hx * hx * a + hy * hy * b + hz * hz * c + - sign( value ) * hx * hy * hz * sqrt( ( hx * hx + hy * hy + hz * hz)/v - - hz * hz * ( a - b ) * ( a - b ) + hy * hy * ( a - c ) * ( a - c ) + - hx * hx * ( b - c ) * ( b - c ) ) )/( hx * hx + hy * hy + hz * hz ); - - - u[ cell.getIndex() ] = argAbsMin( value, tmp ); + RealType pom[6] = { a, b, c, (RealType)hx, (RealType)hy, (RealType)hz}; + sortMinims( pom ); + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]; + if( fabs( tmp ) < fabs( pom[ 1 ] ) ) + { + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + } + else + { + tmp = ( pom[ 3 ] * pom[ 3 ] * pom[ 1 ] + pom[ 4 ] * pom[ 4 ] * pom[ 0 ] + + TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - + ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); + if( fabs( tmp ) < fabs( pom[ 2 ]) ) + { + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + } + else + { + tmp = ( hy * hy * hz * hz * a + hx * hx * hz * hz * b + hx * hx * hy * hy * c + + TNL::sign( value ) * hx * hy * hz * TNL::sqrt( ( hx * hx * hz * hz + hy * hy * hz * hz + hx * hx * hy * hy)/( v * v ) - + hz * hz * ( a - b ) * ( a - b ) - hy * hy * ( a - c ) * ( a - c ) - + hx * hx * ( b - c ) * ( b - c ) ) )/( hx * hx * hy * hy + hy * hy * hz * hz + hz * hz * hx *hx ); + u[ cell.getIndex() ] = argAbsMin( value, tmp ); + } + } } template < typename T1, typename T2 > @@ -470,10 +523,10 @@ T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double T1 tmp; if( fabs( a ) != TypeInfo< T1 >::getMaxValue() && fabs( b ) != TypeInfo< T1 >::getMaxValue() && - fabs( a - b ) <= TNL::sqrt( (ha * ha + hb * hb)/v ) ) + fabs( a - b ) < ha/v )//TNL::sqrt( (ha * ha + hb * hb)/2 )/v ) { - tmp = ( ha * ha * a + hb * hb * b + - sign( value ) * hb * hb * sqrt( ( ha * ha + hb * hb )/v - + tmp = ( ha * ha * b + hb * hb * a + + TNL::sign( value ) * ha * hb * TNL::sqrt( ( ha * ha + hb * hb )/( v * v ) - ( a - b ) * ( a - b ) ) )/( ha * ha + hb * hb ); } else @@ -487,26 +540,35 @@ T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double template < typename T1 > void sortMinims( T1 pom[]) { - T1 tmp[6]; + T1 tmp[6] = {0.0,0.0,0.0,0.0,0.0,0.0}; if( fabs(pom[0]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[2])){ - tmp[0] = pom[0]; tmp[1] = pom[1]; tmp[2] = pom[3]; tmp[3] = pom[4]; + tmp[0] = pom[0]; tmp[1] = pom[1]; tmp[2] = pom[2]; + tmp[3] = pom[3]; tmp[4] = pom[4]; tmp[5] = pom[5]; + } else if( fabs(pom[0]) <= fabs(pom[2]) && fabs(pom[2]) <= fabs(pom[1]) ){ - tmp[0] = pom[0]; tmp[1] = pom[2]; tmp[2] = pom[3]; tmp[3] = pom[5]; + tmp[0] = pom[0]; tmp[1] = pom[2]; tmp[2] = pom[1]; + tmp[3] = pom[3]; tmp[4] = pom[5]; tmp[5] = pom[4]; } else if( fabs(pom[1]) <= fabs(pom[0]) && fabs(pom[0]) <= fabs(pom[2]) ){ - tmp[0] = pom[1]; tmp[1] = pom[0]; tmp[2] = pom[4]; tmp[3] = pom[3]; + tmp[0] = pom[1]; tmp[1] = pom[0]; tmp[2] = pom[2]; + tmp[3] = pom[4]; tmp[4] = pom[3]; tmp[5] = pom[5]; } else if( fabs(pom[1]) <= fabs(pom[2]) && fabs(pom[2]) <= fabs(pom[0]) ){ - tmp[0] = pom[1]; tmp[1] = pom[2]; tmp[2] = pom[4]; tmp[3] = pom[5]; + tmp[0] = pom[1]; tmp[1] = pom[2]; tmp[2] = pom[0]; + tmp[3] = pom[4]; tmp[4] = pom[5]; tmp[5] = pom[3]; } else if( fabs(pom[2]) <= fabs(pom[0]) && fabs(pom[0]) <= fabs(pom[1]) ){ - tmp[0] = pom[2]; tmp[1] = pom[0]; tmp[2] = pom[5]; tmp[3] = pom[3]; + tmp[0] = pom[2]; tmp[1] = pom[0]; tmp[2] = pom[1]; + tmp[3] = pom[5]; tmp[4] = pom[3]; tmp[5] = pom[4]; } else if( fabs(pom[2]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[0]) ){ - tmp[0] = pom[2]; tmp[1] = pom[1]; tmp[2] = pom[5]; tmp[3] = pom[4]; + tmp[0] = pom[2]; tmp[1] = pom[1]; tmp[2] = pom[0]; + tmp[3] = pom[5]; tmp[4] = pom[4]; tmp[5] = pom[3]; } + for( int i = 0; i < 6; i++ ) + { pom[ i ] = tmp[ i ]; - + } } \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index bb1d4a018..e90743a80 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -85,7 +85,8 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - aux.save( "aux-1.tnl" ); + + //aux.save( "aux-1.tnl" ); for( cell.getCoordinates().y() = 0; cell.getCoordinates().y() < mesh->getDimensions().y(); @@ -101,7 +102,8 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - aux.save( "aux-2.tnl" ); + + //aux.save( "aux-2.tnl" ); for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; cell.getCoordinates().y() >= 0 ; @@ -117,9 +119,9 @@ solve( const MeshPointer& mesh, this->updateCell( aux, cell ); } } - aux.save( "aux-3.tnl" ); - - + + //aux.save( "aux-3.tnl" ); + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; cell.getCoordinates().y() >= 0; cell.getCoordinates().y()-- ) @@ -133,8 +135,74 @@ solve( const MeshPointer& mesh, if( ! interfaceMap( cell ) ) this->updateCell( aux, cell ); } - } - aux.save( "aux-4.tnl" ); + } + + //aux.save( "aux-4.tnl" ); + + /*for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().y(); + cell.getCoordinates().x()++ ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().x(); + cell.getCoordinates().y()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + + + aux.save( "aux-5.tnl" ); + + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().y(); + cell.getCoordinates().x()++ ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + aux.save( "aux-6.tnl" ); + + for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().x(); + cell.getCoordinates().y()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + aux.save( "aux-7.tnl" ); + + for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; + cell.getCoordinates().x() >= 0; + cell.getCoordinates().x()-- ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + }*/ + iteration++; } aux.save("aux-final.tnl"); diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 2c281617f..9844c4fca 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -89,7 +89,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-1.tnl" ); + //aux.save( "aux-1.tnl" ); for( cell.getCoordinates().z() = 0; cell.getCoordinates().z() < mesh->getDimensions().z(); @@ -110,7 +110,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-2.tnl" ); + //aux.save( "aux-2.tnl" ); for( cell.getCoordinates().z() = 0; cell.getCoordinates().z() < mesh->getDimensions().z(); cell.getCoordinates().z()++ ) @@ -130,7 +130,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-3.tnl" ); + //aux.save( "aux-3.tnl" ); for( cell.getCoordinates().z() = 0; cell.getCoordinates().z() < mesh->getDimensions().z(); @@ -151,7 +151,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-4.tnl" ); + //aux.save( "aux-4.tnl" ); for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; cell.getCoordinates().z() >= 0; @@ -172,7 +172,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-5.tnl" ); + //aux.save( "aux-5.tnl" ); for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; cell.getCoordinates().z() >= 0; @@ -193,7 +193,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-6.tnl" ); + //aux.save( "aux-6.tnl" ); for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; cell.getCoordinates().z() >= 0; @@ -214,7 +214,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-7.tnl" ); + //aux.save( "aux-7.tnl" ); for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; cell.getCoordinates().z() >= 0; @@ -235,7 +235,7 @@ solve( const MeshPointer& mesh, } } } - aux.save( "aux-8.tnl" ); + //aux.save( "aux-8.tnl" ); iteration++; } -- GitLab From bb045e76958f3b54a244b993e8267d49cbbee4c1 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Thu, 5 Apr 2018 11:48:06 +0200 Subject: [PATCH 10/28] Added CUDA switch. --- .../tnlDirectEikonalMethodsBase.h | 17 +- .../tnlFastSweepingMethod2D_impl.h | 234 +++++++++--------- 2 files changed, 129 insertions(+), 122 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 4dc8e9228..2dabb5f1a 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -9,6 +9,7 @@ #include #include +#include using namespace TNL; @@ -36,8 +37,8 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > InterfaceMapType& interfaceMap ); template< typename MeshEntity > - void updateCell( MeshFunctionType& u, - const MeshEntity& cell ); + __cuda_callable__ void updateCell( MeshFunctionType& u, + const MeshEntity& cell ); }; @@ -61,9 +62,9 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > InterfaceMapType& interfaceMap ); template< typename MeshEntity > - void updateCell( MeshFunctionType& u, - const MeshEntity& cell, - const RealType velocity = 1.0 ); + __cuda_callable__ void updateCell( MeshFunctionType& u, + const MeshEntity& cell, + const RealType velocity = 1.0 ); }; template< typename Real, @@ -85,9 +86,9 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > InterfaceMapType& interfaceMap ); template< typename MeshEntity > - void updateCell( MeshFunctionType& u, - const MeshEntity& cell, - const RealType velocity = 1.0); + __cuda_callable__ void updateCell( MeshFunctionType& u, + const MeshEntity& cell, + const RealType velocity = 1.0); /*Real sort( Real a, Real b, Real c, const RealType& ha, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index e90743a80..b727f0cd9 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -71,137 +71,143 @@ solve( const MeshPointer& mesh, IndexType iteration( 0 ); while( iteration < this->maxIterations ) { - - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) + if( std::is_same< DeviceType, Devices::Host >::value ) { - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); - cell.getCoordinates().x()++ ) + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + + //aux.save( "aux-1.tnl" ); + + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + + //aux.save( "aux-2.tnl" ); + + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) { - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } } - } - - //aux.save( "aux-1.tnl" ); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) - { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) + //aux.save( "aux-3.tnl" ); + + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) { - //std::cerr << "2 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } } - } - - //aux.save( "aux-2.tnl" ); - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0 ; - cell.getCoordinates().y()-- ) + //aux.save( "aux-4.tnl" ); + + /*for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().y(); + cell.getCoordinates().x()++ ) { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().x(); + cell.getCoordinates().y()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + + + aux.save( "aux-5.tnl" ); + for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x() < mesh->getDimensions().y(); cell.getCoordinates().x()++ ) - { - //std::cerr << "3 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - - //aux.save( "aux-3.tnl" ); - - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0; - cell.getCoordinates().y()-- ) { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + aux.save( "aux-6.tnl" ); + + for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) + cell.getCoordinates().x()-- ) { - //std::cerr << "4 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().x(); + cell.getCoordinates().y()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } } - } - - //aux.save( "aux-4.tnl" ); - - /*for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().y(); - cell.getCoordinates().x()++ ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().x(); - cell.getCoordinates().y()++ ) + aux.save( "aux-7.tnl" ); + + for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; + cell.getCoordinates().x() >= 0; + cell.getCoordinates().x()-- ) { - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - - - aux.save( "aux-5.tnl" ); - - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().y(); - cell.getCoordinates().x()++ ) + for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + }*/ + } + if( std::is_same< DeviceType, Devices::Cuda >::value ) { - for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; - cell.getCoordinates().y() >= 0 ; - cell.getCoordinates().y()-- ) - { - //std::cerr << "2 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } + // TODO: CUDA code } - aux.save( "aux-6.tnl" ); - - for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().x(); - cell.getCoordinates().y()++ ) - { - //std::cerr << "3 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - aux.save( "aux-7.tnl" ); - - for( cell.getCoordinates().x() = mesh->getDimensions().y() - 1; - cell.getCoordinates().x() >= 0; - cell.getCoordinates().x()-- ) - { - for( cell.getCoordinates().y() = mesh->getDimensions().x() - 1; - cell.getCoordinates().y() >= 0 ; - cell.getCoordinates().y()-- ) - { - //std::cerr << "4 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - }*/ iteration++; } -- GitLab From c04814b8bbdf2cec64ed78828286b3bd2d078492 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Thu, 12 Apr 2018 12:11:52 +0200 Subject: [PATCH 11/28] Added CUDA build for eikonal solver. --- .../Solvers/hamilton-jacobi/CMakeLists.txt | 9 +++++++-- .../Solvers/hamilton-jacobi/tnlFastSweepingMethod.h | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt index 176c9859e..fa8dd56d3 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt @@ -10,8 +10,13 @@ set( tnl_hamilton_jacobi_SOURCES #ADD_EXECUTABLE(tnl-hamilton-jacobi${debugExt} main.cpp) #target_link_libraries (tnl-hamilton-jacobi${debugExt} tnl${debugExt}-${tnlVersion} ) -ADD_EXECUTABLE(tnl-direct-eikonal-solver${debugExt} tnl-direct-eikonal-solver.cpp ) -target_link_libraries (tnl-direct-eikonal-solver${debugExt} tnl${debugExt}-${tnlVersion} ) +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(tnl-direct-eikonal-solver${debugExt} tnl-direct-eikonal-solver.cu ) + target_link_libraries (tnl-direct-eikonal-solver${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(tnl-direct-eikonal-solver${debugExt} tnl-direct-eikonal-solver.cpp ) + target_link_libraries (tnl-direct-eikonal-solver${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) INSTALL( TARGETS #tnl-hamilton-jacobi${debugExt} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h index 17d139b0e..61104a143 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h @@ -28,7 +28,7 @@ template< typename Real, class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy > : public tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > { - static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); + //static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); public: @@ -66,7 +66,7 @@ template< typename Real, class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy > : public tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > { - static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); + //static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); public: @@ -104,7 +104,7 @@ template< typename Real, class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy > : public tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > { - static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); + //static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." ); public: -- GitLab From 092c253803f6ba824126e16b48b361452b58701b Mon Sep 17 00:00:00 2001 From: fencl Date: Tue, 17 Apr 2018 15:04:48 +0200 Subject: [PATCH 12/28] Cuda init start --- .../tnlDirectEikonalMethodsBase.h | 15 +- .../tnlDirectEikonalMethodsBase_impl.h | 275 ++++++++++++------ .../tnlFastSweepingMethod2D_impl.h | 49 +++- 3 files changed, 245 insertions(+), 94 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 2dabb5f1a..e6781a7d6 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -49,7 +49,6 @@ template< typename Real, class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > { public: - typedef Meshes::Grid< 2, Real, Device, Index > MeshType; typedef Real RealType; typedef Device DevcieType; @@ -65,6 +64,8 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > __cuda_callable__ void updateCell( MeshFunctionType& u, const MeshEntity& cell, const RealType velocity = 1.0 ); + protected: + }; template< typename Real, @@ -100,6 +101,16 @@ template < typename T1, typename T2 > T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double v = 1); template < typename T1 > -void sortMinims( T1 pom[] ); +__cuda_callable__ void sortMinims( T1 pom[] ); + + +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ); + +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ); #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index caa2f533f..1df41cf80 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -8,7 +8,9 @@ #pragma once #include + #include +#include "tnlFastSweepingMethod.h" template< typename Real, typename Device, typename Index > @@ -67,7 +69,6 @@ updateCell( MeshFunctionType& u, { } - template< typename Real, typename Device, typename Index > @@ -75,102 +76,125 @@ void tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: initInterface( const MeshFunctionType& input, MeshFunctionType& output, - InterfaceMapType& interfaceMap ) + InterfaceMapType& interfaceMap ) { + /* + doplnit přepočty pro cudu: + * overit is_same device + * na kazdy bod jedno cuda vlakno + */ const MeshType& mesh = input.getMesh(); typedef typename MeshType::Cell Cell; Cell cell( mesh ); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh.getDimensions().y(); - cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh.getDimensions().x(); - cell.getCoordinates().x() ++ ) - { - cell.refresh(); - output[ cell.getIndex() ] = - input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : - - TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; - } - - const RealType& hx = mesh.getSpaceSteps().x(); - const RealType& hy = mesh.getSpaceSteps().y(); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh.getDimensions().y(); - cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh.getDimensions().x(); - cell.getCoordinates().x() ++ ) - { - cell.refresh(); - const RealType& c = input( cell ); - if( ! cell.isBoundaryEntity() ) - { - auto neighbors = cell.getNeighborEntities(); - Real pom = 0; - const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); - const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); - //Try init with exact data: - if( c * input[ n ] <= 0 ) - { - output[ cell.getIndex() ] = c; - output[ n ] = input[ n ]; - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ n ] = true; - } - if( c * input[ e ] <= 0 ) - { - output[ cell.getIndex() ] = c; - output[ e ] = input[ e ]; - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ e ] = true; - } - /*if( c * input[ n ] <= 0 ) - { - if( c >= 0 ) - { - pom = ( hy * c )/( c - input[ n ]); - if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; - if( output[ n ] < pom - hy ) - output[ n ] = pom - hy; //( hy * c )/( c - input[ n ]) - hy; - }else + + if( std::is_same< Device, Devices::Cuda >::value ) + { +#ifdef HAVE_CUDA + const int cudaBlockSize( 16 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize ); + int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().y(), cudaBlockSize ); + dim3 blockSize( cudaBlockSize, cudaBlockSize ); + dim3 gridSize( numBlocksX, numBlocksY ); + Devices::Cuda::synchronizeDevice(); + CudaInitCaller< Real, Device, Index ><<< gridSize, blockSize >>>( input, output, interfaceMap ); + TNL_CHECK_CUDA_DEVICE; +#endif + } + if( std::is_same< Device, Devices::Host >::value ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) { - pom = - ( hy * c )/( c - input[ n ]); - if( output[ cell.getIndex() ] < pom ) - output[ cell.getIndex() ] = pom; - if( output[ n ] > hy + pom ) - output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); + cell.refresh(); + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; } - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ n ] = true; - } - if( c * input[ e ] <= 0 ) - { - if( c >= 0 ) + + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const IndexType e = neighbors.template getEntityIndex< 1, 0 >(); + const IndexType n = neighbors.template getEntityIndex< 0, 1 >(); + //Try init with exact data: + /*if( c * input[ n ] <= 0 ) { - pom = ( hx * c )/( c - input[ e ]); - if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; - - pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ e ] < pom ) - output[ e ] = pom; - }else + output[ cell.getIndex() ] = c; + output[ n ] = input[ n ]; + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; + } + if( c * input[ e ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ e ] = input[ e ]; + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + }*/ + if( c * input[ n ] <= 0 ) { - pom = - (hx * c)/( c - input[ e ]); - if( output[ cell.getIndex() ] < pom ) - output[ cell.getIndex() ] = pom; - - pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ e ] > pom ) - output[ e ] = pom; + /*if( c >= 0 ) + {*/ + pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + pom = pom - TNL::sign( c )*hy; + if( TNL::abs( output[ n ] ) > TNL::abs( pom ) ) + output[ n ] = pom; //( hy * c )/( c - input[ n ]) - hy; + /*}else + { + pom = - ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + if( output[ n ] > hy + pom ) + output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); + }*/ + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; } - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ e ] = true; - }*/ - } + if( c * input[ e ] <= 0 ) + { + /*if( c >= 0 ) + {*/ + pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + pom = pom - TNL::sign( c )*hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( TNL::abs( output[ e ] ) > TNL::abs( pom ) ) + output[ e ] = pom; + /*}else + { + pom = - (hx * c)/( c - input[ e ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ e ] > pom ) + output[ e ] = pom; + }*/ + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + } + } + } } } @@ -190,7 +214,7 @@ updateCell( MeshFunctionType& u, const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType value = u( cell ); - RealType a, b, tmp1, tmp = TypeInfo< RealType >::getMaxValue(); + RealType a, b, tmp = TypeInfo< RealType >::getMaxValue(); if( cell.getCoordinates().x() == 0 ) a = u[ neighborEntities.template getEntityIndex< 1, 0 >() ]; @@ -538,7 +562,7 @@ T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double } template < typename T1 > -void sortMinims( T1 pom[]) +__cuda_callable__ void sortMinims( T1 pom[]) { T1 tmp[6] = {0.0,0.0,0.0,0.0,0.0,0.0}; if( fabs(pom[0]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[2])){ @@ -571,4 +595,75 @@ void sortMinims( T1 pom[]) { pom[ i ] = tmp[ i ]; } +} + +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + const Meshes::Grid< 2, Real, Device, Index >& mesh = input.getMesh(); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + { + typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; + cell.refresh(); + + + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : + - TypeInfo< Real >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + + const Real& hx = mesh.getSpaceSteps().x(); + const Real& hy = mesh.getSpaceSteps().y(); + cell.refresh(); + const Real& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const Index e = neighbors.template getEntityIndex< 1, 0 >(); + const Index w = neighbors.template getEntityIndex< -1, 0 >(); + const Index n = neighbors.template getEntityIndex< 0, 1 >(); + const Index s = neighbors.template getEntityIndex< 0, -1 >(); + + if( c * input[ n ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + } + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + } + if( c * input[ w ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + } + if( c * input[ s ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + } + } + } } \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index b727f0cd9..0f939d755 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -64,7 +64,17 @@ solve( const MeshPointer& mesh, interfaceMap.setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, aux, interfaceMap ); - aux.save( "aux-ini.tnl" ); + + //if( std::is_same< DeviceType, Devices::Cuda >::value ) + //{ + // Functions::MeshFunction< Meshes::Grid< 2, Real, TNL::Devices::Host, Index > > h_aux; + //cudaMemcpy( h_aux, aux, sizeof(MeshFunctionType), cudaMemcpyDeviceToHost ); + //h_aux->save("aux-init-cuda.tnl"); + //} + //if( std::is_same< DeviceType, Devices::Host >::value ) + { + aux.save( "aux-ini.tnl" ); + } typename MeshType::Cell cell( *mesh ); @@ -207,10 +217,45 @@ solve( const MeshPointer& mesh, if( std::is_same< DeviceType, Devices::Cuda >::value ) { // TODO: CUDA code + int numBlocks = 2; + int threadsPerBlock; + if( mesh->getDimensions().x() >= mesh->getDimensions().y() ) + threadsPerBlock = (int)( mesh->getDimensions().x() ); + else + threadsPerBlock = (int)( mesh->getDimensions().y() ); + + CudaUpdateCellCaller< Real, Device, Index ><<< numBlocks, threadsPerBlock >>>( interfaceMap, aux ); + cudaDeviceSynchronize(); //copak dela? } - iteration++; } aux.save("aux-final.tnl"); } +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = threadIdx.y + blockDim.y*blockIdx.y; + const Meshes::Grid< 2, Real, Device, Index >& mesh = aux.getMesh(); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + { + //make cell of aux from index + typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; + cell.refresh(); + + //update cell value few times + //for( int i = 0; i < mesh.getDimensions() ; i++ ) + //{ + cell.refresh(); + if( ! interfaceMap( cell ) ) + { + // tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >::updateCell( aux, cell ); + } + //} + } +} -- GitLab From db36cd42cfeb2e6a6c018b9f9ff6c2186a68cc7e Mon Sep 17 00:00:00 2001 From: fencl Date: Wed, 18 Apr 2018 15:55:25 +0200 Subject: [PATCH 13/28] CUDA init problem not solved --- .../tnlDirectEikonalMethodsBase.h | 8 ++++-- .../tnlDirectEikonalMethodsBase_impl.h | 28 ++++++++++++++----- .../tnlFastSweepingMethod2D_impl.h | 20 +++++-------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index e6781a7d6..ed176f08a 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -104,13 +104,17 @@ template < typename T1 > __cuda_callable__ void sortMinims( T1 pom[] ); +#ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ); -template < typename Real, typename Device, typename Index > +/*template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ); + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap );*/ + +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ); +#endif #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 1df41cf80..8444b6c37 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -83,25 +83,30 @@ initInterface( const MeshFunctionType& input, * overit is_same device * na kazdy bod jedno cuda vlakno */ - const MeshType& mesh = input.getMesh(); - typedef typename MeshType::Cell Cell; - Cell cell( mesh ); + if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA + const MeshType& mesh = input.getMesh(); + const int cudaBlockSize( 16 ); int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize ); int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().y(), cudaBlockSize ); dim3 blockSize( cudaBlockSize, cudaBlockSize ); dim3 gridSize( numBlocksX, numBlocksY ); Devices::Cuda::synchronizeDevice(); - CudaInitCaller< Real, Device, Index ><<< gridSize, blockSize >>>( input, output, interfaceMap ); + //CudaInitCaller< Real, Device, Index ><<< gridSize, blockSize >>>( input, output, interfaceMap ); + CudaInitCaller<<< gridSize, blockSize >>>( input ); + cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; #endif } if( std::is_same< Device, Devices::Host >::value ) { + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); for( cell.getCoordinates().y() = 0; cell.getCoordinates().y() < mesh.getDimensions().y(); cell.getCoordinates().y() ++ ) @@ -597,7 +602,7 @@ __cuda_callable__ void sortMinims( T1 pom[]) } } -template < typename Real, typename Device, typename Index > +/*template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ) @@ -606,7 +611,7 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, int j = blockDim.y*blockIdx.y + threadIdx.y; const Meshes::Grid< 2, Real, Device, Index >& mesh = input.getMesh(); - if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + //if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; Cell cell( mesh ); @@ -666,4 +671,13 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, } } } -} \ No newline at end of file +}*/ + + +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + //const Meshes::Grid< 2, double, TNL::Devices::Cuda, int >& mesh = input.getMesh(); + +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 0f939d755..48640e3fc 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -64,17 +64,9 @@ solve( const MeshPointer& mesh, interfaceMap.setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, aux, interfaceMap ); - - //if( std::is_same< DeviceType, Devices::Cuda >::value ) - //{ - // Functions::MeshFunction< Meshes::Grid< 2, Real, TNL::Devices::Host, Index > > h_aux; - //cudaMemcpy( h_aux, aux, sizeof(MeshFunctionType), cudaMemcpyDeviceToHost ); - //h_aux->save("aux-init-cuda.tnl"); - //} - //if( std::is_same< DeviceType, Devices::Host >::value ) - { - aux.save( "aux-ini.tnl" ); - } + cudaDeviceSynchronize(); + + aux.save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); @@ -217,7 +209,8 @@ solve( const MeshPointer& mesh, if( std::is_same< DeviceType, Devices::Cuda >::value ) { // TODO: CUDA code - int numBlocks = 2; +#ifdef HAVE_CUDA + /*int numBlocks = 2; int threadsPerBlock; if( mesh->getDimensions().x() >= mesh->getDimensions().y() ) threadsPerBlock = (int)( mesh->getDimensions().x() ); @@ -225,7 +218,8 @@ solve( const MeshPointer& mesh, threadsPerBlock = (int)( mesh->getDimensions().y() ); CudaUpdateCellCaller< Real, Device, Index ><<< numBlocks, threadsPerBlock >>>( interfaceMap, aux ); - cudaDeviceSynchronize(); //copak dela? + cudaDeviceSynchronize(); //copak dela?*/ +#endif } iteration++; } -- GitLab From 6d1a8d988ab4960715d100af5c6023f3b719207f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 18 Apr 2018 21:19:42 +0200 Subject: [PATCH 14/28] Fixed FSM interface initiation in CUDA. --- .../tnlDirectEikonalMethodsBase.h | 30 +++++++----- .../tnlDirectEikonalMethodsBase_impl.h | 49 ++++++++++++------- .../hamilton-jacobi/tnlDirectEikonalProblem.h | 8 +-- .../tnlDirectEikonalProblem_impl.h | 6 +-- .../hamilton-jacobi/tnlFastSweepingMethod.h | 30 +++++++----- .../tnlFastSweepingMethod1D_impl.h | 14 +++--- .../tnlFastSweepingMethod2D_impl.h | 18 ++++--- .../tnlFastSweepingMethod3D_impl.h | 18 ++++--- 8 files changed, 102 insertions(+), 71 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index ed176f08a..d8770b0e7 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -31,10 +31,12 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > typedef Index IndexType; typedef Functions::MeshFunction< MeshType > MeshFunctionType; typedef Functions::MeshFunction< MeshType, 1, bool > InterfaceMapType; + using MeshFunctionPointer = SharedPointer< MeshFunctionType >; + using InterfaceMapPointer = SharedPointer< InterfaceMapType >; - void initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ); + void initInterface( const MeshFunctionPointer& input, + MeshFunctionPointer& output, + InterfaceMapPointer& interfaceMap ); template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, @@ -55,10 +57,12 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > typedef Index IndexType; typedef Functions::MeshFunction< MeshType > MeshFunctionType; typedef Functions::MeshFunction< MeshType, 2, bool > InterfaceMapType; + using MeshFunctionPointer = SharedPointer< MeshFunctionType >; + using InterfaceMapPointer = SharedPointer< InterfaceMapType >; - void initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ); + void initInterface( const MeshFunctionPointer& input, + MeshFunctionPointer& output, + InterfaceMapPointer& interfaceMap ); template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, @@ -81,10 +85,12 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > typedef Index IndexType; typedef Functions::MeshFunction< MeshType > MeshFunctionType; typedef Functions::MeshFunction< MeshType, 3, bool > InterfaceMapType; + using MeshFunctionPointer = SharedPointer< MeshFunctionType >; + using InterfaceMapPointer = SharedPointer< InterfaceMapType >; - void initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ); + void initInterface( const MeshFunctionPointer& input, + MeshFunctionPointer& output, + InterfaceMapPointer& interfaceMap ); template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, @@ -109,12 +115,12 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ); -/*template < typename Real, typename Device, typename Index > +template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap );*/ + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ); -__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ); +//__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ); #endif #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 8444b6c37..37fd24512 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -16,12 +16,15 @@ template< typename Real, typename Index > void tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >:: -initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ) +initInterface( const MeshFunctionPointer& _input, + MeshFunctionPointer& _output, + InterfaceMapPointer& _interfaceMap ) { - const MeshType& mesh = input.getMesh(); + const MeshType& mesh = _input->getMesh(); typedef typename MeshType::Cell Cell; + const MeshFunctionType& input = _input.getData(); + MeshFunctionType& output = _output.modifyData(); + InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); Cell cell( mesh ); for( cell.getCoordinates().x() = 1; cell.getCoordinates().x() < mesh.getDimensions().x() - 1; @@ -74,9 +77,9 @@ template< typename Real, typename Index > void tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: -initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ) +initInterface( const MeshFunctionPointer& _input, + MeshFunctionPointer& _output, + InterfaceMapPointer& _interfaceMap ) { /* doplnit přepočty pro cudu: @@ -88,7 +91,7 @@ initInterface( const MeshFunctionType& input, if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA - const MeshType& mesh = input.getMesh(); + const MeshType& mesh = _input->getMesh(); const int cudaBlockSize( 16 ); int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize ); @@ -96,14 +99,19 @@ initInterface( const MeshFunctionType& input, dim3 blockSize( cudaBlockSize, cudaBlockSize ); dim3 gridSize( numBlocksX, numBlocksY ); Devices::Cuda::synchronizeDevice(); - //CudaInitCaller< Real, Device, Index ><<< gridSize, blockSize >>>( input, output, interfaceMap ); - CudaInitCaller<<< gridSize, blockSize >>>( input ); + CudaInitCaller<<< gridSize, blockSize >>>( _input.template getData< Device >(), + _output.template modifyData< Device >(), + _interfaceMap.template modifyData< Device >() ); + //CudaInitCaller<<< gridSize, blockSize >>>( input ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; #endif } if( std::is_same< Device, Devices::Host >::value ) { + const MeshFunctionType& input = _input.getData(); + MeshFunctionType& output = _output.modifyData(); + InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); const MeshType& mesh = input.getMesh(); typedef typename MeshType::Cell Cell; Cell cell( mesh ); @@ -289,10 +297,13 @@ template< typename Real, typename Index > void tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >:: -initInterface( const MeshFunctionType& input, - MeshFunctionType& output, - InterfaceMapType& interfaceMap ) +initInterface( const MeshFunctionPointer& _input, + MeshFunctionPointer& _output, + InterfaceMapPointer& _interfaceMap ) { + const MeshFunctionType& input = _input.getData(); + MeshFunctionType& output = _output.modifyData(); + InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); const MeshType& mesh = input.getMesh(); typedef typename MeshType::Cell Cell; Cell cell( mesh ); @@ -602,16 +613,16 @@ __cuda_callable__ void sortMinims( T1 pom[]) } } -/*template < typename Real, typename Device, typename Index > +template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ) { int i = threadIdx.x + blockDim.x*blockIdx.x; int j = blockDim.y*blockIdx.y + threadIdx.y; - const Meshes::Grid< 2, Real, Device, Index >& mesh = input.getMesh(); + const Meshes::Grid< 2, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); - //if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; Cell cell( mesh ); @@ -671,13 +682,13 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, } } } -}*/ +} -__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ) +/*__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ) { int i = threadIdx.x + blockDim.x*blockIdx.x; int j = blockDim.y*blockIdx.y + threadIdx.y; //const Meshes::Grid< 2, double, TNL::Devices::Cuda, int >& mesh = input.getMesh(); -} +}*/ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h index ca3b8368c..66513d76f 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h @@ -36,6 +36,8 @@ class tnlDirectEikonalProblem typedef Functions::MeshFunction< Mesh > MeshFunctionType; typedef Problems::PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; using AnisotropyType = Anisotropy; + using AnisotropyPointer = SharedPointer< AnisotropyType, DeviceType >; + using MeshFunctionPointer = SharedPointer< MeshFunctionType >; using typename BaseType::MeshType; using typename BaseType::DofVectorType; @@ -76,11 +78,11 @@ class tnlDirectEikonalProblem protected: - MeshFunctionType u; + MeshFunctionPointer u; - MeshFunctionType initialData; + MeshFunctionPointer initialData; - AnisotropyType anisotropy; + AnisotropyPointer anisotropy; }; diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h index b10c6949e..57ac7d689 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h @@ -95,7 +95,7 @@ tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: bindDofs( const MeshPointer& mesh, const DofVectorPointer& dofs ) { - this->u.bind( mesh, dofs ); + this->u->bind( mesh, dofs ); } template< typename Mesh, @@ -110,8 +110,8 @@ setInitialCondition( const Config::ParameterContainer& parameters, MeshDependentDataPointer& meshdependentData ) { String inputFile = parameters.getParameter< String >( "input-file" ); - this->initialData.setMesh( mesh ); - if( !this->initialData.boundLoad( inputFile ) ) + this->initialData->setMesh( mesh ); + if( !this->initialData->boundLoad( inputFile ) ) return false; return true; } diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h index 61104a143..48f330132 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h @@ -34,14 +34,18 @@ class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy > typedef Meshes::Grid< 1, Real, Device, Index > MeshType; typedef Real RealType; - typedef TNL::Devices::Host DeviceType; + typedef Device DeviceType; typedef Index IndexType; typedef Anisotropy AnisotropyType; typedef tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > BaseType; using MeshPointer = SharedPointer< MeshType >; + using AnisotropyPointer = SharedPointer< AnisotropyType, DeviceType >; using typename BaseType::InterfaceMapType; using typename BaseType::MeshFunctionType; + using typename BaseType::InterfaceMapPointer; + using typename BaseType::MeshFunctionPointer; + FastSweepingMethod(); @@ -50,8 +54,8 @@ class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy > void setMaxIterations( const IndexType& maxIterations ); void solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ); + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ); protected: @@ -72,14 +76,17 @@ class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy > typedef Meshes::Grid< 2, Real, Device, Index > MeshType; typedef Real RealType; - typedef TNL::Devices::Host DeviceType; + typedef Device DeviceType; typedef Index IndexType; typedef Anisotropy AnisotropyType; typedef tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > BaseType; using MeshPointer = SharedPointer< MeshType >; + using AnisotropyPointer = SharedPointer< AnisotropyType, DeviceType >; using typename BaseType::InterfaceMapType; using typename BaseType::MeshFunctionType; + using typename BaseType::InterfaceMapPointer; + using typename BaseType::MeshFunctionPointer; FastSweepingMethod(); @@ -88,8 +95,8 @@ class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy > void setMaxIterations( const IndexType& maxIterations ); void solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ); + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ); protected: @@ -110,14 +117,17 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy > typedef Meshes::Grid< 3, Real, Device, Index > MeshType; typedef Real RealType; - typedef TNL::Devices::Host DeviceType; + typedef Device DeviceType; typedef Index IndexType; typedef Anisotropy AnisotropyType; typedef tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > BaseType; using MeshPointer = SharedPointer< MeshType >; + using AnisotropyPointer = SharedPointer< AnisotropyType, DeviceType >; using typename BaseType::InterfaceMapType; using typename BaseType::MeshFunctionType; + using typename BaseType::InterfaceMapPointer; + using typename BaseType::MeshFunctionPointer; FastSweepingMethod(); @@ -126,8 +136,8 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy > void setMaxIterations( const IndexType& maxIterations ); void solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ); + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ); protected: @@ -135,8 +145,6 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy > const IndexType maxIterations; }; - - #include "tnlFastSweepingMethod1D_impl.h" #include "tnlFastSweepingMethod2D_impl.h" #include "tnlFastSweepingMethod3D_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h index 874945eaf..105f1ceda 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h @@ -55,16 +55,16 @@ template< typename Real, void FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >:: solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ) + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ) { - MeshFunctionType aux; - InterfaceMapType interfaceMap; - aux.setMesh( mesh ); - interfaceMap.setMesh( mesh ); + MeshFunctionPointer aux; + InterfaceMapPointer interfaceMap; + aux->setMesh( mesh ); + interfaceMap->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, aux, interfaceMap ); - aux.save( "aux-ini.tnl" ); + aux->save( "aux-ini.tnl" ); } diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 48640e3fc..e36224d07 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -55,22 +55,24 @@ template< typename Real, void FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >:: solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ) + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ) { - MeshFunctionType aux; - InterfaceMapType interfaceMap; - aux.setMesh( mesh ); - interfaceMap.setMesh( mesh ); + MeshFunctionPointer auxPtr; + InterfaceMapPointer interfaceMapPtr; + auxPtr->setMesh( mesh ); + interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; - BaseType::initInterface( u, aux, interfaceMap ); + BaseType::initInterface( u, auxPtr, interfaceMapPtr ); cudaDeviceSynchronize(); - aux.save( "aux-ini.tnl" ); + auxPtr->save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); IndexType iteration( 0 ); + InterfaceMapType interfaceMap = *interfaceMapPtr; + MeshFunctionType aux = *auxPtr; while( iteration < this->maxIterations ) { if( std::is_same< DeviceType, Devices::Host >::value ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 9844c4fca..1fd8c9f2a 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -55,20 +55,22 @@ template< typename Real, void FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >:: solve( const MeshPointer& mesh, - const AnisotropyType& anisotropy, - MeshFunctionType& u ) + const AnisotropyPointer& anisotropy, + MeshFunctionPointer& u ) { - MeshFunctionType aux; - InterfaceMapType interfaceMap; - aux.setMesh( mesh ); - interfaceMap.setMesh( mesh ); + MeshFunctionPointer auxPtr; + InterfaceMapPointer interfaceMapPtr; + auxPtr->setMesh( mesh ); + interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; - BaseType::initInterface( u, aux, interfaceMap ); - aux.save( "aux-ini.tnl" ); + BaseType::initInterface( u, auxPtr, interfaceMapPtr ); + auxPtr->save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); IndexType iteration( 0 ); + MeshFunctionType aux = *auxPtr; + InterfaceMapType interfaceMap = * interfaceMapPtr; while( iteration < this->maxIterations ) { for( cell.getCoordinates().z() = 0; -- GitLab From 5d1fab6e4fa455940aa0edf159e1ca3229738a36 Mon Sep 17 00:00:00 2001 From: fencl Date: Mon, 23 Apr 2018 11:01:29 +0200 Subject: [PATCH 15/28] CUDA implemented for exact number of loops in 2D and 3D --- .../tnlDirectEikonalMethodsBase.h | 23 +- .../tnlDirectEikonalMethodsBase_impl.h | 456 +++++++++++------- .../hamilton-jacobi/tnlFastSweepingMethod.h | 2 + .../tnlFastSweepingMethod2D_impl.h | 49 +- .../tnlFastSweepingMethod3D_impl.h | 380 ++++++++------- 5 files changed, 542 insertions(+), 368 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index d8770b0e7..138671a3b 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -67,9 +67,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, const MeshEntity& cell, - const RealType velocity = 1.0 ); - protected: - + const RealType velocity = 1.0 ); }; template< typename Real, @@ -78,7 +76,6 @@ template< typename Real, class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > { public: - typedef Meshes::Grid< 3, Real, Device, Index > MeshType; typedef Real RealType; typedef Device DevcieType; @@ -96,11 +93,6 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > __cuda_callable__ void updateCell( MeshFunctionType& u, const MeshEntity& cell, const RealType velocity = 1.0); - - /*Real sort( Real a, Real b, Real c, - const RealType& ha, - const RealType& hb, - const RealType& hc ); */ }; template < typename T1, typename T2 > @@ -112,7 +104,8 @@ __cuda_callable__ void sortMinims( T1 pom[] ); #ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > -__global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ); template < typename Real, typename Device, typename Index > @@ -120,7 +113,15 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ); -//__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ); +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap ); + +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux ); #endif #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 37fd24512..bf78a02a4 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -11,6 +11,7 @@ #include #include "tnlFastSweepingMethod.h" + template< typename Real, typename Device, typename Index > @@ -81,13 +82,7 @@ initInterface( const MeshFunctionPointer& _input, MeshFunctionPointer& _output, InterfaceMapPointer& _interfaceMap ) { - /* - doplnit přepočty pro cudu: - * overit is_same device - * na kazdy bod jedno cuda vlakno - */ - - + if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA @@ -102,7 +97,6 @@ initInterface( const MeshFunctionPointer& _input, CudaInitCaller<<< gridSize, blockSize >>>( _input.template getData< Device >(), _output.template modifyData< Device >(), _interfaceMap.template modifyData< Device >() ); - //CudaInitCaller<<< gridSize, blockSize >>>( input ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; #endif @@ -215,6 +209,7 @@ template< typename Real, typename Device, typename Index > template< typename MeshEntity > +__cuda_callable__ void tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: updateCell( MeshFunctionType& u, @@ -301,162 +296,187 @@ initInterface( const MeshFunctionPointer& _input, MeshFunctionPointer& _output, InterfaceMapPointer& _interfaceMap ) { - const MeshFunctionType& input = _input.getData(); - MeshFunctionType& output = _output.modifyData(); - InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); - const MeshType& mesh = input.getMesh(); - typedef typename MeshType::Cell Cell; - Cell cell( mesh ); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh.getDimensions().z(); - cell.getCoordinates().z() ++ ) - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh.getDimensions().y(); - cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh.getDimensions().x(); - cell.getCoordinates().x() ++ ) - { - cell.refresh(); - output[ cell.getIndex() ] = - input( cell ) > 0 ? TypeInfo< RealType >::getMaxValue() : - - TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; - } - - const RealType& hx = mesh.getSpaceSteps().x(); - const RealType& hy = mesh.getSpaceSteps().y(); - const RealType& hz = mesh.getSpaceSteps().z(); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh.getDimensions().z(); - cell.getCoordinates().z() ++ ) - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh.getDimensions().y(); - cell.getCoordinates().y() ++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh.getDimensions().x(); - cell.getCoordinates().x() ++ ) - { - cell.refresh(); - const RealType& c = input( cell ); - if( ! cell.isBoundaryEntity() ) - { - auto neighbors = cell.getNeighborEntities(); - Real pom = 0; - const IndexType e = neighbors.template getEntityIndex< 1, 0, 0 >(); - const IndexType n = neighbors.template getEntityIndex< 0, 1, 0 >(); - const IndexType t = neighbors.template getEntityIndex< 0, 0, 1 >(); - //Try exact initiation - /*const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); - const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); - const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); - if( c * input[ e ] <= 0 ) - { - output[ cell.getIndex() ] = c; - output[ e ] = input[ e ]; - interfaceMap[ e ] = true; - interfaceMap[ cell.getIndex() ] = true; - } - else if( c * input[ n ] <= 0 ) - { - output[ cell.getIndex() ] = c; - output[ n ] = input[ n ]; - interfaceMap[ n ] = true; - interfaceMap[ cell.getIndex() ] = true; - } - else if( c * input[ t ] <= 0 ) - { - output[ cell.getIndex() ] = c; - output[ t ] = input[ t ]; - interfaceMap[ t ] = true; - interfaceMap[ cell.getIndex() ] = true; - }*/ - if( c * input[ n ] <= 0 ) - { - if( c >= 0 ) - { - pom = ( hy * c )/( c - input[ n ]); - if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; - - if ( output[ n ] < pom - hy) - output[ n ] = pom - hy; // ( hy * c )/( c - input[ n ]) - hy; - - }else - { - pom = - ( hy * c )/( c - input[ n ]); - if( output[ cell.getIndex() ] < pom ) - output[ cell.getIndex() ] = pom; - if( output[ n ] > hy + pom ) - output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); - - } - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ n ] = true; - } - if( c * input[ e ] <= 0 ) - { - if( c >= 0 ) - { - pom = ( hx * c )/( c - input[ e ]); - if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; - - pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ e ] < pom ) - output[ e ] = pom; - - }else - { - pom = - (hx * c)/( c - input[ e ]); - if( output[ cell.getIndex() ] < pom ) - output[ cell.getIndex() ] = pom; - - pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ e ] > pom ) - output[ e ] = pom; - } - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ e ] = true; - } - if( c * input[ t ] <= 0 ) - { - if( c >= 0 ) - { - pom = ( hz * c )/( c - input[ t ]); - if( output[ cell.getIndex() ] > pom ) - output[ cell.getIndex() ] = pom; - - pom = pom - hz; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; - if( output[ t ] < pom ) - output[ t ] = pom; - - }else - { - pom = - (hz * c)/( c - input[ t ]); - if( output[ cell.getIndex() ] < pom ) - output[ cell.getIndex() ] = pom; - - pom = pom + hz; //output[ e ] = hx - (hx * c)/( c - input[ e ]); - if( output[ t ] > pom ) - output[ t ] = pom; - - } - interfaceMap[ cell.getIndex() ] = true; - interfaceMap[ t ] = true; - } - } - /*output[ cell.getIndex() ] = - c > 0 ? TypeInfo< RealType >::getMaxValue() : - -TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false;*/ //is on line 245 - } + if( std::is_same< Device, Devices::Cuda >::value ) + { +#ifdef HAVE_CUDA + const MeshType& mesh = _input->getMesh(); + + const int cudaBlockSize( 8 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize ); + int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().y(), cudaBlockSize ); + int numBlocksZ = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().z(), cudaBlockSize ); + if( cudaBlockSize * cudaBlockSize * cudaBlockSize > 1024 || numBlocksX > 1024 || numBlocksY > 1024 || numBlocksZ > 64 ) + std::cout << "Invalid kernel call. Dimensions of grid are max: [1024,1024,64], and maximum threads per block are 1024!" << std::endl; + dim3 blockSize( cudaBlockSize, cudaBlockSize, cudaBlockSize ); + dim3 gridSize( numBlocksX, numBlocksY, numBlocksZ ); + Devices::Cuda::synchronizeDevice(); + CudaInitCaller3d<<< gridSize, blockSize >>>( _input.template getData< Device >(), + _output.template modifyData< Device >(), + _interfaceMap.template modifyData< Device >() ); + cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; +#endif + } + if( std::is_same< Device, Devices::Host >::value ) + { + const MeshFunctionType& input = _input.getData(); + MeshFunctionType& output = _output.modifyData(); + InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh.getDimensions().z(); + cell.getCoordinates().z() ++ ) + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + output[ cell.getIndex() ] = + input( cell ) > 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } + + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y(); + const RealType& hz = mesh.getSpaceSteps().z(); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh.getDimensions().z(); + cell.getCoordinates().z() ++ ) + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const IndexType e = neighbors.template getEntityIndex< 1, 0, 0 >(); + const IndexType n = neighbors.template getEntityIndex< 0, 1, 0 >(); + const IndexType t = neighbors.template getEntityIndex< 0, 0, 1 >(); + //Try exact initiation + /*const IndexType w = neighbors.template getEntityIndex< -1, 0, 0 >(); + const IndexType s = neighbors.template getEntityIndex< 0, -1, 0 >(); + const IndexType b = neighbors.template getEntityIndex< 0, 0, -1 >(); + if( c * input[ e ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ e ] = input[ e ]; + interfaceMap[ e ] = true; + interfaceMap[ cell.getIndex() ] = true; + } + else if( c * input[ n ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ n ] = input[ n ]; + interfaceMap[ n ] = true; + interfaceMap[ cell.getIndex() ] = true; + } + else if( c * input[ t ] <= 0 ) + { + output[ cell.getIndex() ] = c; + output[ t ] = input[ t ]; + interfaceMap[ t ] = true; + interfaceMap[ cell.getIndex() ] = true; + }*/ + if( c * input[ n ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + if ( output[ n ] < pom - hy) + output[ n ] = pom - hy; // ( hy * c )/( c - input[ n ]) - hy; + + }else + { + pom = - ( hy * c )/( c - input[ n ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + if( output[ n ] > hy + pom ) + output[ n ] = hy + pom; //hy - ( hy * c )/( c - input[ n ]); + + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ n ] = true; + } + if( c * input[ e ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hx * c )/( c - input[ e ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + pom = pom - hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( output[ e ] < pom ) + output[ e ] = pom; + + }else + { + pom = - (hx * c)/( c - input[ e ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hx; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ e ] > pom ) + output[ e ] = pom; + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + } + if( c * input[ t ] <= 0 ) + { + if( c >= 0 ) + { + pom = ( hz * c )/( c - input[ t ]); + if( output[ cell.getIndex() ] > pom ) + output[ cell.getIndex() ] = pom; + + pom = pom - hz; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( output[ t ] < pom ) + output[ t ] = pom; + + }else + { + pom = - (hz * c)/( c - input[ t ]); + if( output[ cell.getIndex() ] < pom ) + output[ cell.getIndex() ] = pom; + + pom = pom + hz; //output[ e ] = hx - (hx * c)/( c - input[ e ]); + if( output[ t ] > pom ) + output[ t ] = pom; + + } + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ t ] = true; + } + } + /*output[ cell.getIndex() ] = + c > 0 ? TypeInfo< RealType >::getMaxValue() : + -TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false;*/ //is on line 245 + } + } } template< typename Real, typename Device, typename Index > template< typename MeshEntity > +__cuda_callable__ void tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >:: updateCell( MeshFunctionType& u, @@ -628,12 +648,13 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Cell cell( mesh ); cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.refresh(); + const Index cind = cell.getIndex(); - output[ cell.getIndex() ] = + output[ cind ] = input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : - TypeInfo< Real >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; + interfaceMap[ cind ] = false; const Real& hx = mesh.getSpaceSteps().x(); const Real& hy = mesh.getSpaceSteps().y(); @@ -647,48 +668,131 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, const Index w = neighbors.template getEntityIndex< -1, 0 >(); const Index n = neighbors.template getEntityIndex< 0, 1 >(); const Index s = neighbors.template getEntityIndex< 0, -1 >(); - + if( c * input[ n ] <= 0 ) { pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); - if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) - output[ cell.getIndex() ] = pom; + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; interfaceMap[ cell.getIndex() ] = true; } if( c * input[ e ] <= 0 ) { pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); - if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) - output[ cell.getIndex() ] = pom; + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; - interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ cind ] = true; } if( c * input[ w ] <= 0 ) { pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); - if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) - output[ cell.getIndex() ] = pom; + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; - interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ cind ] = true; } if( c * input[ s ] <= 0 ) { pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); - if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) - output[ cell.getIndex() ] = pom; + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; - interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ cind ] = true; } } } } - -/*__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, double, TNL::Devices::Cuda, int > >& input ) +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap ) { int i = threadIdx.x + blockDim.x*blockIdx.x; int j = blockDim.y*blockIdx.y + threadIdx.y; - //const Meshes::Grid< 2, double, TNL::Devices::Cuda, int >& mesh = input.getMesh(); + int k = blockDim.z*blockIdx.z + threadIdx.z; + const Meshes::Grid< 3, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); -}*/ + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) + { + typedef typename Meshes::Grid< 3, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; + cell.refresh(); + const Index cind = cell.getIndex(); + + + output[ cind ] = + input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : + - TypeInfo< Real >::getMaxValue(); + interfaceMap[ cind ] = false; + cell.refresh(); + + const Real& hx = mesh.getSpaceSteps().x(); + const Real& hy = mesh.getSpaceSteps().y(); + const Real& hz = mesh.getSpaceSteps().z(); + const Real& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const Index e = neighbors.template getEntityIndex< 1, 0, 0 >(); + const Index w = neighbors.template getEntityIndex< -1, 0, 0 >(); + const Index n = neighbors.template getEntityIndex< 0, 1, 0 >(); + const Index s = neighbors.template getEntityIndex< 0, -1, 0 >(); + const Index t = neighbors.template getEntityIndex< 0, 0, 1 >(); + const Index b = neighbors.template getEntityIndex< 0, 0, -1 >(); + + if( c * input[ n ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ w ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ s ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ b ] <= 0 ) + { + pom = TNL::sign( c )*( hz * c )/( c - input[ b ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ t ] <= 0 ) + { + pom = TNL::sign( c )*( hz * c )/( c - input[ t ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + } + } +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h index 48f330132..e44aaca87 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h @@ -15,6 +15,7 @@ #include #include "tnlDirectEikonalMethodsBase.h" + template< typename Mesh, typename Anisotropy = Functions::Analytic::Constant< Mesh::getMeshDimension(), typename Mesh::RealType > > class FastSweepingMethod @@ -145,6 +146,7 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy > const IndexType maxIterations; }; + #include "tnlFastSweepingMethod1D_impl.h" #include "tnlFastSweepingMethod2D_impl.h" #include "tnlFastSweepingMethod3D_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index e36224d07..73e170895 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -14,6 +14,9 @@ #pragma once #include "tnlFastSweepingMethod.h" +#include +#include + template< typename Real, typename Device, @@ -212,15 +215,23 @@ solve( const MeshPointer& mesh, { // TODO: CUDA code #ifdef HAVE_CUDA - /*int numBlocks = 2; - int threadsPerBlock; - if( mesh->getDimensions().x() >= mesh->getDimensions().y() ) - threadsPerBlock = (int)( mesh->getDimensions().x() ); - else - threadsPerBlock = (int)( mesh->getDimensions().y() ); + const int cudaBlockSize( 16 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().x(), cudaBlockSize ); + int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().y(), cudaBlockSize ); + dim3 blockSize( cudaBlockSize, cudaBlockSize ); + dim3 gridSize( numBlocksX, numBlocksY ); + Devices::Cuda::synchronizeDevice(); + int DIM = mesh->getDimensions().x(); - CudaUpdateCellCaller< Real, Device, Index ><<< numBlocks, threadsPerBlock >>>( interfaceMap, aux ); - cudaDeviceSynchronize(); //copak dela?*/ + tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; + for( int k = 0; k < numBlocksX; k++) + CudaUpdateCellCaller< Real, Device, Index ><<< gridSize, blockSize >>>( ptr, + interfaceMapPtr.template getData< Device >(), + auxPtr.template modifyData< Device>() ); + cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; + aux = *auxPtr; + interfaceMap = *interfaceMapPtr; #endif } iteration++; @@ -228,30 +239,30 @@ solve( const MeshPointer& mesh, aux.save("aux-final.tnl"); } +//#ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > -__global__ void CudaUpdateCellCaller( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ) { int i = threadIdx.x + blockDim.x*blockIdx.x; - int j = threadIdx.y + blockDim.y*blockIdx.y; - const Meshes::Grid< 2, Real, Device, Index >& mesh = aux.getMesh(); + int j = blockDim.y*blockIdx.y + threadIdx.y; + const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { - //make cell of aux from index typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; Cell cell( mesh ); cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.refresh(); - - //update cell value few times - //for( int i = 0; i < mesh.getDimensions() ; i++ ) - //{ - cell.refresh(); + //tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; + for( int k = 0; k < 16; k++ ) + { if( ! interfaceMap( cell ) ) { - // tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >::updateCell( aux, cell ); + ptr.updateCell( aux, cell ); } - //} + } } } +//#endif \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 1fd8c9f2a..3e8cb7bb1 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -21,7 +21,7 @@ template< typename Real, typename Anisotropy > FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >:: FastSweepingMethod() -: maxIterations( 1 ) +: maxIterations( 2 ) { } @@ -64,6 +64,7 @@ solve( const MeshPointer& mesh, interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, auxPtr, interfaceMapPtr ); + cudaDeviceSynchronize(); auxPtr->save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); @@ -71,172 +72,201 @@ solve( const MeshPointer& mesh, IndexType iteration( 0 ); MeshFunctionType aux = *auxPtr; InterfaceMapType interfaceMap = * interfaceMapPtr; - while( iteration < this->maxIterations ) - { - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh->getDimensions().z(); - cell.getCoordinates().z()++ ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) - { - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); - cell.getCoordinates().x()++ ) - { - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-1.tnl" ); + while( iteration < this->maxIterations ) + { + if( std::is_same< DeviceType, Devices::Host >::value ) + { + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-1.tnl" ); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh->getDimensions().z(); - cell.getCoordinates().z()++ ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) - { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) - { - //std::cerr << "2 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-2.tnl" ); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh->getDimensions().z(); - cell.getCoordinates().z()++ ) - { - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0 ; - cell.getCoordinates().y()-- ) - { - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); - cell.getCoordinates().x()++ ) - { - //std::cerr << "3 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-3.tnl" ); - - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < mesh->getDimensions().z(); - cell.getCoordinates().z()++ ) - { - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0; - cell.getCoordinates().y()-- ) - { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) - { - //std::cerr << "4 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-4.tnl" ); - - for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; - cell.getCoordinates().z() >= 0; - cell.getCoordinates().z()-- ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) - { - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); - cell.getCoordinates().x()++ ) - { - //std::cerr << "5 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-5.tnl" ); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-2.tnl" ); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-3.tnl" ); - for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; - cell.getCoordinates().z() >= 0; - cell.getCoordinates().z()-- ) - { - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < mesh->getDimensions().y(); - cell.getCoordinates().y()++ ) - { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) - { - //std::cerr << "6 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-6.tnl" ); - - for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; - cell.getCoordinates().z() >= 0; - cell.getCoordinates().z()-- ) - { - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0 ; - cell.getCoordinates().y()-- ) - { - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < mesh->getDimensions().x(); - cell.getCoordinates().x()++ ) - { - //std::cerr << "7 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } - } - //aux.save( "aux-7.tnl" ); + for( cell.getCoordinates().z() = 0; + cell.getCoordinates().z() < mesh->getDimensions().z(); + cell.getCoordinates().z()++ ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-4.tnl" ); - for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; - cell.getCoordinates().z() >= 0; - cell.getCoordinates().z()-- ) + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "5 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-5.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh->getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "6 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-6.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "7 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + //aux.save( "aux-7.tnl" ); + + for( cell.getCoordinates().z() = mesh->getDimensions().z() - 1; + cell.getCoordinates().z() >= 0; + cell.getCoordinates().z()-- ) + { + for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "8 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + } + } + if( std::is_same< DeviceType, Devices::Cuda >::value ) { - for( cell.getCoordinates().y() = mesh->getDimensions().y() - 1; - cell.getCoordinates().y() >= 0; - cell.getCoordinates().y()-- ) - { - for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; - cell.getCoordinates().x() >= 0 ; - cell.getCoordinates().x()-- ) - { - //std::cerr << "8 -> "; - cell.refresh(); - if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); - } - } + // TODO: CUDA code +#ifdef HAVE_CUDA + const int cudaBlockSize( 8 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().x(), cudaBlockSize ); + int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().y(), cudaBlockSize ); + int numBlocksZ = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().z(), cudaBlockSize ); + if( cudaBlockSize * cudaBlockSize * cudaBlockSize > 1024 || numBlocksX > 1024 || numBlocksY > 1024 || numBlocksZ > 64 ) + std::cout << "Invalid kernel call. Dimensions of grid are max: [1024,1024,64], and maximum threads per block are 1024!" << std::endl; + dim3 blockSize( cudaBlockSize, cudaBlockSize, cudaBlockSize ); + dim3 gridSize( numBlocksX, numBlocksY, numBlocksZ ); + Devices::Cuda::synchronizeDevice(); + + tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; + for( int k = 0; k < numBlocksX; k++) + CudaUpdateCellCaller< Real, Device, Index ><<< gridSize, blockSize >>>( ptr, + interfaceMapPtr.template getData< Device >(), + auxPtr.template modifyData< Device>() ); + cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; + aux = *auxPtr; + interfaceMap = *interfaceMapPtr; +#endif } + //aux.save( "aux-8.tnl" ); iteration++; @@ -244,3 +274,29 @@ solve( const MeshPointer& mesh, aux.save("aux-final.tnl"); } +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + int k = blockDim.z*blockIdx.z + threadIdx.z; + const Meshes::Grid< 3, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) + { + typedef typename Meshes::Grid< 3, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; + cell.refresh(); + //tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; + for( int l = 0; l < 8; l++ ) + { + if( ! interfaceMap( cell ) ) + { + ptr.updateCell( aux, cell ); + } + } + } +} \ No newline at end of file -- GitLab From 9c196197633cd9eeee8fbe3ceeba7aee28a33bf0 Mon Sep 17 00:00:00 2001 From: fencl Date: Wed, 9 May 2018 19:32:45 +0200 Subject: [PATCH 16/28] Implementation of Blocks 18 * 18 using shared memory in 2D. --- .../tnlDirectEikonalMethodsBase.h | 12 +- .../tnlDirectEikonalMethodsBase_impl.h | 231 +++++++++++++++++- .../hamilton-jacobi/tnlFastSweepingMethod.h | 1 - .../tnlFastSweepingMethod2D_impl.h | 47 +++- .../tnlFastSweepingMethod3D_impl.h | 6 +- 5 files changed, 277 insertions(+), 20 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 138671a3b..69fce1467 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -67,7 +67,17 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, const MeshEntity& cell, - const RealType velocity = 1.0 ); + const RealType velocity = 1.0 ); + + __cuda_callable__ void updateCell( Real sArray[18][18], + int thri, int thrj, const Real hx, const Real hy, + const Real velocity = 1.0 ); + + __cuda_callable__ void setsArray( MeshFunctionType& aux, Real sArray[18][18], + int dimX, int dimY, int i, int j ); + + /*__cuda_callable__ void getsArray( MeshFunctionType& aux, Real sArray[18][18], + int dimX, int dimY, int i, int j );*/ }; template< typename Real, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index bf78a02a4..a89d230f6 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -218,7 +218,6 @@ updateCell( MeshFunctionType& u, { const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); const MeshType& mesh = cell.getMesh(); - const RealType& hx = mesh.getSpaceSteps().x(); const RealType& hy = mesh.getSpaceSteps().y(); const RealType value = u( cell ); @@ -598,7 +597,7 @@ T1 meet2DCondition( T1 a, T1 b, const T2 ha, const T2 hb, const T1 value, double } template < typename T1 > -__cuda_callable__ void sortMinims( T1 pom[]) +__cuda_callable__ void sortMinims( T1 pom[] ) { T1 tmp[6] = {0.0,0.0,0.0,0.0,0.0,0.0}; if( fabs(pom[0]) <= fabs(pom[1]) && fabs(pom[1]) <= fabs(pom[2])){ @@ -796,3 +795,231 @@ __global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3 } } } + +template< typename Real, + typename Device, + typename Index > +__cuda_callable__ void +tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: +setsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int blockIdx, int blockIdy ) +{ + int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); + int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); + int xkolik = 18; + int ykolik = 18; + int xOd = 0; + int yOd = 0; + + if( blockIdx == 0 ) + xOd = 1; + if( blockIdy == 0 ) + yOd = 1; + + if( numOfBlockx - 1 == blockIdx ) + xkolik = dimX - (numOfBlockx-1)*16+1; + + if( numOfBlocky -1 == blockIdy ) + ykolik = dimY - (numOfBlocky-1)*16+1; + + if( dimX > (blockIdx+1) * 16 ) + { + for( int i = yOd; i < ykolik; i++ ) + { + sArray[i][17] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + i*dimX + 17 ]; + } + } + if( blockIdx != 0 ) + { + for( int i = yOd; i < ykolik; i++ ) + { + sArray[i][0] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + i*dimX + 0]; + } + } + if( dimY > (blockIdy+1) * 16 ) + { + for( int i = xOd; i < xkolik; i++ ) + { + sArray[17][i] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + 17*dimX + i ]; + } + } + if( blockIdy != 0 ) + { + for( int i = xOd; i < xkolik; i++ ) + { + sArray[0][i] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + 0*dimX + i ]; + } + } + + /*int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); + int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); + int xkolik = 18; + int ykolik = 18; + + if( numOfBlockx - 1 == blockIdx ) + xkolik = dimX - (numOfBlockx-1)*16+1; + + if( numOfBlocky -1 == blockIdy ) + ykolik = dimY - (numOfBlocky-1)*16+1; + + + if( numOfBlockx == 0 || numOfBlocky == 0 ) + return; + else + { + if( blockIdx == 0 ) + { + if( blockIdy == 0 ) + { + for( int j = 0; j < ykolik-1; j++ ) + for( int i = 0; i < xkolik-1; i++ ) + { + sArray[ j+1 ][ i+1 ] = aux[ j*dimX + i ]; + } + + //vypis( *sArray ); + } + else + { + for( int j = 0; j < ykolik; j++ ) + for( int i = 0; i < xkolik-1; i++ ) + { + sArray[ j ][ i+1 ] = aux[ blockIdy*16*dimX - dimX + j*dimX + i ]; + } + } + } + else if( blockIdy == 0 ) + { + for( int j = 0; j < ykolik-1; j++ ) + for( int i = 0; i < xkolik; i++ ) + { + sArray[ j+1 ][ i ] = aux[ blockIdx*16 - 1 + j*dimX + i ]; + } + } + else + { + for( int j = 0; j < ykolik; j++ ) + for( int i = 0; i < xkolik; i++ ) + { + //if( dimX*dimY-1 > blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ) + sArray[ j ][ i ] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ]; + } + } + }*/ +} + +/*template< typename Real, + typename Device, + typename Index > +__cuda_callable__ void +tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: +getsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int blockIdx, int blockIdy ) +{ + int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); + int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); + int xkolik = 18; + int ykolik = 18; + + if( numOfBlockx - 1 == blockIdx ) + xkolik = dimX - (numOfBlockx-1)*16+2; + + if( numOfBlocky -1 == blockIdy ) + ykolik = dimY - (numOfBlocky-1)*16+2; + + if( numOfBlockx == 0 || numOfBlocky == 0 ) + return; + else + { + if( blockIdx == 0 ) + { + if( blockIdy == 0 ) + { + for( int j = 0; j < ykolik-2; j++ ) + for( int i = 0; i < xkolik-2; i++ ) + { + aux[ j*dimX + i ] = sArray[ j+1 ][ i+1 ]; + } + } + else + { + for( int j = 1; j < ykolik-1; j++ ) + for( int i = 0; i < xkolik-2; i++ ) + { + aux[ blockIdy*16*dimX - dimX + j*dimX + i ] = sArray[ j ][ i+1 ]; + } + } + } + else if( blockIdy == 0 ) + { + for( int j = 0; j < ykolik-2; j++ ) + for( int i = 1; i < xkolik-1; i++ ) + { + aux[ blockIdx*16 - 1 + j*dimX + i ] = sArray[ j+1 ][ i ]; + } + } + else + { + for( int j = 1; j < ykolik-1; j++ ) + for( int i = 1; i < xkolik-1; i++ ) + { + aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ] = sArray[ j ][ i ]; + } + } + } +}*/ + +template< typename Real, + typename Device, + typename Index > +__cuda_callable__ +void +tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: +updateCell( Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, + const Real v ) +{ + + //const Meshes::Grid< 2, Real, Device, Index >& mesh = u.template getMesh< Devices::Cuda >(); + /*typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; + cell.refresh(); + + const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); + const RealType& hx = mesh.getSpaceSteps().x(); + const RealType& hy = mesh.getSpaceSteps().y();*/ + const RealType value = sArray[ thrj ][ thri ];//u( cell ); + RealType a, b, tmp = TypeInfo< RealType >::getMaxValue(); + + /*if( value != u[ cell.getIndex() ] ) + return;*/ + + b = TNL::argAbsMin( sArray[ thrj+1 ][ thri ], + sArray[ thrj-1 ][ thri ] ); + + a = TNL::argAbsMin( sArray[ thrj ][ thri+1 ], + sArray[ thrj ][ thri-1 ] ); + + + + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && + fabs( b ) == TypeInfo< RealType >::getMaxValue() ) + return; + + RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, 0.0 }; + sortMinims( pom ); + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]/v; + + + if( fabs( tmp ) < fabs( pom[ 1 ] ) ) + { + //u[ cell.getIndex() ]= argAbsMin( value, tmp ); + sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); + } + else + { + tmp = ( pom[ 3 ] * pom[ 3 ] * pom[ 1 ] + pom[ 4 ] * pom[ 4 ] * pom[ 0 ] + + TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - + ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); + //u[ cell.getIndex() ]= argAbsMin( value, tmp ); + sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); + } +} \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h index e44aaca87..54e577dac 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h @@ -99,7 +99,6 @@ class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy > const AnisotropyPointer& anisotropy, MeshFunctionPointer& u ); - protected: const IndexType maxIterations; diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 73e170895..80976772c 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -221,11 +221,12 @@ solve( const MeshPointer& mesh, dim3 blockSize( cudaBlockSize, cudaBlockSize ); dim3 gridSize( numBlocksX, numBlocksY ); Devices::Cuda::synchronizeDevice(); - int DIM = mesh->getDimensions().x(); tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; - for( int k = 0; k < numBlocksX; k++) - CudaUpdateCellCaller< Real, Device, Index ><<< gridSize, blockSize >>>( ptr, + int nBlockIter = numBlocksX > numBlocksY ? numBlocksX : numBlocksY; + nBlockIter = numBlocksX == numBlocksY ? nBlockIter + 1 : nBlockIter; + for( int k = 0; k < nBlockIter; k++) + CudaUpdateCellCaller<<< gridSize, blockSize, 18 * 18 * sizeof( Real ) >>>( ptr, interfaceMapPtr.template getData< Device >(), auxPtr.template modifyData< Device>() ); cudaDeviceSynchronize(); @@ -245,24 +246,44 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ) { - int i = threadIdx.x + blockDim.x*blockIdx.x; - int j = blockDim.y*blockIdx.y + threadIdx.y; + int thri = threadIdx.x; int thrj = threadIdx.y; // nelze ke stejnym pristupovat znovu pres threadIdx (vzdy da jine hodnoty) + int blIdx = blockIdx.x; int blIdy = blockIdx.y; + int i = thri + blockDim.x*blIdx; + int j = blockDim.y*blIdy + thrj; const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); + const Real hx = mesh.getSpaceSteps().x(); + const Real hy = mesh.getSpaceSteps().y(); + + __shared__ Real sArray[ 18 ][ 18 ]; + for( int k = 0; k < 18; k++ ) + for( int l = 0; l < 18; l++ ) + sArray[ k ][ l ] = TypeInfo< Real >::getMaxValue(); + __syncthreads(); + /*//filling shared array + ptr.setsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); + __syncthreads();*/ if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { - typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; - Cell cell( mesh ); - cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; - cell.refresh(); - //tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; - for( int k = 0; k < 16; k++ ) + sArray[thrj+1][thri+1] = aux[ j*mesh.getDimensions().x() + i ]; + ptr.setsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); //fill edges of sArray + __syncthreads(); + + + if( ! interfaceMap[ j*mesh.getDimensions().x() + i ] ) { - if( ! interfaceMap( cell ) ) + for( int k = 0; k < 17; k++ ) { - ptr.updateCell( aux, cell ); + ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); + __syncthreads(); } } + /*for( int k = 0; k < mesh.getDimensions().x(); k++) + for( int l = 0; l < mesh.getDimensions().y(); l++) + aux[ k*mesh.getDimensions().x() + l ] = TypeInfo< Real >::getMaxValue();*/ + aux[j*mesh.getDimensions().x() + i] = sArray[thrj+1][thri+1]; + __syncthreads(); } + //ptr.getsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); } //#endif \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 3e8cb7bb1..5ddd3bdeb 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -21,7 +21,7 @@ template< typename Real, typename Anisotropy > FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >:: FastSweepingMethod() -: maxIterations( 2 ) +: maxIterations( 1 ) { } @@ -257,7 +257,7 @@ solve( const MeshPointer& mesh, tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; for( int k = 0; k < numBlocksX; k++) - CudaUpdateCellCaller< Real, Device, Index ><<< gridSize, blockSize >>>( ptr, + CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, interfaceMapPtr.template getData< Device >(), auxPtr.template modifyData< Device>() ); cudaDeviceSynchronize(); @@ -291,7 +291,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; cell.refresh(); //tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; - for( int l = 0; l < 8; l++ ) + for( int l = 0; l < 10; l++ ) { if( ! interfaceMap( cell ) ) { -- GitLab From 67997f67ce75ea053ace967a3c556c768e08cb45 Mon Sep 17 00:00:00 2001 From: fencl Date: Thu, 10 May 2018 21:26:48 +0200 Subject: [PATCH 17/28] trying git problem --- .../tnlDirectEikonalMethodsBase_impl.h | 334 +++++++++--------- .../tnlFastSweepingMethod2D_impl.h | 6 +- .../tnlFastSweepingMethod3D_impl.h | 6 +- 3 files changed, 178 insertions(+), 168 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index a89d230f6..e52f2fe1c 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -632,170 +632,6 @@ __cuda_callable__ void sortMinims( T1 pom[] ) } } -template < typename Real, typename Device, typename Index > -__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ) -{ - int i = threadIdx.x + blockDim.x*blockIdx.x; - int j = blockDim.y*blockIdx.y + threadIdx.y; - const Meshes::Grid< 2, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); - - if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) - { - typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; - Cell cell( mesh ); - cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; - cell.refresh(); - const Index cind = cell.getIndex(); - - - output[ cind ] = - input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : - - TypeInfo< Real >::getMaxValue(); - interfaceMap[ cind ] = false; - - const Real& hx = mesh.getSpaceSteps().x(); - const Real& hy = mesh.getSpaceSteps().y(); - cell.refresh(); - const Real& c = input( cell ); - if( ! cell.isBoundaryEntity() ) - { - auto neighbors = cell.getNeighborEntities(); - Real pom = 0; - const Index e = neighbors.template getEntityIndex< 1, 0 >(); - const Index w = neighbors.template getEntityIndex< -1, 0 >(); - const Index n = neighbors.template getEntityIndex< 0, 1 >(); - const Index s = neighbors.template getEntityIndex< 0, -1 >(); - - if( c * input[ n ] <= 0 ) - { - pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cell.getIndex() ] = true; - } - if( c * input[ e ] <= 0 ) - { - pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ w ] <= 0 ) - { - pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ s ] <= 0 ) - { - pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - } - } -} - -template < typename Real, typename Device, typename Index > -__global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& input, - Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& output, - Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap ) -{ - int i = threadIdx.x + blockDim.x*blockIdx.x; - int j = blockDim.y*blockIdx.y + threadIdx.y; - int k = blockDim.z*blockIdx.z + threadIdx.z; - const Meshes::Grid< 3, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); - - if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) - { - typedef typename Meshes::Grid< 3, Real, Device, Index >::Cell Cell; - Cell cell( mesh ); - cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; - cell.refresh(); - const Index cind = cell.getIndex(); - - - output[ cind ] = - input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : - - TypeInfo< Real >::getMaxValue(); - interfaceMap[ cind ] = false; - cell.refresh(); - - const Real& hx = mesh.getSpaceSteps().x(); - const Real& hy = mesh.getSpaceSteps().y(); - const Real& hz = mesh.getSpaceSteps().z(); - const Real& c = input( cell ); - if( ! cell.isBoundaryEntity() ) - { - auto neighbors = cell.getNeighborEntities(); - Real pom = 0; - const Index e = neighbors.template getEntityIndex< 1, 0, 0 >(); - const Index w = neighbors.template getEntityIndex< -1, 0, 0 >(); - const Index n = neighbors.template getEntityIndex< 0, 1, 0 >(); - const Index s = neighbors.template getEntityIndex< 0, -1, 0 >(); - const Index t = neighbors.template getEntityIndex< 0, 0, 1 >(); - const Index b = neighbors.template getEntityIndex< 0, 0, -1 >(); - - if( c * input[ n ] <= 0 ) - { - pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ e ] <= 0 ) - { - pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ w ] <= 0 ) - { - pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ s ] <= 0 ) - { - pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ b ] <= 0 ) - { - pom = TNL::sign( c )*( hz * c )/( c - input[ b ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - if( c * input[ t ] <= 0 ) - { - pom = TNL::sign( c )*( hz * c )/( c - input[ t ]); - if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) - output[ cind ] = pom; - - interfaceMap[ cind ] = true; - } - } - } -} - template< typename Real, typename Device, typename Index > @@ -967,6 +803,173 @@ getsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int b } }*/ + +#ifdef HAVE_CUDA +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + const Meshes::Grid< 2, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + { + typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; + cell.refresh(); + const Index cind = cell.getIndex(); + + + output[ cind ] = + input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : + - TypeInfo< Real >::getMaxValue(); + interfaceMap[ cind ] = false; + + const Real& hx = mesh.getSpaceSteps().x(); + const Real& hy = mesh.getSpaceSteps().y(); + cell.refresh(); + const Real& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const Index e = neighbors.template getEntityIndex< 1, 0 >(); + const Index w = neighbors.template getEntityIndex< -1, 0 >(); + const Index n = neighbors.template getEntityIndex< 0, 1 >(); + const Index s = neighbors.template getEntityIndex< 0, -1 >(); + + if( c * input[ n ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + } + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ w ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ s ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + } + } +} + +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + int k = blockDim.z*blockIdx.z + threadIdx.z; + const Meshes::Grid< 3, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) + { + typedef typename Meshes::Grid< 3, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; + cell.refresh(); + const Index cind = cell.getIndex(); + + + output[ cind ] = + input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : + - TypeInfo< Real >::getMaxValue(); + interfaceMap[ cind ] = false; + cell.refresh(); + + const Real& hx = mesh.getSpaceSteps().x(); + const Real& hy = mesh.getSpaceSteps().y(); + const Real& hz = mesh.getSpaceSteps().z(); + const Real& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const Index e = neighbors.template getEntityIndex< 1, 0, 0 >(); + const Index w = neighbors.template getEntityIndex< -1, 0, 0 >(); + const Index n = neighbors.template getEntityIndex< 0, 1, 0 >(); + const Index s = neighbors.template getEntityIndex< 0, -1, 0 >(); + const Index t = neighbors.template getEntityIndex< 0, 0, 1 >(); + const Index b = neighbors.template getEntityIndex< 0, 0, -1 >(); + + if( c * input[ n ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ n ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ e ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ w ] <= 0 ) + { + pom = TNL::sign( c )*( hx * c )/( c - input[ w ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ s ] <= 0 ) + { + pom = TNL::sign( c )*( hy * c )/( c - input[ s ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ b ] <= 0 ) + { + pom = TNL::sign( c )*( hz * c )/( c - input[ b ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ t ] <= 0 ) + { + pom = TNL::sign( c )*( hz * c )/( c - input[ t ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + } + } +} + + template< typename Real, typename Device, typename Index > @@ -1022,4 +1025,5 @@ updateCell( Real sArray[18][18], int thri, int thrj, const Real hx, const Real h //u[ cell.getIndex() ]= argAbsMin( value, tmp ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); } -} \ No newline at end of file +} +#endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 80976772c..1279e3437 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -67,7 +67,9 @@ solve( const MeshPointer& mesh, interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, auxPtr, interfaceMapPtr ); +#ifdef HAVE_CUDA cudaDeviceSynchronize(); +#endif auxPtr->save( "aux-ini.tnl" ); @@ -240,7 +242,7 @@ solve( const MeshPointer& mesh, aux.save("aux-final.tnl"); } -//#ifdef HAVE_CUDA +#ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, @@ -286,4 +288,4 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< } //ptr.getsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); } -//#endif \ No newline at end of file +#endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index 5ddd3bdeb..e9fa72e66 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -64,7 +64,9 @@ solve( const MeshPointer& mesh, interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, auxPtr, interfaceMapPtr ); +#ifdef HAVE_CUDA cudaDeviceSynchronize(); +#endif auxPtr->save( "aux-ini.tnl" ); typename MeshType::Cell cell( *mesh ); @@ -274,6 +276,7 @@ solve( const MeshPointer& mesh, aux.save("aux-final.tnl"); } +#ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap, @@ -299,4 +302,5 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< } } } -} \ No newline at end of file +} +#endif -- GitLab From 8a8b083e31f59bce56fefdff27375b7c04027ab8 Mon Sep 17 00:00:00 2001 From: fencl Date: Thu, 17 May 2018 08:54:40 +0200 Subject: [PATCH 18/28] pyramid reduction in 2D with loopCounter --- .../tnlDirectEikonalMethodsBase.h | 5 +- .../tnlDirectEikonalMethodsBase_impl.h | 141 ++------------ .../tnlFastSweepingMethod2D_impl.h | 184 +++++++++++++++--- 3 files changed, 177 insertions(+), 153 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 69fce1467..979c70e7b 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -69,7 +69,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > const MeshEntity& cell, const RealType velocity = 1.0 ); - __cuda_callable__ void updateCell( Real sArray[18][18], + __cuda_callable__ bool updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real velocity = 1.0 ); @@ -116,7 +116,8 @@ __cuda_callable__ void sortMinims( T1 pom[] ); template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ); + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, + bool *BlockIterDevice ); template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index e52f2fe1c..a3af357c9 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -684,124 +684,9 @@ setsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int b { sArray[0][i] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + 0*dimX + i ]; } - } - - /*int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); - int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); - int xkolik = 18; - int ykolik = 18; - - if( numOfBlockx - 1 == blockIdx ) - xkolik = dimX - (numOfBlockx-1)*16+1; - - if( numOfBlocky -1 == blockIdy ) - ykolik = dimY - (numOfBlocky-1)*16+1; - - - if( numOfBlockx == 0 || numOfBlocky == 0 ) - return; - else - { - if( blockIdx == 0 ) - { - if( blockIdy == 0 ) - { - for( int j = 0; j < ykolik-1; j++ ) - for( int i = 0; i < xkolik-1; i++ ) - { - sArray[ j+1 ][ i+1 ] = aux[ j*dimX + i ]; - } - - //vypis( *sArray ); - } - else - { - for( int j = 0; j < ykolik; j++ ) - for( int i = 0; i < xkolik-1; i++ ) - { - sArray[ j ][ i+1 ] = aux[ blockIdy*16*dimX - dimX + j*dimX + i ]; - } - } - } - else if( blockIdy == 0 ) - { - for( int j = 0; j < ykolik-1; j++ ) - for( int i = 0; i < xkolik; i++ ) - { - sArray[ j+1 ][ i ] = aux[ blockIdx*16 - 1 + j*dimX + i ]; - } - } - else - { - for( int j = 0; j < ykolik; j++ ) - for( int i = 0; i < xkolik; i++ ) - { - //if( dimX*dimY-1 > blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ) - sArray[ j ][ i ] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ]; - } - } - }*/ + } } -/*template< typename Real, - typename Device, - typename Index > -__cuda_callable__ void -tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: -getsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int blockIdx, int blockIdy ) -{ - int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); - int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); - int xkolik = 18; - int ykolik = 18; - - if( numOfBlockx - 1 == blockIdx ) - xkolik = dimX - (numOfBlockx-1)*16+2; - - if( numOfBlocky -1 == blockIdy ) - ykolik = dimY - (numOfBlocky-1)*16+2; - - if( numOfBlockx == 0 || numOfBlocky == 0 ) - return; - else - { - if( blockIdx == 0 ) - { - if( blockIdy == 0 ) - { - for( int j = 0; j < ykolik-2; j++ ) - for( int i = 0; i < xkolik-2; i++ ) - { - aux[ j*dimX + i ] = sArray[ j+1 ][ i+1 ]; - } - } - else - { - for( int j = 1; j < ykolik-1; j++ ) - for( int i = 0; i < xkolik-2; i++ ) - { - aux[ blockIdy*16*dimX - dimX + j*dimX + i ] = sArray[ j ][ i+1 ]; - } - } - } - else if( blockIdy == 0 ) - { - for( int j = 0; j < ykolik-2; j++ ) - for( int i = 1; i < xkolik-1; i++ ) - { - aux[ blockIdx*16 - 1 + j*dimX + i ] = sArray[ j+1 ][ i ]; - } - } - else - { - for( int j = 1; j < ykolik-1; j++ ) - for( int i = 1; i < xkolik-1; i++ ) - { - aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + j*dimX + i ] = sArray[ j ][ i ]; - } - } - } -}*/ #ifdef HAVE_CUDA @@ -974,9 +859,9 @@ template< typename Real, typename Device, typename Index > __cuda_callable__ -void +bool tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: -updateCell( Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, +updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real v ) { @@ -991,39 +876,39 @@ updateCell( Real sArray[18][18], int thri, int thrj, const Real hx, const Real h const RealType& hy = mesh.getSpaceSteps().y();*/ const RealType value = sArray[ thrj ][ thri ];//u( cell ); RealType a, b, tmp = TypeInfo< RealType >::getMaxValue(); - - /*if( value != u[ cell.getIndex() ] ) - return;*/ - + b = TNL::argAbsMin( sArray[ thrj+1 ][ thri ], sArray[ thrj-1 ][ thri ] ); a = TNL::argAbsMin( sArray[ thrj ][ thri+1 ], sArray[ thrj ][ thri-1 ] ); - - if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && fabs( b ) == TypeInfo< RealType >::getMaxValue() ) - return; + return false; - RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, 0.0 }; + RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, TypeInfo< Real >::getMaxValue() }; sortMinims( pom ); tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]/v; if( fabs( tmp ) < fabs( pom[ 1 ] ) ) { - //u[ cell.getIndex() ]= argAbsMin( value, tmp ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); + if ( fabs( value - sArray[ thrj ][ thri ] ) > 0.001 ) + return true; + return false; } else { tmp = ( pom[ 3 ] * pom[ 3 ] * pom[ 1 ] + pom[ 4 ] * pom[ 4 ] * pom[ 0 ] + TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); - //u[ cell.getIndex() ]= argAbsMin( value, tmp ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); + if ( fabs( value - sArray[ thrj ][ thri ] ) > 0.001 ) + return true; + return false; } + return false; } #endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 1279e3437..d4cb1f63b 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -227,12 +227,47 @@ solve( const MeshPointer& mesh, tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; int nBlockIter = numBlocksX > numBlocksY ? numBlocksX : numBlocksY; nBlockIter = numBlocksX == numBlocksY ? nBlockIter + 1 : nBlockIter; - for( int k = 0; k < nBlockIter; k++) + + bool isNotDone = true; + bool* BlockIter = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + + bool *BlockIterDevice; + cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + + while( isNotDone ) + { + for( int i = 0; i < numBlocksX * numBlocksY; i++ ) + BlockIter[ i ] = false; + + isNotDone = false; + CudaUpdateCellCaller<<< gridSize, blockSize, 18 * 18 * sizeof( Real ) >>>( ptr, interfaceMapPtr.template getData< Device >(), - auxPtr.template modifyData< Device>() ); + auxPtr.template modifyData< Device>(), + BlockIterDevice ); + cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyDeviceToHost); + for( int i = 0; i < numBlocksX; i++ ) + { for( int j = 0; j < numBlocksY; j++ ) + { + if( BlockIter[ j * numBlocksY + i ] ) + std::cout << "true." << "\t"; + else + std::cout << "false." << "\t"; + } + std::cout << std::endl; + } + std::cout << std::endl; + + for( int i = 0; i < numBlocksX * numBlocksY; i++ ) + isNotDone = isNotDone || BlockIter[ i ]; + + } + delete[] BlockIter; + cudaFree( BlockIterDevice ); cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; + aux = *auxPtr; interfaceMap = *interfaceMapPtr; #endif @@ -246,46 +281,149 @@ solve( const MeshPointer& mesh, template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux ) + Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, + bool *BlockIterDevice ) { int thri = threadIdx.x; int thrj = threadIdx.y; // nelze ke stejnym pristupovat znovu pres threadIdx (vzdy da jine hodnoty) int blIdx = blockIdx.x; int blIdy = blockIdx.y; int i = thri + blockDim.x*blIdx; int j = blockDim.y*blIdy + thrj; + + __shared__ volatile bool changed[256]; + changed[ thrj * blockDim.x + thri ] = false; + __shared__ volatile bool SmallCycleBoolin; + if( thrj == 0 && thri == 0 ) + SmallCycleBoolin = true; + + const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); const Real hx = mesh.getSpaceSteps().x(); const Real hy = mesh.getSpaceSteps().y(); - __shared__ Real sArray[ 18 ][ 18 ]; - for( int k = 0; k < 18; k++ ) - for( int l = 0; l < 18; l++ ) - sArray[ k ][ l ] = TypeInfo< Real >::getMaxValue(); - __syncthreads(); - /*//filling shared array - ptr.setsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); - __syncthreads();*/ + __shared__ volatile Real sArray[ 18 ][ 18 ]; + sArray[thrj][thri] = TypeInfo< Real >::getMaxValue(); - if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + //filling sArray edges + int dimX = mesh.getDimensions().x(); int dimY = mesh.getDimensions().y(); + int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); + int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); + int xkolik = 17; + int ykolik = 17; + + + if( numOfBlockx - 1 == blIdx ) + xkolik = dimX - (blIdx)*16+1; + + if( numOfBlocky -1 == blIdy ) + ykolik = dimY - (blIdy)*16+1; + + + if( thri == 0 ) + { + if( dimX > (blIdx+1) * 16 && thrj+1 < ykolik ) + sArray[thrj+1][xkolik] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + (thrj+1)*dimX + 17 ]; + else + sArray[thrj+1][xkolik] = TypeInfo< Real >::getMaxValue(); + } + + if( thri == 1 ) + { + if( blIdx != 0 && thrj+1 < ykolik ) + sArray[thrj+1][0] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + (thrj+1)*dimX + 0]; + else + sArray[thrj+1][0] = TypeInfo< Real >::getMaxValue(); + } + + if( thrj == 0 ) { + if( dimY > (blIdy+1) * 16 && thri+1 < xkolik ) + sArray[ykolik][thri+1] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + 17*dimX + thri+1 ]; + else + sArray[ykolik][thri+1] = TypeInfo< Real >::getMaxValue(); + } + + if( thrj == 1 ) + { + if( blIdy != 0 && thri+1 < xkolik ) + sArray[0][thri+1] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + 0*dimX + thri+1 ]; + else + sArray[0][thri+1] = TypeInfo< Real >::getMaxValue(); + } + + //filling BlockIterDevice + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = false; + + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + { sArray[thrj+1][thri+1] = aux[ j*mesh.getDimensions().x() + i ]; - ptr.setsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); //fill edges of sArray __syncthreads(); - + } + + __shared__ int loopcounter; + if( thri == 0 && thrj == 0 ) + loopcounter= 0; + //if( blIdx == 5 && blIdy == 4 ) + while( SmallCycleBoolin ) + { + if( thri == 1 && thrj == 1 ) + SmallCycleBoolin = false; + + changed[ thrj * 16 + thri ] = false; + __syncthreads(); - if( ! interfaceMap[ j*mesh.getDimensions().x() + i ] ) + //calculation of update cell + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + { + if( ! interfaceMap[ j * mesh.getDimensions().x() + i ] ) + { + changed[ thrj * 16 + thri ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); + __syncthreads(); + } + } + + //pyramid reduction + if( blockDim.x*blockDim.y >= 256 ) + { + if( (thrj * 16 + thri) < 128 ) + { + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 128 ]; + } + __syncthreads(); + } + if( blockDim.x*blockDim.y >= 128 ) { - for( int k = 0; k < 17; k++ ) + if( (thrj * 16 + thri) < 64 ) { - ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); - __syncthreads(); + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 64 ]; } + __syncthreads(); + } + if( (thrj * 16 + thri) < 32 ) + { + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 32 ]; + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 16 ]; + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 8 ]; + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 4 ]; + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 2 ]; + changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 1 ]; + } + __syncthreads(); + + if( thrj == 1 && thri == 1 ) + { + loopcounter++; + if( loopcounter > 1000 ) + break; + SmallCycleBoolin = changed[ 0 ]; + //if( SmallCycleBoolin ) + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = SmallCycleBoolin; } - /*for( int k = 0; k < mesh.getDimensions().x(); k++) - for( int l = 0; l < mesh.getDimensions().y(); l++) - aux[ k*mesh.getDimensions().x() + l ] = TypeInfo< Real >::getMaxValue();*/ - aux[j*mesh.getDimensions().x() + i] = sArray[thrj+1][thri+1]; __syncthreads(); } - //ptr.getsArray( aux, sArray, mesh.getDimensions().x(), mesh.getDimensions().y(), blIdx, blIdy ); + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) + aux[ j * mesh.getDimensions().x() + i ] = sArray[ thrj + 1 ][ thri + 1 ]; + } #endif -- GitLab From 02251467ef38f31508762d0019b2c0ba52ba3b69 Mon Sep 17 00:00:00 2001 From: fencl Date: Thu, 7 Jun 2018 08:49:09 +0200 Subject: [PATCH 19/28] debugging kernel for update cell, still not clear what is wrong. --- .../tnlDirectEikonalMethodsBase.h | 4 +- .../tnlDirectEikonalMethodsBase_impl.h | 25 +- .../tnlFastSweepingMethod2D_impl.h | 222 +++++++++++------- 3 files changed, 152 insertions(+), 99 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 979c70e7b..fe83b61c0 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -69,7 +69,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > const MeshEntity& cell, const RealType velocity = 1.0 ); - __cuda_callable__ bool updateCell( volatile Real sArray[18][18], + __cuda_callable__ double updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real velocity = 1.0 ); @@ -117,7 +117,7 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - bool *BlockIterDevice ); + Real *BlockIterDevice ); template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index a3af357c9..098dace4b 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -859,7 +859,7 @@ template< typename Real, typename Device, typename Index > __cuda_callable__ -bool +double tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real v ) @@ -885,9 +885,9 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && fabs( b ) == TypeInfo< RealType >::getMaxValue() ) - return false; + return 0; - RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, TypeInfo< Real >::getMaxValue() }; + RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, 0.0 }; sortMinims( pom ); tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]/v; @@ -895,9 +895,11 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con if( fabs( tmp ) < fabs( pom[ 1 ] ) ) { sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); - if ( fabs( value - sArray[ thrj ][ thri ] ) > 0.001 ) - return true; - return false; + tmp = value - sArray[ thrj ][ thri ]; + if ( fabs( tmp ) > 0.1 ) + return 10; + else + return 0; } else { @@ -905,10 +907,13 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); - if ( fabs( value - sArray[ thrj ][ thri ] ) > 0.001 ) - return true; - return false; + tmp = value - sArray[ thrj ][ thri ]; + if ( fabs( tmp ) > 0.1 ) + return 10; + else + return 0; } - return false; + + return 0; } #endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index d4cb1f63b..e24201936 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -225,39 +225,46 @@ solve( const MeshPointer& mesh, Devices::Cuda::synchronizeDevice(); tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; - int nBlockIter = numBlocksX > numBlocksY ? numBlocksX : numBlocksY; - nBlockIter = numBlocksX == numBlocksY ? nBlockIter + 1 : nBlockIter; - bool isNotDone = true; - bool* BlockIter = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); - bool *BlockIterDevice; - cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + /*int nBlockIter = numBlocksX > numBlocksY ? numBlocksX : numBlocksY; + nBlockIter = numBlocksX == numBlocksY ? nBlockIter + 1 : nBlockIter;*/ - while( isNotDone ) + bool isNotDone = true; numBlocksX = 16; numBlocksY = 16; + double* BlockIter = (double*)malloc( ( numBlocksX * numBlocksY ) * sizeof( double ) ); + + double *BlockIterDevice; + cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( double ) ); + + //while( isNotDone ) { for( int i = 0; i < numBlocksX * numBlocksY; i++ ) - BlockIter[ i ] = false; + BlockIter[ i ] = 0.0; + cudaMemcpy(BlockIterDevice, BlockIter, ( numBlocksX * numBlocksY ) * sizeof( double ), cudaMemcpyHostToDevice); isNotDone = false; - CudaUpdateCellCaller<<< gridSize, blockSize, 18 * 18 * sizeof( Real ) >>>( ptr, - interfaceMapPtr.template getData< Device >(), - auxPtr.template modifyData< Device>(), - BlockIterDevice ); - cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyDeviceToHost); - for( int i = 0; i < numBlocksX; i++ ) - { for( int j = 0; j < numBlocksY; j++ ) + CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, + interfaceMapPtr.template getData< Device >(), + auxPtr.template modifyData< Device>(), + BlockIterDevice ); + cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; + cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( double ), cudaMemcpyDeviceToHost); + + for( int j = numBlocksY-1; j > -1; j-- ) + { + for( int i = 0; i < numBlocksX; i++ ) { - if( BlockIter[ j * numBlocksY + i ] ) - std::cout << "true." << "\t"; - else - std::cout << "false." << "\t"; + //if( BlockIter[ j * numBlocksX + i ] ) + std::cout << BlockIter[ j * numBlocksY + i ] << "\t"; + //else + // std::cout << "0" << " "; } std::cout << std::endl; } std::cout << std::endl; - + for( int i = 0; i < numBlocksX * numBlocksY; i++ ) isNotDone = isNotDone || BlockIter[ i ]; @@ -282,148 +289,189 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - bool *BlockIterDevice ) + Real *BlockIterDevice ) { - int thri = threadIdx.x; int thrj = threadIdx.y; // nelze ke stejnym pristupovat znovu pres threadIdx (vzdy da jine hodnoty) + int thri = threadIdx.x; int thrj = threadIdx.y; int blIdx = blockIdx.x; int blIdy = blockIdx.y; int i = thri + blockDim.x*blIdx; int j = blockDim.y*blIdy + thrj; + int currentIndex = thrj * 16 + thri; + + __shared__ volatile Real changed[256]; + changed[ currentIndex ] = 0.0; + __syncthreads(); - __shared__ volatile bool changed[256]; - changed[ thrj * blockDim.x + thri ] = false; - __shared__ volatile bool SmallCycleBoolin; if( thrj == 0 && thri == 0 ) - SmallCycleBoolin = true; + changed[ 0 ] = 10.0; + __syncthreads(); + //SmallCycleBoolin = true; const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); - const Real hx = mesh.getSpaceSteps().x(); - const Real hy = mesh.getSpaceSteps().y(); + __shared__ Real hx; + __shared__ Real hy; + if( thrj == 0 && thri == 0 ) + { + hx = mesh.getSpaceSteps().x(); + hy = mesh.getSpaceSteps().y(); + } + __syncthreads(); __shared__ volatile Real sArray[ 18 ][ 18 ]; sArray[thrj][thri] = TypeInfo< Real >::getMaxValue(); + __syncthreads(); //filling sArray edges int dimX = mesh.getDimensions().x(); int dimY = mesh.getDimensions().y(); - int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); - int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); - int xkolik = 17; - int ykolik = 17; - + __shared__ volatile int numOfBlockx; + __shared__ volatile int numOfBlocky; + __shared__ int xkolik; + __shared__ int ykolik; + if( thri == 0 && thrj == 0 ) + { + xkolik = blockDim.x + 1; + ykolik = blockDim.y + 1; + numOfBlocky = dimY/blockDim.y + ((dimY%blockDim.y != 0) ? 1:0); + numOfBlockx = dimX/blockDim.x + ((dimX%blockDim.x != 0) ? 1:0); - if( numOfBlockx - 1 == blIdx ) - xkolik = dimX - (blIdx)*16+1; + if( numOfBlockx - 1 == blIdx ) + xkolik = dimX - (blIdx)*blockDim.x+1; - if( numOfBlocky -1 == blIdy ) - ykolik = dimY - (blIdy)*16+1; - + if( numOfBlocky -1 == blIdy ) + ykolik = dimY - (blIdy)*blockDim.y+1; + + //filling BlockIterDevice + //BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = 0.0; + } + /*if( blIdx == 2 && blIdy == 3 ) + BlockIterDevice[ currentIndex ] = 0.0;*/ + __syncthreads(); if( thri == 0 ) { - if( dimX > (blIdx+1) * 16 && thrj+1 < ykolik ) - sArray[thrj+1][xkolik] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + (thrj+1)*dimX + 17 ]; + if( dimX > (blIdx+1) * blockDim.x && thrj+1 < ykolik ) + sArray[thrj+1][xkolik] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + (thrj+1)*dimX + xkolik ]; else sArray[thrj+1][xkolik] = TypeInfo< Real >::getMaxValue(); } + __syncthreads(); if( thri == 1 ) { if( blIdx != 0 && thrj+1 < ykolik ) - sArray[thrj+1][0] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + (thrj+1)*dimX + 0]; + sArray[thrj+1][0] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + (thrj+1)*dimX ]; else sArray[thrj+1][0] = TypeInfo< Real >::getMaxValue(); } + __syncthreads(); if( thrj == 0 ) { - if( dimY > (blIdy+1) * 16 && thri+1 < xkolik ) - sArray[ykolik][thri+1] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + 17*dimX + thri+1 ]; + if( dimY > (blIdy+1) * blockDim.y && thri+1 < xkolik ) + sArray[ykolik][thri+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + ykolik*dimX + thri+1 ]; else sArray[ykolik][thri+1] = TypeInfo< Real >::getMaxValue(); } + __syncthreads(); if( thrj == 1 ) { if( blIdy != 0 && thri+1 < xkolik ) - sArray[0][thri+1] = aux[ blIdy*16*dimX - dimX + blIdx*16 - 1 + 0*dimX + thri+1 ]; + sArray[0][thri+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + thri+1 ]; else sArray[0][thri+1] = TypeInfo< Real >::getMaxValue(); } + __syncthreads(); - //filling BlockIterDevice - BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = false; - - + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { sArray[thrj+1][thri+1] = aux[ j*mesh.getDimensions().x() + i ]; __syncthreads(); - } + } - __shared__ int loopcounter; - if( thri == 0 && thrj == 0 ) - loopcounter= 0; - //if( blIdx == 5 && blIdy == 4 ) - while( SmallCycleBoolin ) + int loopcounter; + loopcounter = 0; + __syncthreads(); + + /*if( ( blIdx == 4 && blIdy == 5 ) || ( blIdx == 2 && blIdy == 2 ) || ( blIdx == 2 && blIdy == 3 ) || + ( blIdx == 5 && blIdy == 5 ) || ( blIdx == 6 && blIdy == 5 ) || ( blIdx == 5 && blIdy == 4 ) || + ( blIdx == 5 && blIdy == 2 ) || ( blIdx == 3 && blIdy == 2 ) || ( blIdx == 4 && blIdy == 2 ) )*/ + while( changed[ 0 ] > 0.1 ) { - if( thri == 1 && thrj == 1 ) - SmallCycleBoolin = false; - - changed[ thrj * 16 + thri ] = false; + changed[ currentIndex] = 0.0; __syncthreads(); //calculation of update cell if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) - { + { if( ! interfaceMap[ j * mesh.getDimensions().x() + i ] ) { - changed[ thrj * 16 + thri ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); - __syncthreads(); + changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); + __syncthreads(); } } + __syncthreads(); //pyramid reduction if( blockDim.x*blockDim.y >= 256 ) { - if( (thrj * 16 + thri) < 128 ) + if( currentIndex < 128 ) { - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 128 ]; + changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 128 ]; } - __syncthreads(); } + __syncthreads(); if( blockDim.x*blockDim.y >= 128 ) { - if( (thrj * 16 + thri) < 64 ) + if( currentIndex < 64 ) { - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 64 ]; + changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 64 ]; } - __syncthreads(); - } - if( (thrj * 16 + thri) < 32 ) - { - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 32 ]; - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 16 ]; - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 8 ]; - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 4 ]; - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 2 ]; - changed[ thrj * 16 + thri ] = changed[ thrj * 16 + thri ] || changed[ thrj * 16 + thri + 1 ]; } __syncthreads(); - - if( thrj == 1 && thri == 1 ) + if( currentIndex < 32 ) //POUZE IF JSOU SINCHRONNI NA JEDNOM WARPU { - loopcounter++; - if( loopcounter > 1000 ) - break; - SmallCycleBoolin = changed[ 0 ]; - //if( SmallCycleBoolin ) - BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = SmallCycleBoolin; + if( true ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 32 ]; + if( currentIndex < 16 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 16 ]; + if( currentIndex < 8 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 8 ]; + if( currentIndex < 4 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 4 ]; + if( currentIndex < 2 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 2 ]; + if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 1 ]; } __syncthreads(); - } - if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) - aux[ j * mesh.getDimensions().x() + i ] = sArray[ thrj + 1 ][ thri + 1 ]; + + loopcounter++; + __syncthreads(); + if( currentIndex != 0 ) + changed[ currentIndex ] = 0.0; + __syncthreads(); + + if( loopcounter > 200 ) + changed[ currentIndex ] = 0.0; + __syncthreads(); + } + /*__syncthreads(); + if( blIdy == 3 && blIdx == 1 ) + { + BlockIterDevice[ currentIndex ] = changed[ currentIndex ]; + BlockIterDevice[ 0 ] = loopcounter; + }*/ + __syncthreads(); + if( blIdx == 2 && blIdy == 3 ) + { + //SmallCycleBoolin = changed[ 0 ]; + //if( changed[ 0 ] ) + BlockIterDevice[ currentIndex ] = changed[ currentIndex ];// loopcounter; + BlockIterDevice[ 0 ] = loopcounter; + + } + + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && (!interfaceMap[ j * mesh.getDimensions().x() + i ]) ) + aux[ j * mesh.getDimensions().x() + i ] = sArray[ thrj + 1 ][ thri + 1 ]; + __syncthreads(); } #endif -- GitLab From b387101c185fb66d078734baa16e46afb5c713f1 Mon Sep 17 00:00:00 2001 From: fencl Date: Tue, 19 Jun 2018 08:49:04 +0200 Subject: [PATCH 20/28] Mistake found and repaied from 2D. Problem with EOC appeared. --- .../tnlDirectEikonalMethodsBase.h | 4 +- .../tnlDirectEikonalMethodsBase_impl.h | 30 ++-- .../tnlFastSweepingMethod2D_impl.h | 139 ++++++------------ 3 files changed, 59 insertions(+), 114 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index fe83b61c0..979c70e7b 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -69,7 +69,7 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > const MeshEntity& cell, const RealType velocity = 1.0 ); - __cuda_callable__ double updateCell( volatile Real sArray[18][18], + __cuda_callable__ bool updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real velocity = 1.0 ); @@ -117,7 +117,7 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - Real *BlockIterDevice ); + bool *BlockIterDevice ); template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 098dace4b..9ec95c25f 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -859,22 +859,12 @@ template< typename Real, typename Device, typename Index > __cuda_callable__ -double +bool tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real v ) { - - //const Meshes::Grid< 2, Real, Device, Index >& mesh = u.template getMesh< Devices::Cuda >(); - /*typedef typename Meshes::Grid< 2, Real, Device, Index >::Cell Cell; - Cell cell( mesh ); - cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; - cell.refresh(); - - const auto& neighborEntities = cell.template getNeighborEntities< 2 >(); - const RealType& hx = mesh.getSpaceSteps().x(); - const RealType& hy = mesh.getSpaceSteps().y();*/ - const RealType value = sArray[ thrj ][ thri ];//u( cell ); + const RealType value = sArray[ thrj ][ thri ]; RealType a, b, tmp = TypeInfo< RealType >::getMaxValue(); b = TNL::argAbsMin( sArray[ thrj+1 ][ thri ], @@ -885,7 +875,7 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && fabs( b ) == TypeInfo< RealType >::getMaxValue() ) - return 0; + return false; RealType pom[6] = { a, b, TypeInfo< Real >::getMaxValue(), (RealType)hx, (RealType)hy, 0.0 }; sortMinims( pom ); @@ -896,10 +886,10 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con { sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); tmp = value - sArray[ thrj ][ thri ]; - if ( fabs( tmp ) > 0.1 ) - return 10; + if ( fabs( tmp ) > 0.001 ) + return true; else - return 0; + return false; } else { @@ -908,12 +898,12 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); tmp = value - sArray[ thrj ][ thri ]; - if ( fabs( tmp ) > 0.1 ) - return 10; + if ( fabs( tmp ) > 0.01 ) + return true; else - return 0; + return false; } - return 0; + return false; } #endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index e24201936..e72710408 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -227,46 +227,38 @@ solve( const MeshPointer& mesh, tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; - /*int nBlockIter = numBlocksX > numBlocksY ? numBlocksX : numBlocksY; - nBlockIter = numBlocksX == numBlocksY ? nBlockIter + 1 : nBlockIter;*/ - bool isNotDone = true; numBlocksX = 16; numBlocksY = 16; - double* BlockIter = (double*)malloc( ( numBlocksX * numBlocksY ) * sizeof( double ) ); + bool* BlockIter = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); - double *BlockIterDevice; - cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( double ) ); + bool *BlockIterDevice; + cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ) ); - //while( isNotDone ) + while( BlockIter[ 0 ] ) { for( int i = 0; i < numBlocksX * numBlocksY; i++ ) - BlockIter[ i ] = 0.0; - cudaMemcpy(BlockIterDevice, BlockIter, ( numBlocksX * numBlocksY ) * sizeof( double ), cudaMemcpyHostToDevice); - - isNotDone = false; - + BlockIter[ i ] = false; + cudaMemcpy(BlockIterDevice, BlockIter, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyHostToDevice); + CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, interfaceMapPtr.template getData< Device >(), auxPtr.template modifyData< Device>(), BlockIterDevice ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; - cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( double ), cudaMemcpyDeviceToHost); + cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyDeviceToHost); - for( int j = numBlocksY-1; j > -1; j-- ) + /*for( int j = numBlocksY-1; j > -1; j-- ) { for( int i = 0; i < numBlocksX; i++ ) { - //if( BlockIter[ j * numBlocksX + i ] ) - std::cout << BlockIter[ j * numBlocksY + i ] << "\t"; - //else - // std::cout << "0" << " "; + std::cout << BlockIter[ j * numBlocksY + i ] << "\t"; } std::cout << std::endl; } - std::cout << std::endl; + std::cout << std::endl;*/ - for( int i = 0; i < numBlocksX * numBlocksY; i++ ) - isNotDone = isNotDone || BlockIter[ i ]; + for( int i = 1; i < numBlocksX * numBlocksY; i++ ) + BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ]; } delete[] BlockIter; @@ -289,7 +281,7 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - Real *BlockIterDevice ) + bool *BlockIterDevice ) { int thri = threadIdx.x; int thrj = threadIdx.y; int blIdx = blockIdx.x; int blIdy = blockIdx.y; @@ -297,15 +289,12 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< int j = blockDim.y*blIdy + thrj; int currentIndex = thrj * 16 + thri; - __shared__ volatile Real changed[256]; - changed[ currentIndex ] = 0.0; - __syncthreads(); + __shared__ volatile bool changed[256]; + changed[ currentIndex ] = false; if( thrj == 0 && thri == 0 ) - changed[ 0 ] = 10.0; + changed[ 0 ] = true; __syncthreads(); - //SmallCycleBoolin = true; - const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); __shared__ Real hx; @@ -315,11 +304,9 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< hx = mesh.getSpaceSteps().x(); hy = mesh.getSpaceSteps().y(); } - __syncthreads(); __shared__ volatile Real sArray[ 18 ][ 18 ]; sArray[thrj][thri] = TypeInfo< Real >::getMaxValue(); - __syncthreads(); //filling sArray edges int dimX = mesh.getDimensions().x(); int dimY = mesh.getDimensions().y(); @@ -339,12 +326,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( numOfBlocky -1 == blIdy ) ykolik = dimY - (blIdy)*blockDim.y+1; - - //filling BlockIterDevice - //BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = 0.0; - } - /*if( blIdx == 2 && blIdy == 3 ) - BlockIterDevice[ currentIndex ] = 0.0;*/ + } __syncthreads(); if( thri == 0 ) @@ -354,7 +336,6 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< else sArray[thrj+1][xkolik] = TypeInfo< Real >::getMaxValue(); } - __syncthreads(); if( thri == 1 ) { @@ -363,7 +344,6 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< else sArray[thrj+1][0] = TypeInfo< Real >::getMaxValue(); } - __syncthreads(); if( thrj == 0 ) { @@ -372,7 +352,6 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< else sArray[ykolik][thri+1] = TypeInfo< Real >::getMaxValue(); } - __syncthreads(); if( thrj == 1 ) { @@ -381,44 +360,47 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< else sArray[0][thri+1] = TypeInfo< Real >::getMaxValue(); } - __syncthreads(); if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { sArray[thrj+1][thri+1] = aux[ j*mesh.getDimensions().x() + i ]; - __syncthreads(); - } - - int loopcounter; - loopcounter = 0; - __syncthreads(); - - /*if( ( blIdx == 4 && blIdy == 5 ) || ( blIdx == 2 && blIdy == 2 ) || ( blIdx == 2 && blIdy == 3 ) || - ( blIdx == 5 && blIdy == 5 ) || ( blIdx == 6 && blIdy == 5 ) || ( blIdx == 5 && blIdy == 4 ) || - ( blIdx == 5 && blIdy == 2 ) || ( blIdx == 3 && blIdy == 2 ) || ( blIdx == 4 && blIdy == 2 ) )*/ - while( changed[ 0 ] > 0.1 ) + } + __syncthreads(); + + while( changed[ 0 ] ) { - changed[ currentIndex] = 0.0; __syncthreads(); + changed[ currentIndex] = false; + //calculation of update cell if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() ) { if( ! interfaceMap[ j * mesh.getDimensions().x() + i ] ) { - changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); - __syncthreads(); + changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); } } __syncthreads(); + /*if( thri == 0 && thrj == 0 && blIdx == 1 && blIdy == 3 ){ + for( int h = 15; h > -1; h-- ){ + for( int g = 0; g < 16; g++ ){ + printf( "%d\t", changed[h*16+g] ); + } + printf("\n"); + } + printf("\n"); + } + __syncthreads();*/ + //pyramid reduction if( blockDim.x*blockDim.y >= 256 ) { if( currentIndex < 128 ) { - changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 128 ]; + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 128 ]; } } __syncthreads(); @@ -426,52 +408,25 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< { if( currentIndex < 64 ) { - changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 64 ]; + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 64 ]; } } __syncthreads(); if( currentIndex < 32 ) //POUZE IF JSOU SINCHRONNI NA JEDNOM WARPU { - if( true ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 32 ]; - if( currentIndex < 16 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 16 ]; - if( currentIndex < 8 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 8 ]; - if( currentIndex < 4 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 4 ]; - if( currentIndex < 2 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 2 ]; - if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] + changed[ currentIndex + 1 ]; + if( true ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 32 ]; + if( currentIndex < 16 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 16 ]; + if( currentIndex < 8 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 8 ]; + if( currentIndex < 4 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 4 ]; + if( currentIndex < 2 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 2 ]; + if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 1 ]; } + if( changed[ 0 ] && thri == 0 && thrj == 0 ) + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = changed[ 0 ]; __syncthreads(); - - - - loopcounter++; - __syncthreads(); - if( currentIndex != 0 ) - changed[ currentIndex ] = 0.0; - __syncthreads(); - - if( loopcounter > 200 ) - changed[ currentIndex ] = 0.0; - __syncthreads(); - } - /*__syncthreads(); - if( blIdy == 3 && blIdx == 1 ) - { - BlockIterDevice[ currentIndex ] = changed[ currentIndex ]; - BlockIterDevice[ 0 ] = loopcounter; - }*/ - __syncthreads(); - if( blIdx == 2 && blIdy == 3 ) - { - //SmallCycleBoolin = changed[ 0 ]; - //if( changed[ 0 ] ) - BlockIterDevice[ currentIndex ] = changed[ currentIndex ];// loopcounter; - BlockIterDevice[ 0 ] = loopcounter; - } - - + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && (!interfaceMap[ j * mesh.getDimensions().x() + i ]) ) aux[ j * mesh.getDimensions().x() + i ] = sArray[ thrj + 1 ][ thri + 1 ]; - __syncthreads(); } #endif -- GitLab From c822988ebf6264b2aa6c438488f028e38db7d8ba Mon Sep 17 00:00:00 2001 From: fencl Date: Sun, 1 Jul 2018 16:22:54 +0200 Subject: [PATCH 21/28] Implementation of 1D solver is done for both CPU and GPU. 2D solver is now working fine --- .../tnlDirectEikonalMethodsBase.h | 23 +- .../tnlDirectEikonalMethodsBase_impl.h | 278 ++++++++++++------ .../tnlDirectEikonalProblem_impl.h | 2 +- .../tnlFastSweepingMethod1D_impl.h | 191 +++++++++++- .../tnlFastSweepingMethod2D_impl.h | 67 +++-- 5 files changed, 420 insertions(+), 141 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 979c70e7b..fe7d4b9ba 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -40,8 +40,12 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > template< typename MeshEntity > __cuda_callable__ void updateCell( MeshFunctionType& u, - const MeshEntity& cell ); + const MeshEntity& cell, + const RealType velocity = 1.0 ); + __cuda_callable__ bool updateCell( volatile Real sArray[18], + int thri, const Real h, + const Real velocity = 1.0 ); }; @@ -72,12 +76,6 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > __cuda_callable__ bool updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, const Real hy, const Real velocity = 1.0 ); - - __cuda_callable__ void setsArray( MeshFunctionType& aux, Real sArray[18][18], - int dimX, int dimY, int i, int j ); - - /*__cuda_callable__ void getsArray( MeshFunctionType& aux, Real sArray[18][18], - int dimX, int dimY, int i, int j );*/ }; template< typename Real, @@ -113,6 +111,17 @@ __cuda_callable__ void sortMinims( T1 pom[] ); #ifdef HAVE_CUDA +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index >, 1, bool >& interfaceMap ); + +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index >, 1, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& aux, + bool *BlockIterDevice ); + template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 9ec95c25f..c742a11b5 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -21,45 +21,72 @@ initInterface( const MeshFunctionPointer& _input, MeshFunctionPointer& _output, InterfaceMapPointer& _interfaceMap ) { - const MeshType& mesh = _input->getMesh(); - typedef typename MeshType::Cell Cell; - const MeshFunctionType& input = _input.getData(); - MeshFunctionType& output = _output.modifyData(); - InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); - Cell cell( mesh ); - for( cell.getCoordinates().x() = 1; - cell.getCoordinates().x() < mesh.getDimensions().x() - 1; - cell.getCoordinates().x() ++ ) - { - cell.refresh(); - const RealType& c = input( cell ); - if( ! cell.isBoundaryEntity() ) - { - const auto& neighbors = cell.getNeighborEntities(); - const RealType& h = mesh.getSpaceSteps().x(); - //const IndexType& c = cell.getIndex(); - const IndexType e = neighbors.template getEntityIndex< 1 >(); - const IndexType w = neighbors.template getEntityIndex< -1 >(); - if( c * input[ e ] <=0 ) - { - output[ cell.getIndex() ] = - c >= 0 ? ( h * c )/( c - input[ e ] ) : - - ( h * c )/( c - input[ e ] ); - interfaceMap[ cell.getIndex() ] = true; - } - if( c * input[ w ] <=0 ) - { - output[ cell.getIndex() ] = - c >= 0 ? ( h * c )/( c - input[ w ] ) : - - ( h * c )/( c - input[ w ] ); - interfaceMap[ cell.getIndex() ] = true; - } - } - output[ cell.getIndex() ] = - c > 0 ? TNL::TypeInfo< RealType >::getMaxValue() : - -TypeInfo< RealType >::getMaxValue(); - interfaceMap[ cell.getIndex() ] = false; - } + if( std::is_same< Device, Devices::Cuda >::value ) + { +#ifdef HAVE_CUDA + const MeshType& mesh = _input->getMesh(); + + const int cudaBlockSize( 16 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize ); + dim3 blockSize( cudaBlockSize ); + dim3 gridSize( numBlocksX ); + Devices::Cuda::synchronizeDevice(); + CudaInitCaller<<< gridSize, blockSize >>>( _input.template getData< Device >(), + _output.template modifyData< Device >(), + _interfaceMap.template modifyData< Device >() ); + cudaDeviceSynchronize(); + TNL_CHECK_CUDA_DEVICE; +#endif + } + if( std::is_same< Device, Devices::Host >::value ) + { + const MeshType& mesh = _input->getMesh(); + typedef typename MeshType::Cell Cell; + const MeshFunctionType& input = _input.getData(); + MeshFunctionType& output = _output.modifyData(); + InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); + Cell cell( mesh ); + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + output[ cell.getIndex() ] = + input( cell ) >= 0 ? TypeInfo< RealType >::getMaxValue() : + - TypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } + + + const RealType& h = mesh.getSpaceSteps().x(); + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x() - 1; + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + const auto& neighbors = cell.getNeighborEntities(); + Real pom = 0; + //const IndexType& c = cell.getIndex(); + const IndexType e = neighbors.template getEntityIndex< 1 >(); + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( h * c )/( c - input[ e ]); + if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) ) + output[ cell.getIndex() ] = pom; + + pom = pom - TNL::sign( c )*h; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; + if( TNL::abs( output[ e ] ) > TNL::abs( pom ) ) + output[ e ] = pom; + + interfaceMap[ cell.getIndex() ] = true; + interfaceMap[ e ] = true; + } + } + } + } } template< typename Real, @@ -69,8 +96,31 @@ template< typename Real, void tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >:: updateCell( MeshFunctionType& u, - const MeshEntity& cell ) + const MeshEntity& cell, + const RealType v ) { + const auto& neighborEntities = cell.template getNeighborEntities< 1 >(); + const MeshType& mesh = cell.getMesh(); + const RealType& h = mesh.getSpaceSteps().x(); + const RealType value = u( cell ); + RealType a, tmp = TypeInfo< RealType >::getMaxValue(); + + if( cell.getCoordinates().x() == 0 ) + a = u[ neighborEntities.template getEntityIndex< 1 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + a = u[ neighborEntities.template getEntityIndex< -1 >() ]; + else + { + a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1 >() ], + u[ neighborEntities.template getEntityIndex< 1 >() ] ); + } + + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() ) + return; + + tmp = a + TNL::sign( value ) * h/v; + + u[ cell.getIndex() ] = argAbsMin( value, tmp ); } template< typename Real, @@ -103,7 +153,20 @@ initInterface( const MeshFunctionPointer& _input, } if( std::is_same< Device, Devices::Host >::value ) { - const MeshFunctionType& input = _input.getData(); + MeshFunctionType input = _input.getData(); + + double A[320][320]; + std::ifstream fileInit("/home/maty/Downloads/initData.txt"); + + for (int i = 0; i < 320; i++) + for (int j = 0; j < 320; j++) + fileInit >> A[i][j]; + fileInit.close(); + for (int i = 0; i < 320; i++) + for (int j = 0; j < 320; j++) + input[i*320 + j] = A[i][j]; + + MeshFunctionType& output = _output.modifyData(); InterfaceMapType& interfaceMap = _interfaceMap.modifyData(); const MeshType& mesh = input.getMesh(); @@ -186,7 +249,7 @@ initInterface( const MeshFunctionPointer& _input, pom = pom - TNL::sign( c )*hx; //output[ e ] = (hx * c)/( c - input[ e ]) - hx; if( TNL::abs( output[ e ] ) > TNL::abs( pom ) ) - output[ e ] = pom; + output[ e ] = pom; /*}else { pom = - (hx * c)/( c - input[ e ]); @@ -632,64 +695,60 @@ __cuda_callable__ void sortMinims( T1 pom[] ) } } -template< typename Real, - typename Device, - typename Index > -__cuda_callable__ void -tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >:: -setsArray( MeshFunctionType& aux, Real sArray[18][18], int dimX, int dimY, int blockIdx, int blockIdy ) -{ - int numOfBlockx = dimX/16 + ((dimX%16 != 0) ? 1:0); - int numOfBlocky = dimY/16 + ((dimY%16 != 0) ? 1:0); - int xkolik = 18; - int ykolik = 18; - int xOd = 0; - int yOd = 0; - - if( blockIdx == 0 ) - xOd = 1; - if( blockIdy == 0 ) - yOd = 1; - - if( numOfBlockx - 1 == blockIdx ) - xkolik = dimX - (numOfBlockx-1)*16+1; - if( numOfBlocky -1 == blockIdy ) - ykolik = dimY - (numOfBlocky-1)*16+1; + +#ifdef HAVE_CUDA +template < typename Real, typename Device, typename Index > +__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& input, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& output, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index >, 1, bool >& interfaceMap ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + const Meshes::Grid< 1, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >(); - if( dimX > (blockIdx+1) * 16 ) - { - for( int i = yOd; i < ykolik; i++ ) - { - sArray[i][17] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + i*dimX + 17 ]; - } - } - if( blockIdx != 0 ) - { - for( int i = yOd; i < ykolik; i++ ) - { - sArray[i][0] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + i*dimX + 0]; - } - } - if( dimY > (blockIdy+1) * 16 ) + if( i < mesh.getDimensions().x() ) { - for( int i = xOd; i < xkolik; i++ ) + typedef typename Meshes::Grid< 1, Real, Device, Index >::Cell Cell; + Cell cell( mesh ); + cell.getCoordinates().x() = i; + cell.refresh(); + const Index cind = cell.getIndex(); + + + output[ cind ] = + input( cell ) >= 0 ? TypeInfo< Real >::getMaxValue() : + - TypeInfo< Real >::getMaxValue(); + interfaceMap[ cind ] = false; + + const Real& h = mesh.getSpaceSteps().x(); + cell.refresh(); + const Real& c = input( cell ); + if( ! cell.isBoundaryEntity() ) { - sArray[17][i] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + 17*dimX + i ]; + auto neighbors = cell.getNeighborEntities(); + Real pom = 0; + const Index e = neighbors.template getEntityIndex< 1 >(); + const Index w = neighbors.template getEntityIndex< -1 >(); + if( c * input[ e ] <= 0 ) + { + pom = TNL::sign( c )*( h * c )/( c - input[ e ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } + if( c * input[ w ] <= 0 ) + { + pom = TNL::sign( c )*( h * c )/( c - input[ w ]); + if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) ) + output[ cind ] = pom; + + interfaceMap[ cind ] = true; + } } } - if( blockIdy != 0 ) - { - for( int i = xOd; i < xkolik; i++ ) - { - sArray[0][i] = aux[ blockIdy*16*dimX - dimX + blockIdx*16 - 1 + 0*dimX + i ]; - } - } + } - - - -#ifdef HAVE_CUDA template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, @@ -886,7 +945,7 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con { sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); tmp = value - sArray[ thrj ][ thri ]; - if ( fabs( tmp ) > 0.001 ) + if ( fabs( tmp ) > 0.01*hx ) return true; else return false; @@ -898,7 +957,7 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); sArray[ thrj ][ thri ] = argAbsMin( value, tmp ); tmp = value - sArray[ thrj ][ thri ]; - if ( fabs( tmp ) > 0.01 ) + if ( fabs( tmp ) > 0.01*hx ) return true; else return false; @@ -906,4 +965,33 @@ updateCell( volatile Real sArray[18][18], int thri, int thrj, const Real hx, con return false; } + +template< typename Real, + typename Device, + typename Index > +__cuda_callable__ +bool +tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >:: +updateCell( volatile Real sArray[18], int thri, const Real h, const Real v ) +{ + const RealType value = sArray[ thri ]; + RealType a, tmp = TypeInfo< RealType >::getMaxValue(); + + a = TNL::argAbsMin( sArray[ thri+1 ], + sArray[ thri-1 ] ); + + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() ) + return false; + + tmp = a + TNL::sign( value ) * h/v; + + + sArray[ thri ] = argAbsMin( value, tmp ); + + tmp = value - sArray[ thri ]; + if ( fabs( tmp ) > 0.01*h ) + return true; + else + return false; +} #endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h index 57ac7d689..d1eb8fe2e 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h @@ -125,7 +125,7 @@ bool tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: solve( const MeshPointer& mesh, DofVectorPointer& dofs ) -{ +{ FastSweepingMethod< MeshType, AnisotropyType > fsm; fsm.solve( mesh, anisotropy, initialData ); return true; diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h index 105f1ceda..87974c684 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h @@ -57,14 +57,191 @@ FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >:: solve( const MeshPointer& mesh, const AnisotropyPointer& anisotropy, MeshFunctionPointer& u ) -{ - MeshFunctionPointer aux; - InterfaceMapPointer interfaceMap; - aux->setMesh( mesh ); - interfaceMap->setMesh( mesh ); +{ + MeshFunctionPointer auxPtr; + InterfaceMapPointer interfaceMapPtr; + auxPtr->setMesh( mesh ); + interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; - BaseType::initInterface( u, aux, interfaceMap ); - aux->save( "aux-ini.tnl" ); + BaseType::initInterface( u, auxPtr, interfaceMapPtr ); + + auxPtr->save( "aux-ini.tnl" ); + + typename MeshType::Cell cell( *mesh ); + + IndexType iteration( 0 ); + InterfaceMapType interfaceMap = *interfaceMapPtr; + MeshFunctionType aux = *auxPtr; + while( iteration < this->maxIterations ) + { + if( std::is_same< DeviceType, Devices::Host >::value ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh->getDimensions().x(); + cell.getCoordinates().x()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + + + for( cell.getCoordinates().x() = mesh->getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + if( std::is_same< DeviceType, Devices::Cuda >::value ) + { + // TODO: CUDA code +#ifdef HAVE_CUDA + const int cudaBlockSize( 16 ); + int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().x(), cudaBlockSize ); + dim3 blockSize( cudaBlockSize ); + dim3 gridSize( numBlocksX ); + + tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > ptr; + + + + bool* BlockIter = (bool*)malloc( ( numBlocksX ) * sizeof( bool ) ); + + bool *BlockIterDevice; + cudaMalloc(&BlockIterDevice, ( numBlocksX ) * sizeof( bool ) ); + + while( BlockIter[ 0 ] ) + { + for( int i = 0; i < numBlocksX; i++ ) + BlockIter[ i ] = false; + cudaMemcpy(BlockIterDevice, BlockIter, ( numBlocksX ) * sizeof( bool ), cudaMemcpyHostToDevice); + + CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, + interfaceMapPtr.template getData< Device >(), + auxPtr.template modifyData< Device>(), + BlockIterDevice ); + cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX ) * sizeof( bool ), cudaMemcpyDeviceToHost); + + for( int i = 1; i < numBlocksX; i++ ) + BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ]; + + } + delete[] BlockIter; + cudaFree( BlockIterDevice ); + cudaDeviceSynchronize(); + + TNL_CHECK_CUDA_DEVICE; + + aux = *auxPtr; + interfaceMap = *interfaceMapPtr; +#endif + } + iteration++; + } + + aux.save("aux-final.tnl"); +} + +#ifdef HAVE_CUDA +template < typename Real, typename Device, typename Index > +__global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > ptr, + const Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index >, 1, bool >& interfaceMap, + Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& aux, + bool *BlockIterDevice ) +{ + int thri = threadIdx.x; + int blIdx = blockIdx.x; + int i = thri + blockDim.x*blIdx; + + __shared__ volatile bool changed[16]; + changed[ thri ] = false; + + if( thri == 0 ) + changed[ 0 ] = true; + + const Meshes::Grid< 1, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); + __shared__ Real h; + if( thri == 1 ) + { + h = mesh.getSpaceSteps().x(); + } + + __shared__ volatile Real sArray[ 18 ]; + sArray[thri] = TypeInfo< Real >::getMaxValue(); + + //filling sArray edges + int dimX = mesh.getDimensions().x(); + __shared__ volatile int numOfBlockx; + __shared__ int xkolik; + if( thri == 0 ) + { + xkolik = blockDim.x + 1; + numOfBlockx = dimX/blockDim.x + ((dimX%blockDim.x != 0) ? 1:0); + + if( numOfBlockx - 1 == blIdx ) + xkolik = dimX - (blIdx)*blockDim.x+1; + } + __syncthreads(); + + if( thri == 0 ) + { + if( dimX > (blIdx+1) * blockDim.x ) + sArray[xkolik] = aux[ blIdx*blockDim.x - 1 + xkolik ]; + else + sArray[xkolik] = TypeInfo< Real >::getMaxValue(); + } + + if( thri == 1 ) + { + if( blIdx != 0 ) + sArray[0] = aux[ blIdx*blockDim.x - 1 ]; + else + sArray[0] = TypeInfo< Real >::getMaxValue(); + } + + + if( i < mesh.getDimensions().x() ) + { + sArray[thri+1] = aux[ i ]; + } + __syncthreads(); + while( changed[ 0 ] ) + { + __syncthreads(); + + changed[ thri ] = false; + + //calculation of update cell + if( i < mesh.getDimensions().x() ) + { + if( ! interfaceMap[ i ] ) + { + changed[ thri ] = ptr.updateCell( sArray, thri+1, h ); + } + } + __syncthreads(); + + + + //pyramid reduction + if( thri < 8 ) changed[ thri ] = changed[ thri ] || changed[ thri + 8 ]; + if( thri < 4 ) changed[ thri ] = changed[ thri ] || changed[ thri + 4 ]; + if( thri < 2 ) changed[ thri ] = changed[ thri ] || changed[ thri + 2 ]; + if( thri < 1 ) changed[ thri ] = changed[ thri ] || changed[ thri + 1 ]; + __syncthreads(); + + if( changed[ 0 ] && thri == 0 ) + BlockIterDevice[ blIdx ] = true; + __syncthreads(); + } + + if( i < mesh.getDimensions().x() && (!interfaceMap[ i ]) ) + aux[ i ] = sArray[ thri + 1 ]; } +#endif + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index e72710408..e5a9c39f3 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -18,13 +18,16 @@ #include +#include +#include + template< typename Real, typename Device, typename Index, typename Anisotropy > FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >:: FastSweepingMethod() -: maxIterations( 1 ) +: maxIterations( 2 ) { } @@ -61,15 +64,31 @@ solve( const MeshPointer& mesh, const AnisotropyPointer& anisotropy, MeshFunctionPointer& u ) { + MeshFunctionType v; + v.setMesh(mesh); + double A[320][320]; + for (int i = 0; i < 320; i++) + for (int j = 0; j < 320; j++) + A[i][j] = 0; + + std::ifstream file("/home/maty/Downloads/mapa2.txt"); + + for (int i = 0; i < 320; i++) + for (int j = 0; j < 320; j++) + file >> A[i][j]; + file.close(); + for (int i = 0; i < 320; i++) + for (int j = 0; j < 320; j++) + v[i*320 + j] = A[i][j]; + v.save("mapa.tnl"); + + MeshFunctionPointer auxPtr; InterfaceMapPointer interfaceMapPtr; auxPtr->setMesh( mesh ); interfaceMapPtr->setMesh( mesh ); std::cout << "Initiating the interface cells ..." << std::endl; BaseType::initInterface( u, auxPtr, interfaceMapPtr ); -#ifdef HAVE_CUDA - cudaDeviceSynchronize(); -#endif auxPtr->save( "aux-ini.tnl" ); @@ -92,7 +111,7 @@ solve( const MeshPointer& mesh, { cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + this->updateCell( aux, cell, v( cell ) ); } } @@ -109,7 +128,7 @@ solve( const MeshPointer& mesh, //std::cerr << "2 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + this->updateCell( aux, cell, v( cell ) ); } } @@ -126,7 +145,7 @@ solve( const MeshPointer& mesh, //std::cerr << "3 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + this->updateCell( aux, cell, v( cell ) ); } } @@ -143,7 +162,7 @@ solve( const MeshPointer& mesh, //std::cerr << "4 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell ); + this->updateCell( aux, cell, v( cell ) ); } } @@ -222,7 +241,6 @@ solve( const MeshPointer& mesh, int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().y(), cudaBlockSize ); dim3 blockSize( cudaBlockSize, cudaBlockSize ); dim3 gridSize( numBlocksX, numBlocksY ); - Devices::Cuda::synchronizeDevice(); tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; @@ -243,20 +261,8 @@ solve( const MeshPointer& mesh, interfaceMapPtr.template getData< Device >(), auxPtr.template modifyData< Device>(), BlockIterDevice ); - cudaDeviceSynchronize(); - TNL_CHECK_CUDA_DEVICE; cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyDeviceToHost); - - /*for( int j = numBlocksY-1; j > -1; j-- ) - { - for( int i = 0; i < numBlocksX; i++ ) - { - std::cout << BlockIter[ j * numBlocksY + i ] << "\t"; - } - std::cout << std::endl; - } - std::cout << std::endl;*/ - + for( int i = 1; i < numBlocksX * numBlocksY; i++ ) BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ]; @@ -294,12 +300,11 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( thrj == 0 && thri == 0 ) changed[ 0 ] = true; - __syncthreads(); const Meshes::Grid< 2, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); __shared__ Real hx; __shared__ Real hy; - if( thrj == 0 && thri == 0 ) + if( thrj == 1 && thri == 1 ) { hx = mesh.getSpaceSteps().x(); hy = mesh.getSpaceSteps().y(); @@ -345,20 +350,20 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< sArray[thrj+1][0] = TypeInfo< Real >::getMaxValue(); } - if( thrj == 0 ) + if( thri == 2 ) { if( dimY > (blIdy+1) * blockDim.y && thri+1 < xkolik ) - sArray[ykolik][thri+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + ykolik*dimX + thri+1 ]; + sArray[ykolik][thrj+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + ykolik*dimX + thrj+1 ]; else - sArray[ykolik][thri+1] = TypeInfo< Real >::getMaxValue(); + sArray[ykolik][thrj+1] = TypeInfo< Real >::getMaxValue(); } - if( thrj == 1 ) + if( thri == 3 ) { if( blIdy != 0 && thri+1 < xkolik ) - sArray[0][thri+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + thri+1 ]; + sArray[0][thrj+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + thrj+1 ]; else - sArray[0][thri+1] = TypeInfo< Real >::getMaxValue(); + sArray[0][thrj+1] = TypeInfo< Real >::getMaxValue(); } @@ -422,7 +427,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 1 ]; } if( changed[ 0 ] && thri == 0 && thrj == 0 ) - BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = changed[ 0 ]; + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = true; __syncthreads(); } -- GitLab From 2d97cf97b0a50451791a0f48a47f9962fdb1dce6 Mon Sep 17 00:00:00 2001 From: fencl Date: Wed, 4 Jul 2018 09:35:29 +0200 Subject: [PATCH 22/28] Forgot to comment wildfire computation --- .../tnlDirectEikonalMethodsBase_impl.h | 4 ++-- .../hamilton-jacobi/tnlFastSweepingMethod2D_impl.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index c742a11b5..cd4eb9e24 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -155,7 +155,7 @@ initInterface( const MeshFunctionPointer& _input, { MeshFunctionType input = _input.getData(); - double A[320][320]; + /*double A[320][320]; std::ifstream fileInit("/home/maty/Downloads/initData.txt"); for (int i = 0; i < 320; i++) @@ -164,7 +164,7 @@ initInterface( const MeshFunctionPointer& _input, fileInit.close(); for (int i = 0; i < 320; i++) for (int j = 0; j < 320; j++) - input[i*320 + j] = A[i][j]; + input[i*320 + j] = A[i][j];*/ MeshFunctionType& output = _output.modifyData(); diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index e5a9c39f3..83333b190 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -64,7 +64,7 @@ solve( const MeshPointer& mesh, const AnisotropyPointer& anisotropy, MeshFunctionPointer& u ) { - MeshFunctionType v; + /*MeshFunctionType v; v.setMesh(mesh); double A[320][320]; for (int i = 0; i < 320; i++) @@ -80,7 +80,7 @@ solve( const MeshPointer& mesh, for (int i = 0; i < 320; i++) for (int j = 0; j < 320; j++) v[i*320 + j] = A[i][j]; - v.save("mapa.tnl"); + v.save("mapa.tnl");*/ MeshFunctionPointer auxPtr; @@ -111,7 +111,7 @@ solve( const MeshPointer& mesh, { cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell, v( cell ) ); + this->updateCell( aux, cell ); } } @@ -128,7 +128,7 @@ solve( const MeshPointer& mesh, //std::cerr << "2 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell, v( cell ) ); + this->updateCell( aux, cell ); } } @@ -145,7 +145,7 @@ solve( const MeshPointer& mesh, //std::cerr << "3 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell, v( cell ) ); + this->updateCell( aux, cell ); } } @@ -162,7 +162,7 @@ solve( const MeshPointer& mesh, //std::cerr << "4 -> "; cell.refresh(); if( ! interfaceMap( cell ) ) - this->updateCell( aux, cell, v( cell ) ); + this->updateCell( aux, cell ); } } -- GitLab From b4d605d125cdae2e0065f747f0e9c2334fc41a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 4 Jul 2018 21:26:59 +0200 Subject: [PATCH 23/28] Added compilation of tnl-direct-eikonal-solver with float. --- .../Solvers/hamilton-jacobi/MainBuildConfig.h | 58 +++++++++---------- .../tnl-direct-eikonal-solver.h | 4 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h index 1b904c0c8..41cd2e5d0 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h @@ -1,64 +1,62 @@ /*************************************************************************** - MainBuildConfig.h - description + HamiltonJacobiBuildConfigTag.h - description ------------------- begin : Jul 7, 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. * - * * - ***************************************************************************/ +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include -#ifndef MAINBUILDCONFIG_H_ -#define MAINBUILDCONFIG_H_ +//namespace TNL { +//namespace Solvers { -#include +using namespace TNL::Solvers; -class MainBuildConfig +class HamiltonJacobiBuildConfig { public: - static void print() { cerr << "MainBuildConfig" << endl; } + static void print() { std::cerr << "HamiltonJacobiBuildConfig" << std::endl; } }; /**** * Turn off support for float and long double. */ -template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; -template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; +//template<> struct ConfigTagReal< HamiltonJacobiBuildConfig, float > { enum { enabled = false }; }; +template<> struct ConfigTagReal< HamiltonJacobiBuildConfig, long double > { enum { enabled = false }; }; /**** * Turn off support for short int and long int indexing. */ -template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; -template<> struct tnlConfigTagIndex< MainBuildConfig, long int >{ enum { enabled = false }; }; +template<> struct ConfigTagIndex< HamiltonJacobiBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct ConfigTagIndex< HamiltonJacobiBuildConfig, long int >{ enum { enabled = false }; }; /**** - * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types. + * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. */ -template< int Dimensions, typename Real, typename Device, typename Index > - struct tnlConfigTagMesh< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > - { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && - tnlConfigTagReal< MainBuildConfig, Real >::enabled && - tnlConfigTagDevice< MainBuildConfig, Device >::enabled && - tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; +/*template< int Dimension, typename Real, typename Device, typename Index > + struct ConfigTagMesh< HamiltonJacobiBuildConfig, Meshes::Grid< Dimension, Real, Device, Index > > + { enum { enabled = ConfigTagDimension< HamiltonJacobiBuildConfig, Dimension >::enabled && + ConfigTagReal< HamiltonJacobiBuildConfig, Real >::enabled && + ConfigTagDevice< HamiltonJacobiBuildConfig, Device >::enabled && + ConfigTagIndex< HamiltonJacobiBuildConfig, Index >::enabled }; };*/ /**** * Please, chose your preferred time discretisation here. */ -template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; -template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; -template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; +template<> struct ConfigTagTimeDiscretisation< HamiltonJacobiBuildConfig, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct ConfigTagTimeDiscretisation< HamiltonJacobiBuildConfig, SemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct ConfigTagTimeDiscretisation< HamiltonJacobiBuildConfig, ImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; /**** * Only the Runge-Kutta-Merson solver is enabled by default. */ -template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; +//template<> struct ConfigTagExplicitSolver< HamiltonJacobiBuildConfig, ExplicitEulerSolverTag >{ enum { enabled = false }; }; -#endif /* MAINBUILDCONFIG_H_ */ +//} // namespace Solvers +//} // namespace TNL diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h index 225ce04b9..29c89cae8 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h @@ -20,11 +20,13 @@ #include #include #include "tnlDirectEikonalProblem.h" +#include "MainBuildConfig.h" using namespace TNL; //typedef tnlDefaultBuildMeshConfig BuildConfig; -typedef Solvers::FastBuildConfig BuildConfig; +//typedef Solvers::FastBuildConfig BuildConfig; +typedef HamiltonJacobiBuildConfig BuildConfig; template< typename MeshConfig > class tnlDirectEikonalSolverConfig -- GitLab From b4611f421a5aa2001a06f2fa10bbad0dd680bad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 4 Jul 2018 23:26:23 +0200 Subject: [PATCH 24/28] Added grids with float to tnl-diff. --- src/Tools/tnl-diff.cpp | 52 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index 013f7bf21..48e25156f 100644 --- a/src/Tools/tnl-diff.cpp +++ b/src/Tools/tnl-diff.cpp @@ -68,23 +68,55 @@ int main( int argc, char* argv[] ) int dimensions = atoi( parsedMeshType[ 1 ].getString() ); if( dimensions == 1 ) { - typedef Meshes::Grid< 1, double, Devices::Host, int > MeshType; - if( ! processFiles< MeshType >( parameters ) ) - return EXIT_FAILURE; + if( parsedMeshType[ 1 ] == "float" ) + { + typedef Meshes::Grid< 1, float, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } + if( parsedMeshType[ 1 ] == "double" ) + { + typedef Meshes::Grid< 1, double, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } } if( dimensions == 2 ) { - typedef Meshes::Grid< 2, double, Devices::Host, int > MeshType; - if( ! processFiles< MeshType >( parameters ) ) - return EXIT_FAILURE; + if( parsedMeshType[ 1 ] == "float" ) + { + typedef Meshes::Grid< 2, float, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } + if( parsedMeshType[ 1 ] == "double" ) + { + typedef Meshes::Grid< 2, double, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } } if( dimensions == 3 ) { - typedef Meshes::Grid< 3, double, Devices::Host, int > MeshType; - if( ! processFiles< MeshType >( parameters ) ) - return EXIT_FAILURE; + if( parsedMeshType[ 1 ] == "float" ) + { + typedef Meshes::Grid< 3, float, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } + if( parsedMeshType[ 1 ] == "double" ) + { + typedef Meshes::Grid< 3, double, Devices::Host, int > MeshType; + if( ! processFiles< MeshType >( parameters ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } } - return EXIT_SUCCESS; } return EXIT_FAILURE; } -- GitLab From ccb30dce5f4f52b058e95afbbaefea06707f4e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 5 Jul 2018 09:20:21 +0200 Subject: [PATCH 25/28] Fixed tnl-diff. --- src/Tools/tnl-diff.cpp | 12 ++++++------ src/Tools/tnl-diff.h | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index 48e25156f..df87a57b7 100644 --- a/src/Tools/tnl-diff.cpp +++ b/src/Tools/tnl-diff.cpp @@ -68,14 +68,14 @@ int main( int argc, char* argv[] ) int dimensions = atoi( parsedMeshType[ 1 ].getString() ); if( dimensions == 1 ) { - if( parsedMeshType[ 1 ] == "float" ) + if( parsedMeshType[ 2 ] == "float" ) { typedef Meshes::Grid< 1, float, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) return EXIT_FAILURE; return EXIT_SUCCESS; } - if( parsedMeshType[ 1 ] == "double" ) + if( parsedMeshType[ 2 ] == "double" ) { typedef Meshes::Grid< 1, double, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) @@ -85,14 +85,14 @@ int main( int argc, char* argv[] ) } if( dimensions == 2 ) { - if( parsedMeshType[ 1 ] == "float" ) + if( parsedMeshType[ 2 ] == "float" ) { typedef Meshes::Grid< 2, float, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) return EXIT_FAILURE; return EXIT_SUCCESS; } - if( parsedMeshType[ 1 ] == "double" ) + if( parsedMeshType[ 2 ] == "double" ) { typedef Meshes::Grid< 2, double, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) @@ -102,14 +102,14 @@ int main( int argc, char* argv[] ) } if( dimensions == 3 ) { - if( parsedMeshType[ 1 ] == "float" ) + if( parsedMeshType[ 2 ] == "float" ) { typedef Meshes::Grid< 3, float, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) return EXIT_FAILURE; return EXIT_SUCCESS; } - if( parsedMeshType[ 1 ] == "double" ) + if( parsedMeshType[ 2 ] == "double" ) { typedef Meshes::Grid< 3, double, Devices::Host, int > MeshType; if( ! processFiles< MeshType >( parameters ) ) diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 66f707593..cb7fcfff5 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -300,6 +300,7 @@ bool computeDifference( const MeshPointer& meshPointer, const String& objectType if( objectType == "Containers::Vector" || objectType == "tnlVector" || objectType == "tnlSharedVector" ) // TODO: remove deprecated type name return computeDifferenceOfVectors< MeshPointer, Element, Real, Index >( meshPointer, parameters ); + std::cerr << "Unknown object type " << objectType << "." << std::endl; return false; } -- GitLab From 68f3276ebc650ddf8f6b1259583bfd0a8e3a2caf Mon Sep 17 00:00:00 2001 From: fencl Date: Thu, 5 Jul 2018 19:27:34 +0200 Subject: [PATCH 26/28] Parallel reduction grid level. --- .../tnlDirectEikonalMethodsBase.h | 3 +- .../tnlFastSweepingMethod2D_impl.h | 86 +++++++++++++++---- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index fe7d4b9ba..74393f1fd 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -126,7 +126,8 @@ template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - bool *BlockIterDevice ); + int *BlockIterDevice ); +__global__ void CudaParallelReduc( int *BlockIterDevice, int *dBlock, int nBlocks ); template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index 83333b190..efdb13da8 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -27,7 +27,7 @@ template< typename Real, typename Anisotropy > FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >:: FastSweepingMethod() -: maxIterations( 2 ) +: maxIterations( 1 ) { } @@ -246,29 +246,37 @@ solve( const MeshPointer& mesh, - bool* BlockIter = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + //int BlockIter = 1;// = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + + int *BlockIterDevice; + int BlockIterD = 1; - bool *BlockIterDevice; - cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ) ); + cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( int ) ); + int nBlocks = ( numBlocksX * numBlocksY )/512 + ((( numBlocksX * numBlocksY )%512 != 0) ? 1:0); + int *dBlock; + cudaMalloc(&dBlock, nBlocks * sizeof( int ) ); - while( BlockIter[ 0 ] ) + while( BlockIterD ) { - for( int i = 0; i < numBlocksX * numBlocksY; i++ ) - BlockIter[ i ] = false; - cudaMemcpy(BlockIterDevice, BlockIter, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyHostToDevice); + /*for( int i = 0; i < numBlocksX * numBlocksY; i++ ) + BlockIter[ i ] = false;*/ CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, interfaceMapPtr.template getData< Device >(), auxPtr.template modifyData< Device>(), BlockIterDevice ); - cudaMemcpy(BlockIter, BlockIterDevice, ( numBlocksX * numBlocksY ) * sizeof( bool ), cudaMemcpyDeviceToHost); + + CudaParallelReduc<<< nBlocks , 512 >>>( BlockIterDevice, dBlock, ( numBlocksX * numBlocksY ) ); + CudaParallelReduc<<< 1, nBlocks >>>( dBlock, dBlock, nBlocks ); + + cudaMemcpy(&BlockIterD, &dBlock[0], sizeof( int ), cudaMemcpyDeviceToHost); - for( int i = 1; i < numBlocksX * numBlocksY; i++ ) - BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ]; + /*for( int i = 1; i < numBlocksX * numBlocksY; i++ ) + BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ];*/ } - delete[] BlockIter; cudaFree( BlockIterDevice ); + cudaFree( dBlock ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; @@ -283,11 +291,58 @@ solve( const MeshPointer& mesh, } #ifdef HAVE_CUDA +__global__ void CudaParallelReduc( int *BlockIterDevice, int *dBlock, int nBlocks ) +{ + int i = threadIdx.x; + int blId = blockIdx.x; + __shared__ volatile int sArray[ 512 ]; + sArray[ i ] = false; + if(blId * 1024 + i < nBlocks ) + sArray[ i ] = BlockIterDevice[ blId * 1024 + i ]; + + if (blockDim.x * blockDim.y == 1024) { + if (i < 512) + sArray[ i ] += sArray[ i ]; + } + __syncthreads(); + if (blockDim.x * blockDim.y >= 512) { + if (i < 256) { + sArray[ i ] += sArray[ i ]; + } + } + if (blockDim.x * blockDim.y >= 256) { + if (i < 128) { + sArray[ i ] += sArray[ i + 128 ]; + } + } + __syncthreads(); + if (blockDim.x * blockDim.y >= 128) { + if (i < 64) { + sArray[ i ] += sArray[ i + 64 ]; + } + } + __syncthreads(); + if (i < 32 ) + { + if( blockDim.x * blockDim.y >= 64 ) sArray[ i ] += sArray[ i + 32 ]; + if( blockDim.x * blockDim.y >= 32 ) sArray[ i ] += sArray[ i + 16 ]; + if( blockDim.x * blockDim.y >= 16 ) sArray[ i ] += sArray[ i + 8 ]; + if( blockDim.x * blockDim.y >= 8 ) sArray[ i ] += sArray[ i + 4 ]; + if( blockDim.x * blockDim.y >= 4 ) sArray[ i ] += sArray[ i + 2 ]; + if( blockDim.x * blockDim.y >= 2 ) sArray[ i ] += sArray[ i + 1 ]; + } + + if( i == 0 ) + dBlock[ blId ] = sArray[ 0 ]; +} + + + template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - bool *BlockIterDevice ) + int *BlockIterDevice ) { int thri = threadIdx.x; int thrj = threadIdx.y; int blIdx = blockIdx.x; int blIdy = blockIdx.y; @@ -331,6 +386,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( numOfBlocky -1 == blIdy ) ykolik = dimY - (blIdy)*blockDim.y+1; + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = 0; } __syncthreads(); @@ -360,7 +416,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( thri == 3 ) { - if( blIdy != 0 && thri+1 < xkolik ) + if( blIdy != 0 && thrj+1 < xkolik ) sArray[0][thrj+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + thrj+1 ]; else sArray[0][thrj+1] = TypeInfo< Real >::getMaxValue(); @@ -427,7 +483,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 1 ]; } if( changed[ 0 ] && thri == 0 && thrj == 0 ) - BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = true; + BlockIterDevice[ blIdy * numOfBlockx + blIdx ] = 1; __syncthreads(); } -- GitLab From 223c69a75ed82b7a8adabb8713f97ee716fcd3ae Mon Sep 17 00:00:00 2001 From: fencl Date: Thu, 23 Aug 2018 11:10:16 +0200 Subject: [PATCH 27/28] Parallel version for CUDA of FSM is implemented. --- .../tnlDirectEikonalMethodsBase.h | 14 +- .../tnlDirectEikonalMethodsBase_impl.h | 74 ++++++ .../tnlFastSweepingMethod2D_impl.h | 73 ++++-- .../tnlFastSweepingMethod3D_impl.h | 237 ++++++++++++++++-- 4 files changed, 359 insertions(+), 39 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h index 74393f1fd..a406a5b17 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -101,6 +101,10 @@ class tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > __cuda_callable__ void updateCell( MeshFunctionType& u, const MeshEntity& cell, const RealType velocity = 1.0); + + __cuda_callable__ bool updateCell( volatile Real sArray[10][10][10], + int thri, int thrj, int thrk, const Real hx, const Real hy, const Real hz, + const Real velocity = 1.0 ); }; template < typename T1, typename T2 > @@ -125,10 +129,13 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, - int *BlockIterDevice ); + Real *aux, + int *BlockIterDevice); __global__ void CudaParallelReduc( int *BlockIterDevice, int *dBlock, int nBlocks ); +template < typename Real, typename Device, typename Index > +__global__ void aux1( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, Real *dAux, int a ); + template < typename Real, typename Device, typename Index > __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& input, Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& output, @@ -142,7 +149,8 @@ __global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3 template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux ); + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux, + int *BlockIterDevice ); #endif #include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index cd4eb9e24..31bc95df5 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -994,4 +994,78 @@ updateCell( volatile Real sArray[18], int thri, const Real h, const Real v ) else return false; } + +template< typename Real, + typename Device, + typename Index > +__cuda_callable__ +bool +tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >:: +updateCell( volatile Real sArray[10][10][10], int thri, int thrj, int thrk, + const Real hx, const Real hy, const Real hz, const Real v ) +{ + const RealType value = sArray[thrk][thrj][thri]; + //std::cout << value << std::endl; + RealType a, b, c, tmp = TypeInfo< RealType >::getMaxValue(); + + c = TNL::argAbsMin( sArray[ thrk+1 ][ thrj ][ thri ], + sArray[ thrk-1 ][ thrj ][ thri ] ); + + b = TNL::argAbsMin( sArray[ thrk ][ thrj+1 ][ thri ], + sArray[ thrk ][ thrj-1 ][ thri ] ); + + a = TNL::argAbsMin( sArray[ thrk ][ thrj ][ thri+1 ], + sArray[ thrk ][ thrj ][ thri-1 ] ); + + + if( fabs( a ) == TypeInfo< RealType >::getMaxValue() && + fabs( b ) == TypeInfo< RealType >::getMaxValue() && + fabs( c ) == TypeInfo< RealType >::getMaxValue() ) + return false; + + RealType pom[6] = { a, b, c, (RealType)hx, (RealType)hy, (RealType)hz}; + + sortMinims( pom ); + + tmp = pom[ 0 ] + TNL::sign( value ) * pom[ 3 ]; + if( fabs( tmp ) < fabs( pom[ 1 ] ) ) + { + sArray[ thrk ][ thrj ][ thri ] = argAbsMin( value, tmp ); + tmp = value - sArray[ thrk ][ thrj ][ thri ]; + if ( fabs( tmp ) > 0.01*hx ) + return true; + else + return false; + } + else + { + tmp = ( pom[ 3 ] * pom[ 3 ] * pom[ 1 ] + pom[ 4 ] * pom[ 4 ] * pom[ 0 ] + + TNL::sign( value ) * pom[ 3 ] * pom[ 4 ] * TNL::sqrt( ( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] )/( v * v ) - + ( pom[ 1 ] - pom[ 0 ] ) * ( pom[ 1 ] - pom[ 0 ] ) ) )/( pom[ 3 ] * pom[ 3 ] + pom[ 4 ] * pom[ 4 ] ); + if( fabs( tmp ) < fabs( pom[ 2 ]) ) + { + sArray[ thrk ][ thrj ][ thri ] = argAbsMin( value, tmp ); + tmp = value - sArray[ thrk ][ thrj ][ thri ]; + if ( fabs( tmp ) > 0.01*hx ) + return true; + else + return false; + } + else + { + tmp = ( hy * hy * hz * hz * a + hx * hx * hz * hz * b + hx * hx * hy * hy * c + + TNL::sign( value ) * hx * hy * hz * TNL::sqrt( ( hx * hx * hz * hz + hy * hy * hz * hz + hx * hx * hy * hy)/( v * v ) - + hz * hz * ( a - b ) * ( a - b ) - hy * hy * ( a - c ) * ( a - c ) - + hx * hx * ( b - c ) * ( b - c ) ) )/( hx * hx * hy * hy + hy * hy * hz * hz + hz * hz * hx *hx ); + sArray[ thrk ][ thrj ][ thri ] = argAbsMin( value, tmp ); + tmp = value - sArray[ thrk ][ thrj ][ thri ]; + if ( fabs( tmp ) > 0.01*hx ) + return true; + else + return false; + } + } + + return false; +} #endif diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index efdb13da8..7d5f8cbaa 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -27,7 +27,7 @@ template< typename Real, typename Anisotropy > FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >:: FastSweepingMethod() -: maxIterations( 1 ) +: maxIterations( 100 ) { } @@ -236,6 +236,13 @@ solve( const MeshPointer& mesh, { // TODO: CUDA code #ifdef HAVE_CUDA + + Real *dAux; + cudaMalloc(&dAux, ( mesh->getDimensions().x() * mesh->getDimensions().y() ) * sizeof( Real ) ); + + + + const int cudaBlockSize( 16 ); int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().x(), cudaBlockSize ); int numBlocksY = Devices::Cuda::getNumberOfBlocks( mesh->getDimensions().y(), cudaBlockSize ); @@ -244,7 +251,7 @@ solve( const MeshPointer& mesh, tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr; - + aux1<<< gridSize, blockSize >>>( auxPtr.template modifyData< Device>(), dAux,1 ); //int BlockIter = 1;// = (bool*)malloc( ( numBlocksX * numBlocksY ) * sizeof( bool ) ); @@ -263,7 +270,7 @@ solve( const MeshPointer& mesh, CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, interfaceMapPtr.template getData< Device >(), - auxPtr.template modifyData< Device>(), + dAux, BlockIterDevice ); CudaParallelReduc<<< nBlocks , 512 >>>( BlockIterDevice, dBlock, ( numBlocksX * numBlocksY ) ); @@ -275,14 +282,16 @@ solve( const MeshPointer& mesh, BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ];*/ } + aux1<<>>( auxPtr.template modifyData< Device>(), dAux, 0 ); + cudaFree( dAux ); cudaFree( BlockIterDevice ); cudaFree( dBlock ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; - aux = *auxPtr; - interfaceMap = *interfaceMapPtr; + //aux = *auxPtr; + //interfaceMap = *interfaceMapPtr; #endif } iteration++; @@ -291,6 +300,23 @@ solve( const MeshPointer& mesh, } #ifdef HAVE_CUDA +template < typename Real, typename Device, typename Index > +__global__ void aux1( Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, Real *dAux, int a ) +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + const Meshes::Grid< 2, Real, Device, Index >& mesh = aux.template getMesh< Devices::Cuda >(); + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && a == 1 ) + { + dAux[ j*mesh.getDimensions().x() + i ] = aux[ j*mesh.getDimensions().x() + i ]; + } + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && a == 0 ) + { + aux[ j*mesh.getDimensions().x() + i ] = dAux[ j*mesh.getDimensions().x() + i ]; + } + +} + __global__ void CudaParallelReduc( int *BlockIterDevice, int *dBlock, int nBlocks ) { int i = threadIdx.x; @@ -341,16 +367,17 @@ __global__ void CudaParallelReduc( int *BlockIterDevice, int *dBlock, int nBlock template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index >, 2, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 2, Real, Device, Index > >& aux, + Real *aux, int *BlockIterDevice ) { int thri = threadIdx.x; int thrj = threadIdx.y; int blIdx = blockIdx.x; int blIdy = blockIdx.y; int i = thri + blockDim.x*blIdx; int j = blockDim.y*blIdy + thrj; - int currentIndex = thrj * 16 + thri; + int currentIndex = thrj * blockDim.x + thri; - __shared__ volatile bool changed[256]; + //__shared__ volatile bool changed[ blockDim.x*blockDim.y ]; + __shared__ volatile bool changed[16*16]; changed[ currentIndex ] = false; if( thrj == 0 && thri == 0 ) @@ -365,7 +392,8 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< hy = mesh.getSpaceSteps().y(); } - __shared__ volatile Real sArray[ 18 ][ 18 ]; + //__shared__ volatile Real sArray[ blockDim.y+2 ][ blockDim.x+2 ]; + __shared__ volatile Real sArray[18][18]; sArray[thrj][thri] = TypeInfo< Real >::getMaxValue(); //filling sArray edges @@ -440,23 +468,28 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< { if( ! interfaceMap[ j * mesh.getDimensions().x() + i ] ) { - changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, hx, hy ); + changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, hx,hy); } } __syncthreads(); - /*if( thri == 0 && thrj == 0 && blIdx == 1 && blIdy == 3 ){ - for( int h = 15; h > -1; h-- ){ - for( int g = 0; g < 16; g++ ){ - printf( "%d\t", changed[h*16+g] ); - } - printf("\n"); + //pyramid reduction + if( blockDim.x*blockDim.y == 1024 ) + { + if( currentIndex < 512 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 512 ]; } - printf("\n"); } - __syncthreads();*/ - - //pyramid reduction + __syncthreads(); + if( blockDim.x*blockDim.y >= 512 ) + { + if( currentIndex < 256 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 256 ]; + } + } + __syncthreads(); if( blockDim.x*blockDim.y >= 256 ) { if( currentIndex < 128 ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index e9fa72e66..c20d9a2fa 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -255,13 +255,34 @@ solve( const MeshPointer& mesh, std::cout << "Invalid kernel call. Dimensions of grid are max: [1024,1024,64], and maximum threads per block are 1024!" << std::endl; dim3 blockSize( cudaBlockSize, cudaBlockSize, cudaBlockSize ); dim3 gridSize( numBlocksX, numBlocksY, numBlocksZ ); - Devices::Cuda::synchronizeDevice(); - + tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; - for( int k = 0; k < numBlocksX; k++) - CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, - interfaceMapPtr.template getData< Device >(), - auxPtr.template modifyData< Device>() ); + + int *BlockIterDevice; + int BlockIterD = 1; + + cudaMalloc(&BlockIterDevice, ( numBlocksX * numBlocksY * numBlocksZ ) * sizeof( int ) ); + int nBlocks = ( numBlocksX * numBlocksY * numBlocksZ )/512 + ((( numBlocksX * numBlocksY * numBlocksZ )%512 != 0) ? 1:0); + int *dBlock; + cudaMalloc(&dBlock, nBlocks * sizeof( int ) ); + + while( BlockIterD ) + { + CudaUpdateCellCaller<<< gridSize, blockSize >>>( ptr, + interfaceMapPtr.template getData< Device >(), + auxPtr.template modifyData< Device>(), + BlockIterDevice ); + CudaParallelReduc<<< nBlocks , 512 >>>( BlockIterDevice, dBlock, ( numBlocksX * numBlocksY * numBlocksZ ) ); + CudaParallelReduc<<< 1, nBlocks >>>( dBlock, dBlock, nBlocks ); + + cudaMemcpy(&BlockIterD, &dBlock[0], sizeof( int ), cudaMemcpyDeviceToHost); + + /*for( int i = 1; i < numBlocksX * numBlocksY; i++ ) + BlockIter[ 0 ] = BlockIter[ 0 ] || BlockIter[ i ];*/ + + } + cudaFree( BlockIterDevice ); + cudaFree( dBlock ); cudaDeviceSynchronize(); TNL_CHECK_CUDA_DEVICE; aux = *auxPtr; @@ -280,27 +301,211 @@ solve( const MeshPointer& mesh, template < typename Real, typename Device, typename Index > __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr, const Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index >, 3, bool >& interfaceMap, - Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux ) + Functions::MeshFunction< Meshes::Grid< 3, Real, Device, Index > >& aux, + int *BlockIterDevice ) { + int thri = threadIdx.x; int thrj = threadIdx.y; int thrk = threadIdx.z; + int blIdx = blockIdx.x; int blIdy = blockIdx.y; int blIdz = blockIdx.z; int i = threadIdx.x + blockDim.x*blockIdx.x; int j = blockDim.y*blockIdx.y + threadIdx.y; int k = blockDim.z*blockIdx.z + threadIdx.z; + int currentIndex = thrk * blockDim.x * blockDim.y + thrj * blockDim.x + thri; + + __shared__ volatile bool changed[8*8*8]; + changed[ currentIndex ] = false; + + if( thrj == 0 && thri == 0 && thrk == 0 ) + changed[ 0 ] = true; + const Meshes::Grid< 3, Real, Device, Index >& mesh = interfaceMap.template getMesh< Devices::Cuda >(); + __shared__ Real hx; + __shared__ Real hy; + __shared__ Real hz; + if( thrj == 1 && thri == 1 && thrk == 1 ) + { + hx = mesh.getSpaceSteps().x(); + hy = mesh.getSpaceSteps().y(); + hz = mesh.getSpaceSteps().z(); + } + __shared__ volatile Real sArray[10][10][10]; + sArray[thrk][thrj][thri] = TypeInfo< Real >::getMaxValue(); + if(thri == 0 ) + { + sArray[8][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[9][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][thrj+1][8] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][thrj+1][9] = TypeInfo< Real >::getMaxValue(); + sArray[thrj+1][8][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[thrj+1][9][thrk+1] = TypeInfo< Real >::getMaxValue(); + } + + //filling sArray edges + int dimX = mesh.getDimensions().x(); int dimY = mesh.getDimensions().y(); + int dimZ = mesh.getDimensions().z(); + __shared__ volatile int numOfBlockx; + __shared__ volatile int numOfBlocky; + __shared__ volatile int numOfBlockz; + __shared__ int xkolik; + __shared__ int ykolik; + __shared__ int zkolik; + if( thri == 0 && thrj == 0 && thrk == 0 ) + { + xkolik = blockDim.x + 1; + ykolik = blockDim.y + 1; + zkolik = blockDim.z + 1; + numOfBlocky = dimY/blockDim.y + ((dimY%blockDim.y != 0) ? 1:0); + numOfBlockx = dimX/blockDim.x + ((dimX%blockDim.x != 0) ? 1:0); + numOfBlockz = dimZ/blockDim.z + ((dimZ%blockDim.z != 0) ? 1:0); + + if( numOfBlockx - 1 == blIdx ) + xkolik = dimX - (blIdx)*blockDim.x+1; + + if( numOfBlocky -1 == blIdy ) + ykolik = dimY - (blIdy)*blockDim.y+1; + if( numOfBlockz-1 == blIdz ) + zkolik = dimZ - (blIdz)*blockDim.z+1; + + BlockIterDevice[ blIdz * numOfBlockx * numOfBlocky + blIdy * numOfBlockx + blIdx ] = 0; + } + __syncthreads(); + + if( thri == 0 ) + { + if( blIdx != 0 && thrj+1 < ykolik && thrk+1 < zkolik ) + sArray[thrk+1][thrj+1][0] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x + thrj * dimX -1 + thrk*dimX*dimY ]; + else + sArray[thrk+1][thrj+1][0] = TypeInfo< Real >::getMaxValue(); + } + + if( thri == 1 ) + { + if( dimX > (blIdx+1) * blockDim.x && thrj+1 < ykolik && thrk+1 < zkolik ) + sArray[thrk+1][thrj+1][9] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy *blockDim.y*dimX+ blIdx*blockDim.x + blockDim.x + thrj * dimX + thrk*dimX*dimY ]; + else + sArray[thrk+1][thrj+1][9] = TypeInfo< Real >::getMaxValue(); + } + if( thri == 2 ) + { + if( blIdy != 0 && thrj+1 < xkolik && thrk+1 < zkolik ) + sArray[thrk+1][0][thrj+1] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x - dimX + thrj + thrk*dimX*dimY ]; + else + sArray[thrk+1][0][thrj+1] = TypeInfo< Real >::getMaxValue(); + } + + if( thri == 3 ) + { + if( dimY > (blIdy+1) * blockDim.y && thrj+1 < xkolik && thrk+1 < zkolik ) + sArray[thrk+1][9][thrj+1] = aux[ blIdz*blockDim.z * dimX * dimY + (blIdy+1) * blockDim.y*dimX + blIdx*blockDim.x + thrj + thrk*dimX*dimY ]; + else + sArray[thrk+1][9][thrj+1] = TypeInfo< Real >::getMaxValue(); + } + if( thri == 4 ) + { + if( blIdz != 0 && thrj+1 < ykolik && thrk+1 < xkolik ) + sArray[0][thrj+1][thrk+1] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x - dimX * dimY + thrj * dimX + thrk ]; + else + sArray[0][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + } + + if( thri == 5 ) + { + if( dimZ > (blIdz+1) * blockDim.z && thrj+1 < ykolik && thrk+1 < xkolik ) + sArray[9][thrj+1][thrk+1] = aux[ (blIdz+1)*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x + thrj * dimX + thrk ]; + else + sArray[9][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + } if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) { - typedef typename Meshes::Grid< 3, Real, Device, Index >::Cell Cell; - Cell cell( mesh ); - cell.getCoordinates().x() = i; cell.getCoordinates().y() = j; cell.getCoordinates().z() = k; - cell.refresh(); - //tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > ptr; - for( int l = 0; l < 10; l++ ) + sArray[thrk+1][thrj+1][thri+1] = aux[ k*dimX*dimY + j*dimX + i ]; + } + __shared__ volatile int loopcounter; + loopcounter = 0; + __syncthreads(); + while( changed[ 0 ] ) + { + __syncthreads(); + + changed[ currentIndex ] = false; + + //calculation of update cell + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < dimZ ) { - if( ! interfaceMap( cell ) ) + if( ! interfaceMap[ k*dimX*dimY + j * mesh.getDimensions().x() + i ] ) { - ptr.updateCell( aux, cell ); + changed[ currentIndex ] = ptr.updateCell( sArray, thri+1, thrj+1, thrk+1, hx,hy,hz); } } + __syncthreads(); + + //pyramid reduction + if( blockDim.x*blockDim.y*blockDim.z == 1024 ) + { + if( currentIndex < 512 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 512 ]; + } + } + __syncthreads(); + if( blockDim.x*blockDim.y*blockDim.z >= 512 ) + { + if( currentIndex < 256 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 256 ]; + } + } + __syncthreads(); + if( blockDim.x*blockDim.y*blockDim.z >= 256 ) + { + if( currentIndex < 128 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 128 ]; + } + } + __syncthreads(); + if( blockDim.x*blockDim.y*blockDim.z >= 128 ) + { + if( currentIndex < 64 ) + { + changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 64 ]; + } + } + __syncthreads(); + if( currentIndex < 32 ) //POUZE IF JSOU SINCHRONNI NA JEDNOM WARPU + { + if( true ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 32 ]; + if( currentIndex < 16 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 16 ]; + if( currentIndex < 8 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 8 ]; + if( currentIndex < 4 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 4 ]; + if( currentIndex < 2 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 2 ]; + if( currentIndex < 1 ) changed[ currentIndex ] = changed[ currentIndex ] || changed[ currentIndex + 1 ]; + } + __syncthreads(); + + /*if(thri == 0 && thrj ==0 && thrk ==0 && blIdx == 0 && blIdy == 0 && blIdz == 0) + { + for(int m = 0; m < 8; m++){ + for(int n = 0; n<8; n++){ + for(int b=0; b<8; b++) + printf(" %i ", changed[m*64 + n*8 + b]); + printf("\n"); + } + printf("\n \n"); + } + }*/ + if( changed[ 0 ] && thri == 0 && thrj == 0 && thrk == 0 ) + { + //loopcounter++; + BlockIterDevice[ blIdz * numOfBlockx * numOfBlocky + blIdy * numOfBlockx + blIdx ] = 1; + } + __syncthreads(); + /*if(thri == 0 && thrj==0 && thrk==0) + printf("%i \n",loopcounter); + if(loopcounter == 500) + break;*/ } -} + + if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < dimZ && (!interfaceMap[ k*dimX*dimY+j * mesh.getDimensions().x() + i ]) ) + aux[ k*dimX*dimY + j * mesh.getDimensions().x() + i ] = sArray[thrk+1][ thrj + 1 ][ thri + 1 ]; +} #endif -- GitLab From 9609830d5d6c7859a3cd249e61c7413e53aa6287 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 4 Sep 2018 16:56:27 +0200 Subject: [PATCH 28/28] Fixes after merge. --- .../tnlDirectEikonalMethodsBase_impl.h | 12 ++++----- .../tnlFastSweepingMethod1D_impl.h | 6 ++--- .../tnlFastSweepingMethod2D_impl.h | 10 +++---- .../tnlFastSweepingMethod3D_impl.h | 26 +++++++++---------- src/TNL/Math.h | 7 ++++- 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h index 626282b02..649a5ad43 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -716,8 +716,8 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 1, output[ cind ] = - input( cell ) >= 0 ? std::numeric_limits< RealType >::max() : - - std::numeric_limits< RealType >::max(); + input( cell ) >= 0 ? std::numeric_limits< Real >::max() : + - std::numeric_limits< Real >::max(); interfaceMap[ cind ] = false; const Real& h = mesh.getSpaceSteps().x(); @@ -768,8 +768,8 @@ __global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 2, output[ cind ] = - input( cell ) >= 0 ? std::numeric_limits< RealType >::max() : - - std::numeric_limits< RealType >::max(); + input( cell ) >= 0 ? std::numeric_limits< Real >::max() : + - std::numeric_limits< Real >::max(); interfaceMap[ cind ] = false; const Real& hx = mesh.getSpaceSteps().x(); @@ -841,8 +841,8 @@ __global__ void CudaInitCaller3d( const Functions::MeshFunction< Meshes::Grid< 3 output[ cind ] = - input( cell ) >= 0 ? std::numeric_limits< RealType >::max() : - - std::numeric_limits< RealType >::max(); + input( cell ) >= 0 ? std::numeric_limits< Real >::max() : + - std::numeric_limits< Real >::max(); interfaceMap[ cind ] = false; cell.refresh(); diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h index 87974c684..890c6cb4c 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h @@ -170,7 +170,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< } __shared__ volatile Real sArray[ 18 ]; - sArray[thri] = TypeInfo< Real >::getMaxValue(); + sArray[thri] = std::numeric_limits< Real >::max(); //filling sArray edges int dimX = mesh.getDimensions().x(); @@ -191,7 +191,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimX > (blIdx+1) * blockDim.x ) sArray[xkolik] = aux[ blIdx*blockDim.x - 1 + xkolik ]; else - sArray[xkolik] = TypeInfo< Real >::getMaxValue(); + sArray[xkolik] = std::numeric_limits< Real >::max(); } if( thri == 1 ) @@ -199,7 +199,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( blIdx != 0 ) sArray[0] = aux[ blIdx*blockDim.x - 1 ]; else - sArray[0] = TypeInfo< Real >::getMaxValue(); + sArray[0] = std::numeric_limits< Real >::max(); } diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h index c390bde69..6703843c1 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -393,7 +393,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< //__shared__ volatile Real sArray[ blockDim.y+2 ][ blockDim.x+2 ]; __shared__ volatile Real sArray[18][18]; - sArray[thrj][thri] = TypeInfo< Real >::getMaxValue(); + sArray[thrj][thri] = std::numeric_limits< Real >::max(); //filling sArray edges int dimX = mesh.getDimensions().x(); int dimY = mesh.getDimensions().y(); @@ -422,7 +422,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimX > (blIdx+1) * blockDim.x && thrj+1 < ykolik ) sArray[thrj+1][xkolik] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + (thrj+1)*dimX + xkolik ]; else - sArray[thrj+1][xkolik] = TypeInfo< Real >::getMaxValue(); + sArray[thrj+1][xkolik] = std::numeric_limits< Real >::max(); } if( thri == 1 ) @@ -430,7 +430,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( blIdx != 0 && thrj+1 < ykolik ) sArray[thrj+1][0] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + (thrj+1)*dimX ]; else - sArray[thrj+1][0] = TypeInfo< Real >::getMaxValue(); + sArray[thrj+1][0] = std::numeric_limits< Real >::max(); } if( thri == 2 ) @@ -438,7 +438,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimY > (blIdy+1) * blockDim.y && thri+1 < xkolik ) sArray[ykolik][thrj+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + ykolik*dimX + thrj+1 ]; else - sArray[ykolik][thrj+1] = TypeInfo< Real >::getMaxValue(); + sArray[ykolik][thrj+1] = std::numeric_limits< Real >::max(); } if( thri == 3 ) @@ -446,7 +446,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( blIdy != 0 && thrj+1 < xkolik ) sArray[0][thrj+1] = aux[ blIdy*blockDim.y*dimX - dimX + blIdx*blockDim.x - 1 + thrj+1 ]; else - sArray[0][thrj+1] = TypeInfo< Real >::getMaxValue(); + sArray[0][thrj+1] = std::numeric_limits< Real >::max(); } diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h index c20d9a2fa..b024979cc 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -328,15 +328,15 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< hz = mesh.getSpaceSteps().z(); } __shared__ volatile Real sArray[10][10][10]; - sArray[thrk][thrj][thri] = TypeInfo< Real >::getMaxValue(); + sArray[thrk][thrj][thri] = std::numeric_limits< Real >::max(); if(thri == 0 ) { - sArray[8][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); - sArray[9][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); - sArray[thrk+1][thrj+1][8] = TypeInfo< Real >::getMaxValue(); - sArray[thrk+1][thrj+1][9] = TypeInfo< Real >::getMaxValue(); - sArray[thrj+1][8][thrk+1] = TypeInfo< Real >::getMaxValue(); - sArray[thrj+1][9][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[8][thrj+1][thrk+1] = std::numeric_limits< Real >::max(); + sArray[9][thrj+1][thrk+1] = std::numeric_limits< Real >::max(); + sArray[thrk+1][thrj+1][8] = std::numeric_limits< Real >::max(); + sArray[thrk+1][thrj+1][9] = std::numeric_limits< Real >::max(); + sArray[thrj+1][8][thrk+1] = std::numeric_limits< Real >::max(); + sArray[thrj+1][9][thrk+1] = std::numeric_limits< Real >::max(); } //filling sArray edges @@ -374,7 +374,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( blIdx != 0 && thrj+1 < ykolik && thrk+1 < zkolik ) sArray[thrk+1][thrj+1][0] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x + thrj * dimX -1 + thrk*dimX*dimY ]; else - sArray[thrk+1][thrj+1][0] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][thrj+1][0] = std::numeric_limits< Real >::max(); } if( thri == 1 ) @@ -382,14 +382,14 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimX > (blIdx+1) * blockDim.x && thrj+1 < ykolik && thrk+1 < zkolik ) sArray[thrk+1][thrj+1][9] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy *blockDim.y*dimX+ blIdx*blockDim.x + blockDim.x + thrj * dimX + thrk*dimX*dimY ]; else - sArray[thrk+1][thrj+1][9] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][thrj+1][9] = std::numeric_limits< Real >::max(); } if( thri == 2 ) { if( blIdy != 0 && thrj+1 < xkolik && thrk+1 < zkolik ) sArray[thrk+1][0][thrj+1] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x - dimX + thrj + thrk*dimX*dimY ]; else - sArray[thrk+1][0][thrj+1] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][0][thrj+1] = std::numeric_limits< Real >::max(); } if( thri == 3 ) @@ -397,14 +397,14 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimY > (blIdy+1) * blockDim.y && thrj+1 < xkolik && thrk+1 < zkolik ) sArray[thrk+1][9][thrj+1] = aux[ blIdz*blockDim.z * dimX * dimY + (blIdy+1) * blockDim.y*dimX + blIdx*blockDim.x + thrj + thrk*dimX*dimY ]; else - sArray[thrk+1][9][thrj+1] = TypeInfo< Real >::getMaxValue(); + sArray[thrk+1][9][thrj+1] = std::numeric_limits< Real >::max(); } if( thri == 4 ) { if( blIdz != 0 && thrj+1 < ykolik && thrk+1 < xkolik ) sArray[0][thrj+1][thrk+1] = aux[ blIdz*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x - dimX * dimY + thrj * dimX + thrk ]; else - sArray[0][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[0][thrj+1][thrk+1] = std::numeric_limits< Real >::max(); } if( thri == 5 ) @@ -412,7 +412,7 @@ __global__ void CudaUpdateCellCaller( tnlDirectEikonalMethodsBase< Meshes::Grid< if( dimZ > (blIdz+1) * blockDim.z && thrj+1 < ykolik && thrk+1 < xkolik ) sArray[9][thrj+1][thrk+1] = aux[ (blIdz+1)*blockDim.z * dimX * dimY + blIdy * blockDim.y*dimX + blIdx*blockDim.x + thrj * dimX + thrk ]; else - sArray[9][thrj+1][thrk+1] = TypeInfo< Real >::getMaxValue(); + sArray[9][thrj+1][thrk+1] = std::numeric_limits< Real >::max(); } if( i < mesh.getDimensions().x() && j < mesh.getDimensions().y() && k < mesh.getDimensions().z() ) diff --git a/src/TNL/Math.h b/src/TNL/Math.h index 1f754bcec..67e9f5e08 100644 --- a/src/TNL/Math.h +++ b/src/TNL/Math.h @@ -72,7 +72,12 @@ template< class T > __cuda_callable__ inline T abs( const T& n ) { -#if defined(__MIC__) +#if defined(__CUDA_ARCH__) + if( std::is_integral< T >::value ) + return ::abs( n ); + else + return ::fabs( n ); +#elif defined(__MIC__) if( n < ( T ) 0 ) return -n; return n; -- GitLab