16 #include <stk_mesh/base/Types.hpp> 17 #include <stk_mesh/base/MetaData.hpp> 18 #include <stk_mesh/base/FieldData.hpp> 19 #include <stk_mesh/base/FieldParallel.hpp> 20 #include <stk_mesh/base/Entity.hpp> 21 #include <stk_mesh/base/BulkData.hpp> 22 #include <stk_mesh/base/BulkModification.hpp> 23 #include <stk_mesh/base/Selector.hpp> 24 #include <stk_mesh/base/GetEntities.hpp> 25 #include <stk_mesh/base/GetBuckets.hpp> 27 #include <stk_mesh/fixtures/GearsFixture.hpp> 28 #include <stk_mesh/fixtures/Gear.hpp> 30 #include <stk_mesh/fem/Stencils.hpp> 31 #include <stk_mesh/fem/FEMHelpers.hpp> 32 #include <stk_mesh/fem/BoundaryAnalysis.hpp> 34 #include <Shards_BasicTopologies.hpp> 38 const stk_classic::mesh::EntityRank NODE_RANK = stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
40 const unsigned ONE_STATE = 1;
41 const unsigned TWO_STATE = 2;
43 typedef shards::Hexahedron<8> Hex8 ;
44 typedef shards::Wedge<6> Wedge6 ;
52 GearsFixture::GearsFixture(
ParallelMachine pm,
size_t num_gears, GearParams gear_params)
53 : NUM_GEARS(num_gears)
54 , meta_data( SpatialDimension )
55 , bulk_data( fem::FEMMetaData::get_meta_data(meta_data) , pm )
56 , element_rank( meta_data.element_rank() )
57 , cylindrical_coord_part( meta_data.
declare_part(
"cylindrical_coord_part", element_rank))
58 , hex_part( fem::
declare_part<Hex8>(meta_data,
"hex8_part"))
59 , wedge_part( fem::
declare_part<Wedge6>(meta_data,
"wedge6_part"))
60 , cartesian_coord_field( meta_data.declare_field<CartesianField>(
"coordinates", ONE_STATE))
61 , displacement_field( meta_data.declare_field<CartesianField>(
"displacement", TWO_STATE))
62 , translation_field( meta_data.declare_field<CartesianField>(
"translation", ONE_STATE))
63 , cylindrical_coord_field( meta_data.declare_field<CylindricalField>(
"cylindrical_coordinates", ONE_STATE))
68 cartesian_coord_field,
70 meta_data.universal_part(),
77 meta_data.universal_part(),
84 cylindrical_coord_part,
89 cylindrical_coord_field,
91 cylindrical_coord_part,
95 m_gears.resize(NUM_GEARS);
97 for (
size_t i = 0; i < NUM_GEARS; ++i) {
98 std::ostringstream oss;
100 m_gears[i] =
new Gear (
103 meta_data.declare_part(oss.str(),SpatialDimension),
104 cylindrical_coord_part,
107 cartesian_coord_field,
110 cylindrical_coord_field,
111 gear_params.element_size,
112 gear_params.radius_min,
113 gear_params.radius_max,
114 gear_params.height_min,
115 gear_params.height_max
120 GearsFixture::~GearsFixture()
122 for( std::vector<Gear *>::iterator i = m_gears.begin();
131 void GearsFixture::generate_mesh() {
134 bulk_data.modification_begin();
136 const unsigned p_size = bulk_data.parallel_size();
137 const unsigned p_rank = bulk_data.parallel_rank();
140 for(
size_t i = 0; i < m_gears.size(); ++i) {
141 if (( (i*p_size)/m_gears.size()) == p_rank) {
142 Gear & gear = get_gear(i);
143 gear.generate_gear();
146 std::vector<size_t> empty_requests(meta_data.entity_rank_count(), 0);
147 EntityVector empty_entities;
148 bulk_data.generate_new_entities(empty_requests, empty_entities);
153 bulk_data.modification_end();
156 communicate_model_fields();
158 for (
size_t i = 0 ; i < m_gears.size() ; ++i ) {
160 distribute_gear_across_processors(get_gear(i),cylindrical_coord_field);
165 void GearsFixture::communicate_model_fields()
169 std::vector< const FieldBase *> fields;
171 fields.push_back(& cartesian_coord_field);
172 fields.push_back(& translation_field);
173 fields.push_back(& cylindrical_coord_field);
178 communicate_field_data(bulk_data.shared_aura(), fields);
182 double scale_angle_2pi(
double angle) {
183 while ( angle < 0.0 ) {
186 while ( angle >= TWO_PI) {
193 void select_nodal_data(
194 GearsFixture::CylindricalField & cylindrical_coord_field,
204 PairIterRelation node_relations = element.relations(NODE_RANK);
205 int numNodes = node_relations.second - node_relations.first;
206 for ( ; node_relations.first != node_relations.second ; ++(node_relations.first) ) {
207 Entity * node = node_relations.first->entity();
208 EntityArray<GearsFixture::CylindricalField> cylindrical_data( cylindrical_coord_field, *node);
209 radius += cylindrical_data(0);
210 angle = std::min(angle,cylindrical_data(1));
211 height += cylindrical_data(2);
218 void distribute_gear_across_processors(Gear & gear, GearsFixture::CylindricalField & cylindrical_coord_field)
220 BulkData & bulk_data = gear.bulk_data;
222 const unsigned p_size = bulk_data.parallel_size();
223 const unsigned p_rank = bulk_data.parallel_rank();
225 EntityProcVec elements_to_change_owner;
227 Selector locally_owned = gear.meta_data.locally_owned_part();
229 BucketVector all_elements;
231 std::set<Entity *> node_set;
232 for (BucketVector::iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) {
234 for (
size_t i=0 ; i<b.size() ; ++i) {
235 Entity * element = &b[i];
239 select_nodal_data(cylindrical_coord_field, *element,radius,angle,height);
240 unsigned destination_processor_rank = destination_processor(gear,radius,angle,height,p_rank,p_size);
241 elements_to_change_owner.push_back(
EntityProc(element,destination_processor_rank));
243 PairIterRelation node_relations = element->relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK);
244 for ( ; node_relations.first != node_relations.second ; ++(node_relations.first) ) {
245 Entity * node = node_relations.first->entity();
246 if (node_set.count(node)==0) {
247 elements_to_change_owner.push_back(
EntityProc(node,destination_processor_rank));
248 node_set.insert(node);
256 bulk_data.modification_begin();
257 bulk_data.change_entity_owner(elements_to_change_owner);
259 bulk_data.modification_end();
283 double floor0(
double value)
285 double result = std::floor( std::fabs( value ) );
286 return (value < 0.0) ? -result : result;
290 void scale_p_rank(
unsigned & p_rank,
unsigned p_size)
292 if (p_rank >= p_size) {
297 unsigned destination_processor(
const Gear & gear,
double rad,
double angle,
double height,
unsigned p_rank,
unsigned p_size)
301 angle = scale_angle_2pi(angle);
302 result =
static_cast<unsigned>(floor0((angle/TWO_PI)*p_size));
320 scale_p_rank(result,p_size);
Newest state of a field with two states.
field_type & put_field(field_type &field, EntityRank entity_rank, const Part &part, const void *init_value=NULL)
Declare a field to exist for a given entity type and Part.
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Part & declare_part(FEMMetaData &meta_data, const std::string &name)
Declare a part with a given cell topology. This is just a convenient function that wraps FEMMetaData'...
Previous state of a field with two states.
AllSelectedBucketsRange get_buckets(const Selector &selector, const BulkData &mesh)