Sierra Toolkit  Version of the Day
IossBridge.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010, 2011 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <string.h>
10 #include <iostream>
11 #include <complex>
12 
13 #include <init/Ionit_Initializer.h>
14 #include <Ioss_SubSystem.h>
15 #include <Ioss_NullEntity.h>
16 
17 #include <stk_util/util/tokenize.hpp>
18 #include <stk_io/IossBridge.hpp>
19 
20 #include <stk_util/parallel/Parallel.hpp>
21 
22 #include <stk_mesh/base/Types.hpp>
23 #include <stk_mesh/base/Field.hpp>
24 #include <stk_mesh/base/GetEntities.hpp>
25 #include <stk_mesh/base/FieldData.hpp>
26 #include <stk_mesh/base/MetaData.hpp>
27 #include <stk_mesh/base/BulkData.hpp>
28 #include <stk_mesh/fem/FEMHelpers.hpp>
29 
30 #include <Shards_BasicTopologies.hpp>
31 
32 namespace {
33 
34 stk_classic::mesh::EntityRank get_entity_rank(const Ioss::GroupingEntity *entity,
35  const stk_classic::mesh::MetaData &meta)
36 {
37  switch (entity->type()) {
38  case Ioss::NODEBLOCK:
39  return stk_classic::io::node_rank(meta);
40 
41  case Ioss::NODESET:
42  return stk_classic::io::node_rank(meta);
43 
44  case Ioss::ELEMENTBLOCK:
45  return stk_classic::io::element_rank(meta);
46 
47  case Ioss::SUPERELEMENT:
48  return stk_classic::io::element_rank(meta);
49 
50  case Ioss::SIDESET:
51  {
52  const Ioss::SideSet *sset = dynamic_cast<const Ioss::SideSet*>(entity);
53  assert(sset != NULL);
54  int my_rank = sset->max_parametric_dimension();
55  if (my_rank == 2)
56  return stk_classic::io::face_rank(meta);
57  if (my_rank == 1)
58  return stk_classic::io::edge_rank(meta);
59  if (my_rank == 0)
60  return stk_classic::io::node_rank(meta);
61  else
62  return stk_classic::mesh::InvalidEntityRank;
63  }
64 
65  case Ioss::SIDEBLOCK:
66  {
67  const Ioss::SideBlock *sblk = dynamic_cast<const Ioss::SideBlock*>(entity);
68  assert(sblk != NULL);
69  int rank = sblk->topology()->parametric_dimension();
70  if (rank == 2)
71  return stk_classic::io::face_rank(meta);
72  if (rank == 1)
73  return stk_classic::io::edge_rank(meta);
74  if (rank == 0)
75  return stk_classic::io::node_rank(meta);
76  else
77  return stk_classic::mesh::InvalidEntityRank;
78  }
79  default:
80  return stk_classic::mesh::InvalidEntityRank;
81  }
82 }
83 
84 const CellTopologyData *map_ioss_to_topology( const std::string &element_type ,
85  const int node_count)
86 {
89 
90  const CellTopologyData* celltopo = NULL ;
91 
92  const char *etype = element_type.c_str();
93  if ( 0 == strncasecmp( "circle" , etype , 6 ) ) {
94  celltopo = shards::getCellTopologyData< shards::Particle >();
95  }
96  else if ( 0 == strncasecmp( "sphere" , etype , 6) ) {
97  celltopo = shards::getCellTopologyData< shards::Particle >();
98  }
99  // bar, beam, truss, rod...
100  else if ( 0 == strncasecmp( "bar" , etype , 3 ) ) {
101  if ( node_count == 2 ) {
102  celltopo = shards::getCellTopologyData< shards::Beam<2> >();
103  }
104  else if ( node_count == 3 ) {
105  celltopo = shards::getCellTopologyData< shards::Beam<3> >();
106  }
107  }
108  else if ( 0 == strncasecmp( "shellline2d" , etype , 11 ) ) {
109  if ( node_count == 2) {
110  celltopo = shards::getCellTopologyData< shards::ShellLine<2> >();
111  }
112  else if ( node_count == 3) {
113  celltopo = shards::getCellTopologyData< shards::ShellLine<3> >();
114  }
115  } else if ( 0 == strncasecmp( "shell" , etype , 5 ) ) {
116  // shell4, shell8, shell9
117  if ( node_count == 4 ) {
118  celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<4> >();
119  }
120  else if ( node_count == 8 ) {
121  celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<8> >();
122  }
123  else if ( node_count == 9 ) {
124  celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<9> >();
125  }
126  }
127  else if ( 0 == strncasecmp( "quad" , etype , 3 ) ) {
128  // The 2D types would be quad4, quad8, and quad9.
129  // The 3D types would be quad faces of a hex... quadface4,
130  // quadface8, quadface9.
131  if ( node_count == 4 ) {
132  celltopo = shards::getCellTopologyData< shards::Quadrilateral<4> >();
133  }
134  else if ( node_count == 8 ) {
135  celltopo = shards::getCellTopologyData< shards::Quadrilateral<8> >();
136  }
137  else if ( node_count == 9 ) {
138  celltopo = shards::getCellTopologyData< shards::Quadrilateral<9> >();
139  }
140  }
141  else if ( 0 == strncasecmp( "trishell" , etype , 8 ) ) {
142  if ( node_count == 3 ) {
143  celltopo = shards::getCellTopologyData< shards::ShellTriangle<3> >();
144  }
145  else if ( node_count == 6 ) {
146  celltopo = shards::getCellTopologyData< shards::ShellTriangle<6> >();
147  }
148  }
149 
150  else if (0 == strncasecmp("triface", etype, 7) ||
151  0 == strncasecmp("tri", etype, 3)) {
152  if ( node_count == 3 ) {
153  celltopo = shards::getCellTopologyData< shards::Triangle<3> >();
154  }
155  else if ( node_count == 4 ) {
156  celltopo = shards::getCellTopologyData< shards::Triangle<4> >();
157  }
158  else if ( node_count == 6 ) {
159  celltopo = shards::getCellTopologyData< shards::Triangle<6> >();
160  }
161  }
162 
163  else if ( 0 == strncasecmp( "pyramid" , etype , 7 ) ) {
164  if ( node_count == 5 ) {
165  celltopo = shards::getCellTopologyData< shards::Pyramid<5> >();
166  }
167  else if ( node_count == 13 ) {
168  celltopo = shards::getCellTopologyData< shards::Pyramid<13> >();
169  }
170  else if ( node_count == 14 ) {
171  celltopo = shards::getCellTopologyData< shards::Pyramid<14> >();
172  }
173  }
174 
176  else if ( 0 == strncasecmp( "tetra" , etype , 5 ) ) {
177  if ( node_count == 4 ) {
178  celltopo = shards::getCellTopologyData< shards::Tetrahedron<4> >();
179  }
180  else if ( node_count == 8 ) {
181  celltopo = shards::getCellTopologyData< shards::Tetrahedron<8> >();
182  }
183  else if ( node_count == 10 ) {
184  celltopo = shards::getCellTopologyData< shards::Tetrahedron<10> >();
185  }
186  }
187  else if ( 0 == strncasecmp( "wedge" , etype , 5 ) ) {
188  if ( node_count == 6 ) {
189  celltopo = shards::getCellTopologyData< shards::Wedge<6> >();
190  }
191  else if ( node_count == 15 ) {
192  celltopo = shards::getCellTopologyData< shards::Wedge<15> >();
193  }
194  else if ( node_count == 18 ) {
195  celltopo = shards::getCellTopologyData< shards::Wedge<18> >();
196  }
197  }
198  else if ( 0 == strncasecmp( "hex" , etype , 3 ) ) {
199  if ( node_count == 8 ) {
200  celltopo = shards::getCellTopologyData< shards::Hexahedron<8> >();
201  }
202  else if ( node_count == 20 ) {
203  celltopo = shards::getCellTopologyData< shards::Hexahedron<20> >();
204  }
205  else if ( node_count == 27 ) {
206  celltopo = shards::getCellTopologyData< shards::Hexahedron<27> >();
207  }
208  }
209 
210  else if (0 == strncasecmp("edge", etype, 4)) {
211  if ( node_count == 2) {
212  // edge2, edge2d2, edge3d2
213  celltopo = shards::getCellTopologyData< shards::Line<2> >();
214  }
215  else if ( node_count == 3) {
216  // edge3, edge2d3, edge3d3
217  celltopo = shards::getCellTopologyData< shards::Line<3> >();
218  }
219  }
220 
221  else if (0 == strncasecmp("node", etype, 4)) {
222  celltopo = shards::getCellTopologyData< shards::Node >();
223  }
224 
225  if ( NULL == celltopo ) {
226  std::ostringstream oss;
227  oss << "ERROR, unsupported topology name = '" << element_type
228  << "' , node_count = " << node_count;
229  throw std::runtime_error(oss.str());
230  }
231 
232  return celltopo;
233 }
234 
235 template <typename T>
236 const stk_classic::mesh::FieldBase *declare_ioss_field_internal(stk_classic::mesh::MetaData &meta,
237  stk_classic::mesh::EntityRank type,
239  const Ioss::Field &io_field,
240  bool use_cartesian_for_scalar, T /*dummy*/)
241 {
242  stk_classic::mesh::FieldBase *field_ptr = NULL;
243  std::string field_type = io_field.transformed_storage()->name();
244  std::string name = io_field.get_name();
245  size_t num_components = io_field.transformed_storage()->component_count();
246 
247  if (field_type == "scalar" || num_components == 1) {
248  if (!use_cartesian_for_scalar) {
250  stk_classic::mesh::put_field(field, type, part);
251  field_ptr = &field;
252  } else {
255  stk_classic::mesh::put_field(field, type, part, 1);
256  field_ptr = &field;
257  }
258  }
259  else if (field_type == "vector_2d") {
262  stk_classic::mesh::put_field(field, type, part, 2);
263  field_ptr = &field;
264  }
265  else if (field_type == "vector_3d") {
269  stk_classic::mesh::put_field(field, type, part, 3);
270  field_ptr = &field;
271  }
272  else if (field_type == "sym_tensor_33") {
276  stk_classic::mesh::put_field(field, type, part, 6);
277  field_ptr = &field;
278  }
279  else if (field_type == "full_tensor_36") {
283  stk_classic::mesh::put_field(field, type, part, 9);
284  field_ptr = &field;
285  }
286  else {
287  // Just create a field with the correct number of components...
290  stk_classic::mesh::put_field(field, type, part, num_components);
291  field_ptr = &field;
292  }
293 
294  if (field_ptr != NULL) {
295  stk_classic::io::set_field_role(*field_ptr, io_field.get_role());
296  }
297  return field_ptr;
298 }
299 
300 const stk_classic::mesh::FieldBase *declare_ioss_field(stk_classic::mesh::MetaData &meta,
301  stk_classic::mesh::EntityRank type,
303  const Ioss::Field &io_field,
304  bool use_cartesian_for_scalar)
305 {
306  const stk_classic::mesh::FieldBase *field_ptr = NULL;
307  if (io_field.get_type() == Ioss::Field::INTEGER) {
308  field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, (int)1);
309  } else if (io_field.get_type() == Ioss::Field::REAL) {
310  field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, (double)1.0);
311  } else if (io_field.get_type() == Ioss::Field::COMPLEX) {
312  field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, std::complex<double>(0.0,0.0));
313  } else {
314  std::ostringstream errmsg;
315  errmsg << "ERROR: Unrecognized field type for IO field '"
316  << io_field.get_name() << "'.";
317  throw std::runtime_error(errmsg.str());
318  }
319  return field_ptr;
320 }
321 
322 template <typename T>
323 void internal_field_data_from_ioss(const Ioss::Field &io_field,
324  const stk_classic::mesh::FieldBase *field,
325  std::vector<stk_classic::mesh::Entity*> &entities,
326  Ioss::GroupingEntity *io_entity,
327  T /*dummy */)
328 {
329  size_t field_component_count = io_field.transformed_storage()->component_count();
330 
331  std::vector<T> io_field_data;
332  size_t io_entity_count = io_entity->get_field_data(io_field.get_name(), io_field_data);
333  assert(io_field_data.size() == entities.size() * field_component_count);
334 
335  size_t entity_count = entities.size();
336 
337  if (io_entity_count != entity_count) {
338  std::ostringstream errmsg;
339  errmsg << "ERROR: Field count mismatch for IO field '"
340  << io_field.get_name() << "'. The IO system has " << io_entity_count
341  << " entries, but the stk:mesh system has " << entity_count
342  << " entries. The two counts must match.";
343  throw std::runtime_error(errmsg.str());
344  }
345 
346  for (size_t i=0; i < entity_count; ++i) {
349  if (entities[i] != NULL) {
350  T *fld_data = (T*)stk_classic::mesh::field_data(*field, *entities[i]);
351  assert(fld_data != NULL);
352  for(size_t j=0; j<field_component_count; ++j) {
353  fld_data[j] = io_field_data[i*field_component_count+j];
354  }
355  }
356  }
357 }
358 
359 template <typename T>
360 void internal_field_data_to_ioss(const Ioss::Field &io_field,
361  const stk_classic::mesh::FieldBase *field,
362  std::vector<stk_classic::mesh::Entity*> &entities,
363  Ioss::GroupingEntity *io_entity,
364  T /*dummy */)
365 {
366  size_t field_component_count = io_field.transformed_storage()->component_count();
367  size_t entity_count = entities.size();
368 
369  std::vector<T> io_field_data(entity_count*field_component_count);
370 
371  for (size_t i=0; i < entity_count; ++i) {
374  if (entities[i] != NULL) {
375  T *fld_data = (T*)stk_classic::mesh::field_data(*field, *entities[i]);
376  assert(fld_data != NULL);
377  for(size_t j=0; j<field_component_count; ++j) {
378  io_field_data[i*field_component_count+j] = fld_data[j];
379  }
380  } else {
381  for(size_t j=0; j<field_component_count; ++j) {
382  io_field_data[i*field_component_count+j] = 0;
383  }
384  }
385  }
386 
387  size_t io_entity_count = io_entity->put_field_data(io_field.get_name(), io_field_data);
388  assert(io_field_data.size() == entities.size() * field_component_count);
389 
390  if (io_entity_count != entity_count) {
391  std::ostringstream errmsg;
392  errmsg << "ERROR: Field count mismatch for IO field '"
393  << io_field.get_name() << "'. The IO system has " << io_entity_count
394  << " entries, but the stk:mesh system has " << entity_count
395  << " entries. The two counts must match.";
396  throw std::runtime_error(errmsg.str());
397  }
398 }
399 
400 }//namespace <empty>
401 
402 namespace stk_classic {
403 namespace io {
404 
405 size_t db_api_int_size(const Ioss::GroupingEntity *entity)
406 {
407  return entity->get_database()->int_byte_size_api();
408 }
409 
410 bool invalid_rank(stk_classic::mesh::EntityRank rank)
411 {
412  return rank == mesh::InvalidEntityRank;
413 }
414 
415 stk_classic::mesh::EntityRank part_primary_entity_rank(const stk_classic::mesh::Part &part)
416 {
417  if (mesh::MetaData::get(part).universal_part() == part) {
418  return stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
419  }
420  else {
421  return part.primary_entity_rank();
422  }
423 }
424 
425 stk_classic::mesh::EntityRank element_rank(const stk_classic::mesh::MetaData &meta)
426 {
428 }
429 
430 stk_classic::mesh::EntityRank side_rank(const stk_classic::mesh::MetaData &meta)
431 {
433 }
434 
435 stk_classic::mesh::EntityRank face_rank(const stk_classic::mesh::MetaData &meta)
436 {
438 }
439 
440 stk_classic::mesh::EntityRank edge_rank(const stk_classic::mesh::MetaData &meta)
441 {
443 }
444 
445 stk_classic::mesh::EntityRank node_rank(const stk_classic::mesh::MetaData& meta)
446 {
447  return stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
448 }
449 
450 void set_cell_topology(stk_classic::mesh::Part &part, const CellTopologyData * const cell_topology)
451 {
452  stk_classic::mesh::fem::set_cell_topology(part, cell_topology);
453 }
454 
455 const CellTopologyData *get_cell_topology(const stk_classic::mesh::Part &part)
456 {
457  return stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData();
458 }
459 
460 void initialize_spatial_dimension(stk_classic::mesh::fem::FEMMetaData & fem_meta, size_t spatial_dimension,
461  const std::vector<std::string> &entity_rank_names)
462 {
463  if (!fem_meta.is_FEM_initialized() ) {
464  fem_meta.FEM_initialize(spatial_dimension, entity_rank_names);
465  }
466 }
467 
468 void initialize_spatial_dimension(stk_classic::mesh::MetaData &meta, size_t spatial_dimension,
469  const std::vector<std::string> &entity_rank_names)
470 {
472  initialize_spatial_dimension(fem_meta, spatial_dimension, entity_rank_names);
473 }
474 
475 void get_io_field_type(const stk_classic::mesh::FieldBase *field,
477  std::pair<std::string, Ioss::Field::BasicType> *result)
478 {
479  static const std::string invalid("invalid");
480  static const std::string scalar("scalar");
481  static const std::string vector_2d("vector_2d");
482  static const std::string vector_3d("vector_3d");
483  static const std::string quaternion_2d("quaternion_2d");
484  static const std::string quaternion_3d("quaternion_3d");
485  static const std::string full_tensor_36("full_tensor_36");
486  static const std::string full_tensor_32("full_tensor_32");
487  static const std::string full_tensor_22("full_tensor_22");
488  static const std::string full_tensor_16("full_tensor_16");
489  static const std::string full_tensor_12("full_tensor_12");
490  static const std::string sym_tensor_33("sym_tensor_33");
491  static const std::string sym_tensor_31("sym_tensor_31");
492  static const std::string sym_tensor_21("sym_tensor_21");
493  static const std::string sym_tensor_13("sym_tensor_13");
494  static const std::string sym_tensor_11("sym_tensor_11");
495  static const std::string sym_tensor_10("sym_tensor_10");
496  static const std::string asym_tensor_03("asym_tensor_03");
497  static const std::string asym_tensor_02("asym_tensor_02");
498  static const std::string asym_tensor_01("asym_tensor_01");
499  static const std::string matrix_22("matrix_22");
500  static const std::string matrix_33("matrix_33");
501 
502  const unsigned rank = field->rank();
503  const shards::ArrayDimTag * const * const tags = field->dimension_tags();
504 
505  result->second = Ioss::Field::INVALID;
506 
507  if ( field->type_is<double>() ) {
508  result->second = Ioss::Field::REAL;
509  }
510  else if ( field->type_is<int>() ) {
511  result->second = Ioss::Field::INTEGER;
512  }
513 
514  if ( 0 == rank ) {
515  result->first = scalar ;
516  }
517  else if ( 1 == rank ) {
518  size_t num_comp = res.stride(0);
519  if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 1 == num_comp ) {
520  result->first = scalar ;
521  }
522  else if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 2 == num_comp ) {
523  result->first = vector_2d ;
524  }
525  else if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 3 == num_comp ) {
526  result->first = vector_3d ;
527  }
528  else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 9 == num_comp ) {
529  result->first = full_tensor_36 ;
530  }
531  else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 5 == num_comp ) {
532  result->first = full_tensor_32 ;
533  }
534  else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 4 == num_comp ) {
535  result->first = full_tensor_22 ;
536  }
537  else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 3 == num_comp ) {
538  result->first = full_tensor_12 ;
539  }
540  else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 6 == num_comp ) {
541  result->first = sym_tensor_33 ;
542  }
543  else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 4 == num_comp ) {
544  result->first = sym_tensor_31 ;
545  }
546  else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 3 == num_comp ) {
547  result->first = sym_tensor_21 ;
548  }
549  }
550 
551  if ( result->first.empty() ) {
552  size_t num_comp = res.stride(rank-1);
553  std::ostringstream tmp ;
554  tmp << "Real[" << num_comp << "]" ;
555  result->first = tmp.str();
556  }
557 }
558 
559 //----------------------------------------------------------------------
560 const Ioss::GroupingEntity *get_associated_ioss_entity(const mesh::Part &part)
561 {
562  const Ioss::GroupingEntity *entity = part.attribute<Ioss::GroupingEntity>();
563  if (!entity || entity->type() == Ioss::INVALID_TYPE) {
564  return NULL;
565  } else {
566  return entity;
567  }
568 }
569 
570 void put_io_part_attribute(mesh::Part & part, Ioss::GroupingEntity *entity)
571 {
572  if (part.attribute<Ioss::GroupingEntity>() != NULL) {
573  std::string msg = "stk_classic::io::put_io_part_attribute( ";
574  msg += part.name();
575  msg += " ) FAILED:";
576  msg += " io_part_attribute is already defined";
577  throw std::runtime_error( msg );
578  }
579 
580  mesh::MetaData & meta = mesh::MetaData::get(part);
581  if (entity) {
582  meta.declare_attribute_no_delete(part, entity);
583  } else {
584  Ioss::GroupingEntity *attr = new Ioss::NullEntity();
585  meta.declare_attribute_with_delete(part, attr);
586  }
587 }
588 
590 {
591  const Ioss::GroupingEntity *entity = part.attribute<Ioss::GroupingEntity>();
592  if (entity == NULL) {
593  std::string msg = "stk_classic::io::remove_io_part_attribute( ";
594  msg += part.name();
595  msg += " ) FAILED:";
596  msg += " io_part_attribute is not defined on this part";
597  throw std::runtime_error( msg );
598  } else {
599  mesh::MetaData & meta = mesh::MetaData::get(part);
600  bool success = meta.remove_attribute(part, entity);
601  if (!success) {
602  std::string msg = "stk_classic::io::remove_io_part_attribute( ";
603  msg += part.name();
604  msg += " ) FAILED:";
605  msg += " meta.remove_attribute(..) returned failure.";
606  throw std::runtime_error( msg );
607  }
608 
609  if (entity->type() == Ioss::INVALID_TYPE) {
610  delete entity;
611  }
612 
613  }
614 }
615 
621  const stk_classic::mesh::EntityRank part_type,
622  const stk_classic::mesh::Part &part,
623  const stk_classic::mesh::Part &universal,
624  const Ioss::Field::RoleType filter_role,
625  bool add_all)
626 {
627  const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*field);
628 
629  if (!add_all && role == NULL) {
630  return false;
631  }
632 
633  if (role != NULL && *role != filter_role)
634  return false;
635 
636  const stk_classic::mesh::FieldBase::Restriction &res = field->restriction(part_type, part);
637  if (res.dimension() > 0) {
638  // The field exists on the current 'part'. Now check (for
639  // node types only) whether the 'part' is *either* the
640  // universal_part() *or* the field *doesn't* exist on the
641  // universal part...
642  // Note that for "node" type parts, the IO database has a part
643  // (nodeblock) that corresponds to the universal_part(), so
644  // fields defined on all nodes are output on the nodeblock and
645  // fields defined on only a subset of the parts should be
646  // output on that subset which maps to a nodeset. For other
647  // part types, there is no IO entity that corresponds to a
648  // universal part, so fields must be output on the part they
649  // exist on. There may be a problem if we start using element
650  // sets ..., but wait until we get to that point; current code
651  // works with current entity set.
652  if (part_type != node_rank(mesh::MetaData::get(part)) || part == universal) {
653  return true;
654  }
655 
656  const stk_classic::mesh::FieldBase::Restriction &res_universe = field->restriction(part_type, universal);
657  if (res_universe.dimension() <= 0) {
658  // Field exists on current part, but not on the universal
659  // set (and this part is not the universal part)
660  return true;
661  }
662  }
663  return false;
664 }
665 
669 // ========================================================================
670 const CellTopologyData *map_topology_ioss_to_cell(const Ioss::ElementTopology *topology)
671 {
678 
679  std::string name = topology->name();
680  int io_nodes_per_element = topology->number_nodes();
681 
682  const CellTopologyData *cell_topology = map_ioss_to_topology(name, io_nodes_per_element);
683 
684  return cell_topology;
685 }
686 
687 std::string map_topology_cell_to_ioss( const CellTopologyData *cell_top,
688  int spatial_dimension)
689 {
690  std::string extype = "unknown";
691 
692  if (cell_top == NULL)
693  return extype;
694 
695  if(strcmp(cell_top->name, "super") == 0) {
696  std::stringstream oss;
697  oss << "super" << cell_top->node_count;
698  return oss.str();
699  }
700  else if(strncasecmp(cell_top->name, "super", 5) == 0) {
701  return cell_top->name;
702  }
703 
704  switch( cell_top->key ) {
705  case shards::Node::key : extype.assign( "node" ); break ;
706  case shards::Particle::key :
707  if (spatial_dimension == 2) extype = "circle1";
708  else extype = "sphere1";
709  break ;
710 
711  case shards::Beam<2>::key :
712  extype = "bar2";
713  break ;
714 
715  case shards::Beam<3>::key :
716  extype = "bar3";
717  break ;
718 
719  case shards::Line<2>::key :
720  extype = "edge2";
721  break ;
722  case shards::Line<3>::key :
723  extype = "edge3";
724  break ;
725 
726  case shards::ShellLine<2>::key : extype.assign( "shellline2d2" ); break ;
727  case shards::ShellLine<3>::key : extype.assign( "shellline2d3" ); break ;
728 
729  case shards::Triangle<3>::key :
730  extype = "tri3";
731  break ;
732  case shards::Triangle<4>::key :
733  extype = "tri4";
734  break ;
735  case shards::Triangle<6>::key :
736  extype = "tri6";
737  break ;
738 
739  case shards::ShellTriangle<3>::key : extype.assign( "trishell3" ); break ;
740  case shards::ShellTriangle<6>::key : extype.assign( "trishell6" ); break ;
741 
742  case shards::Quadrilateral<4>::key :
743  extype = "quad4";
744  break ;
745  case shards::Quadrilateral<8>::key :
746  extype = "quad8";
747  break ;
748  case shards::Quadrilateral<9>::key :
749  extype = "quad9";
750  break ;
751 
752  case shards::ShellQuadrilateral<4>::key : extype.assign( "shell4" ); break ;
753  case shards::ShellQuadrilateral<8>::key : extype.assign( "shell8" ); break ;
754  case shards::ShellQuadrilateral<9>::key : extype.assign( "shell9" ); break ;
755 
756  case shards::Tetrahedron< 4>::key : extype.assign( "tetra4" ); break ;
757  case shards::Tetrahedron<8>::key : extype.assign( "tetra8" ); break ;
758  case shards::Tetrahedron<10>::key : extype.assign( "tetra10" ); break ;
759 
760  case shards::Pyramid< 5>::key : extype.assign( "pyramid5" ); break ;
761  case shards::Pyramid<13>::key : extype.assign( "pyramid13" ); break ;
762  case shards::Pyramid<14>::key : extype.assign( "pyramid14" ); break ;
763 
764  case shards::Wedge< 6>::key : extype.assign( "wedge6" ); break ;
765  case shards::Wedge<15>::key : extype.assign( "wedge15" ); break ;
766  case shards::Wedge<18>::key : extype.assign( "wedge18" ); break ;
767 
768  case shards::Hexahedron< 8>::key : extype.assign( "hex8" ); break ;
769  case shards::Hexahedron<20>::key : extype.assign( "hex20" ); break ;
770  case shards::Hexahedron<27>::key : extype.assign( "hex27" ); break ;
771 
772  default:
773  std::ostringstream oss;
774  oss << "stk_classic::io::map_topology_to_ioss( '" << cell_top->name
775  << "' ) ERROR unmapped topology" << std::endl ;
776  throw std::runtime_error(oss.str());
777  }
778 
779  return extype ;
780 }
781 
782 void internal_part_processing(Ioss::GroupingEntity *entity, stk_classic::mesh::fem::FEMMetaData &meta)
783 {
784  internal_part_processing(entity, meta.get_meta_data(meta));
785 }
786 
787 void internal_part_processing(Ioss::EntityBlock *entity, stk_classic::mesh::fem::FEMMetaData &meta)
788 {
789  internal_part_processing(entity, meta.get_meta_data(meta));
790 }
791 
792 void internal_part_processing(Ioss::GroupingEntity *entity, stk_classic::mesh::MetaData &meta)
793 {
794  if (include_entity(entity)) {
796  mesh::EntityRank type = get_entity_rank(entity, meta);
797  if (fem_meta) {
798  stk_classic::mesh::Part & part = fem_meta->declare_part(entity->name(), type);
800  } else {
801  stk_classic::mesh::Part & part = meta.declare_part(entity->name(), type);
803  }
804  }
805 }
806 
807 void internal_part_processing(Ioss::EntityBlock *entity, stk_classic::mesh::MetaData &meta)
808 {
809  if (include_entity(entity)) {
810  mesh::EntityRank type = get_entity_rank(entity, meta);
812  //const stk_classic::mesh::fem::FEMMetaData * fem_meta = meta.get_attribute<stk_classic::mesh::fem::FEMMetaData>();
813  stk_classic::mesh::Part * part = NULL;
814  if( fem_meta )
815  part = &fem_meta->declare_part(entity->name(), type);
816  else
817  part = &meta.declare_part(entity->name(), type);
819 
820  const Ioss::ElementTopology *topology = entity->topology();
821  // Check spatial dimension of the element topology here so we
822  // can issue a more meaningful error message. If the
823  // dimension is bad and we continue to the following calls,
824  // there is an exception and we get unintelligible (to the
825  // user) error messages. Could also do a catch...
826 
827  if (entity->type() == Ioss::ELEMENTBLOCK) {
828  assert(topology != NULL);
829  if (fem_meta && (topology->spatial_dimension() < (int)fem_meta->spatial_dimension())) {
830  // NOTE: The comparison is '<' and not '!=' since a 2D mesh
831  // can contain a "3d" element -- a Beam is both a 2D and
832  // 3D element...
833 
834  std::ostringstream msg ;
835  msg << "\n\nERROR: Element Block " << entity->name()
836  << " contains " << topology->name() << " elements with spatial dimension "
837  << topology->spatial_dimension()
838  << "\n which does not match the spatial dimension of the model which is "
839  << fem_meta->spatial_dimension() << "\n\n";
840  throw std::runtime_error( msg.str() );
841  }
842  }
843 
844  const CellTopologyData * const cell_topology = map_topology_ioss_to_cell(topology);
845  // \todo IMPLEMENT Determine whether application can work
846  // with this topology type... Perhaps map_topology_ioss_to_cell only
847  // returns a valid topology if the application has registered
848  // that it can handle that specific topology.
849 
850  if (cell_topology != NULL) {
851  if( fem_meta ) {
852  const stk_classic::mesh::fem::CellTopology cell_topo(cell_topology);
853  stk_classic::mesh::fem::set_cell_topology(*part, cell_topo);
854  }
855  stk_classic::io::set_cell_topology(*part, cell_topology);
856  } else {
857  // \todo IMPLEMENT handle cell_topolgy mapping error...
858  }
859  stk_classic::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE, *part, type);
860  }
861 }
862 
863 //----------------------------------------------------------------------
869  const stk_classic::mesh::EntityRank part_type,
870  Ioss::GroupingEntity *entity,
871  const Ioss::Field::RoleType filter_role,
872  const bool add_all)
873 {
874  const stk_classic::mesh::MetaData & meta = mesh::MetaData::get(part);
875  const stk_classic::mesh::Part &universal = meta.universal_part();
876 
877  const std::vector<mesh::FieldBase*> &fields = meta.get_fields();
878 
879  std::vector<mesh::FieldBase *>::const_iterator I = fields.begin();
880  while (I != fields.end()) {
881  const stk_classic::mesh::FieldBase *f = *I; ++I;
882  if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role, add_all)) {
883  const stk_classic::mesh::FieldBase::Restriction &res = f->restriction(part_type, part);
884  std::pair<std::string, Ioss::Field::BasicType> field_type;
885  get_io_field_type(f, res, &field_type);
886  if (field_type.second != Ioss::Field::INVALID) {
887  size_t entity_size = entity->get_property("entity_count").get_int();
888  const std::string& name = f->name();
889  entity->field_add(Ioss::Field(name, field_type.second, field_type.first,
890  filter_role, entity_size));
891  }
892  }
893  }
894 }
895 
905 void define_io_fields(Ioss::GroupingEntity *entity,
906  Ioss::Field::RoleType role,
908  stk_classic::mesh::EntityRank part_type)
909 {
910  stk_classic::mesh::MetaData &meta = mesh::MetaData::get(part);
911 
912  bool use_cartesian_for_scalar = false;
913  if (role == Ioss::Field::ATTRIBUTE)
914  use_cartesian_for_scalar = true;
915 
916  Ioss::NameList names;
917  entity->field_describe(role, &names);
918 
919  for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
920  // \todo IMPLEMENT Need a field selection mechanism and a field naming
921  // (ioss_name -> stk_classic::name) For now, select all and give the
922  // stk field the same name as the ioss field.
923 
924  // Skip the attribute field that is named "attribute"
925  if (*I == "attribute" && names.size() > 1)
926  continue;
927 
928  // \todo IMPLEMENT Need to determine whether these are
929  // multi-state fields or constant, or interpolated, or ...
930  Ioss::Field io_field = entity->get_field(*I);
931  declare_ioss_field(meta, part_type, part, io_field, use_cartesian_for_scalar);
932  }
933 }
934 
935 template <typename INT>
936 void get_entity_list(Ioss::GroupingEntity *io_entity,
937  stk_classic::mesh::EntityRank part_type,
938  const stk_classic::mesh::BulkData &bulk,
939  std::vector<stk_classic::mesh::Entity*> &entities, INT /*dummy*/)
940 {
941  std::vector<INT> ids ;
942  io_entity->get_field_data("ids", ids);
943 
944  size_t count = ids.size();
945  entities.reserve(count);
946 
947  for(size_t i=0; i<count; ++i) {
948  entities.push_back(bulk.get_entity( part_type, ids[i] ));
949  }
950 }
951 
952 void get_entity_list(Ioss::GroupingEntity *io_entity,
953  stk_classic::mesh::EntityRank part_type,
954  const stk_classic::mesh::BulkData &bulk,
955  std::vector<stk_classic::mesh::Entity*> &entities)
956 {
957  if (db_api_int_size(io_entity) == 4) {
958  get_entity_list(io_entity, part_type, bulk, entities, (int)0);
959  } else {
960  get_entity_list(io_entity, part_type, bulk, entities, (int64_t)0);
961  }
962 }
963 
965  std::vector<stk_classic::mesh::Entity*> &entities,
966  Ioss::GroupingEntity *io_entity,
967  const std::string &io_fld_name)
968 {
971 
972  if (field != NULL && io_entity->field_exists(io_fld_name)) {
973  const Ioss::Field &io_field = io_entity->get_fieldref(io_fld_name);
974  if (field->type_is<double>()) {
975  internal_field_data_from_ioss(io_field, field, entities, io_entity,
976  static_cast<double>(1.0));
977  } else if (field->type_is<int>()) {
978  // Make sure the IO field type matches the STK field type.
979  // By default, all IO fields are created of type 'double'
980  if (db_api_int_size(io_entity) == 4) {
981  if (io_field.get_type() != Ioss::Field::INTEGER) {
982  Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field);
983  tmp.reset_type(Ioss::Field::INTEGER);
984  }
985  internal_field_data_from_ioss(io_field, field, entities, io_entity,
986  static_cast<int>(1));
987  } else {
988  if (io_field.get_type() != Ioss::Field::INT64) {
989  Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field);
990  tmp.reset_type(Ioss::Field::INT64);
991  }
992  internal_field_data_from_ioss(io_field, field, entities, io_entity,
993  static_cast<int64_t>(1));
994  }
995  }
996  }
997 }
998 
1000  std::vector<stk_classic::mesh::Entity*> &entities,
1001  Ioss::GroupingEntity *io_entity,
1002  const std::string &io_fld_name,
1003  Ioss::Field::RoleType filter_role)
1004 {
1007 
1008  if (field != NULL && io_entity->field_exists(io_fld_name)) {
1009  const Ioss::Field &io_field = io_entity->get_fieldref(io_fld_name);
1010  if (io_field.get_role() == filter_role) {
1011  if (field->type_is<double>()) {
1012  internal_field_data_to_ioss(io_field, field, entities, io_entity,
1013  static_cast<double>(1.0));
1014  } else if (field->type_is<int>()) {
1015  if (io_field.get_type() != Ioss::Field::INTEGER) {
1016  Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field);
1017  tmp.reset_type(Ioss::Field::INTEGER);
1018  }
1019  // FIX 64?
1020  internal_field_data_to_ioss(io_field, field, entities, io_entity,
1021  static_cast<int>(1));
1022  }
1023  }
1024  }
1025 }
1026 
1027 //----------------------------------------------------------------------
1028 
1029 // ----------------------------------------------------------------------
1030 // Returns true if 'entity' should be a 'part' in the analysis mesh.
1031 // Returns false if the application is only using a subset of the
1032 // database entities and this entity is not to be used. The
1033 // "omitted" property is set by the application during parsing or
1034 // pre-mesh reading time.
1035 bool include_entity(const Ioss::GroupingEntity *entity)
1036 {
1037  assert(entity);
1038 
1039  // Check whether entity has "omitted" property...
1040  bool omitted = (entity->property_exists("omitted")) &&
1041  (entity->get_property("omitted").get_int() == 1);
1042 
1043  return !omitted;
1044 }
1045 
1046 namespace {
1047 
1048 void define_side_block(stk_classic::mesh::Part &part,
1049  Ioss::SideSet *sset,
1050  stk_classic::mesh::EntityRank type,
1051  size_t side_count, int spatial_dimension)
1052 {
1053  const stk_classic::mesh::EntityRank siderank = side_rank(mesh::MetaData::get(part));
1054  const stk_classic::mesh::EntityRank edgerank = edge_rank(mesh::MetaData::get(part));
1055  ThrowRequire(type == siderank || type == edgerank);
1056 
1057  const CellTopologyData *const side_topology = stk_classic::io::get_cell_topology(part) ?
1058  stk_classic::io::get_cell_topology(part) :
1059  stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData();
1060 
1061  if (side_topology == NULL && side_count > 0) {
1062  // Non-empty side blocks must have an associated topology
1063  std::ostringstream msg ;
1064  msg << " INTERNAL_ERROR: Part " << part.name() << " returned NULL from get_cell_topology()";
1065  throw std::runtime_error( msg.str() );
1066  }
1067 
1068  std::string io_topo = map_topology_cell_to_ioss(side_topology, spatial_dimension);
1069  std::string element_topo_name = "unknown";
1070 
1071  // Get sideblock parent element topology quantities...
1072  // Try to decode from part name...
1073  std::vector<std::string> tokens;
1074  stk_classic::util::tokenize(part.name(), "_", tokens);
1075  if (tokens.size() >= 4) {
1076  // Name of form: "name_eltopo_sidetopo_id" or
1077  // "name_block_id_sidetopo_id"
1078  // "name" is typically "surface".
1079  const Ioss::ElementTopology *element_topo = Ioss::ElementTopology::factory(tokens[tokens.size()-3], true);
1080  if (element_topo != NULL) {
1081  element_topo_name = element_topo->name();
1082  }
1083  }
1084 
1085  Ioss::SideBlock *side_block = new Ioss::SideBlock( sset->get_database() ,
1086  part.name() ,
1087  io_topo, element_topo_name, side_count);
1088  assert(sset->get_side_block(part.name()) == NULL);
1089  sset->add(side_block);
1090 
1091  const mesh::Field<double, mesh::ElementNode> *df = get_distribution_factor_field(part);
1092  if (df != NULL) {
1093  int nodes_per_side = side_topology->node_count;
1094  std::string storage_type = "Real[";
1095  storage_type += Ioss::Utils::to_string(nodes_per_side);
1096  storage_type += "]";
1097  side_block->field_add(Ioss::Field("distribution_factors", Ioss::Field::REAL, storage_type,
1098  Ioss::Field::MESH, side_count));
1099  }
1100 
1101  // Add the attribute fields.
1102  ioss_add_fields(part, part_primary_entity_rank(part), side_block, Ioss::Field::ATTRIBUTE);
1103 }
1104 
1105 void define_side_blocks(stk_classic::mesh::Part &part,
1106  const stk_classic::mesh::BulkData &bulk_data,
1107  Ioss::SideSet *sset,
1108  stk_classic::mesh::EntityRank type,
1109  int spatial_dimension,
1110  const stk_classic::mesh::Selector *anded_selector)
1111 {
1112  mesh::MetaData & meta = mesh::MetaData::get(part);
1113  ThrowRequire(type == face_rank(meta) || type == edge_rank(meta));
1114 
1115  const stk_classic::mesh::PartVector &blocks = part.subsets();
1116  if (blocks.size() > 0) {
1117  for (size_t j = 0; j < blocks.size(); j++) {
1118  mesh::Part & side_block_part = *blocks[j];
1119  stk_classic::mesh::EntityRank side_rank = side_block_part.primary_entity_rank();
1120  mesh::Selector selector = meta.locally_owned_part() & side_block_part;
1121  if (anded_selector) selector &= *anded_selector;
1122 
1123  size_t num_side = count_selected_entities(selector, bulk_data.buckets(side_rank));
1124 
1125  define_side_block(side_block_part, sset, side_rank, num_side, spatial_dimension);
1126  }
1127  } else {
1128  stk_classic::mesh::EntityRank side_rank = part.primary_entity_rank();
1129  mesh::Selector selector = meta.locally_owned_part() & part;
1130  if (anded_selector) selector &= *anded_selector;
1131  size_t num_side = count_selected_entities(selector, bulk_data.buckets(side_rank));
1132  define_side_block(part, sset, side_rank, num_side, spatial_dimension);
1133  }
1134 }
1135 
1136 //----------------------------------------------------------------------
1137 //----------------------------------------------------------------------
1138 //----------------------------------------------------------------------
1139 
1140 void define_node_block(stk_classic::mesh::Part &part,
1141  const stk_classic::mesh::BulkData &bulk,
1142  Ioss::Region &io_region,
1143  const stk_classic::mesh::Selector *anded_selector)
1144 {
1145  //--------------------------------
1146  // Set the spatial dimension:
1147  mesh::MetaData & meta = mesh::MetaData::get(part);
1148 
1153  mesh::Field<double, mesh::Cartesian> *coord_field =
1154  meta.get_field<stk_classic::mesh::Field<double, mesh::Cartesian> >(std::string("coordinates"));
1155  assert(coord_field != NULL);
1156  const mesh::FieldBase::Restriction &res = coord_field->restriction(node_rank(meta), part);
1157 
1161  const int spatial_dim = res.dimension() ;
1162 
1163  //--------------------------------
1164  // Create the special universal node block:
1165 
1166  mesh::Selector selector = meta.locally_owned_part() | meta.globally_shared_part();
1167  if (anded_selector) selector &= *anded_selector;
1168 
1169  size_t num_nodes = count_selected_entities(selector, bulk.buckets(node_rank(meta)));
1170 
1171  const std::string name("nodeblock_1");
1172 
1173  Ioss::NodeBlock * const nb = new Ioss::NodeBlock(io_region.get_database(),
1174  name, num_nodes, spatial_dim);
1175  io_region.add( nb );
1176 
1177  // Add the attribute fields.
1178  ioss_add_fields(part, part_primary_entity_rank(part), nb, Ioss::Field::ATTRIBUTE);
1179 }
1180 
1181 
1182 void define_element_block(stk_classic::mesh::Part &part,
1183  const stk_classic::mesh::BulkData &bulk,
1184  Ioss::Region &io_region,
1185  const stk_classic::mesh::Selector *anded_selector)
1186 {
1187 
1188  mesh::MetaData & meta = mesh::MetaData::get(part);
1189  const stk_classic::mesh::EntityRank elem_rank = element_rank(meta);
1190 
1191  const CellTopologyData * const cell_top =
1192  stk_classic::io::get_cell_topology(part) ?
1193  stk_classic::io::get_cell_topology(part) :
1194  stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData();
1195 
1196  if (cell_top == NULL) {
1197  std::ostringstream msg ;
1198  msg << " INTERNAL_ERROR: Part " << part.name() << " returned NULL from get_cell_topology()";
1199  throw std::runtime_error( msg.str() );
1200  }
1201 
1202  mesh::Selector selector = meta.locally_owned_part() & part;
1203  if (anded_selector) selector &= *anded_selector;
1204  const size_t num_elems = count_selected_entities( selector, bulk.buckets(elem_rank));
1205 
1206  int spatial_dim = io_region.get_property("spatial_dimension").get_int();
1207 
1208  // Defer the counting of attributes until after we define the
1209  // element block so we can count them as we add them as fields to
1210  // the element block
1211  Ioss::ElementBlock *eb = new Ioss::ElementBlock(io_region.get_database() ,
1212  part.name() ,
1213  map_topology_cell_to_ioss(cell_top, spatial_dim) ,
1214  num_elems);
1215  io_region.add(eb);
1216 
1217  // Add the attribute fields.
1218  ioss_add_fields(part, part_primary_entity_rank(part), eb, Ioss::Field::ATTRIBUTE);
1219 }
1220 
1221 void define_side_set(stk_classic::mesh::Part &part,
1222  const stk_classic::mesh::BulkData &bulk,
1223  Ioss::Region &io_region,
1224  const stk_classic::mesh::Selector *anded_selector)
1225 {
1226  const stk_classic::mesh::EntityRank si_rank = side_rank(mesh::MetaData::get(part));
1227 
1228  bool create_sideset = true;
1229  if (part.subsets().empty()) {
1230  // Only define a sideset for this part if its superset part is
1231  // not a side-containing part.. (i.e., this part is not a subset part
1232  // in a surface...)
1233  const stk_classic::mesh::PartVector &supersets = part.supersets();
1234  for (size_t i=0; i < supersets.size(); i++) {
1235  if (is_part_io_part(*supersets[i]) && supersets[i]->primary_entity_rank() == si_rank) {
1236  create_sideset = false;
1237  break;
1238  }
1239  }
1240  }
1241  if (create_sideset) {
1242  Ioss::SideSet * const ss = new Ioss::SideSet(io_region.get_database(), part.name());
1243 
1244  io_region.add(ss);
1245  int spatial_dim = io_region.get_property("spatial_dimension").get_int();
1246  define_side_blocks(part, bulk, ss, si_rank, spatial_dim, anded_selector);
1247  }
1248 }
1249 
1250 void define_node_set(stk_classic::mesh::Part &part,
1251  const stk_classic::mesh::BulkData &bulk,
1252  Ioss::Region &io_region,
1253  const stk_classic::mesh::Selector *anded_selector)
1254 {
1255  mesh::MetaData & meta = mesh::MetaData::get(part);
1256 
1257  mesh::Selector selector = ( meta.locally_owned_part() | meta.globally_shared_part() ) & part;
1258  if (anded_selector) selector &= *anded_selector;
1259 
1260  const size_t num_nodes =
1261  count_selected_entities(selector, bulk.buckets(node_rank(meta)));
1262 
1263  Ioss::NodeSet * const ns =
1264  new Ioss::NodeSet( io_region.get_database(), part.name(), num_nodes);
1265  io_region.add(ns);
1266 
1267  // Add the attribute fields.
1268  ioss_add_fields(part, part_primary_entity_rank(part), ns, Ioss::Field::ATTRIBUTE);
1269 }
1270 } // namespace <blank>
1271 
1272 struct part_compare {
1273  bool operator() (stk_classic::mesh::Part *i, stk_classic::mesh::Part *j) { return (i->name() < j->name()); }
1274 };
1275 
1276 void define_output_db(Ioss::Region & io_region ,
1277  const mesh::BulkData &bulk_data,
1278  const Ioss::Region *input_region,
1279  const stk_classic::mesh::Selector *anded_selector,
1280  const bool sort_stk_parts)
1281 {
1282  const mesh::MetaData & meta_data = mesh::MetaData::get(bulk_data);
1283 
1284  const stk_classic::mesh::EntityRank no_rank = node_rank(meta_data);
1285  const stk_classic::mesh::EntityRank el_rank = element_rank(meta_data);
1286  const stk_classic::mesh::EntityRank fa_rank = face_rank(meta_data);
1287  const stk_classic::mesh::EntityRank ed_rank = edge_rank(meta_data);
1288 
1289  io_region.begin_mode( Ioss::STATE_DEFINE_MODEL );
1290 
1291  define_node_block(meta_data.universal_part(), bulk_data, io_region, anded_selector);
1292 
1293  // All parts of the meta data:
1294  //const mesh::PartVector & all_parts = meta_data.get_parts();
1295  const mesh::PartVector & all_parts_unsorted = meta_data.get_parts();
1296 
1297  // sort parts so they go out the same on all processors (srk: this was induced by streaming refine)
1298  mesh::PartVector all_parts = all_parts_unsorted;
1299  if (sort_stk_parts)
1300  std::sort(all_parts.begin(), all_parts.end(), part_compare());
1301 
1302  for (mesh::PartVector::const_iterator i = all_parts.begin();
1303  i != all_parts.end(); ++i) {
1304 
1305  mesh::Part * const part = *i ;
1306 
1307  if (is_part_io_part(*part)) {
1308  if (invalid_rank(part->primary_entity_rank()))
1309  continue;
1310  else if (part->primary_entity_rank() == no_rank)
1311  define_node_set(*part, bulk_data, io_region, anded_selector);
1312  else if (part->primary_entity_rank() == el_rank)
1313  define_element_block(*part, bulk_data, io_region, anded_selector);
1314  else if (part->primary_entity_rank() == fa_rank)
1315  define_side_set(*part, bulk_data, io_region, anded_selector);
1316  else if (part->primary_entity_rank() == ed_rank)
1317  define_side_set(*part, bulk_data, io_region, anded_selector);
1318  }
1319  }
1320 
1321  if (input_region != NULL)
1322  io_region.synchronize_id_and_name(input_region, true);
1323 
1324  // for streaming refinement, each "pseudo-processor" doesn't know about others, so we pick a sort order
1325  // and use it for all pseudo-procs - the original_block_order property is used to set the order
1326  // on all procs.
1327  if (sort_stk_parts)
1328  {
1329  int offset=0;
1330  for (mesh::PartVector::const_iterator i = all_parts.begin();
1331  i != all_parts.end(); ++i) {
1332 
1333  mesh::Part * const part = *i ;
1334 
1335  if (is_part_io_part(*part)) {
1336  if (invalid_rank(part->primary_entity_rank()))
1337  continue;
1338  else if (part->primary_entity_rank() == el_rank)
1339  {
1340  Ioss::GroupingEntity *element_block = io_region.get_entity(part->name());
1341  if (element_block)
1342  {
1343  if (element_block->property_exists("original_block_order")) {
1344  element_block->property_erase("original_block_order");
1345  }
1346  element_block->property_add(Ioss::Property("original_block_order", offset));
1347  ++offset;
1348  }
1349  }
1350  }
1351  }
1352  }
1353 
1354  io_region.end_mode( Ioss::STATE_DEFINE_MODEL );
1355 }
1356 
1357 //----------------------------------------------------------------------
1358 
1359 namespace {
1360 
1361 size_t get_entities(stk_classic::mesh::Part &part,
1362  const stk_classic::mesh::BulkData &bulk,
1363  std::vector<mesh::Entity*> &entities,
1364  bool include_shared,
1365  const stk_classic::mesh::Selector *anded_selector)
1366 {
1367  mesh::MetaData & meta = mesh::MetaData::get(part);
1368  mesh::EntityRank type = part_primary_entity_rank(part);
1369  if (invalid_rank(type))
1370  type = node_rank(meta);
1371 
1372  mesh::Selector own_share = meta.locally_owned_part();
1373  if (include_shared)
1374  own_share |= meta.globally_shared_part();
1375 
1376  mesh::Selector selector = part & own_share;
1377  if (anded_selector) selector &= *anded_selector;
1378 
1379  get_selected_entities(selector, bulk.buckets(type), entities);
1380  return entities.size();
1381 }
1382 
1383 
1384 template <typename INT>
1385 void write_side_data_to_ioss( Ioss::GroupingEntity & io ,
1386  mesh::Part * const part ,
1387  const mesh::BulkData & bulk_data,
1388  const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/ )
1389 {
1390  //std::cout << "tmp write_side_data_to_ioss part= " << part->name() << std::endl;
1391  const mesh::MetaData & meta_data = mesh::MetaData::get(*part);
1392 
1393  std::vector<mesh::Entity *> sides ;
1394  size_t num_sides = get_entities(*part, bulk_data, sides, false, anded_selector);
1395 
1396  std::vector<INT> elem_side_ids; elem_side_ids.reserve(num_sides*2);
1397 
1398  stk_classic::mesh::EntityRank elem_rank = element_rank(meta_data);
1399  for(size_t i=0; i<num_sides; ++i) {
1400 
1401  const mesh::Entity &side = *sides[i] ;
1402  const mesh::PairIterRelation side_elem = side.relations( elem_rank );
1403 
1404  // Which element to use?
1405  // Any locally owned element that has the "correct" orientation
1406 
1407  const size_t num_side_elem = side_elem.size();
1408 
1409  const mesh::Relation *rel = NULL ;
1410 
1411  for ( size_t j = 0 ; j < num_side_elem && ! rel ; ++j ) {
1412  const mesh::Entity & elem = *side_elem[j].entity();
1413 
1414  if ( elem.bucket().member( meta_data.locally_owned_part() ) &&
1415  (num_side_elem == 1 || stk_classic::mesh::fem::element_side_polarity(elem, side, side_elem[j].identifier())) ) {
1416  rel = &side_elem[j];
1417  }
1418  }
1419 
1420  if (rel == NULL) { // no suitable element found
1421  std::ostringstream oss;
1422  oss << "ERROR, no suitable element found";
1423  throw std::runtime_error(oss.str());
1424  }
1425 
1426  elem_side_ids.push_back(rel->entity()->identifier());
1427  elem_side_ids.push_back(rel->identifier() + 1) ; // Ioss is 1-based, mesh is 0-based.
1428  }
1429 
1430  const size_t num_side_written = io.put_field_data("element_side",elem_side_ids);
1431 
1432  if ( num_sides != num_side_written ) {
1433  std::ostringstream msg ;
1434 
1435  msg << "stk_classic::io::write_side_data_to_ioss FAILED for " ;
1436  msg << io.name();
1437  msg << " in Ioss::GroupingEntity::put_field_data:" ;
1438  msg << " num_sides = " << num_sides ;
1439  msg << " , num_side_written = " << num_side_written ;
1440  throw std::runtime_error( msg.str() );
1441  }
1442 
1443  const mesh::Field<double, mesh::ElementNode> *df = get_distribution_factor_field(*part);
1444  if (df != NULL) {
1445  field_data_to_ioss(df, sides, &io, "distribution_factors", Ioss::Field::MESH);
1446  }
1447 
1448  const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields();
1449  std::vector<mesh::FieldBase *>::const_iterator I = fields.begin();
1450  while (I != fields.end()) {
1451  const mesh::FieldBase *f = *I ; ++I ;
1452  const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f);
1453  if (role != NULL && *role == Ioss::Field::ATTRIBUTE) {
1454  stk_classic::io::field_data_to_ioss(f, sides, &io, f->name(), Ioss::Field::ATTRIBUTE);
1455  }
1456  }
1457 }
1458 
1459 //----------------------------------------------------------------------
1460 template <typename INT>
1461 void output_node_block(Ioss::NodeBlock &nb,
1463  const stk_classic::mesh::BulkData &bulk,
1464  const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/)
1465 {
1466  //----------------------------------
1467  // Exactly one node block to obtain the nodal coordinates and ids:
1468  // Note that the "ids" field of the nodes needs to be written
1469  // before any other bulk data that uses node ids since it sets up
1470  // the global->local mapping of nodes for the output database.
1471  // Similarly for the element "ids" field related to bulk data
1472  // using element ids.
1473  std::vector<mesh::Entity *> nodes ;
1474  size_t num_nodes = get_entities(part, bulk, nodes, true, anded_selector);
1475 
1476  std::vector<INT> node_ids; node_ids.reserve(num_nodes);
1477  for(size_t i=0; i<num_nodes; ++i) {
1478  const mesh::Entity & node = * nodes[i] ;
1479  node_ids.push_back(node.identifier());
1480  }
1481 
1482  size_t num_ids_written = nb.put_field_data("ids", node_ids);
1483  if ( num_nodes != num_ids_written) {
1484  std::ostringstream msg ;
1485  msg << " FAILED in Ioss::NodeBlock::put_field_data:" ;
1486  msg << " num_nodes = " << num_nodes ;
1487  msg << " , num_ids_written = " << num_ids_written ;
1488  throw std::runtime_error( msg.str() );
1489  }
1490 
1495  const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk);
1496  mesh::Field<double, mesh::Cartesian> *coord_field =
1497  meta_data.get_field<stk_classic::mesh::Field<double, mesh::Cartesian> >(std::string("coordinates"));
1498  assert(coord_field != NULL);
1499  field_data_to_ioss(coord_field, nodes, &nb, "mesh_model_coordinates", Ioss::Field::MESH);
1500 
1501  const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields();
1502  std::vector<mesh::FieldBase *>::const_iterator I = fields.begin();
1503  while (I != fields.end()) {
1504  const mesh::FieldBase *f = *I ; ++I ;
1505  if (stk_classic::io::is_valid_part_field(f, part_primary_entity_rank(part), part,
1506  meta_data.universal_part(), Ioss::Field::ATTRIBUTE, false)) {
1507  stk_classic::io::field_data_to_ioss(f, nodes, &nb, f->name(), Ioss::Field::ATTRIBUTE);
1508  }
1509  }
1510 }
1511 
1512 template <typename INT>
1513 void output_element_block(Ioss::ElementBlock *block,
1514  const stk_classic::mesh::BulkData &bulk,
1515  const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/)
1516 {
1517  const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk);
1518  const std::string& name = block->name();
1519  mesh::Part* part = meta_data.get_part(name);
1520 
1521  assert(part != NULL);
1522  std::vector<mesh::Entity *> elements;
1523  size_t num_elems = get_entities(*part, bulk, elements, false, anded_selector);
1524 
1525  const CellTopologyData * cell_topo =
1526  stk_classic::io::get_cell_topology(*part) ?
1527  stk_classic::io::get_cell_topology(*part) :
1528  stk_classic::mesh::fem::FEMMetaData::get(*part).get_cell_topology(*part).getCellTopologyData();
1529  if (cell_topo == NULL) {
1530  std::ostringstream msg ;
1531  msg << " INTERNAL_ERROR: Part " << part->name() << " returned NULL from get_cell_topology()";
1532  throw std::runtime_error( msg.str() );
1533  }
1534  size_t nodes_per_elem = cell_topo->node_count;
1535 
1536  std::vector<INT> elem_ids; elem_ids.reserve(num_elems);
1537  std::vector<INT> connectivity; connectivity.reserve(num_elems*nodes_per_elem);
1538 
1539  stk_classic::mesh::EntityRank no_rank = node_rank(meta_data);
1540  for (size_t i = 0; i < num_elems; ++i) {
1541 
1542  elem_ids.push_back(elements[i]->identifier());
1543 
1544  const mesh::PairIterRelation elem_nodes = elements[i]->relations(no_rank);
1545 
1546  for (size_t j = 0; j < nodes_per_elem; ++j) {
1547  connectivity.push_back(elem_nodes[j].entity()->identifier());
1548  }
1549  }
1550 
1551  const size_t num_ids_written = block->put_field_data("ids", elem_ids);
1552  const size_t num_con_written = block->put_field_data("connectivity", connectivity);
1553 
1554  if ( num_elems != num_ids_written || num_elems != num_con_written ) {
1555  std::ostringstream msg ;
1556  msg << " FAILED in Ioss::ElementBlock::put_field_data:" << std::endl ;
1557  msg << " num_elems = " << num_elems << std::endl ;
1558  msg << " num_ids_written = " << num_ids_written << std::endl ;
1559  msg << " num_connectivity_written = " << num_con_written << std::endl ;
1560  throw std::runtime_error( msg.str() );
1561  }
1562 
1563  stk_classic::mesh::EntityRank elem_rank = element_rank(meta_data);
1564  const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields();
1565  std::vector<mesh::FieldBase *>::const_iterator I = fields.begin();
1566  while (I != fields.end()) {
1567  const mesh::FieldBase *f = *I ; ++I ;
1568  const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f);
1569  if (role != NULL && *role == Ioss::Field::ATTRIBUTE) {
1570  const mesh::FieldBase::Restriction &res = f->restriction(elem_rank, *part);
1571  if (res.dimension() > 0) {
1572  stk_classic::io::field_data_to_ioss(f, elements, block, f->name(), Ioss::Field::ATTRIBUTE);
1573  }
1574  }
1575  }
1576 }
1577 
1578 template <typename INT>
1579 void output_node_set(Ioss::NodeSet *ns, const stk_classic::mesh::BulkData &bulk,
1580  const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/)
1581 {
1582  const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk);
1583  const std::string& name = ns->name();
1584  stk_classic::mesh::Part* part = meta_data.get_part(name);
1585  assert(part != NULL);
1586 
1587  std::vector<stk_classic::mesh::Entity *> nodes ;
1588  size_t num_nodes = get_entities(*part, bulk, nodes, true, anded_selector);
1589 
1590  std::vector<INT> node_ids; node_ids.reserve(num_nodes);
1591  for(size_t i=0; i<num_nodes; ++i) {
1592  const stk_classic::mesh::Entity & node = * nodes[i] ;
1593  node_ids.push_back(node.identifier());
1594  }
1595 
1596  size_t num_ids_written = ns->put_field_data("ids", node_ids);
1597  if ( num_nodes != num_ids_written ) {
1598  std::ostringstream msg ;
1599  msg << " FAILED in Ioss::NodeSet::put_field_data:"
1600  << " num_nodes = " << num_nodes
1601  << ", num_ids_written = " << num_ids_written;
1602  throw std::runtime_error( msg.str() );
1603  }
1604 
1606  meta_data.get_field<stk_classic::mesh::Field<double> >("distribution_factors");
1607  if (df_field != NULL) {
1608  stk_classic::io::field_data_to_ioss(df_field, nodes, ns, "distribution_factors", Ioss::Field::MESH);
1609  }
1610 
1611  const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields();
1612  std::vector<mesh::FieldBase *>::const_iterator I = fields.begin();
1613  while (I != fields.end()) {
1614  const mesh::FieldBase *f = *I ; ++I ;
1615  const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f);
1616  if (role != NULL && *role == Ioss::Field::ATTRIBUTE) {
1617  const mesh::FieldBase::Restriction &res = f->restriction(0, *part);
1618  if (res.dimension() > 0) {
1619  stk_classic::io::field_data_to_ioss(f, nodes, ns, f->name(), Ioss::Field::ATTRIBUTE);
1620  }
1621  }
1622  }
1623 }
1624 
1625 template <typename INT>
1626 void output_side_set(Ioss::SideSet *ss,
1627  const stk_classic::mesh::BulkData &bulk,
1628  const stk_classic::mesh::Selector *anded_selector, INT dummy)
1629 {
1630  const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk);
1631  size_t block_count = ss->block_count();
1632  for (size_t i=0; i < block_count; i++) {
1633  Ioss::SideBlock *block = ss->get_block(i);
1634  if (stk_classic::io::include_entity(block)) {
1635  stk_classic::mesh::Part * const part = meta_data.get_part(block->name());
1636  stk_classic::io::write_side_data_to_ioss(*block, part, bulk, anded_selector, dummy);
1637  }
1638  }
1639 }
1640 
1641 } // namespace <blank>
1642 
1643 void write_output_db(Ioss::Region& io_region,
1644  const stk_classic::mesh::BulkData& bulk,
1645  const stk_classic::mesh::Selector *anded_selector)
1646 {
1647  const stk_classic::mesh::MetaData & meta = mesh::MetaData::get(bulk);
1648 
1649  bool ints64bit = db_api_int_size(&io_region) == 8;
1650 
1651  io_region.begin_mode( Ioss::STATE_MODEL );
1652 
1653  int64_t z64 = 0;
1654  int z32 = 0;
1655 
1656  Ioss::NodeBlock & nb = *io_region.get_node_blocks()[0];
1657  if (ints64bit)
1658  output_node_block(nb, meta.universal_part(), bulk, anded_selector, z64);
1659  else
1660  output_node_block(nb, meta.universal_part(), bulk, anded_selector, z32);
1661 
1662  //----------------------------------
1663  const Ioss::ElementBlockContainer& elem_blocks = io_region.get_element_blocks();
1664  for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
1665  it != elem_blocks.end(); ++it) {
1666  if (ints64bit)
1667  output_element_block(*it, bulk, anded_selector, z64);
1668  else
1669  output_element_block(*it, bulk, anded_selector, z32);
1670  }
1671 
1672  //----------------------------------
1673  const Ioss::NodeSetContainer& node_sets = io_region.get_nodesets();
1674  for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
1675  it != node_sets.end(); ++it) {
1676  if (ints64bit)
1677  output_node_set(*it, bulk, anded_selector, z64);
1678  else
1679  output_node_set(*it, bulk, anded_selector, z32);
1680  }
1681 
1682  //----------------------------------
1683  const Ioss::SideSetContainer& side_sets = io_region.get_sidesets();
1684  for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
1685  it != side_sets.end(); ++it) {
1686  if (ints64bit)
1687  output_side_set(*it, bulk, anded_selector, z64);
1688  else
1689  output_side_set(*it, bulk, anded_selector, z32);
1690  }
1691 
1692  io_region.end_mode( Ioss::STATE_MODEL );
1693 }
1694 
1695 //----------------------------------------------------------------------
1697 {
1698  return NULL != part.attribute<Ioss::GroupingEntity>();
1699 }
1700 
1702 {
1704 }
1705 
1708 {
1709  stk_classic::mesh::MetaData &m = mesh::MetaData::get(p);
1710  m.declare_attribute_no_delete(p,&df_field);
1711 }
1712 
1713 const Ioss::Field::RoleType* get_field_role(const stk_classic::mesh::FieldBase &f)
1714 {
1715  return f.attribute<Ioss::Field::RoleType>();
1716 }
1717 
1718 void set_field_role(stk_classic::mesh::FieldBase &f, const Ioss::Field::RoleType &role)
1719 {
1720  Ioss::Field::RoleType *my_role = new Ioss::Field::RoleType(role);
1721  stk_classic::mesh::MetaData &m = mesh::MetaData::get(f);
1722  const Ioss::Field::RoleType *check = m.declare_attribute_with_delete(f, my_role);
1723  if ( check != my_role ) {
1724  if (*check != *my_role) {
1725  std::ostringstream msg ;
1726  msg << " FAILED in IossBridge -- set_field_role:"
1727  << " The role type had already been set to " << *check
1728  << ", so it is not possible to change it to " << *my_role;
1729  throw std::runtime_error( msg.str() );
1730  }
1731  delete my_role;
1732  }
1733 }
1734 
1735 }//namespace io
1736 }//namespace stk_classic
1737 
void write_output_db(Ioss::Region &io_region, const stk_classic::mesh::BulkData &bulk, const stk_classic::mesh::Selector *anded_selector)
EntityRank face_rank() const
Returns the face rank which changes depending on spatial dimension.
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
static const SymmetricTensor33 & tag()
Singleton.
unsigned count_selected_entities(const Selector &selector, const std::vector< Bucket * > &input_buckets)
Count entities in selected buckets (selected by the given selector instance), and sorted by ID...
Definition: GetEntities.cpp:59
const Restriction & restriction(unsigned entity_rank, const Part &part) const
Query a field restriction, result is volatile until the owning meta data manager is committed...
Definition: FieldBase.hpp:127
void field_data_from_ioss(const stk_classic::mesh::FieldBase *field, std::vector< stk_classic::mesh::Entity *> &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name)
Definition: IossBridge.cpp:964
EntityRank side_rank() const
Returns the side rank which changes depending on spatial dimension.
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
Definition: FieldData.hpp:116
void define_output_db(Ioss::Region &io_region, const mesh::BulkData &bulk_data, const Ioss::Region *input_region, const stk_classic::mesh::Selector *anded_selector, const bool sort_stk_parts)
const Ioss::Field::RoleType * get_field_role(const stk_classic::mesh::FieldBase &f)
Implement an shards::ArrayDimTag for FullTensor.
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
void put_io_part_attribute(mesh::Part &part, Ioss::GroupingEntity *entity)
Definition: IossBridge.cpp:570
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
Part & globally_shared_part() const
Subset for the problem domain that is shared with another process. Ghost entities are not members of ...
Definition: MetaData.hpp:98
Implement an shards::ArrayDimTag for SymmetricTensor.
Part * get_part(const std::string &p_name, const char *required_by=NULL) const
Get an existing part by its application-defined text name.
Definition: MetaData.cpp:185
static const FullTensor36 & tag()
Singleton.
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195
unsigned primary_entity_rank() const
The primary entity type for this part.
Definition: Part.hpp:64
const FieldVector & get_fields() const
Get all defined fields.
Definition: MetaData.hpp:218
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.
bool include_entity(const Ioss::GroupingEntity *entity)
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
static const Cartesian3d & tag()
Singleton.
std::string map_topology_cell_to_ioss(const CellTopologyData *cell_top, int spatial_dimension)
Definition: IossBridge.cpp:687
An application-defined subset of a problem domain.
Definition: Part.hpp:49
void get_selected_entities(const Selector &selector, const std::vector< Bucket * > &input_buckets, std::vector< Entity * > &entities)
Get entities in selected buckets (selected by the given selector instance), and sorted by ID...
Definition: GetEntities.cpp:77
bool is_FEM_initialized() const
This function returns whether this class has been initialized or not.
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part...
Definition: MetaData.hpp:88
Part & locally_owned_part() const
Subset for the problem domain that is owned by the local process. Ghost entities are not members of t...
Definition: MetaData.hpp:93
Part & declare_part(const std::string &name, fem::CellTopology cell_topology)
Declare a part with a given cell topology.
bool is_part_io_part(stk_classic::mesh::Part &part)
Implement an shards::ArrayDimTag for Cartesian coordinate dimensions.
const std::string & name() const
Application-defined text name of this part.
Definition: Part.hpp:67
Part & declare_part(const std::string &p_name, EntityRank rank)
Declare a part of the given name and entity rank Redeclaration returns the previously declared part...
Definition: MetaData.cpp:214
void get_entities(const BulkData &mesh, EntityRank entity_rank, std::vector< Entity *> &entities)
Get all entities of the specified type, sorted by ID.
Definition: GetEntities.cpp:25
const PartVector & supersets() const
Parts that are supersets of this part.
Definition: Part.hpp:75
const A * attribute() const
Query attribute that has been attached to this part.
Definition: Part.hpp:94
const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > * get_distribution_factor_field(const stk_classic::mesh::Part &p)
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
const std::string & name() const
Application-defined text name of this field.
Definition: FieldBase.hpp:66
const CellTopologyData * map_topology_ioss_to_cell(const Ioss::ElementTopology *topology)
Definition: IossBridge.cpp:670
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
const PartVector & subsets() const
Parts that are subsets of this part.
Definition: Part.hpp:78
const T * declare_attribute_with_delete(Part &part, const T *attribute)
Declare an attribute on a part. Return the attribute of that type, which may be an already existing v...
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
const PartVector & get_parts() const
Query all parts of the mesh ordered by the parts&#39; ordinal.
Definition: MetaData.hpp:120
EntityRank edge_rank() const
Returns the edge rank which changes depending on spatial dimension.
bool is_valid_part_field(const stk_classic::mesh::FieldBase *field, const stk_classic::mesh::EntityRank part_type, const stk_classic::mesh::Part &part, const stk_classic::mesh::Part &universal, const Ioss::Field::RoleType filter_role, bool add_all)
Definition: IossBridge.cpp:620
size_t spatial_dimension() const
Returns the spatial dimension that was passed in through FEM_initialize.
void field_data_to_ioss(const stk_classic::mesh::FieldBase *field, std::vector< stk_classic::mesh::Entity *> &entities, Ioss::GroupingEntity *io_entity, const std::string &io_fld_name, Ioss::Field::RoleType filter_role)
Definition: IossBridge.cpp:999
void set_field_role(stk_classic::mesh::FieldBase &f, const Ioss::Field::RoleType &role)
field_type & declare_field(const std::string &name, unsigned number_of_states=1)
Declare a field of the given field_type, test name, and number of states.
const A * attribute() const
Query attribute that has been attached to this field.
Definition: FieldBase.hpp:106
void ioss_add_fields(const stk_classic::mesh::Part &part, const stk_classic::mesh::EntityRank part_type, Ioss::GroupingEntity *entity, const Ioss::Field::RoleType filter_role, const bool add_all)
Definition: IossBridge.cpp:868
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
Definition: Entity.hpp:133
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
static FEMMetaData & get(const MetaData &meta)
Getter for FEMMetaData off of a MetaData object.
void define_io_fields(Ioss::GroupingEntity *entity, Ioss::Field::RoleType role, stk_classic::mesh::Part &part, stk_classic::mesh::EntityRank part_type)
Definition: IossBridge.cpp:905
field_type * get_field(const std::string &name) const
Get a field, return NULL if it does not exist.
void remove_io_part_attribute(mesh::Part &part)
Definition: IossBridge.cpp:589
bool element_side_polarity(const Entity &elem, const Entity &side, int local_side_id)
Determine the polarity of the local side, more efficient if the local_side_id is known.
Definition: FEMHelpers.cpp:401
void set_distribution_factor_field(stk_classic::mesh::Part &p, const stk_classic::mesh::Field< double, stk_classic::mesh::ElementNode > &df_field)
std::string to_string(const T &t)
Definition: StringUtil.cpp:135
fem::CellTopology get_cell_topology(const Part &part) const
Return the cell topology associated with the given part. The cell topology is set on a part through p...
void FEM_initialize(size_t spatial_dimension, const std::vector< std::string > &in_entity_rank_names=std::vector< std::string >())
Initialize the spatial dimension and an optional list of entity rank names associated with each rank...
Definition: FEMMetaData.cpp:61