Commit fff77f0b authored by Nils Kohl's avatar Nils Kohl 🌝
Browse files

Merge branch 'kohl-mohr/toMatrix' into kohl/toMatrix

parents 0768f4a0 881e81b2
Pipeline #34474 failed with stages
in 18 minutes and 56 seconds
......@@ -39,7 +39,7 @@ template < typename value_t >
class BlockFunction
{
public:
typedef value_t ValueType;
typedef value_t valueType;
template < typename VType >
using FunctionType = BlockFunction< VType >;
......@@ -267,11 +267,11 @@ class BlockFunction
std::vector< uint_t > doFsPerRank = walberla::mpi::allGather( counterDoFs );
ValueType offset = 0;
valueType offset = 0;
for ( uint_t i = 0; i < uint_c( walberla::MPIManager::instance()->rank() ); ++i )
{
offset += static_cast< ValueType >( doFsPerRank[i] );
offset += static_cast< valueType >( doFsPerRank[i] );
}
for ( uint_t k = 0; k < subFunc_.size(); k++ )
......@@ -296,22 +296,4 @@ class BlockFunction
}
};
// Special version of numberOfLocalDoFs for BlockFunctions
template < typename value_t >
inline uint_t numberOfLocalDoFs( const BlockFunction< value_t >& func, const uint_t& level )
{
return func.getNumberOfLocalDoFs( level );
}
// Special version of numberOfGlobalDoFs for BlockFunctions
template < typename value_t >
inline uint_t numberOfGlobalDoFs( const BlockFunction< value_t >& func,
const uint_t& level,
const MPI_Comm& communicator = walberla::mpi::MPIManager::instance()->comm(),
const bool& onRootOnly = false )
{
return func.getNumberOfGlobalDoFs( level, communicator, onRootOnly );
}
} // namespace hyteg
......@@ -30,6 +30,10 @@ using walberla::real_c;
using walberla::real_t;
using namespace walberla::mpistubs;
// some forward declarations
template < typename value_t > class BlockFunction;
template < typename value_t > class GenericFunction;
template < typename FunctionTag_T, typename PrimitiveType >
inline uint_t numberOfInnerDoFs( const uint_t& level );
......@@ -186,7 +190,15 @@ inline uint_t numberOfLocalDoFs< P2P2StokesFunctionTag >( const PrimitiveStorage
template < typename func_t >
inline uint_t numberOfLocalDoFs( const func_t& func, const uint_t& level )
{
return numberOfLocalDoFs< typename func_t::Tag >( *( func.getStorage() ), level );
if constexpr ( std::is_base_of< BlockFunction< typename func_t::valueType >, func_t >::value ||
std::is_same< GenericFunction< typename func_t::valueType >, func_t >::value )
{
return func.getNumberOfLocalDoFs( level );
}
else
{
return numberOfLocalDoFs< typename func_t::Tag >( *( func.getStorage() ), level );
}
}
template < typename FunctionTag_T >
......@@ -214,7 +226,15 @@ inline uint_t numberOfGlobalDoFs( const func_t& func,
const MPI_Comm& communicator = walberla::mpi::MPIManager::instance()->comm(),
const bool& onRootOnly = false )
{
return numberOfGlobalDoFs< typename func_t::Tag >( *( func.getStorage() ), level, communicator, onRootOnly );
if constexpr ( std::is_base_of< BlockFunction< typename func_t::valueType >, func_t >::value ||
std::is_same< GenericFunction< typename func_t::valueType >, func_t >::value )
{
return func.getNumberOfGlobalDoFs( level, communicator, onRootOnly );
}
else
{
return numberOfGlobalDoFs< typename func_t::Tag >( *( func.getStorage() ), level, communicator, onRootOnly );
}
}
template < typename FunctionTag_T >
......
......@@ -42,6 +42,8 @@ class GenericFunction
public:
virtual ~GenericFunction(){};
typedef value_t valueType;
template < typename func_t >
func_t& unwrap()
{
......@@ -148,21 +150,4 @@ class GenericFunction
#endif
};
// Special version of numberOfLocalDoFs for GenericFunctions
template < typename value_t >
inline uint_t numberOfLocalDoFs( const GenericFunction< value_t >& func, const uint_t& level )
{
return func.getNumberOfLocalDoFs( level );
}
// Special version of numberOfLocalDoFs for GenericFunctions
template < typename value_t >
inline uint_t numberOfGlobalDoFs( const GenericFunction< value_t >& func,
const uint_t& level,
const MPI_Comm& communicator = walberla::mpi::MPIManager::instance()->comm(),
const bool& onRootOnly = false )
{
return func.getNumberOfGlobalDoFs( level, communicator, onRootOnly );
}
} // namespace hyteg
......@@ -36,11 +36,11 @@ using walberla::real_t;
template < class srcBlockFunc_t, class dstBlockFunc_t >
class BlockOperator : public Operator< srcBlockFunc_t, dstBlockFunc_t >,
public GSSmoothable< srcBlockFunc_t >,
public GSSmoothable< GenericFunction< typename srcBlockFunc_t::ValueType > >
public GSSmoothable< GenericFunction< typename srcBlockFunc_t::valueType > >
{
public:
// temporary, need to add corresponding FunctionTrait?
typedef typename srcBlockFunc_t::ValueType value_t;
typedef typename srcBlockFunc_t::valueType value_t;
BlockOperator( const std::shared_ptr< PrimitiveStorage >& storage,
size_t minLevel,
......
......@@ -107,6 +107,33 @@ void testAssembly( std::shared_ptr< PrimitiveStorage >& storage, uint_t level, s
matrix.createMatrixFromOperator( oper, level, enumeratorSrc, enumeratorDst, All );
}
template < template < class > class fKind >
void testAssembly( BlockOperator< fKind< real_t >, fKind< real_t > >& oper,
std::shared_ptr< PrimitiveStorage >& storage,
uint_t level,
std::string tag,
bool actuallyTest = true )
{
if ( actuallyTest )
{
WALBERLA_LOG_INFO_ON_ROOT( " * " << tag );
}
else
{
WALBERLA_LOG_INFO_ON_ROOT( " * ~ SKIPPING (BUT COMPILES): " << tag );
return;
}
typedef BlockOperator< fKind< real_t >, fKind< real_t > > operType;
fKind< PetscInt > enumerator( "enumerator", storage, level, level );
enumerator.enumerate( level );
PETScManager petscManager;
PETScSparseMatrix< operType > matrix( enumerator, level, tag.c_str() );
matrix.createMatrixFromOperator( oper, level, enumerator, All );
}
// Version for operators the require a form in their ctors
template < class operType, class formType >
void testAssembly( std::shared_ptr< PrimitiveStorage >& storage,
......@@ -366,26 +393,18 @@ int main( int argc, char* argv[] )
// ------------------
// Block Operators
// ------------------
// #define FUTURE_OR_WIP
#ifdef FUTURE_OR_WIP
WALBERLA_LOG_INFO_ON_ROOT( "" << rule << "\n BLOCK OPERATORS\n" << rule );
// setup empty block operator
// setup an artificial block operator
typedef BlockOperator< P2P1TaylorHoodBlockFunction< real_t >, P2P1TaylorHoodBlockFunction< real_t > > myBlockOper;
auto oper = std::make_shared< myBlockOper >( storage, level, level, 3, 3 );
oper->setSubOperator( 0, 0, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 1, 0, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 2, 0, std::make_shared< OperatorWrapper< P1ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 0, 1, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 1, 1, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 2, 1, std::make_shared< OperatorWrapper< P1ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 0, 2, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 1, 2, std::make_shared< OperatorWrapper< P2ConstantLaplaceOperator > >( storage, level, level ) );
oper->setSubOperator( 2, 2, std::make_shared< OperatorWrapper< P1ConstantLaplaceOperator > >( storage, level, level ) );
testAssembly_newAPI< myBlockOper >( storage, level, "myBlockOper" );
#endif
myBlockOper oper( storage, level, level, 2, 2 );
oper.setSubOperator( 0, 0, std::make_shared< OperatorWrapper< P2ConstantVectorLaplaceOperator > >( storage, level, level ) );
oper.setSubOperator( 1, 0, nullptr );
oper.setSubOperator( 0, 1, nullptr );
oper.setSubOperator( 1, 1, std::make_shared< OperatorWrapper< P1ConstantMassOperator > >( storage, level, level ) );
testAssembly< P2P1TaylorHoodBlockFunction >( oper, storage, level, "artificial diagonal BlockOperator" );
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment