Gear::Gear( stk::mesh::MetaData & S , const std::string & name , const GearFields & gear_fields , const double center[] , const double rad_min , const double rad_max , const size_t rad_num , const double z_min , const double z_max , const size_t z_num , const size_t angle_num , const int turn_direction ) : m_mesh_meta_data( S ), m_mesh( NULL ), m_gear( S.declare_part(std::string("Gear_").append(name), stk::topology::ELEMENT_RANK) ), m_surf( S.declare_part(std::string("Surf_").append(name), m_mesh_meta_data.side_rank()) ), m_gear_coord( gear_fields.gear_coord ), m_model_coord(gear_fields.model_coord ) { enum { SpatialDimension = GearFields::SpatialDimension }; stk::io::put_io_part_attribute(m_gear); stk::io::put_io_part_attribute(m_surf); stk::mesh::set_topology( m_gear, stk::topology::HEX_8 ); stk::mesh::set_topology( m_surf, stk::topology::QUAD_8 ); // Meshing parameters for this gear: const double TWO_PI = 2.0 * acos( static_cast<double>(-1.0) ); m_center[0] = center[0] ; m_center[1] = center[1] ; m_center[2] = center[2] ; m_z_min = z_min ; m_z_max = z_max ; m_z_inc = (z_max - z_min) / static_cast<double>(z_num - 1); m_rad_min = rad_min ; m_rad_max = rad_max ; m_rad_inc = (rad_max - rad_min) / static_cast<double>(rad_num - 1); m_ang_inc = TWO_PI / static_cast<double>(angle_num) ; m_rad_num = rad_num ; m_z_num = z_num ; m_angle_num = angle_num ; m_turn_dir = turn_direction ; }
// ======================================================================== void process_surface_entity(Ioss::SideSet *sset, stk::mesh::MetaData &meta, stk::mesh::EntityRank sset_rank) { assert(sset->type() == Ioss::SIDESET); Ioss::SideSet *fs = dynamic_cast<Ioss::SideSet *>(sset); assert(fs != NULL); const Ioss::SideBlockContainer& blocks = fs->get_side_blocks(); stk::io::default_part_processing(blocks, meta, sset_rank); stk::mesh::Part* const fs_part = meta.get_part(sset->name()); STKIORequire(fs_part != NULL); stk::mesh::Field<double, stk::mesh::ElementNode> *distribution_factors_field = NULL; bool surface_df_defined = false; // Has the surface df field been defined yet? int block_count = sset->block_count(); for (int i=0; i < block_count; i++) { Ioss::SideBlock *side_block = sset->get_block(i); if (stk::io::include_entity(side_block)) { stk::mesh::Part * const side_block_part = meta.get_part(side_block->name()); STKIORequire(side_block_part != NULL); meta.declare_part_subset(*fs_part, *side_block_part); const stk::mesh::EntityRank part_rank = side_block_part->primary_entity_rank(); if (side_block->field_exists("distribution_factors")) { if (!surface_df_defined) { std::string field_name = sset->name() + "_distribution_factors"; distribution_factors_field = &meta.declare_field<stk::mesh::Field<double, stk::mesh::ElementNode> >(static_cast<stk::topology::rank_t>(part_rank), field_name); stk::io::set_distribution_factor_field(*fs_part, *distribution_factors_field); surface_df_defined = true; } stk::io::set_distribution_factor_field(*side_block_part, *distribution_factors_field); int side_node_count = side_block->topology()->number_nodes(); stk::mesh::put_field(*distribution_factors_field, *side_block_part, side_node_count); } /** \todo IMPLEMENT truly handle fields... For this case we * are just defining a field for each transient field that is * present in the mesh... */ stk::io::define_io_fields(side_block, Ioss::Field::TRANSIENT, *side_block_part, part_rank); } } }
void clone_part_to_other_meta(const stk::mesh::Part &oldPart, stk::mesh::MetaData &newMeta) { stk::mesh::Part *newPart = create_new_part(oldPart.name(), oldPart.topology(), newMeta); newMeta.set_part_id(*newPart, oldPart.id()); copy_part_supersets(oldPart, *newPart, newMeta); copy_io_part_attributes(oldPart, *newPart); }
void createNodalVectorFields(stk::mesh::MetaData& meshMetaData) { createNodalVectorField(meshMetaData, "disp"); createNodalVectorField(meshMetaData, "vel"); createNodalVectorField(meshMetaData, "acc"); createNodalVectorField(meshMetaData, "force"); meshMetaData.commit(); }
void copy_fields(const stk::mesh::MetaData &oldMeta, stk::mesh::MetaData &newMeta) { const stk::mesh::FieldVector &fields = oldMeta.get_fields(); for(size_t i = 0; i < fields.size(); i++) { stk::mesh::FieldBase* newField = clone_field(*fields[i], newMeta); copy_field_restrictions(*fields[i], newMeta, newField); } }
GearFields::GearFields( stk::mesh::MetaData & S ) : gear_coord( S.declare_field<CylindricalField>(stk::topology::NODE_RANK, std::string("gear_coordinates") ) ), model_coord( S.declare_field<CartesianField>(stk::topology::NODE_RANK, std::string("coordinates") ) ) { const stk::mesh::Part & universe = S.universal_part(); stk::mesh::put_field( gear_coord , universe , SpatialDimension ); stk::mesh::put_field( model_coord , universe , SpatialDimension ); }
// ======================================================================== void process_nodeblocks(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks(); assert(node_blocks.size() == 1); Ioss::NodeBlock *nb = node_blocks[0]; assert(nb->field_exists("mesh_model_coordinates")); Ioss::Field coordinates = nb->get_field("mesh_model_coordinates"); int spatial_dim = coordinates.transformed_storage()->component_count(); stk::mesh::Field<double,stk::mesh::Cartesian> & coord_field = meta.declare_field<stk::mesh::Field<double,stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates"); stk::mesh::put_field( coord_field, meta.universal_part(), spatial_dim); /** \todo IMPLEMENT truly handle fields... For this case we are * just defining a field for each transient field that is present * in the mesh... */ stk::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk::topology::NODE_RANK); }
void copy_field_restrictions(const stk::mesh::FieldBase& field, stk::mesh::MetaData& newMeta, stk::mesh::FieldBase* newField) { const stk::mesh::FieldRestrictionVector& oldRestrictions = field.restrictions(); for(const stk::mesh::FieldRestriction& res : oldRestrictions) { // stk::mesh::Selector selectNewParts = res.selector().clone_for_different_mesh(newMeta); stk::mesh::Selector selectNewParts = res.selector(); // WRONG: needs to use above function newMeta.declare_field_restriction(*newField, selectNewParts, res.num_scalars_per_entity(), res.dimension(), field.get_initial_value()); } }
// ======================================================================== void process_sidesets(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const stk::mesh::EntityRank side_rank = meta.side_rank(); const Ioss::SideSetContainer& side_sets = region.get_sidesets(); stk::io::default_part_processing(side_sets, meta, side_rank); for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); it != side_sets.end(); ++it) { Ioss::SideSet *entity = *it; if (stk::io::include_entity(entity)) { process_surface_entity(entity, meta, side_rank); } } }
void heterogeneous_mesh_meta_data( stk::mesh::MetaData & meta_data , const VectorFieldType & node_coord ) { stk::mesh::Part & universal = meta_data.universal_part(); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("hexes", stk::topology::HEX_8)); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("wedges", stk::topology::WEDGE_6)); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("tets", stk::topology::TET_4)); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("pyramids", stk::topology::PYRAMID_5)); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("quad_shells", stk::topology::SHELL_QUAD_4)); stk::io::put_io_part_attribute(meta_data.declare_part_with_topology("tri_shells", stk::topology::SHELL_TRI_3)); const stk::mesh::FieldBase::Restriction & res = stk::mesh::find_restriction(node_coord, stk::topology::NODE_RANK , universal ); if ( res.num_scalars_per_entity() != 3 ) { std::ostringstream msg ; msg << "stk_mesh/unit_tests/heterogenous_mesh_meta_data FAILED, coordinate dimension must be 3 != " << res.num_scalars_per_entity() ; throw std::runtime_error( msg.str() ); } }
// ======================================================================== void process_nodesets(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const Ioss::NodeSetContainer& node_sets = region.get_nodesets(); stk::io::default_part_processing(node_sets, meta, stk::topology::NODE_RANK); /** \todo REFACTOR should "distribution_factor" be a default field * that is automatically declared on all objects that it exists * on as is done in current framework? */ stk::mesh::Field<double> & distribution_factors_field = meta.declare_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors"); /** \todo REFACTOR How to associate distribution_factors field * with the nodeset part if a node is a member of multiple * nodesets */ for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); it != node_sets.end(); ++it) { Ioss::NodeSet *entity = *it; if (stk::io::include_entity(entity)) { stk::mesh::Part* const part = meta.get_part(entity->name()); STKIORequire(part != NULL); STKIORequire(entity->field_exists("distribution_factors")); stk::mesh::put_field(distribution_factors_field, *part); /** \todo IMPLEMENT truly handle fields... For this case we * are just defining a field for each transient field that is * present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT, *part, part->primary_entity_rank() ) ; } } }
// ======================================================================== void process_elementblocks(Ioss::Region ®ion, stk::mesh::MetaData &meta) { const stk::mesh::EntityRank element_rank = stk::topology::ELEMENT_RANK; const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); stk::io::default_part_processing(elem_blocks, meta, element_rank); // Parts were created above, now handle element block specific // information (topology, attributes, ...); for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); it != elem_blocks.end(); ++it) { Ioss::ElementBlock *entity = *it; if (stk::io::include_entity(entity)) { stk::mesh::Part* const part = meta.get_part(entity->name()); STKIORequire(part != NULL); const stk::mesh::EntityRank part_rank = part->primary_entity_rank(); // Element Block attributes (if any)... /** \todo IMPLEMENT truly handle attribute fields... For this * case we are just defining a field for each attribute field * that is present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE, *part, part_rank); /** \todo IMPLEMENT truly handle fields... For this case we * are just defining a field for each transient field that is * present in the mesh... */ stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT, *part, part_rank); } } }
PromotedElementIO::PromotedElementIO( const ElementDescription& elem, const stk::mesh::MetaData& metaData, stk::mesh::BulkData& bulkData, const stk::mesh::PartVector& baseParts, const std::string& fileName, const VectorFieldType& coordField ) : elem_(elem), metaData_(metaData), bulkData_(bulkData), fileName_(fileName), coordinates_(coordField), nDim_(metaData.spatial_dimension()) { Ioss::Init::Initializer init_db; Ioss::PropertyManager properties; Ioss::Property intSizeAPI("INTEGER_SIZE_API", 8); properties.add(intSizeAPI); Ioss::Property intSizeDB("INTEGER_SIZE_DB", 8); properties.add(intSizeDB); databaseIO = Ioss::IOFactory::create( "exodus", fileName_, Ioss::WRITE_RESULTS, bulkData_.parallel(), properties ); ThrowRequire(databaseIO != nullptr && databaseIO->ok(true)); output_ = make_unique<Ioss::Region>(databaseIO, "HighOrderOutput"); //sink for databaseIO ThrowRequire(output_ != nullptr); const stk::mesh::BucketVector& elem_buckets = bulkData_.get_buckets( stk::topology::ELEM_RANK, stk::mesh::selectUnion(baseParts)); size_t numSubElems = num_sub_elements(nDim_, elem_buckets, elem_.polyOrder); std::vector<stk::mesh::EntityId> subElemIds; bulkData.generate_new_ids(stk::topology::ELEM_RANK, numSubElems, subElemIds); ThrowRequire(subElemIds.size() == numSubElems); superElemParts_ = super_elem_part_vector(baseParts); ThrowRequireMsg(part_vector_is_valid_and_nonempty(superElemParts_), "Not all element parts have a super-element mirror"); output_->begin_mode(Ioss::STATE_DEFINE_MODEL); write_node_block_definitions(superElemParts_); write_elem_block_definitions(superElemParts_); write_sideset_definitions(baseParts); output_->end_mode(Ioss::STATE_DEFINE_MODEL); output_->begin_mode(Ioss::STATE_MODEL); write_coordinate_list(superElemParts_); write_element_connectivity(superElemParts_, subElemIds); write_sideset_connectivity(baseParts); output_->end_mode(Ioss::STATE_MODEL); }
void copy_part_supersets(const stk::mesh::Part &oldPart, stk::mesh::Part &newPart, stk::mesh::MetaData &newMeta) { stk::mesh::OrdinalVector oldSupersets = get_part_supersets(oldPart); for(stk::mesh::PartOrdinal partOrd : oldSupersets) newMeta.declare_part_subset(newMeta.get_part(partOrd), newPart); }
void copy_parts(const stk::mesh::MetaData &oldMeta, stk::mesh::MetaData &newMeta) { const stk::mesh::PartVector &allParts = oldMeta.get_mesh_parts(); for(size_t i = 0; i < allParts.size(); i++) clone_part_to_other_meta(*allParts[i], newMeta); }
void make_small_hybrid_mesh(stk::mesh::MetaData &meta, stk::mesh::BulkData &mesh, bool user_attempt_no_induce = false, bool user_parts_force_no_induce = true) { stk::ParallelMachine pm = MPI_COMM_WORLD; int p_size = stk::parallel_machine_size(pm); if(p_size > 2) { return; } const unsigned p_rank = mesh.parallel_rank(); stk::mesh::Part * hexPart = &meta.get_topology_root_part(stk::topology::HEX_8); stk::mesh::Part * pyrPart = &meta.get_topology_root_part(stk::topology::PYRAMID_5); stk::mesh::Part * tetPart = &meta.get_topology_root_part(stk::topology::TET_4); if (user_attempt_no_induce) { hexPart = &meta.declare_part_with_topology("my_hex_part",stk::topology::HEX_8, user_parts_force_no_induce); pyrPart = &meta.declare_part_with_topology("my_pyr_part",stk::topology::PYRAMID_5, user_parts_force_no_induce); tetPart = &meta.declare_part_with_topology("my_tet_part",stk::topology::TET_4, user_parts_force_no_induce); EXPECT_EQ(user_parts_force_no_induce, hexPart->force_no_induce()); EXPECT_EQ(user_parts_force_no_induce, pyrPart->force_no_induce()); EXPECT_EQ(user_parts_force_no_induce, tetPart->force_no_induce()); } meta.commit(); const size_t numHex = 1; stk::mesh::EntityIdVector hexNodeIDs[] { { 1, 2, 3, 4, 5, 6, 7, 8 } }; stk::mesh::EntityId hexElemIDs[] = { 1 }; const size_t numPyr = 1; stk::mesh::EntityIdVector pyrNodeIDs[] { { 5, 6, 7, 8, 9 } }; stk::mesh::EntityId pyrElemIDs[] = { 2 }; const size_t numTet = 4; stk::mesh::EntityIdVector tetNodeIDs[] { { 7, 8, 9, 12 }, { 6, 9, 10, 7 }, { 7, 9, 10, 12 }, { 7, 12, 10, 11 } }; stk::mesh::EntityId tetElemIDs[] = { 3, 4, 5, 6 }; // list of triplets: (owner-proc, shared-nodeID, sharing-proc) std::vector< std::vector<unsigned> > shared_nodeIDs_and_procs { { 0, 5, 1 }, // proc 0 { 0, 6, 1 }, { 0, 7, 1 }, { 0, 8, 1 }, { 1, 5, 0 }, // proc 1 { 1, 6, 0 }, { 1, 7, 0 }, { 1, 8, 0 } }; mesh.modification_begin(); if (0 == p_rank) { for (size_t i = 0; i < numHex; ++i) { stk::mesh::declare_element(mesh, *hexPart, hexElemIDs[i], hexNodeIDs[i]); } } if ( (1 == p_rank) || (1 == p_size) ) { // setup the pyramids/tets for either np 2 or serial for (size_t i = 0; i < numPyr; ++i) { stk::mesh::declare_element(mesh, *pyrPart, pyrElemIDs[i], pyrNodeIDs[i]); } for (size_t i = 0; i < numTet; ++i) { stk::mesh::declare_element(mesh, *tetPart, tetElemIDs[i], tetNodeIDs[i]); } } if (p_size > 1) { for (size_t nodeIdx = 0, end = shared_nodeIDs_and_procs.size(); nodeIdx < end; ++nodeIdx) { if (p_rank == shared_nodeIDs_and_procs[nodeIdx][0]) { stk::mesh::EntityId nodeID = shared_nodeIDs_and_procs[nodeIdx][1]; int sharingProc = shared_nodeIDs_and_procs[nodeIdx][2]; stk::mesh::Entity node = mesh.get_entity(stk::topology::NODE_RANK, nodeID); mesh.add_node_sharing(node, sharingProc); } } } mesh.modification_end(); }
void stk::app::use_case_14_declare_fields(Fields &fields, stk::mesh::MetaData &meta_data) { // Nodal vector fields fields.model_coordinates = &declare_vector_field_on_all_nodes(meta_data, "coordinates", SpatialDim); fields.coordinates_field = &declare_vector_field_on_all_nodes(meta_data, "current_coordinates", SpatialDim); fields.velocity_field = &declare_vector_field_on_all_nodes(meta_data, "velocity", SpatialDim); fields.fint_field = &declare_vector_field_on_all_nodes(meta_data, "force_internal", SpatialDim); // Element vector fields: fields.Vorticity = &declare_vector_field_on_all_elements(meta_data, "Vorticity" , SpatialDim); // Element scalar fields: fields.Shear_Modulus = &declare_scalar_field_on_all_elements(meta_data, "shear_modulus" ); fields.Dilatational_Modulus = &declare_scalar_field_on_all_elements(meta_data, "dilatational_modulus"); fields.Material_eff_twomu = &declare_scalar_field_on_all_elements(meta_data, "material_effictive_two_mu"); fields.Material_eff_bulk_mod = &declare_scalar_field_on_all_elements(meta_data, "material_effective_bulk_moduli"); fields.Midstep_volume = &declare_scalar_field_on_all_elements(meta_data, "mid_step_volume"); fields.Element_time_step = &declare_scalar_field_on_all_elements(meta_data, "element_time_step"); fields.Element_mass = &declare_scalar_field_on_all_elements(meta_data, "element_mass"); fields.Hourglass_energy = &declare_scalar_field_on_all_elements(meta_data, "hourglass_energy"); fields.Internal_energy = &declare_scalar_field_on_all_elements(meta_data, "internal_energy"); // Element symmetric tensor fields: fields.Stretch = &declare_symmetric_tensor_field_on_all_elements(meta_data, "stretch", 6 ); fields.StrainRate = &declare_symmetric_tensor_field_on_all_elements(meta_data, "StrainRate", 6 ); fields.RotatedStress = &declare_symmetric_tensor_field_on_all_elements(meta_data, "RotatedStress", 6 ); //-------------------------------- // The multi-state fields don't have the 'declare and put' convenience functions (yet) // // For clarity declare a integer to used for the number of states arguments. // const unsigned two_states = 2 ; // Element two state symmetric tensor field, on all elements (as two function calls): fields.StressNew = &meta_data.declare_field< SymmetricTensorField >( "Stress" , two_states ); put_field_on_all_elements( *fields.StressNew , 6 ); // Element two state full tensor field on all elements (as nested function calls): fields.RotationNew = &put_field_on_all_elements( meta_data.declare_field< FullTensorField >("Rotation", two_states ) , 9 ); //-------------------------------- // Hourglass fields, these don't have the convenience functions for 'declare and put' fields.HourglassResistanceNew = &put_field_on_all_elements( meta_data.declare_field< HourglassArrayField >("HourglassResistance" , two_states ) , 12 ); fields.MidHourglassOp = &put_field_on_all_elements( meta_data.declare_field< HourglassOpField >("mid_hourglass_operator") , 32 ); //-------------------------------- // Declare aggressive "gather" fields which are an array of // pointers to the element's nodes' coordinate, velocity, and // internal force field data. // // The declarations specify element fields of the following form: // // double * coord_gather [ nodes_per_element ] // double * velocity_gather[ nodes_per_element ] // // where // // coord_gather[i] == field_data( coordinates_field , element_node[i] ) // velocity_gather[i] == field_data( velocity , element_node[i] ) // // The number of nodes per element could vary, so the field is put // on each element block with a size of the number of nodes per // element in that element block. fields.coord_gather = &declare_element_node_pointer_field( meta_data , "coord_gather" , *fields.coordinates_field ); fields.velocity_gather = &declare_element_node_pointer_field( meta_data , "velocity_gather" , *fields.velocity_field ); //---------------------------------- // Declare an element field with one value per connected node in // which to temporarily store nodal force that is calculated by // the internal force algorithm. fields.force_new_field = &meta_data.declare_field<ElementNodeVectorField>( "force_new_field" , 1 /* 1 state */ ); // All parts of the meta data: { const mesh::PartVector & all_parts = meta_data.get_parts(); for (mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) { mesh::Part * const part = *i ; if ( part->primary_entity_rank() == get_element_rank(meta_data) ) { put_field_on_elements(*fields.coord_gather, *part, shards::Hexahedron<> ::node_count ); put_field_on_elements(*fields.velocity_gather, *part, shards::Hexahedron<> ::node_count ); put_field_on_elements(*fields.force_new_field, *part, SpatialDim, shards::Hexahedron<>::node_count ); } } } }