void UnitTestSTKParallelDistributedIndex::test_update_bad() { typedef stk::parallel::DistributedIndex PDIndex ; stk::ParallelMachine comm = MPI_COMM_WORLD ; int mpi_rank = stk::parallel_machine_rank(comm); int mpi_size = stk::parallel_machine_size(comm); std::vector< PDIndex::KeySpan > partition_spans ; generate_test_spans_10x10000( partition_spans ); PDIndex di( comm , partition_spans ); std::vector<PDIndex::KeyType> keys_to_add ; std::vector<PDIndex::KeyType> keys_to_remove ; std::vector<PDIndex::KeyProc> sharing_of_local_keys ; //------------------------------ // Invalid key on every process keys_to_add.push_back( partition_spans[0].second + 1 + mpi_rank ); STKUNIT_ASSERT_THROW( di.update_keys( keys_to_add , keys_to_remove ) , std::runtime_error ); //------------------------------ keys_to_add.clear(); if ( mpi_size == mpi_rank + 1 ) { keys_to_add.push_back( partition_spans[0].second + 1 ); } STKUNIT_ASSERT_THROW( di.update_keys( keys_to_add , keys_to_remove ) , std::runtime_error ); }
void UnitTestSTKParallelDistributedIndex::test_ctor_bad() { typedef stk::parallel::DistributedIndex PDIndex ; stk::ParallelMachine comm = MPI_COMM_WORLD ; { // Throw for overlapping span std::vector< PDIndex::KeySpan > partition_spans ; generate_test_spans_10x10000( partition_spans ); // Corrupt this span to trigger an error partition_spans[5].first = partition_spans[4].second ; STKUNIT_ASSERT_THROW( PDIndex di( comm , partition_spans ) , std::runtime_error ); } { // Throw for one bad span std::vector< PDIndex::KeySpan > partition_spans ; generate_test_spans_10x10000( partition_spans ); // Corrupt this span to trigger an error std::swap( partition_spans[5].first , partition_spans[5].second ); STKUNIT_ASSERT_THROW( PDIndex( comm , partition_spans ) , std::runtime_error ); } }
void UnitTestSTKParallelDistributedIndex::test_generate_bad() { typedef stk::parallel::DistributedIndex PDIndex ; stk::ParallelMachine comm = MPI_COMM_WORLD ; int mpi_rank = stk::parallel_machine_rank(comm); int mpi_size = stk::parallel_machine_size(comm); std::vector< PDIndex::KeySpan > partition_spans ; generate_test_spans_10x10000( partition_spans ); PDIndex di( comm , partition_spans ); std::vector<size_t> requests( partition_spans.size() , size_t(0) ); std::vector< std::vector<PDIndex::KeyType> > generated_keys ; //------------------------------ for ( size_t i = 0 ; i < requests.size() ; ++i ) { requests[i] = 10 ; } if( mpi_rank == mpi_size -1 ) { requests.clear(); } STKUNIT_ASSERT_THROW( di.generate_new_keys( requests , generated_keys ), std::runtime_error ); if( mpi_rank == mpi_size -1 ) { requests.push_back(2*(partition_spans[0].second - partition_spans[0].first)); } STKUNIT_ASSERT_THROW( di.generate_new_keys( requests , generated_keys ), std::runtime_error ); for ( size_t i = 0 ; i < requests.size() ; ++i ) { requests[i] = partition_spans[i].second - partition_spans[i].first ; } STKUNIT_ASSERT_THROW( di.generate_new_keys( requests , generated_keys ), std::runtime_error ); }
STKUNIT_UNIT_TEST(UnitTestLinsysFunctions, test1) { static const size_t spatial_dimension = 3; MPI_Barrier( MPI_COMM_WORLD ); MPI_Comm comm = MPI_COMM_WORLD; //First create and fill MetaData and BulkData objects: const unsigned bucket_size = 100; //for a real application mesh, bucket_size would be much bigger... stk::mesh::fem::FEMMetaData fem_meta; stk::mesh::fem::FEMMetaData fem_meta2; fem_meta.FEM_initialize(spatial_dimension); fem_meta2.FEM_initialize(spatial_dimension); stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta); stk::mesh::MetaData & meta_data2 = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta2); const stk::mesh::EntityRank element_rank = fem_meta.element_rank(); stk::mesh::BulkData bulk_data( meta_data, comm, bucket_size ); stk::mesh::BulkData bulk_data2( meta_data2, comm, bucket_size ); //create a boundary-condition part for testing later: stk::mesh::Part& bcpart = fem_meta.declare_part("bcpart"); fill_utest_mesh_meta_data( fem_meta ); bool use_temperature=false; fill_utest_mesh_meta_data( fem_meta2, use_temperature ); fill_utest_mesh_bulk_data( bulk_data ); fill_utest_mesh_bulk_data( bulk_data2 ); //set owner-processors to lowest-sharing (stk::mesh defaults to //highest-sharing) If highest-sharing owns, then it isn't correct for the //way the fei library sets ownership of shared nodes for vectors etc. stk::mesh::set_owners<stk::mesh::LowestRankSharingProcOwns>( bulk_data ); //put a node in our boundary-condition part. arbitrarily choose the //first locally-owned node: bulk_data.modification_begin(); std::vector<stk::mesh::Entity*> local_nodes; stk::mesh::Selector select_owned(meta_data.locally_owned_part()); stk::mesh::get_selected_entities(select_owned, bulk_data.buckets(NODE_RANK), local_nodes); stk::mesh::EntityId bc_node_id = 0; if (local_nodes.size() > 0) { stk::mesh::PartVector partvector; partvector.push_back(&bcpart); bulk_data.change_entity_parts(*local_nodes[0], partvector); bc_node_id = stk::linsys::impl::entityid_to_int(local_nodes[0]->identifier()); } bulk_data.modification_end(); stk::mesh::Selector selector = ( meta_data.locally_owned_part() | meta_data.globally_shared_part() ) & *meta_data.get_part("block_1"); std::vector<unsigned> count; stk::mesh::count_entities(selector, bulk_data, count); STKUNIT_ASSERT_EQUAL( count[element_rank], (unsigned)4 ); STKUNIT_ASSERT_EQUAL( count[NODE_RANK], (unsigned)20 ); ScalarField* temperature_field = meta_data.get_field<ScalarField>("temperature"); //Create a fei Factory and stk::linsys::LinearSystem object: fei::SharedPtr<fei::Factory> factory(new Factory_Trilinos(comm)); stk::linsys::LinearSystem ls(comm, factory); stk::linsys::add_connectivities(ls, element_rank, NODE_RANK, *temperature_field, selector, bulk_data); fei::SharedPtr<fei::MatrixGraph> matgraph = ls.get_fei_MatrixGraph(); int num_blocks = matgraph->getNumConnectivityBlocks(); STKUNIT_ASSERT_EQUAL( num_blocks, (int)1 ); ls.synchronize_mappings_and_structure(); ls.create_fei_LinearSystem(); //put 0 throughout the matrix and 3 throughout the rhs: fei::SharedPtr<fei::Matrix> mat = ls.get_fei_LinearSystem()->getMatrix(); ls.get_fei_LinearSystem()->getMatrix()->putScalar(0); ls.get_fei_LinearSystem()->getRHS()->putScalar(3.0); //put 10 on the matrix diagonal to ensure it will be easy to solve later. fei::SharedPtr<fei::VectorSpace> vspace = ls.get_fei_LinearSystem()->getRHS()->getVectorSpace(); int numLocalRows = vspace->getNumIndices_Owned(); std::vector<int> local_rows(numLocalRows); vspace->getIndices_Owned(numLocalRows, &local_rows[0], numLocalRows); for(size_t i=0; i<local_rows.size(); ++i) { int col = local_rows[i]; double coef = 10; double* coefPtr = &coef; mat->sumIn(1, &local_rows[i], 1, &col, &coefPtr); } //now we'll impose a dirichlet bc on our one-node bcpart: stk::linsys::dirichlet_bc(ls, bulk_data, bcpart, NODE_RANK, *temperature_field, 0, 9.0); ls.finalize_assembly(); //now confirm that the rhs value for the equation corresponding to our //bc node is 9.0: fei::SharedPtr<fei::Vector> rhsvec = ls.get_fei_LinearSystem()->getRHS(); double rhs_bc_val = 0; int bc_eqn_index = ls.get_DofMapper().get_global_index(NODE_RANK, bc_node_id, *temperature_field); rhsvec->copyOut(1, &bc_eqn_index, &rhs_bc_val); bool bc_val_is_correct = std::abs(rhs_bc_val - 9.0) < 1.e-13; STKUNIT_ASSERT( bc_val_is_correct ); stk::linsys::copy_vector_to_mesh( *rhsvec, ls.get_DofMapper(), bulk_data); stk::mesh::Entity* bc_node = bulk_data.get_entity(NODE_RANK, local_nodes[0]->identifier()); stk::mesh::FieldTraits<ScalarField>::data_type* bc_node_data = stk::mesh::field_data(*temperature_field, *bc_node); bool bc_node_data_is_correct = std::abs(bc_node_data[0] - 9.0) < 1.e-13; STKUNIT_ASSERT( bc_node_data_is_correct ); //now make sure we get a throw if we use the wrong bulk-data (that doesn't have the //temperature field defined) STKUNIT_ASSERT_THROW(stk::linsys::copy_vector_to_mesh( *rhsvec, ls.get_DofMapper(), bulk_data2), std::runtime_error); //obtain and zero the solution vector fei::SharedPtr<fei::Vector> solnvec = ls.get_fei_LinearSystem()->getSolutionVector(); solnvec->putScalar(0); //copy the vector of zeros into the mesh: stk::linsys::copy_vector_to_mesh( *solnvec, ls.get_DofMapper(), bulk_data); //assert that our bc node's data is now zero. bc_node_data_is_correct = std::abs(bc_node_data[0] - 0) < 1.e-13; STKUNIT_ASSERT( bc_node_data_is_correct ); //call the linear-system solve function. //(note that when we add options to the solve method, we'll need to enhance this //testing to exercise various specific solves.) Teuchos::ParameterList params; int status = 0; ls.solve(status, params); //copy the solution-vector into the mesh: stk::linsys::copy_vector_to_mesh( *solnvec, ls.get_DofMapper(), bulk_data); //now assert that the value 9 (bc value) produced by the solve is in this //node's data. //note that we use a loose tolerance, because the default solver tolerance //is (I think) only 1.e-6. bc_node_data_is_correct = std::abs(bc_node_data[0] - 9.0) < 1.e-6; STKUNIT_ASSERT( bc_node_data_is_correct ); STKUNIT_ASSERT(bc_node_data_is_correct); }
STKUNIT_UNIT_TEST(UnitTestingOfThrowMacros, testUnit) { // Setting assert handler to NULL should cause exception STKUNIT_ASSERT_THROW(stk::set_assert_handler(0), std::runtime_error); // Check that Throw*Msg works STKUNIT_ASSERT_THROW(force_throw_require_trigger(), std::logic_error); STKUNIT_ASSERT_THROW(force_throw_error_trigger(), std::runtime_error); STKUNIT_ASSERT_THROW(force_throw_invarg_trigger(), std::invalid_argument); // Check that Throw* works STKUNIT_ASSERT_THROW(force_throw_require_trigger(false), std::logic_error); STKUNIT_ASSERT_THROW(force_throw_error_trigger(false), std::runtime_error); STKUNIT_ASSERT_THROW(force_throw_invarg_trigger(false), std::invalid_argument); // Check that macro interacts appropriately with if statements STKUNIT_ASSERT_THROW(check_interaction_with_if(), std::logic_error); STKUNIT_ASSERT_THROW(check_interaction_with_if(false), std::logic_error); // Check that usage of ThrowRequireMsg/ThrowAssertMsg does not change program // semantics. Code blocks that are not contained within braces seem to be // the most likely to be problematic. bool expected_execution_path = false; if (false) ThrowRequireMsg(false, "test"); else expected_execution_path = true; STKUNIT_ASSERT(expected_execution_path); expected_execution_path = false; if (false) ThrowAssertMsg(false, "test"); else expected_execution_path = true; STKUNIT_ASSERT(expected_execution_path); expected_execution_path = false; if (false) ThrowErrorMsg("test"); else expected_execution_path = true; STKUNIT_ASSERT(expected_execution_path); // These next four statements are to check compilation success if (false) ThrowRequireMsg(false, "test"); if (false) ThrowAssertMsg(false, "test"); if (false) ThrowRequire(false); if (false) ThrowAssert(false); // Check that do-while still works, again, we are mostly checking compilation // success here. do ThrowRequireMsg(true, "test"); while (false); do ThrowAssertMsg(true, "test"); while (false); // Check that message with put-tos compiles int temp = 0; ThrowRequireMsg(true, "test: " << temp << " blah"); ThrowAssertMsg(true, "test: " << temp << " blah"); // Check that assert behaves as expected (throws in debug, not in opt) #ifdef NDEBUG force_throw_assert(); #else STKUNIT_ASSERT_THROW(force_throw_assert(), std::logic_error); #endif // Check that ThrowErrorMsg works STKUNIT_ASSERT_THROW(test_no_expr_error(), std::runtime_error); // Check that setting handler for asserts works. stk::ErrorHandler orig = stk::set_assert_handler(test_assert_handler); ThrowRequireMsg(false, "test"); STKUNIT_ASSERT(test_assert_handler_called); stk::set_assert_handler(orig); STKUNIT_ASSERT_THROW(force_throw_require_trigger(), std::logic_error); // Check that setting handler for errors works. orig = stk::set_error_handler(test_error_handler); ThrowErrorMsgIf(true, "test"); STKUNIT_ASSERT(test_error_handler_called); stk::set_error_handler(orig); STKUNIT_ASSERT_THROW(force_throw_error_trigger(), std::runtime_error); // Check that setting handler for invalid args works. orig = stk::set_invalid_arg_handler(test_invarg_handler); ThrowInvalidArgMsgIf(true, "test"); STKUNIT_ASSERT(test_invarg_handler_called); stk::set_invalid_arg_handler(orig); STKUNIT_ASSERT_THROW(force_throw_invarg_trigger(), std::invalid_argument); }
void UnitTestSTKParallelDistributedIndex::test_generate_big() { typedef stk::parallel::DistributedIndex PDIndex ; stk::ParallelMachine comm = MPI_COMM_WORLD ; const int mpi_rank = stk::parallel_machine_rank(comm); const int mpi_size = stk::parallel_machine_size(comm); std::vector< PDIndex::KeySpan > partition_spans ; generate_test_spans_10x10000( partition_spans ); PDIndex di( comm , partition_spans ); std::vector<size_t> requests( partition_spans.size() , size_t(0) ); std::vector< std::vector<PDIndex::KeyType> > generated_keys ; //---------------------------------------- if ( mpi_rank == mpi_size - 1 ) { requests[5] = 5000 ; // Half } else { requests[5] = 0 ; } di.generate_new_keys( requests , generated_keys ); STKUNIT_ASSERT_EQ( generated_keys.size() , partition_spans.size() ); for ( size_t i = 0 ; i < generated_keys.size() ; ++i ) { STKUNIT_EXPECT_EQ( generated_keys[i].size() , requests[i] ); } //---------------------------------------- if ( mpi_rank == mpi_size - 1 ) { requests[5] = 4999 ; // Almost half again } else { requests[5] = 0 ; } di.generate_new_keys( requests , generated_keys ); STKUNIT_ASSERT_EQ( generated_keys.size() , partition_spans.size() ); for ( size_t i = 0 ; i < generated_keys.size() ; ++i ) { STKUNIT_EXPECT_EQ( generated_keys[i].size() , requests[i] ); } //---------------------------------------- // This should request generation of one too many keys. if ( mpi_rank == 0 ) { requests[5] = 2 ; // Exceed the total } else { requests[5] = 0 ; } STKUNIT_ASSERT_THROW( di.generate_new_keys( requests , generated_keys ) , std::runtime_error ); }
void testDofMapper( MPI_Comm comm ) { //First create and fill MetaData and BulkData objects: const unsigned bucket_size = 100; //for a real application mesh, bucket_size would be much bigger... stk::mesh::MetaData meta_data( stk::mesh::fem_entity_rank_names() ); stk::mesh::BulkData bulk_data( meta_data, comm, bucket_size ); fill_utest_mesh_meta_data( meta_data ); fill_utest_mesh_bulk_data( bulk_data ); stk::mesh::Selector selector = meta_data.locally_owned_part() | meta_data.globally_shared_part() ; std::vector<unsigned> count; stk::mesh::count_entities(selector, bulk_data, count); STKUNIT_ASSERT_EQUAL( count[stk::mesh::Element], (unsigned)4 ); STKUNIT_ASSERT_EQUAL( count[stk::mesh::Node], (unsigned)20 ); std::vector<stk::mesh::Entity*> nodes; stk::mesh::get_entities(bulk_data, stk::mesh::Node, nodes); stk::mesh::ScalarField* temperature_field = meta_data.get_field<stk::mesh::ScalarField>("temperature"); //Now we're ready to test the DofMapper: stk::linsys::DofMapper dof_mapper(comm); const stk::mesh::Selector select_used = meta_data.locally_owned_part() | meta_data.globally_shared_part(); dof_mapper.add_dof_mappings(bulk_data, select_used, stk::mesh::Node, *temperature_field); stk::mesh::EntityRank ent_type; stk::mesh::EntityId ent_id; const stk::mesh::FieldBase* field = NULL; int offset_into_field; int index = 0; //DofMapper::get_dof can't be called until after DofMapper::finalize() has //been called. //We'll call it now to verify that an exception is thrown: std::cout << "Testing error condition: " << std::endl; STKUNIT_ASSERT_THROW(dof_mapper.get_dof(index, ent_type, ent_id, field, offset_into_field), std::runtime_error ); std::cout << "...Completed testing error condition." << std::endl; dof_mapper.finalize(); //find a node that is in the locally-used part: size_t i_node = 0; while(! select_used( nodes[i_node]->bucket() ) && i_node<nodes.size()) { ++i_node; } //test the get_global_index function: stk::mesh::EntityId node_id = nodes[i_node]->identifier(); index = dof_mapper.get_global_index(stk::mesh::Node, node_id, *temperature_field); STKUNIT_ASSERT_EQUAL( index, (int)(node_id-1) ); std::cout << "Testing error condition: " << std::endl; //call DofMapper::get_global_index with a non-existent ID and verify that an //exception is thrown: STKUNIT_ASSERT_THROW(dof_mapper.get_global_index(stk::mesh::Node, (stk::mesh::EntityId)999999, *temperature_field), std::runtime_error); std::cout << "...Completed testing error condition." << std::endl; int numProcs = 1; numProcs = stk::parallel_machine_size( MPI_COMM_WORLD ); fei::SharedPtr<fei::VectorSpace> fei_vspace = dof_mapper.get_fei_VectorSpace(); int numIndices = fei_vspace->getGlobalNumIndices(); STKUNIT_ASSERT_EQUAL( numIndices, (int)(numProcs*20 - (numProcs-1)*4) ); dof_mapper.get_dof(index, ent_type, ent_id, field, offset_into_field); STKUNIT_ASSERT_EQUAL( ent_type, nodes[i_node]->entity_rank() ); STKUNIT_ASSERT_EQUAL( ent_id, nodes[i_node]->identifier() ); STKUNIT_ASSERT_EQUAL( field->name() == temperature_field->name(), true ); STKUNIT_ASSERT_EQUAL( offset_into_field, (int)0 ); }