示例#1
0
void GridFixture::generate_grid()
{
  const unsigned num_nodes = 25;
  const unsigned num_quad_faces = 16;
  const unsigned p_rank = m_bulk_data.parallel_rank();
  const unsigned p_size = m_bulk_data.parallel_size();
  const EntityRank element_rank = m_fem_meta.element_rank();
  std::vector<Entity*> all_entities;

  // assign ids, quads, nodes, then shells
  // (we need this order to be this way in order for our connectivity setup to  work)
  std::vector<unsigned> quad_face_ids(num_quad_faces);
  std::vector<unsigned> node_ids(num_nodes);
  {
    unsigned curr_id = 1;
    for (unsigned  i = 0 ; i < num_quad_faces; ++i, ++curr_id) {
      quad_face_ids[i] = curr_id;
    }
    for (unsigned  i = 0 ; i < num_nodes; ++i, ++curr_id) {
      node_ids[i] = curr_id;
    }
  }

  // Note:  This block of code would normally be replaced with a call to stk_io
  // to generate the mesh.

  // declare entities such that entity_id - 1 is the index of the
  // entity in the all_entities vector
  {
    const PartVector no_parts;
    const unsigned first_quad = (p_rank * num_quad_faces) / p_size;
    const unsigned end_quad = ((p_rank + 1) * num_quad_faces) / p_size;

    // declare faces
    PartVector face_parts;
    face_parts.push_back(&m_quad_part);
    const unsigned num_nodes_per_quad = 4;
    // (right-hand rule) counterclockwise:
    const int stencil_for_4x4_quad_mesh[num_nodes_per_quad] = {0, 5, 1, -5};
    for (unsigned i = first_quad; i < end_quad; ++i) {

      unsigned face_id = quad_face_ids[i];
      unsigned row = (face_id - 1) / num_nodes_per_quad;

      Entity& face = m_bulk_data.declare_entity(element_rank, face_id, face_parts);

      unsigned node_id = num_quad_faces + face_id + row;

      for (unsigned chg_itr = 0; chg_itr < num_nodes_per_quad; ++chg_itr) {
        node_id += stencil_for_4x4_quad_mesh[chg_itr];
        Entity& node = m_bulk_data.declare_entity(fem::FEMMetaData::NODE_RANK, node_id, no_parts);
        m_bulk_data.declare_relation( face , node , chg_itr);
      }
    }
  }
}
示例#2
0
void
QcOsmPbfReader::read_ways(OSMPBF::PrimitiveGroup primitive_group)
{
  enter_way_transactions();

  int number_of_ways = primitive_group.ways_size();
  for (int i = 0; i < number_of_ways; i++) {
    OSMPBF::Way way = primitive_group.ways(i);
    int64_t way_id = way.id();

    QVector<int64_t> node_ids(way.refs_size());
    int j = 0;
    DeltaCodedInt64 node_id;
    for (auto ref : way.refs()) {
      node_ids[j++] = node_id.update(ref);
    }

    // qDebug().nospace() << "way" << i << way_id << node_ids;

    int number_of_attributes = way.keys_size();
    QVector<KeyValPair> attributes(number_of_attributes);
    for (int i = 0; i < number_of_attributes; i++) {
      int32_t key_id = way.keys(i);
      int32_t val_id = way.vals(i);
      // qDebug() << "  key_val" << way_id << m_string_table[key_id] << m_string_table[val_id];
      attributes[i] = KeyValPair(key_id, val_id);
    }

    yield_way(way_id, node_ids, attributes);

    if (m_read_metadatas and way.has_info()) {
      // qDebug().nospace() << "        with meta-info";
      OSMPBF::Info info = way.info();
      int32_t version = info.version();
      int64_t timestamp = to_timestamp(info.timestamp());
      int64_t changeset = info.changeset();
      int32_t uid = info.uid();
      int32_t user_sid = info.user_sid();
      // bool visible = info.visible();
      // qDebug() << "Meta information:" << version << timestamp << changeset << uid << user_sid;
      // yield_way_metadata(way_id, version, timestamp, changeset, uid, user_sid);
    }
  }

  leave_way_transactions();
}
示例#3
0
bool MyExportCommand::write_file(std::ofstream& output_file, MeshExportInterface *iface)
{
  // Initialize the exporter
  iface->initialize_export();

  // Fetch and output the coordinates
  int number_nodes = iface->get_num_nodes();

  if(!number_nodes)
  {
    CubitMessageHandler* console = CubitInterface::get_cubit_message_handler();
    console->print_message("WARNING: No nodes in model...\n");
    return false;
  }

  output_file << "Test Output for MeshExportInterface\n";
  output_file << "Number of Nodes:  " << number_nodes << "\n";
  output_file << "List of Nodes:\n";

  int buf_size = 100;
  std::vector<double> xcoords(buf_size), ycoords(buf_size), zcoords(buf_size);
  std::vector<int> node_ids(buf_size);

  int start = 0, number_found = 0;
  while ((number_found = iface->get_coords(start, buf_size, xcoords, ycoords, zcoords, node_ids)))
  {
    // Write out the coordinates
    for(int i = 0; i < number_found; i++)
    {
      output_file << node_ids[i] << "  " <<
                     xcoords[i] << "  " <<
                     ycoords[i] << "  " <<
                     zcoords[i] << "\n";
    }
    start += number_found;
  }

  // Write the connectivity
  bool result = write_connectivity(output_file, iface);

  return result;
}
示例#4
0
bool use_case_5_driver( MPI_Comm comm ,
                        const std::string& mesh_options,
                        const std::string& solver_params )
{
  if ( 0 == stk::parallel_machine_rank( comm ) ) {
    std::cout << "stk_linsys use case 5" << std::endl
              << "  Number Processes = " << stk::parallel_machine_size( comm )
              << std::endl ;
  }

  //--------------------------------------------------------------------

  {
    //------------------------------------------------------------------
    // Declare the mesh meta data: element blocks and associated fields

    stk::mesh::fem::FEMMetaData fem_meta(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim) ) ;
    Ioss::Init::Initializer init_db;

    stk::mesh::MetaData & mesh_meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);

    {
      const stk::mesh::fem::FEMMetaData &fmd = fem_meta.get ( mesh_meta_data );
      std::cout <<fmd.is_FEM_initialized()<<endl;
    }

    const stk::mesh::EntityRank element_rank = fem_meta.element_rank();

    //--------------------------------
    // Element-block declarations typically occur when reading the
    // mesh-file meta-data, and thus won't usually appear in application code.
    // Declaring the element blocks and associating an element traits
    // with each element block.

    stk::mesh::Part & universal        = fem_meta.universal_part();
    stk::mesh::Part & block_hex        = fem_meta.declare_part("block_1", element_rank);
    stk::mesh::Part & block_quad_shell = fem_meta.declare_part("block_2", element_rank);

    stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<> >());
    stk::mesh::fem::CellTopology qshell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<> >());
    stk::mesh::fem::set_cell_topology( block_hex, hex_top );
    stk::mesh::fem::set_cell_topology( block_quad_shell, qshell_top );

    stk::io::put_io_part_attribute(block_hex);
    stk::io::put_io_part_attribute(block_quad_shell);

    //--------------------------------
    // Declaring fields of specified types on all nodes:

    VectorFieldType & coordinates_field =
      stk::mesh::put_field(
        fem_meta.declare_field< VectorFieldType >( "coordinates" ) ,
        stk::mesh::fem::FEMMetaData::NODE_RANK , universal , SpatialDim );

    VectorFieldType & displacements_field =
      stk::mesh::put_field(
        fem_meta.declare_field< VectorFieldType >( "displacements" ) ,
        stk::mesh::fem::FEMMetaData::NODE_RANK , universal , SpatialDim );

    //--------------------------------
    // rotation_field only exists on the shell-nodes:

    VectorFieldType & rotation_field =
      stk::mesh::put_field(
        fem_meta.declare_field< VectorFieldType >( "rotation" ),
        stk::mesh::fem::FEMMetaData::NODE_RANK , block_quad_shell , SpatialDim );

    stk::mesh::Part& bcpart = fem_meta.declare_part("bcpart");

    // Define the transient fields that will be output.
    stk::io::set_field_role(displacements_field, Ioss::Field::TRANSIENT);

    //--------------------------------
    // Commit (finalize) the meta data.  Is now ready to be used
    // in the creation and management of mesh bulk data.

    fem_meta.commit();

    //------------------------------------------------------------------
    // stk::mesh::BulkData bulk data conforming to the meta data.

    stk::mesh::BulkData mesh_bulk_data( mesh_meta_data , comm );

    // In a typical app, the mesh would be read from file at this point.
    // But in this use-case, we generate the mesh and initialize
    // field data to use-case defined values.

    use_case_5_generate_mesh(
      mesh_options ,
      mesh_bulk_data ,
      coordinates_field ,
      block_hex ,
      block_quad_shell );

    use_case_5_initialize_data(
      mesh_bulk_data ,
      coordinates_field ,
      displacements_field ,
      rotation_field );

    //Add a node to our boundary-condition part 'bcpart'.
    //let's choose the first locally-owned node. (This will produce a
    //different boundary-condition for different numbers of processors...
    //A more realistic case would simply pick a specific set of nodes
    //regardless of which processors they are on.)

    mesh_bulk_data.modification_begin();

    std::vector<stk::mesh::Entity*> local_nodes;
    stk::mesh::Selector select_owned(fem_meta.locally_owned_part());
    stk::mesh::get_selected_entities(select_owned,
                                     mesh_bulk_data.buckets(stk::mesh::fem::FEMMetaData::NODE_RANK),
                                     local_nodes);

    if (local_nodes.size() > 0) {
      stk::mesh::PartVector partvector;
      partvector.push_back(&bcpart);
      mesh_bulk_data.change_entity_parts(*local_nodes[0], partvector);
    }

    mesh_bulk_data.modification_end();

    //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>( mesh_bulk_data );

    //Note: set_owners should throw an error if not done inside a modification_begin/end block.
    //------------------------------------------------------------------

    const unsigned myProc = mesh_bulk_data.parallel_rank();

    //Now begin the use-case:
    //Create a fei::Factory of type Factory_Trilinos, which will produce
    //fei::Matrix and fei::Vector objects with run-time-type compatible with Trilinos.

    fei::SharedPtr<fei::Factory> feifactory(new Factory_Trilinos(comm));
    stk::linsys::LinearSystem ls(comm, feifactory);

    if (myProc == 0) {
      std::cout << "Adding element-node connectivities for displacements field for all locally-owned "
        << "elements..." << std::endl;
    }

    //Add connectivities for our mesh to the linsys::LinearSystem object. This
    //will enable us to generate a matrix-graph:

    stk::linsys::add_connectivities(ls, element_rank,
                                    stk::mesh::fem::FEMMetaData::NODE_RANK,
                                    displacements_field, select_owned, mesh_bulk_data);

    ls.synchronize_mappings_and_structure();

    ls.create_fei_LinearSystem();

    fei::SharedPtr<fei::MatrixGraph> matgraph = ls.get_fei_MatrixGraph();
    fei::SharedPtr<fei::Matrix> matrix = ls.get_fei_LinearSystem()->getMatrix();
    fei::SharedPtr<fei::Vector> rhs = ls.get_fei_LinearSystem()->getRHS();
    fei::SharedPtr<fei::Vector> solution = ls.get_fei_LinearSystem()->getSolutionVector();

    //Now we'll run through the mesh and load up dense element-matrices and element-vectors
    //to assemble into the global sparse linear-system:
    {
      const std::vector<stk::mesh::Bucket*>& mesh_buckets = mesh_bulk_data.buckets(element_rank);
      std::vector<stk::mesh::Bucket*> part_buckets;
      stk::mesh::get_buckets(select_owned, mesh_buckets, part_buckets);

      stk::linsys::DofMapper& dof_mapper = ls.get_DofMapper();

      int field_id = dof_mapper.get_field_id(displacements_field);

      stk::mesh::Entity& first_entity = *(part_buckets[0]->begin());
      stk::mesh::PairIterRelation rel = first_entity.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
      int num_nodes_per_elem = rel.second - rel.first;

      int pattern_id = matgraph->definePattern(num_nodes_per_elem, stk::mesh::fem::FEMMetaData::NODE_RANK, field_id);

      std::vector<int> node_ids(num_nodes_per_elem);

      const int field_size = dof_mapper.get_fei_VectorSpace()->getFieldSize(field_id);
      const int matsize = num_nodes_per_elem*field_size*num_nodes_per_elem*field_size;
      const int vecsize = num_nodes_per_elem*field_size;

      std::vector<double> elem_matrix_1d(matsize, 0);
      std::vector<double*> elem_matrix_2d(vecsize);

      std::vector<double> elem_vector(vecsize, 0);

      for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
        elem_matrix_2d[i] = &elem_matrix_1d[i*vecsize];
      }

      //fill our dummy elem-matrix:
      //This dummy matrix will be the same for every element. A real application
      //would form a different elem-matrix for each element.
      for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
        double* row = elem_matrix_2d[i];
        if (i>=1) row[i-1] = -1;
        row[i] = 2;
        if (i<elem_matrix_2d.size()-1) row[i+1] = -1;

        elem_vector[i] = 1;
      }

      std::vector<int> eqn_indices(vecsize);

      for(size_t i=0; i<part_buckets.size(); ++i) {
        stk::mesh::Bucket::iterator
          b_iter = part_buckets[i]->begin(),
                 b_end  = part_buckets[i]->end();
        for(; b_iter != b_end; ++b_iter) {
          stk::mesh::Entity& elem = *b_iter;
          rel = elem.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
          for(int j=0; rel.first != rel.second; ++rel.first, ++j) {
            node_ids[j] = rel.first->entity()->identifier();
          }

          matgraph->getPatternIndices(pattern_id, &node_ids[0], eqn_indices);

          matrix->sumIn(vecsize, &eqn_indices[0], vecsize, &eqn_indices[0],
                        &elem_matrix_2d[0]);
          rhs->sumIn(vecsize, &eqn_indices[0], &elem_vector[0]);
        }
      }

      stk::linsys::dirichlet_bc(ls, mesh_bulk_data, bcpart, stk::mesh::fem::FEMMetaData::NODE_RANK,
                                displacements_field, 0, 3.14159265);

      ls.finalize_assembly();

      //Read solver-parameters out of a file. In a real application this would
      //be done during a parsing phase, *not* here in the assembly code.

      Teuchos::ParameterList params;
      if (solver_params != "") {
        Teuchos::ParameterXMLFileReader param_file(solver_params);
        params = param_file.getParameters();
      }

      //Launch the linear-solver:
      int status = 0, ret;
      ret = ls.solve(status, params);

      if (ret != 0) {
        throw std::runtime_error("Error in the linear solver.");
      }

      //Copy the contents of the solution-vector back into our mesh-data:
      copy_vector_to_mesh( *solution, dof_mapper, mesh_bulk_data);
    }

    //This following section writes mesh data out to an exodus file:
    {
      const std::string out_filename("mesh.e");

      stk::io::MeshData mesh;
      stk::io::create_output_mesh(out_filename, comm, mesh_bulk_data, mesh);
      stk::io::define_output_fields(mesh, fem_meta);

      // Write the model to the mesh file (topology, coordinates, attributes, etc)
      stk::io::process_output_request(mesh, mesh_bulk_data, 0.0);
    }

    //Write out our assembled linear-system to files:

    matrix->writeToFile("A.mtx");
    rhs->writeToFile("rhs.vec");
    solution->writeToFile("solution.vec");
  }
  return true;
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntityIntegrationRule, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = 
	Teuchos::DefaultComm<int>::getComm();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );

    // Make a data field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& data_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "test field");
    meta_data.set_coordinate_field( &data_field );
    stk::mesh::put_field( data_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    unsigned num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create a DTK entity for the hex.
    DataTransferKit::Entity dtk_entity = 
	DataTransferKit::STKMeshEntity( hex_entity, bulk_data.ptr() );

    // Create an integration rule.
    Teuchos::RCP<DataTransferKit::EntityIntegrationRule> integration_rule =
	Teuchos::rcp( new DataTransferKit::STKMeshEntityIntegrationRule(bulk_data) );

    // Test the integration rule.
    Teuchos::Array<Teuchos::Array<double> > p_1;
    Teuchos::Array<double> w_1;
    integration_rule->getIntegrationRule( dtk_entity, 1, p_1, w_1 );
    TEST_EQUALITY( 1, w_1.size() );
    TEST_EQUALITY( 1, p_1.size() );
    TEST_EQUALITY( 3, p_1[0].size() );
    TEST_EQUALITY( 8.0, w_1[0] );
    TEST_EQUALITY( 0.0, p_1[0][0] );
    TEST_EQUALITY( 0.0, p_1[0][1] );
    TEST_EQUALITY( 0.0, p_1[0][2] );

    Teuchos::Array<Teuchos::Array<double> > p_2;
    Teuchos::Array<double> w_2;
    integration_rule->getIntegrationRule( dtk_entity, 2, p_2, w_2 );
    TEST_EQUALITY( 8, w_2.size() );
    TEST_EQUALITY( 8, p_2.size() );
    for ( int i = 0; i < 8; ++i )
    {
	TEST_EQUALITY( w_2[i], 1.0 );
	TEST_EQUALITY( p_2[i].size(), 3 );

	for ( int d = 0; d < 3; ++d )
	{
	    TEST_FLOATING_EQUALITY(
		std::abs(p_2[i][d]), 1.0 / std::sqrt(3.0), 1.0e-15 );
	}
    }
}
示例#6
0
bool use_case_3_driver( MPI_Comm comm ,
                        const std::string& mesh_options )
{
    if ( 0 == stk::parallel_machine_rank( comm ) ) {
        std::cout << "stk_linsys use case 3" << std::endl
                  << "  Number Processes = " << stk::parallel_machine_size( comm )
                  << std::endl ;
    }

    //--------------------------------------------------------------------

    {
        //------------------------------------------------------------------
        // Declare the mesh meta data: element blocks and associated fields

        stk::mesh::fem::FEMMetaData fem_meta;
        fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim) ) ;

        stk::mesh::MetaData & mesh_meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
        const stk::mesh::EntityRank element_rank = fem_meta.element_rank();

        //--------------------------------
        // Element-block declarations typically occur when reading the
        // mesh-file meta-data, and thus won't usually appear in application code.
        // Declaring the element blocks and associating an element traits
        // with each element block.

        stk::mesh::Part & universal        = fem_meta.universal_part();
        stk::mesh::Part & block_hex        = fem_meta.declare_part("block_1", element_rank);
        stk::mesh::Part & block_quad_shell = fem_meta.declare_part("block_2", element_rank);

        stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<> >());
        stk::mesh::fem::CellTopology qshell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<> >());
        stk::mesh::fem::set_cell_topology( block_hex, hex_top );
        stk::mesh::fem::set_cell_topology( block_quad_shell, qshell_top );

        //--------------------------------
        // Declaring fields of specified types on all nodes:

        VectorFieldType & coordinates_field =
            stk::mesh::put_field(
                fem_meta.declare_field< VectorFieldType >( "coordinates" ) ,
                stk::mesh::fem::FEMMetaData::NODE_RANK , universal , SpatialDim );

        VectorFieldType & displacements_field =
            stk::mesh::put_field(
                fem_meta.declare_field< VectorFieldType >( "displacements" ) ,
                stk::mesh::fem::FEMMetaData::NODE_RANK , universal , SpatialDim );

        //--------------------------------
        // Put a scalar "pressure" field on all elements, just to use in demonstrating
        // DOF mappings below:

        //    ScalarFieldType & pressure_field =
        stk::mesh::put_field(
            fem_meta.declare_field< ScalarFieldType >("pressure"),
            element_rank, universal);

        //--------------------------------
        // rotation_field only exists on the shell-nodes:

        VectorFieldType & rotation_field =
            stk::mesh::put_field(
                fem_meta.declare_field< VectorFieldType >( "rotation" ),
                stk::mesh::fem::FEMMetaData::NODE_RANK , block_quad_shell , SpatialDim );

        //--------------------------------
        // Commit (finalize) the meta data.  Is now ready to be used
        // in the creation and management of mesh bulk data.

        fem_meta.commit();

        //------------------------------------------------------------------
        // stk::mesh::BulkData bulk data conforming to the meta data.

        stk::mesh::BulkData mesh_bulk_data( mesh_meta_data , comm );

        // In a typical app, the mesh would be read from file at this point.
        // But in this use-case, we generate the mesh and initialize
        // field data to use-case defined values.

        use_case_3_generate_mesh(
            mesh_options ,
            mesh_bulk_data ,
            coordinates_field ,
            block_hex ,
            block_quad_shell );

        use_case_3_initialize_data(
            mesh_bulk_data ,
            coordinates_field ,
            displacements_field ,
            rotation_field );

        mesh_bulk_data.modification_end();

        //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>( mesh_bulk_data );


        //------------------------------------------------------------------

        const unsigned myProc = mesh_bulk_data.parallel_rank();

        stk::mesh::Selector select_owned = fem_meta.locally_owned_part();

        fei::SharedPtr<fei::Factory> feifactory(new Factory_Trilinos(comm));
        stk::linsys::LinearSystem ls(comm, feifactory);

        if (myProc == 0) {
            std::cout << "Adding element-node connectivities for displacements field for all locally-owned "
                      << "elements..." << std::endl;
        }

        stk::linsys::add_connectivities(ls, element_rank,
                                        stk::mesh::fem::FEMMetaData::NODE_RANK,
                                        displacements_field, select_owned, mesh_bulk_data);

        ls.synchronize_mappings_and_structure();

        ls.create_fei_LinearSystem();

        fei::SharedPtr<fei::MatrixGraph> matgraph = ls.get_fei_MatrixGraph();
        fei::SharedPtr<fei::Matrix> matrix = ls.get_fei_LinearSystem()->getMatrix();
        fei::SharedPtr<fei::Vector> rhs = ls.get_fei_LinearSystem()->getRHS();

        {
            const std::vector<stk::mesh::Bucket*>& mesh_buckets = mesh_bulk_data.buckets(element_rank);
            std::vector<stk::mesh::Bucket*> part_buckets;
            stk::mesh::get_buckets(select_owned, mesh_buckets, part_buckets);

            stk::linsys::DofMapper& dof_mapper = ls.get_DofMapper();

            int field_id = dof_mapper.get_field_id(displacements_field);

            stk::mesh::Entity& first_entity = *(part_buckets[0]->begin());
            stk::mesh::PairIterRelation rel = first_entity.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
            int num_nodes_per_elem = rel.second - rel.first;

            int pattern_id = matgraph->definePattern(num_nodes_per_elem, stk::mesh::fem::FEMMetaData::NODE_RANK, field_id);

            std::vector<int> node_ids(num_nodes_per_elem);

            const int field_size = dof_mapper.get_fei_VectorSpace()->getFieldSize(field_id);
            const int matsize = num_nodes_per_elem*field_size*num_nodes_per_elem*field_size;
            const int vecsize = num_nodes_per_elem*field_size;

            std::vector<double> elem_matrix_1d(matsize, 0);
            std::vector<double*> elem_matrix_2d(vecsize);

            std::vector<double> elem_vector(vecsize, 0);

            for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
                elem_matrix_2d[i] = &elem_matrix_1d[i*vecsize];
            }

            //fill the dummy elem-matrix that we will use below for every element:
            for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
                double* row = elem_matrix_2d[i];
                if (i>=1) row[i-1] = -1;
                row[i] = 2;
                if (i<elem_matrix_2d.size()-1) row[i+1] = -1;

                elem_vector[i] = 1;
            }

            std::vector<int> eqn_indices(vecsize);

            for(size_t i=0; i<part_buckets.size(); ++i) {
                stk::mesh::Bucket::iterator
                b_iter = part_buckets[i]->begin(),
                b_end  = part_buckets[i]->end();
                for(; b_iter != b_end; ++b_iter) {
                    stk::mesh::Entity& elem = *b_iter;
                    rel = elem.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
                    for(int j=0; rel.first != rel.second; ++rel.first, ++j) {
                        node_ids[j] = rel.first->entity()->identifier();
                    }

                    matgraph->getPatternIndices(pattern_id, &node_ids[0], eqn_indices);

                    matrix->sumIn(vecsize, &eqn_indices[0], vecsize, &eqn_indices[0],
                                  &elem_matrix_2d[0]);
                    rhs->sumIn(vecsize, &eqn_indices[0], &elem_vector[0]);
                }
            }
        }

        ls.finalize_assembly();

        matrix->writeToFile("A.mtx");
        rhs->writeToFile("rhs.vec");
    }
    return true;
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntitySet, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    int part_1_id = part_1.mesh_meta_data_ordinal();
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );
    int part_2_id = part_2.mesh_meta_data_ordinal();

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    unsigned num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Create an entity set.
    Teuchos::RCP<DataTransferKit::EntitySet> entity_set =
	Teuchos::rcp( new DataTransferKit::STKMeshEntitySet(bulk_data) );

    // Test the set.
    Teuchos::RCP<const Teuchos::Comm<int> > set_comm = 
	entity_set->communicator();
    TEST_EQUALITY( set_comm->getRank(), comm->getRank() );
    TEST_EQUALITY( set_comm->getSize(), comm->getSize() );
    TEST_EQUALITY( space_dim, entity_set->physicalDimension() );

    // Make an iterator for the hex.
    std::function<bool(DataTransferKit::Entity)> all_pred = 
	[=] (DataTransferKit::Entity e){return true;};
    DataTransferKit::EntityIterator volume_iterator = 
	entity_set->entityIterator( space_dim, all_pred );

    // Test the volume iterator.
    TEST_EQUALITY( volume_iterator.size(), 1 );
    TEST_ASSERT( volume_iterator == volume_iterator.begin() );
    TEST_ASSERT( volume_iterator != volume_iterator.end() );

    // Test the volume under the iterator.
    TEST_EQUALITY( hex_id, volume_iterator->id() );
    TEST_EQUALITY( comm_rank, volume_iterator->ownerRank() );
    TEST_EQUALITY( space_dim, volume_iterator->topologicalDimension() );
    TEST_EQUALITY( space_dim, volume_iterator->physicalDimension() );
    TEST_ASSERT( volume_iterator->inBlock(part_1_id) );
    TEST_ASSERT( !volume_iterator->inBlock(part_2_id) );
    TEST_ASSERT( volume_iterator->onBoundary(part_1_id) );
    TEST_ASSERT( !volume_iterator->onBoundary(part_2_id) );

    Teuchos::RCP<DataTransferKit::EntityExtraData> extra_data_1 =
	volume_iterator->extraData();
    TEST_EQUALITY( hex_entity,
		   Teuchos::rcp_dynamic_cast<DataTransferKit::STKMeshEntityExtraData>(
		       extra_data_1)->d_stk_entity );

    Teuchos::Tuple<double,6> hex_bounds_1;
    volume_iterator->boundingBox( hex_bounds_1 );
    TEST_EQUALITY( 0.0, hex_bounds_1[0] );
    TEST_EQUALITY( 0.0, hex_bounds_1[1] );
    TEST_EQUALITY( 0.0, hex_bounds_1[2] );
    TEST_EQUALITY( 1.0, hex_bounds_1[3] );
    TEST_EQUALITY( 1.0, hex_bounds_1[4] );
    TEST_EQUALITY( 1.0, hex_bounds_1[5] );

    // Test the end of the iterator.
    volume_iterator++;
    TEST_ASSERT( volume_iterator != volume_iterator.begin() );
    TEST_ASSERT( volume_iterator == volume_iterator.end() );

    // Make an iterator for the nodes.
    DataTransferKit::EntityIterator node_iterator = 
	entity_set->entityIterator( 0, all_pred );

    // Test the node iterator.
    TEST_EQUALITY( node_iterator.size(), num_nodes );
    TEST_ASSERT( node_iterator == node_iterator.begin() );
    TEST_ASSERT( node_iterator != node_iterator.end() );
    DataTransferKit::EntityIterator node_begin = node_iterator.begin();
    DataTransferKit::EntityIterator node_end = node_iterator.end();
    auto node_id_it = node_ids.begin();
    for ( node_iterator = node_begin;
	  node_iterator != node_end;
	  ++node_iterator, ++node_id_it )
    {
	TEST_EQUALITY( node_iterator->id(), *node_id_it );
    }

    // Get each entity and check.
    DataTransferKit::Entity set_hex;
    entity_set->getEntity( hex_id, space_dim, set_hex );
    TEST_EQUALITY( set_hex.id(), hex_id );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	DataTransferKit::Entity set_node;
	entity_set->getEntity( node_ids[i], 0, set_node );
	TEST_EQUALITY( set_node.id(), node_ids[i] );
    }

    // Check the adjacency function.
    Teuchos::Array<DataTransferKit::Entity> hex_adjacent_volumes;
    entity_set->getAdjacentEntities( set_hex,
				     space_dim,
				     hex_adjacent_volumes );
    TEST_EQUALITY( 0, hex_adjacent_volumes.size() );

    Teuchos::Array<DataTransferKit::Entity> hex_adjacent_nodes;
    entity_set->getAdjacentEntities( set_hex, 0, hex_adjacent_nodes );
    TEST_EQUALITY( num_nodes, hex_adjacent_nodes.size() );
    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	TEST_EQUALITY( hex_adjacent_nodes[i].id(), node_ids[i] );
    }

    for ( unsigned i = 0; i < num_nodes; ++i )
    {
	Teuchos::Array<DataTransferKit::Entity> node_adjacent_volumes;
	entity_set->getAdjacentEntities( hex_adjacent_nodes[i],
					 space_dim,
					 node_adjacent_volumes );
	TEST_EQUALITY( 1, node_adjacent_volumes.size() );
	TEST_EQUALITY( node_adjacent_volumes[0].id(), hex_id );
    }
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntity, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    int part_1_id = part_1.mesh_meta_data_ordinal();
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );
    int part_2_id = part_2.mesh_meta_data_ordinal();

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    int num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( int i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Create a DTK entity for the hex.
    DataTransferKit::Entity dtk_entity = 
	DataTransferKit::STKMeshEntity( hex_entity, bulk_data.ptr() );

    // Print out the entity.
    Teuchos::RCP<Teuchos::FancyOStream>
	fancy_out = Teuchos::VerboseObjectBase::getDefaultOStream();
    dtk_entity.describe( *fancy_out );
    
    // Test the entity.
    TEST_EQUALITY( hex_id, dtk_entity.id() );
    TEST_EQUALITY( comm_rank, dtk_entity.ownerRank() );
    TEST_EQUALITY( 3, dtk_entity.topologicalDimension() );
    TEST_EQUALITY( space_dim, dtk_entity.physicalDimension() );
    TEST_ASSERT( dtk_entity.inBlock(part_1_id) );
    TEST_ASSERT( !dtk_entity.inBlock(part_2_id) );
    TEST_ASSERT( dtk_entity.onBoundary(part_1_id) );
    TEST_ASSERT( !dtk_entity.onBoundary(part_2_id) );

    Teuchos::RCP<DataTransferKit::EntityExtraData> extra_data =
	dtk_entity.extraData();
    TEST_EQUALITY( hex_entity,
		   Teuchos::rcp_dynamic_cast<DataTransferKit::STKMeshEntityExtraData>(
		       extra_data)->d_stk_entity );

    Teuchos::Tuple<double,6> hex_bounds;
    dtk_entity.boundingBox( hex_bounds );
    TEST_EQUALITY( 0.0, hex_bounds[0] );
    TEST_EQUALITY( 0.0, hex_bounds[1] );
    TEST_EQUALITY( 0.0, hex_bounds[2] );
    TEST_EQUALITY( 1.0, hex_bounds[3] );
    TEST_EQUALITY( 1.0, hex_bounds[4] );
    TEST_EQUALITY( 1.0, hex_bounds[5] );
}
int main (int argc, char* argv[])
{
    ApplicationsLib::LogogSetup logog_setup;

    TCLAP::CmdLine cmd("The tool computes the area per node of the surface mesh"
        " and writes the information as txt and csv data.", ' ', "0.1");
    TCLAP::ValueArg<std::string> mesh_in("i", "mesh-input-file",
        "the name of the file containing the input mesh", true,
        "", "file name of input mesh");
    cmd.add(mesh_in);
    TCLAP::ValueArg<std::string> id_prop_name("", "id-prop-name",
        "the name of the property containing the id information", false,
        "OriginalSubsurfaceNodeIDs", "property name");
    cmd.add(id_prop_name);
    TCLAP::ValueArg<std::string> out_base_fname("p", "output-base-name",
        "the path and base file name the output will be written to", false,
        "", "output path and base name as one string");
    cmd.add(out_base_fname);

    cmd.parse(argc, argv);

    std::unique_ptr<MeshLib::Mesh> surface_mesh(
        MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
    INFO("Mesh read: %u nodes, %u elements.", surface_mesh->getNNodes(),
         surface_mesh->getNElements());
    // ToDo check if mesh is read correct and if the mesh is a surface mesh

    // check if a node property containing the subsurface ids is available
    boost::optional<MeshLib::PropertyVector<std::size_t> const&> orig_node_ids(
        surface_mesh->getProperties().getPropertyVector<std::size_t>(
            id_prop_name.getValue()));
    // if the node property is not available generate it
    if (!orig_node_ids) {
        boost::optional<MeshLib::PropertyVector<std::size_t>&> node_ids(
            surface_mesh->getProperties().createNewPropertyVector<std::size_t>(
                id_prop_name.getValue(), MeshLib::MeshItemType::Node, 1));
        if (!node_ids) {
            ERR("Fatal error: could not create property.");
            return EXIT_FAILURE;
        }
        node_ids->resize(surface_mesh->getNNodes());
        std::iota(node_ids->begin(), node_ids->end(), 0);
        orig_node_ids = node_ids;
    }

    std::vector<double> areas(
        MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*surface_mesh));

    // pack area and node id together
    std::vector<std::pair<std::size_t, double>> ids_and_areas;
    std::transform(orig_node_ids->cbegin(), orig_node_ids->cend(),
                   areas.cbegin(), std::back_inserter(ids_and_areas),
                   std::make_pair<std::size_t const&, double const&>);

    // generate file names for output
    std::string path(out_base_fname.getValue());
    if (path.empty())
        path = BaseLib::dropFileExtension(mesh_in.getValue());
    std::string const id_and_area_fname(path+".txt");
    std::string const csv_fname(path+".csv");

    writeToFile(id_and_area_fname, csv_fname, ids_and_areas,
                surface_mesh->getNodes());

    return EXIT_SUCCESS;
}
示例#10
0
MeshLib::Mesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* grid, std::string const& mesh_name)
{
	if (!grid)
		return nullptr;

	// set mesh nodes
	const size_t nNodes = grid->GetPoints()->GetNumberOfPoints();
	std::vector<MeshLib::Node*> nodes(nNodes);
	double* coords = nullptr;
	for (size_t i = 0; i < nNodes; i++)
	{
		coords = grid->GetPoints()->GetPoint(i);
		nodes[i] = new MeshLib::Node(coords[0], coords[1], coords[2]);
	}

	// set mesh elements
	const size_t nElems = grid->GetNumberOfCells();
	std::vector<MeshLib::Element*> elements(nElems);
	vtkDataArray* scalars = grid->GetCellData()->GetScalars("MaterialIDs");
	for (size_t i = 0; i < nElems; i++)
	{
		MeshLib::Element* elem;
		const size_t nElemNodes (grid->GetCell(i)->GetNumberOfPoints());
		std::vector<unsigned> node_ids(nElemNodes);
		for (size_t j=0; j<nElemNodes; j++)
			node_ids[j] = grid->GetCell(i)->GetPointId(j);
		const unsigned material = (scalars) ? static_cast<int>(scalars->GetComponent(i,0)) : 0;

		int cell_type = grid->GetCellType(i);
		switch (cell_type)
		{
		case VTK_LINE: {
			MeshLib::Node** line_nodes = new MeshLib::Node*[2];
			line_nodes[0] = nodes[node_ids[0]];
			line_nodes[1] = nodes[node_ids[1]];
			elem = new MeshLib::Line(line_nodes, material);
			break;
		}
		case VTK_TRIANGLE: {
			MeshLib::Node** tri_nodes = new MeshLib::Node*[3];
			for (unsigned k(0); k<3; k++)
				tri_nodes[k] = nodes[node_ids[k]];
			elem = new MeshLib::Tri(tri_nodes, material);
			break;
		}
		case VTK_QUAD: {
			MeshLib::Node** quad_nodes = new MeshLib::Node*[4];
			for (unsigned k(0); k<4; k++)
				quad_nodes[k] = nodes[node_ids[k]];
			elem = new MeshLib::Quad(quad_nodes, material);
			break;
		}
		case VTK_PIXEL: {
			MeshLib::Node** quad_nodes = new MeshLib::Node*[4];
			quad_nodes[0] = nodes[node_ids[0]];
			quad_nodes[1] = nodes[node_ids[1]];
			quad_nodes[2] = nodes[node_ids[3]];
			quad_nodes[3] = nodes[node_ids[2]];
			elem = new MeshLib::Quad(quad_nodes, material);
			break;
		}
		case VTK_TETRA: {
			MeshLib::Node** tet_nodes = new MeshLib::Node*[4];
			for (unsigned k(0); k<4; k++)
				tet_nodes[k] = nodes[node_ids[k]];
			elem = new MeshLib::Tet(tet_nodes, material);
			break;
		}
		case VTK_HEXAHEDRON: {
			MeshLib::Node** hex_nodes = new MeshLib::Node*[8];
			for (unsigned k(0); k<8; k++)
				hex_nodes[k] = nodes[node_ids[k]];
			elem = new MeshLib::Hex(hex_nodes, material);
			break;
		}
		case VTK_VOXEL: {
			MeshLib::Node** voxel_nodes = new MeshLib::Node*[8];
			voxel_nodes[0] = nodes[node_ids[0]];
			voxel_nodes[1] = nodes[node_ids[1]];
			voxel_nodes[2] = nodes[node_ids[3]];
			voxel_nodes[3] = nodes[node_ids[2]];
			voxel_nodes[4] = nodes[node_ids[4]];
			voxel_nodes[5] = nodes[node_ids[5]];
			voxel_nodes[6] = nodes[node_ids[7]];
			voxel_nodes[7] = nodes[node_ids[6]];
			elem = new MeshLib::Hex(voxel_nodes, material);
			break;
		}
		case VTK_PYRAMID: {
			MeshLib::Node** pyramid_nodes = new MeshLib::Node*[5];
			for (unsigned k(0); k<5; k++)
				pyramid_nodes[k] = nodes[node_ids[k]];
			elem = new MeshLib::Pyramid(pyramid_nodes, material);
			break;
		}
		case VTK_WEDGE: {
			MeshLib::Node** prism_nodes = new MeshLib::Node*[6];
			for (unsigned i=0; i<3; ++i)
			{
				prism_nodes[i] = nodes[node_ids[i+3]];
				prism_nodes[i+3] = nodes[node_ids[i]];
			}
			elem = new MeshLib::Prism(prism_nodes, material);
			break;
		}
		default:
			ERR("VtkMeshConverter::convertUnstructuredGrid(): Unknown mesh element type \"%d\".", cell_type);
			return nullptr;
		}

		elements[i] = elem;
	}

	MeshLib::Mesh* mesh = new MeshLib::Mesh(mesh_name, nodes, elements);
	convertScalarArrays(*grid, *mesh);

	return mesh;
}
示例#11
0
void assemble_elem_matrices_and_vectors(stk::mesh::BulkData& mesh,
                                        stk::mesh::FieldBase& field,
                                        stk::linsys::DofMapper& dof_mapper,
                                        fei::Matrix& matrix,
                                        fei::Vector& rhs)
{
  stk::mesh::fem::FEMMetaData &fem = stk::mesh::fem::FEMMetaData::get(mesh);
  const stk::mesh::EntityRank element_rank = fem.element_rank();

  const std::vector<stk::mesh::Bucket*>& mesh_buckets = mesh.buckets(element_rank);

  std::vector<stk::mesh::Bucket*> part_buckets;
  stk::mesh::Selector select_owned(stk::mesh::MetaData::get(mesh).locally_owned_part());
  stk::mesh::get_buckets(select_owned, mesh_buckets, part_buckets);

  int field_id = dof_mapper.get_field_id(field);

  stk::mesh::Entity& first_entity = *(part_buckets[0]->begin());
  stk::mesh::PairIterRelation rel = first_entity.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
  int num_nodes_per_elem = rel.second - rel.first;

  fei::SharedPtr<fei::MatrixGraph> matgraph = matrix.getMatrixGraph();
  int pattern_id = matgraph->definePattern(num_nodes_per_elem, stk::mesh::fem::FEMMetaData::NODE_RANK, field_id);

  std::vector<int> node_ids(num_nodes_per_elem);

  const int field_size = dof_mapper.get_fei_VectorSpace()->getFieldSize(field_id);
  const int matsize = num_nodes_per_elem*field_size*num_nodes_per_elem*field_size;
  const int vecsize = num_nodes_per_elem*field_size;

  std::vector<double> elem_matrix_1d(matsize, 0);
  std::vector<double*> elem_matrix_2d(vecsize);

  std::vector<double> elem_vector(vecsize, 0);

  for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
    elem_matrix_2d[i] = &elem_matrix_1d[i*vecsize];
  }

  //fill our dummy elem-matrix:
  //This dummy matrix will be the same for every element. A real application
  //would form a different elem-matrix for each element.
  for(size_t i=0; i<elem_matrix_2d.size(); ++i) {
    double* row = elem_matrix_2d[i];
    if (i>=1) row[i-1] = -1;
    row[i] = 2;
    if (i<elem_matrix_2d.size()-1) row[i+1] = -1;

    elem_vector[i] = 1;
  }

  std::vector<int> eqn_indices(vecsize);

  for(size_t i=0; i<part_buckets.size(); ++i) {
    stk::mesh::Bucket::iterator
      b_iter = part_buckets[i]->begin(),
             b_end  = part_buckets[i]->end();
    for(; b_iter != b_end; ++b_iter) {
      stk::mesh::Entity& elem = *b_iter;
      rel = elem.relations(stk::mesh::fem::FEMMetaData::NODE_RANK);
      for(int j=0; rel.first != rel.second; ++rel.first, ++j) {
        node_ids[j] = rel.first->entity()->identifier();
      }

      matgraph->getPatternIndices(pattern_id, &node_ids[0], eqn_indices);

      matrix.sumIn(vecsize, &eqn_indices[0], vecsize, &eqn_indices[0],
                    &elem_matrix_2d[0]);
      rhs.sumIn(vecsize, &eqn_indices[0], &elem_vector[0]);
    }
  }
}
//---------------------------------------------------------------------------//
// Hex-8 test.
TEUCHOS_UNIT_TEST( STKMeshEntityIterator, hex_8_test )
{
    // Extract the raw mpi communicator.
    Teuchos::RCP<const Teuchos::Comm<int> > comm = getDefaultComm<int>();
    Teuchos::RCP<const Teuchos::MpiComm<int> > mpi_comm = 
	Teuchos::rcp_dynamic_cast< const Teuchos::MpiComm<int> >( comm );
    Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > opaque_comm = 
	mpi_comm->getRawMpiComm();
    MPI_Comm raw_comm = (*opaque_comm)();

    // Create meta data.
    int space_dim = 3;
    stk::mesh::MetaData meta_data( space_dim );

    // Make two parts.
    std::string p1_name = "part_1";
    stk::mesh::Part& part_1 = meta_data.declare_part( p1_name );
    stk::mesh::set_topology( part_1, stk::topology::HEX_8 );
    std::string p2_name = "part_2";
    stk::mesh::Part& part_2 = meta_data.declare_part( p2_name );

    // Make a coordinate field.
    stk::mesh::Field<double, stk::mesh::Cartesian3d>& coord_field =
	meta_data.declare_field<
	stk::mesh::Field<double, stk::mesh::Cartesian3d> >(
	    stk::topology::NODE_RANK, "coordinates");
    meta_data.set_coordinate_field( &coord_field );
    stk::mesh::put_field( coord_field, part_1 );
    meta_data.commit();

    // Create bulk data.
    Teuchos::RCP<stk::mesh::BulkData> bulk_data =
	Teuchos::rcp( new stk::mesh::BulkData(meta_data,raw_comm) );
    bulk_data->modification_begin();

    // Make a hex-8.
    int comm_rank = comm->getRank();
    stk::mesh::EntityId hex_id = 23 + comm_rank;
    stk::mesh::Entity hex_entity = 
	bulk_data->declare_entity( stk::topology::ELEM_RANK, hex_id, part_1 );
    int num_nodes = 8;
    Teuchos::Array<stk::mesh::EntityId> node_ids( num_nodes );
    Teuchos::Array<stk::mesh::Entity> nodes( num_nodes );
    for ( int i = 0; i < num_nodes; ++i )
    {
	node_ids[i] = num_nodes*comm_rank + i + 5;
	nodes[i] = bulk_data->declare_entity( 
	    stk::topology::NODE_RANK, node_ids[i], part_1 );
	bulk_data->declare_relation( hex_entity, nodes[i], i );
    }
    bulk_data->modification_end();

    // Create the node coordinates.
    double* node_coords = 0;
    node_coords = stk::mesh::field_data( coord_field, nodes[0] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[1] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[2] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[3] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 0.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[4] );
    node_coords[0] = 0.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[5] );
    node_coords[0] = 1.0;
    node_coords[1] = 0.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[6] );
    node_coords[0] = 1.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    node_coords = stk::mesh::field_data( coord_field, nodes[7] );
    node_coords[0] = 0.0;
    node_coords[1] = 1.0;
    node_coords[2] = 1.0;

    // Make a list of hexes.
    unsigned num_hex = 2;
    std::vector<stk::mesh::Entity> hex_entities( num_hex, hex_entity );

    // Make a range for the iterators.
    Teuchos::RCP<DataTransferKit::STKMeshEntityIteratorRange> iterator_range =
	Teuchos::rcp( new DataTransferKit::STKMeshEntityIteratorRange() );
    iterator_range->d_stk_entities = hex_entities;
    
    // Test the name predicate for part 1.
    DataTransferKit::STKPartNamePredicate part_1_name_pred( 
	Teuchos::Array<std::string>(1,p1_name), bulk_data );
    DataTransferKit::EntityIterator part_1_name_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_name_pred.getFunction() );
    TEST_EQUALITY( part_1_name_iterator.size(), num_hex );

    // Test the name predicate for part 2.
    DataTransferKit::STKPartNamePredicate part_2_name_pred( 
	Teuchos::Array<std::string>(2,p2_name), bulk_data );
    DataTransferKit::EntityIterator part_2_name_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_name_pred.getFunction() );
    TEST_EQUALITY( part_2_name_iterator.size(), 0 );

    // Test the part vector predicate for part 1.
    stk::mesh::PartVector p1_vec( 1, &part_1 );
    DataTransferKit::STKPartVectorPredicate part_1_vec_pred( p1_vec );
    DataTransferKit::EntityIterator part_1_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_vec_pred.getFunction() );
    TEST_EQUALITY( part_1_vec_iterator.size(), num_hex );

    // Test the part vector predicate for part 2.
    stk::mesh::PartVector p2_vec( 2, &part_2 );
    DataTransferKit::STKPartVectorPredicate part_2_vec_pred( p2_vec );
    DataTransferKit::EntityIterator part_2_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_vec_pred.getFunction() );
    TEST_EQUALITY( part_2_vec_iterator.size(), 0 );

    // Test a part vector with 2 part 1's.
    stk::mesh::PartVector p11_vec( 2, &part_1 );
    DataTransferKit::STKPartVectorPredicate part_11_vec_pred( p11_vec );
    DataTransferKit::EntityIterator part_11_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_11_vec_pred.getFunction() );
    TEST_EQUALITY( part_11_vec_iterator.size(), num_hex );

    // Test a part vector with a part 1 and part 2
    stk::mesh::PartVector p12_vec( 2 );
    p12_vec[0] = &part_1;
    p12_vec[1] = &part_2;
    DataTransferKit::STKPartVectorPredicate part_12_vec_pred( p12_vec );
    DataTransferKit::EntityIterator part_12_vec_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_12_vec_pred.getFunction() );
    TEST_EQUALITY( part_12_vec_iterator.size(), 0 );

    // Test the part selector predicate for part 1.
    stk::mesh::Selector p1_sel( part_1 );
    DataTransferKit::STKSelectorPredicate part_1_sel_pred( p1_sel );
    DataTransferKit::EntityIterator part_1_sel_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_1_sel_pred.getFunction() );
    TEST_EQUALITY( part_1_sel_iterator.size(), num_hex );

    // Test the part selector predicate for part 2.
    stk::mesh::Selector p2_sel( part_2 );
    DataTransferKit::STKSelectorPredicate part_2_sel_pred( p2_sel );
    DataTransferKit::EntityIterator part_2_sel_iterator =
	DataTransferKit::STKMeshEntityIterator(
	    iterator_range, bulk_data, part_2_sel_pred.getFunction() );
    TEST_EQUALITY( part_2_sel_iterator.size(), 0 );
}