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); } } } }
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(); }
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; }
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 ); } } }
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; }
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; }
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 ); }