DynamicParMetis::EdgeSource DynamicParMetis::stringToEdgeSource( std::string s ) { string_to_upper( s ); string_trim( s ); if( s == "EDGES_FROM_FOREST" ) return PARMETIS_EDGES_FROM_FOREST; else if( s == "EDGES_FROM_EDGE_WEIGHTS" ) return PARMETIS_EDGES_FROM_EDGE_WEIGHTS; else WALBERLA_ABORT( "Illegal ParMetis weights usage specified (" << s << ")! Valid choices are: \"EDGES_FROM_FOREST\" or \"EDGES_FROM_EDGE_WEIGHTS\"" ); }
DynamicParMetis::WeightsToUse DynamicParMetis::stringToWeightsToUse( std::string s ) { string_to_upper( s ); string_trim( s ); if( s == "NO_WEIGHTS" ) return PARMETIS_NO_WEIGHTS; else if( s == "EDGE_WEIGHTS" ) return PARMETIS_EDGE_WEIGHTS; else if( s == "VERTEX_WEIGHTS" ) return PARMETIS_VERTEX_WEIGHTS; else if( s == "BOTH_WEIGHTS" ) return PARMETIS_BOTH_WEIGHTS; else WALBERLA_ABORT( "Illegal ParMetis weights usage specified (" << s << ")! Valid choices are: \"NO_WEIGHTS\", \"EDGE_WEIGHTS\", \"VERTEX_WEIGHTS\", or \"BOTH_WEIGHTS\"." ); }
ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID storageID, id_t uid, const Vec3& gpos, const std::vector< Vec3 > & pointCloud, MaterialID material, bool global, bool communicating, bool infiniteMass ) { WALBERLA_ASSERT_UNEQUAL( ConvexPolyhedron::getStaticTypeID(), std::numeric_limits<id_t>::max(), "ConvexPolyhedron TypeID not initalized!"); // Checking the side lengths if( pointCloud.size() < size_t(4) ) WALBERLA_ABORT( "Polyhedron needs at leat 4 points!" ); shared_ptr< TriangleMesh > mesh = make_shared<TriangleMesh>(); mesh::QHull<TriangleMesh> qhull( pointCloud, mesh ); qhull.run(); return createConvexPolyhedron( globalStorage, blocks, storageID, uid, gpos, *mesh, material, global, communicating, infiniteMass ); }
DynamicParMetis::Algorithm DynamicParMetis::stringToAlgorithm( std::string s ) { string_to_upper( s ); string_trim( s ); if( s == "PART_GEOM_KWAY" ) return PARMETIS_PART_GEOM_KWAY; else if( s == "PART_GEOM" ) return PARMETIS_PART_GEOM; else if( s == "PART_KWAY" ) return PARMETIS_PART_KWAY; else if( s == "ADAPTIVE_REPART" ) return PARMETIS_ADAPTIVE_REPART; else if( s == "REFINE_KWAY" ) return PARMETIS_REFINE_KWAY; else WALBERLA_ABORT( "Illegal ParMetis algorithm specified (" << s << ")! Valid choices are: \"PART_GEOM_KWAY\", \"PART_GEOM\", \"PART_KWAY\", \"ADAPTIVE_REPART\", or \"REFINE_KWAY\"." ); }
void selectDeviceBasedOnMpiRank() { WALBERLA_ABORT("Your MPI implementation is tool old - it does not support CUDA device selection based on MPI rank"); }
uint_t CartesianDistribution::operator()( SetupBlockForest & forest, const uint_t numberOfProcesses, const memory_t /*perProcessMemoryLimit*/ ) { if( numberOfProcesses != ( numberOfXProcesses_ * numberOfYProcesses_ * numberOfZProcesses_ ) ) WALBERLA_ABORT( "Load balancing failed: The total number of processes must be identical to the product " "of the \'number of processes in x-, y-, and z-direction\'." ); if( numberOfXProcesses_ > forest.getXSize() ) WALBERLA_ABORT( "Load balancing failed: \'Number of processes in x-direction\' must be in (0," << forest.getXSize() << "]. " "You specified \'" << numberOfXProcesses_ << "\'." ); if( numberOfYProcesses_ > forest.getYSize() ) WALBERLA_ABORT( "Load balancing failed: \'Number of processes in y-direction\' must be in (0," << forest.getYSize() << "]. " "You specified \'" << numberOfYProcesses_ << "\'." ); if( numberOfZProcesses_ > forest.getZSize() ) WALBERLA_ABORT( "Load balancing failed: \'Number of processes in z-direction\' must be in (0," << forest.getZSize() << "]. " "You specified \'" << numberOfZProcesses_ << "\'." ); if( processIdMap_ != NULL ) WALBERLA_CHECK_EQUAL( processIdMap_->size(), numberOfProcesses ); uint_t partitions[3]; partitions[0] = numberOfXProcesses_; partitions[1] = numberOfYProcesses_; partitions[2] = numberOfZProcesses_; std::vector< uint_t > indices[3]; for( uint_t i = 0; i != 3; ++i ) { const uint_t div = forest.getSize(i) / partitions[i]; const uint_t mod = forest.getSize(i) % partitions[i]; indices[i].resize( partitions[i] + 1, div ); indices[i][0] = 0; for( uint_t j = 0; j != mod; ++j ) ++indices[i][j+1]; for( uint_t j = 1; j != indices[i].size(); ++j ) indices[i][j] += indices[i][j-1]; } for( uint_t z = 0; z != partitions[2]; ++z ) { for( uint_t y = 0; y != partitions[1]; ++y ) { for( uint_t x = 0; x != partitions[0]; ++x ) { std::vector< SetupBlock * > partitionBlocks; forest.getBlocks( partitionBlocks, indices[0][x], indices[1][y], indices[2][z], indices[0][x+1], indices[1][y+1], indices[2][z+1] ); for( auto block = partitionBlocks.begin(); block != partitionBlocks.end(); ++block ) { const uint_t index = z * partitions[0] * partitions[1] + y * partitions[0] + x; (*block)->assignTargetProcess( ( processIdMap_ != NULL ) ? (*processIdMap_)[ index ] : index ); } } } } return numberOfProcesses; }