コード例 #1
0
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 );
}
コード例 #2
0
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 );
    }
}
コード例 #3
0
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 );

}
コード例 #4
0
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);
}
コード例 #5
0
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);
}
コード例 #6
0
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 );

}
コード例 #7
0
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 );
}