|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010, 2011 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <string.h> 00010 #include <iostream> 00011 #include <complex> 00012 00013 #include <init/Ionit_Initializer.h> 00014 #include <Ioss_SubSystem.h> 00015 #include <Ioss_NullEntity.h> 00016 00017 #include <stk_util/util/tokenize.hpp> 00018 #include <stk_io/IossBridge.hpp> 00019 00020 #include <stk_util/parallel/Parallel.hpp> 00021 00022 #include <stk_mesh/base/Types.hpp> 00023 #include <stk_mesh/base/Field.hpp> 00024 #include <stk_mesh/base/GetEntities.hpp> 00025 #include <stk_mesh/base/FieldData.hpp> 00026 #include <stk_mesh/base/MetaData.hpp> 00027 #include <stk_mesh/base/BulkData.hpp> 00028 #include <stk_mesh/fem/FEMHelpers.hpp> 00029 00030 #include <Shards_BasicTopologies.hpp> 00031 00032 namespace { 00033 00034 stk_classic::mesh::EntityRank get_entity_rank(const Ioss::GroupingEntity *entity, 00035 const stk_classic::mesh::MetaData &meta) 00036 { 00037 switch (entity->type()) { 00038 case Ioss::NODEBLOCK: 00039 return stk_classic::io::node_rank(meta); 00040 00041 case Ioss::NODESET: 00042 return stk_classic::io::node_rank(meta); 00043 00044 case Ioss::ELEMENTBLOCK: 00045 return stk_classic::io::element_rank(meta); 00046 00047 case Ioss::SUPERELEMENT: 00048 return stk_classic::io::element_rank(meta); 00049 00050 case Ioss::SIDESET: 00051 { 00052 const Ioss::SideSet *sset = dynamic_cast<const Ioss::SideSet*>(entity); 00053 assert(sset != NULL); 00054 int my_rank = sset->max_parametric_dimension(); 00055 if (my_rank == 2) 00056 return stk_classic::io::face_rank(meta); 00057 if (my_rank == 1) 00058 return stk_classic::io::edge_rank(meta); 00059 if (my_rank == 0) 00060 return stk_classic::io::node_rank(meta); 00061 else 00062 return stk_classic::mesh::InvalidEntityRank; 00063 } 00064 00065 case Ioss::SIDEBLOCK: 00066 { 00067 const Ioss::SideBlock *sblk = dynamic_cast<const Ioss::SideBlock*>(entity); 00068 assert(sblk != NULL); 00069 int rank = sblk->topology()->parametric_dimension(); 00070 if (rank == 2) 00071 return stk_classic::io::face_rank(meta); 00072 if (rank == 1) 00073 return stk_classic::io::edge_rank(meta); 00074 if (rank == 0) 00075 return stk_classic::io::node_rank(meta); 00076 else 00077 return stk_classic::mesh::InvalidEntityRank; 00078 } 00079 default: 00080 return stk_classic::mesh::InvalidEntityRank; 00081 } 00082 } 00083 00084 const CellTopologyData *map_ioss_to_topology( const std::string &element_type , 00085 const int node_count) 00086 { 00089 00090 const CellTopologyData* celltopo = NULL ; 00091 00092 const char *etype = element_type.c_str(); 00093 if ( 0 == strncasecmp( "circle" , etype , 6 ) ) { 00094 celltopo = shards::getCellTopologyData< shards::Particle >(); 00095 } 00096 else if ( 0 == strncasecmp( "sphere" , etype , 6) ) { 00097 celltopo = shards::getCellTopologyData< shards::Particle >(); 00098 } 00099 // bar, beam, truss, rod... 00100 else if ( 0 == strncasecmp( "bar" , etype , 3 ) ) { 00101 if ( node_count == 2 ) { 00102 celltopo = shards::getCellTopologyData< shards::Beam<2> >(); 00103 } 00104 else if ( node_count == 3 ) { 00105 celltopo = shards::getCellTopologyData< shards::Beam<3> >(); 00106 } 00107 } 00108 else if ( 0 == strncasecmp( "shellline2d" , etype , 11 ) ) { 00109 if ( node_count == 2) { 00110 celltopo = shards::getCellTopologyData< shards::ShellLine<2> >(); 00111 } 00112 else if ( node_count == 3) { 00113 celltopo = shards::getCellTopologyData< shards::ShellLine<3> >(); 00114 } 00115 } else if ( 0 == strncasecmp( "shell" , etype , 5 ) ) { 00116 // shell4, shell8, shell9 00117 if ( node_count == 4 ) { 00118 celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<4> >(); 00119 } 00120 else if ( node_count == 8 ) { 00121 celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<8> >(); 00122 } 00123 else if ( node_count == 9 ) { 00124 celltopo = shards::getCellTopologyData< shards::ShellQuadrilateral<9> >(); 00125 } 00126 } 00127 else if ( 0 == strncasecmp( "quad" , etype , 3 ) ) { 00128 // The 2D types would be quad4, quad8, and quad9. 00129 // The 3D types would be quad faces of a hex... quadface4, 00130 // quadface8, quadface9. 00131 if ( node_count == 4 ) { 00132 celltopo = shards::getCellTopologyData< shards::Quadrilateral<4> >(); 00133 } 00134 else if ( node_count == 8 ) { 00135 celltopo = shards::getCellTopologyData< shards::Quadrilateral<8> >(); 00136 } 00137 else if ( node_count == 9 ) { 00138 celltopo = shards::getCellTopologyData< shards::Quadrilateral<9> >(); 00139 } 00140 } 00141 else if ( 0 == strncasecmp( "trishell" , etype , 8 ) ) { 00142 if ( node_count == 3 ) { 00143 celltopo = shards::getCellTopologyData< shards::ShellTriangle<3> >(); 00144 } 00145 else if ( node_count == 6 ) { 00146 celltopo = shards::getCellTopologyData< shards::ShellTriangle<6> >(); 00147 } 00148 } 00149 00150 else if (0 == strncasecmp("triface", etype, 7) || 00151 0 == strncasecmp("tri", etype, 3)) { 00152 if ( node_count == 3 ) { 00153 celltopo = shards::getCellTopologyData< shards::Triangle<3> >(); 00154 } 00155 else if ( node_count == 4 ) { 00156 celltopo = shards::getCellTopologyData< shards::Triangle<4> >(); 00157 } 00158 else if ( node_count == 6 ) { 00159 celltopo = shards::getCellTopologyData< shards::Triangle<6> >(); 00160 } 00161 } 00162 00163 else if ( 0 == strncasecmp( "pyramid" , etype , 7 ) ) { 00164 if ( node_count == 5 ) { 00165 celltopo = shards::getCellTopologyData< shards::Pyramid<5> >(); 00166 } 00167 else if ( node_count == 13 ) { 00168 celltopo = shards::getCellTopologyData< shards::Pyramid<13> >(); 00169 } 00170 else if ( node_count == 14 ) { 00171 celltopo = shards::getCellTopologyData< shards::Pyramid<14> >(); 00172 } 00173 } 00174 00176 else if ( 0 == strncasecmp( "tetra" , etype , 5 ) ) { 00177 if ( node_count == 4 ) { 00178 celltopo = shards::getCellTopologyData< shards::Tetrahedron<4> >(); 00179 } 00180 else if ( node_count == 8 ) { 00181 celltopo = shards::getCellTopologyData< shards::Tetrahedron<8> >(); 00182 } 00183 else if ( node_count == 10 ) { 00184 celltopo = shards::getCellTopologyData< shards::Tetrahedron<10> >(); 00185 } 00186 } 00187 else if ( 0 == strncasecmp( "wedge" , etype , 5 ) ) { 00188 if ( node_count == 6 ) { 00189 celltopo = shards::getCellTopologyData< shards::Wedge<6> >(); 00190 } 00191 else if ( node_count == 15 ) { 00192 celltopo = shards::getCellTopologyData< shards::Wedge<15> >(); 00193 } 00194 else if ( node_count == 18 ) { 00195 celltopo = shards::getCellTopologyData< shards::Wedge<18> >(); 00196 } 00197 } 00198 else if ( 0 == strncasecmp( "hex" , etype , 3 ) ) { 00199 if ( node_count == 8 ) { 00200 celltopo = shards::getCellTopologyData< shards::Hexahedron<8> >(); 00201 } 00202 else if ( node_count == 20 ) { 00203 celltopo = shards::getCellTopologyData< shards::Hexahedron<20> >(); 00204 } 00205 else if ( node_count == 27 ) { 00206 celltopo = shards::getCellTopologyData< shards::Hexahedron<27> >(); 00207 } 00208 } 00209 00210 else if (0 == strncasecmp("edge", etype, 4)) { 00211 if ( node_count == 2) { 00212 // edge2, edge2d2, edge3d2 00213 celltopo = shards::getCellTopologyData< shards::Line<2> >(); 00214 } 00215 else if ( node_count == 3) { 00216 // edge3, edge2d3, edge3d3 00217 celltopo = shards::getCellTopologyData< shards::Line<3> >(); 00218 } 00219 } 00220 00221 else if (0 == strncasecmp("node", etype, 4)) { 00222 celltopo = shards::getCellTopologyData< shards::Node >(); 00223 } 00224 00225 if ( NULL == celltopo ) { 00226 std::ostringstream oss; 00227 oss << "ERROR, unsupported topology name = '" << element_type 00228 << "' , node_count = " << node_count; 00229 throw std::runtime_error(oss.str()); 00230 } 00231 00232 return celltopo; 00233 } 00234 00235 template <typename T> 00236 const stk_classic::mesh::FieldBase *declare_ioss_field_internal(stk_classic::mesh::MetaData &meta, 00237 stk_classic::mesh::EntityRank type, 00238 stk_classic::mesh::Part &part, 00239 const Ioss::Field &io_field, 00240 bool use_cartesian_for_scalar, T /*dummy*/) 00241 { 00242 stk_classic::mesh::FieldBase *field_ptr = NULL; 00243 std::string field_type = io_field.transformed_storage()->name(); 00244 std::string name = io_field.get_name(); 00245 size_t num_components = io_field.transformed_storage()->component_count(); 00246 00247 if (field_type == "scalar" || num_components == 1) { 00248 if (!use_cartesian_for_scalar) { 00249 stk_classic::mesh::Field<double> & field = meta.declare_field<stk_classic::mesh::Field<double> >(name); 00250 stk_classic::mesh::put_field(field, type, part); 00251 field_ptr = &field; 00252 } else { 00253 stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> & field = 00254 meta.declare_field<stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> >(name); 00255 stk_classic::mesh::put_field(field, type, part, 1); 00256 field_ptr = &field; 00257 } 00258 } 00259 else if (field_type == "vector_2d") { 00260 stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> & field = 00261 meta.declare_field<stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> >(name); 00262 stk_classic::mesh::put_field(field, type, part, 2); 00263 field_ptr = &field; 00264 } 00265 else if (field_type == "vector_3d") { 00266 stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> & field = 00267 meta.declare_field<stk_classic::mesh::Field<double, 00268 stk_classic::mesh::Cartesian> >(name); 00269 stk_classic::mesh::put_field(field, type, part, 3); 00270 field_ptr = &field; 00271 } 00272 else if (field_type == "sym_tensor_33") { 00273 stk_classic::mesh::Field<double, stk_classic::mesh::SymmetricTensor> & field = 00274 meta.declare_field<stk_classic::mesh::Field<double, 00275 stk_classic::mesh::SymmetricTensor> >(name); 00276 stk_classic::mesh::put_field(field, type, part, 6); 00277 field_ptr = &field; 00278 } 00279 else if (field_type == "full_tensor_36") { 00280 stk_classic::mesh::Field<double, stk_classic::mesh::FullTensor> & field = 00281 meta.declare_field<stk_classic::mesh::Field<double, 00282 stk_classic::mesh::FullTensor> >(name); 00283 stk_classic::mesh::put_field(field, type, part, 9); 00284 field_ptr = &field; 00285 } 00286 else { 00287 // Just create a field with the correct number of components... 00288 stk_classic::mesh::Field<double,shards::ArrayDimension> & field = 00289 meta.declare_field<stk_classic::mesh::Field<double,shards::ArrayDimension> >(name); 00290 stk_classic::mesh::put_field(field, type, part, num_components); 00291 field_ptr = &field; 00292 } 00293 00294 if (field_ptr != NULL) { 00295 stk_classic::io::set_field_role(*field_ptr, io_field.get_role()); 00296 } 00297 return field_ptr; 00298 } 00299 00300 const stk_classic::mesh::FieldBase *declare_ioss_field(stk_classic::mesh::MetaData &meta, 00301 stk_classic::mesh::EntityRank type, 00302 stk_classic::mesh::Part &part, 00303 const Ioss::Field &io_field, 00304 bool use_cartesian_for_scalar) 00305 { 00306 const stk_classic::mesh::FieldBase *field_ptr = NULL; 00307 if (io_field.get_type() == Ioss::Field::INTEGER) { 00308 field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, (int)1); 00309 } else if (io_field.get_type() == Ioss::Field::REAL) { 00310 field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, (double)1.0); 00311 } else if (io_field.get_type() == Ioss::Field::COMPLEX) { 00312 field_ptr = declare_ioss_field_internal(meta, type, part, io_field, use_cartesian_for_scalar, std::complex<double>(0.0,0.0)); 00313 } else { 00314 std::ostringstream errmsg; 00315 errmsg << "ERROR: Unrecognized field type for IO field '" 00316 << io_field.get_name() << "'."; 00317 throw std::runtime_error(errmsg.str()); 00318 } 00319 return field_ptr; 00320 } 00321 00322 template <typename T> 00323 void internal_field_data_from_ioss(const Ioss::Field &io_field, 00324 const stk_classic::mesh::FieldBase *field, 00325 std::vector<stk_classic::mesh::Entity*> &entities, 00326 Ioss::GroupingEntity *io_entity, 00327 T /*dummy */) 00328 { 00329 size_t field_component_count = io_field.transformed_storage()->component_count(); 00330 00331 std::vector<T> io_field_data; 00332 size_t io_entity_count = io_entity->get_field_data(io_field.get_name(), io_field_data); 00333 assert(io_field_data.size() == entities.size() * field_component_count); 00334 00335 size_t entity_count = entities.size(); 00336 00337 if (io_entity_count != entity_count) { 00338 std::ostringstream errmsg; 00339 errmsg << "ERROR: Field count mismatch for IO field '" 00340 << io_field.get_name() << "'. The IO system has " << io_entity_count 00341 << " entries, but the stk:mesh system has " << entity_count 00342 << " entries. The two counts must match."; 00343 throw std::runtime_error(errmsg.str()); 00344 } 00345 00346 for (size_t i=0; i < entity_count; ++i) { 00349 if (entities[i] != NULL) { 00350 T *fld_data = (T*)stk_classic::mesh::field_data(*field, *entities[i]); 00351 assert(fld_data != NULL); 00352 for(size_t j=0; j<field_component_count; ++j) { 00353 fld_data[j] = io_field_data[i*field_component_count+j]; 00354 } 00355 } 00356 } 00357 } 00358 00359 template <typename T> 00360 void internal_field_data_to_ioss(const Ioss::Field &io_field, 00361 const stk_classic::mesh::FieldBase *field, 00362 std::vector<stk_classic::mesh::Entity*> &entities, 00363 Ioss::GroupingEntity *io_entity, 00364 T /*dummy */) 00365 { 00366 size_t field_component_count = io_field.transformed_storage()->component_count(); 00367 size_t entity_count = entities.size(); 00368 00369 std::vector<T> io_field_data(entity_count*field_component_count); 00370 00371 for (size_t i=0; i < entity_count; ++i) { 00374 if (entities[i] != NULL) { 00375 T *fld_data = (T*)stk_classic::mesh::field_data(*field, *entities[i]); 00376 assert(fld_data != NULL); 00377 for(size_t j=0; j<field_component_count; ++j) { 00378 io_field_data[i*field_component_count+j] = fld_data[j]; 00379 } 00380 } else { 00381 for(size_t j=0; j<field_component_count; ++j) { 00382 io_field_data[i*field_component_count+j] = 0; 00383 } 00384 } 00385 } 00386 00387 size_t io_entity_count = io_entity->put_field_data(io_field.get_name(), io_field_data); 00388 assert(io_field_data.size() == entities.size() * field_component_count); 00389 00390 if (io_entity_count != entity_count) { 00391 std::ostringstream errmsg; 00392 errmsg << "ERROR: Field count mismatch for IO field '" 00393 << io_field.get_name() << "'. The IO system has " << io_entity_count 00394 << " entries, but the stk:mesh system has " << entity_count 00395 << " entries. The two counts must match."; 00396 throw std::runtime_error(errmsg.str()); 00397 } 00398 } 00399 00400 }//namespace <empty> 00401 00402 namespace stk_classic { 00403 namespace io { 00404 00405 size_t db_api_int_size(const Ioss::GroupingEntity *entity) 00406 { 00407 return entity->get_database()->int_byte_size_api(); 00408 } 00409 00410 bool invalid_rank(stk_classic::mesh::EntityRank rank) 00411 { 00412 return rank == mesh::InvalidEntityRank; 00413 } 00414 00415 stk_classic::mesh::EntityRank part_primary_entity_rank(const stk_classic::mesh::Part &part) 00416 { 00417 if (mesh::MetaData::get(part).universal_part() == part) { 00418 return stk_classic::mesh::fem::FEMMetaData::NODE_RANK; 00419 } 00420 else { 00421 return part.primary_entity_rank(); 00422 } 00423 } 00424 00425 stk_classic::mesh::EntityRank element_rank(const stk_classic::mesh::MetaData &meta) 00426 { 00427 return stk_classic::mesh::fem::FEMMetaData::get(meta).element_rank(); 00428 } 00429 00430 stk_classic::mesh::EntityRank side_rank(const stk_classic::mesh::MetaData &meta) 00431 { 00432 return stk_classic::mesh::fem::FEMMetaData::get(meta).side_rank(); 00433 } 00434 00435 stk_classic::mesh::EntityRank face_rank(const stk_classic::mesh::MetaData &meta) 00436 { 00437 return stk_classic::mesh::fem::FEMMetaData::get(meta).face_rank(); 00438 } 00439 00440 stk_classic::mesh::EntityRank edge_rank(const stk_classic::mesh::MetaData &meta) 00441 { 00442 return stk_classic::mesh::fem::FEMMetaData::get(meta).edge_rank(); 00443 } 00444 00445 stk_classic::mesh::EntityRank node_rank(const stk_classic::mesh::MetaData& meta) 00446 { 00447 return stk_classic::mesh::fem::FEMMetaData::NODE_RANK; 00448 } 00449 00450 void set_cell_topology(stk_classic::mesh::Part &part, const CellTopologyData * const cell_topology) 00451 { 00452 stk_classic::mesh::fem::set_cell_topology(part, cell_topology); 00453 } 00454 00455 const CellTopologyData *get_cell_topology(const stk_classic::mesh::Part &part) 00456 { 00457 return stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData(); 00458 } 00459 00460 void initialize_spatial_dimension(stk_classic::mesh::fem::FEMMetaData & fem_meta, size_t spatial_dimension, 00461 const std::vector<std::string> &entity_rank_names) 00462 { 00463 if (!fem_meta.is_FEM_initialized() ) { 00464 fem_meta.FEM_initialize(spatial_dimension, entity_rank_names); 00465 } 00466 } 00467 00468 void initialize_spatial_dimension(stk_classic::mesh::MetaData &meta, size_t spatial_dimension, 00469 const std::vector<std::string> &entity_rank_names) 00470 { 00471 stk_classic::mesh::fem::FEMMetaData & fem_meta = stk_classic::mesh::fem::FEMMetaData::get(meta); 00472 initialize_spatial_dimension(fem_meta, spatial_dimension, entity_rank_names); 00473 } 00474 00475 void get_io_field_type(const stk_classic::mesh::FieldBase *field, 00476 const stk_classic::mesh::FieldRestriction &res, 00477 std::pair<std::string, Ioss::Field::BasicType> *result) 00478 { 00479 static const std::string invalid("invalid"); 00480 static const std::string scalar("scalar"); 00481 static const std::string vector_2d("vector_2d"); 00482 static const std::string vector_3d("vector_3d"); 00483 static const std::string quaternion_2d("quaternion_2d"); 00484 static const std::string quaternion_3d("quaternion_3d"); 00485 static const std::string full_tensor_36("full_tensor_36"); 00486 static const std::string full_tensor_32("full_tensor_32"); 00487 static const std::string full_tensor_22("full_tensor_22"); 00488 static const std::string full_tensor_16("full_tensor_16"); 00489 static const std::string full_tensor_12("full_tensor_12"); 00490 static const std::string sym_tensor_33("sym_tensor_33"); 00491 static const std::string sym_tensor_31("sym_tensor_31"); 00492 static const std::string sym_tensor_21("sym_tensor_21"); 00493 static const std::string sym_tensor_13("sym_tensor_13"); 00494 static const std::string sym_tensor_11("sym_tensor_11"); 00495 static const std::string sym_tensor_10("sym_tensor_10"); 00496 static const std::string asym_tensor_03("asym_tensor_03"); 00497 static const std::string asym_tensor_02("asym_tensor_02"); 00498 static const std::string asym_tensor_01("asym_tensor_01"); 00499 static const std::string matrix_22("matrix_22"); 00500 static const std::string matrix_33("matrix_33"); 00501 00502 const unsigned rank = field->rank(); 00503 const shards::ArrayDimTag * const * const tags = field->dimension_tags(); 00504 00505 result->second = Ioss::Field::INVALID; 00506 00507 if ( field->type_is<double>() ) { 00508 result->second = Ioss::Field::REAL; 00509 } 00510 else if ( field->type_is<int>() ) { 00511 result->second = Ioss::Field::INTEGER; 00512 } 00513 00514 if ( 0 == rank ) { 00515 result->first = scalar ; 00516 } 00517 else if ( 1 == rank ) { 00518 size_t num_comp = res.stride(0); 00519 if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 1 == num_comp ) { 00520 result->first = scalar ; 00521 } 00522 else if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 2 == num_comp ) { 00523 result->first = vector_2d ; 00524 } 00525 else if ( tags[0] == & stk_classic::mesh::Cartesian::tag() && 3 == num_comp ) { 00526 result->first = vector_3d ; 00527 } 00528 else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 9 == num_comp ) { 00529 result->first = full_tensor_36 ; 00530 } 00531 else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 5 == num_comp ) { 00532 result->first = full_tensor_32 ; 00533 } 00534 else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 4 == num_comp ) { 00535 result->first = full_tensor_22 ; 00536 } 00537 else if ( tags[0] == & stk_classic::mesh::FullTensor::tag() && 3 == num_comp ) { 00538 result->first = full_tensor_12 ; 00539 } 00540 else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 6 == num_comp ) { 00541 result->first = sym_tensor_33 ; 00542 } 00543 else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 4 == num_comp ) { 00544 result->first = sym_tensor_31 ; 00545 } 00546 else if ( tags[0] == & stk_classic::mesh::SymmetricTensor::tag() && 3 == num_comp ) { 00547 result->first = sym_tensor_21 ; 00548 } 00549 } 00550 00551 if ( result->first.empty() ) { 00552 size_t num_comp = res.stride(rank-1); 00553 std::ostringstream tmp ; 00554 tmp << "Real[" << num_comp << "]" ; 00555 result->first = tmp.str(); 00556 } 00557 } 00558 00559 //---------------------------------------------------------------------- 00560 const Ioss::GroupingEntity *get_associated_ioss_entity(const mesh::Part &part) 00561 { 00562 const Ioss::GroupingEntity *entity = part.attribute<Ioss::GroupingEntity>(); 00563 if (!entity || entity->type() == Ioss::INVALID_TYPE) { 00564 return NULL; 00565 } else { 00566 return entity; 00567 } 00568 } 00569 00570 void put_io_part_attribute(mesh::Part & part, Ioss::GroupingEntity *entity) 00571 { 00572 if (part.attribute<Ioss::GroupingEntity>() != NULL) { 00573 std::string msg = "stk_classic::io::put_io_part_attribute( "; 00574 msg += part.name(); 00575 msg += " ) FAILED:"; 00576 msg += " io_part_attribute is already defined"; 00577 throw std::runtime_error( msg ); 00578 } 00579 00580 mesh::MetaData & meta = mesh::MetaData::get(part); 00581 if (entity) { 00582 meta.declare_attribute_no_delete(part, entity); 00583 } else { 00584 Ioss::GroupingEntity *attr = new Ioss::NullEntity(); 00585 meta.declare_attribute_with_delete(part, attr); 00586 } 00587 } 00588 00589 void remove_io_part_attribute(mesh::Part & part) 00590 { 00591 const Ioss::GroupingEntity *entity = part.attribute<Ioss::GroupingEntity>(); 00592 if (entity == NULL) { 00593 std::string msg = "stk_classic::io::remove_io_part_attribute( "; 00594 msg += part.name(); 00595 msg += " ) FAILED:"; 00596 msg += " io_part_attribute is not defined on this part"; 00597 throw std::runtime_error( msg ); 00598 } else { 00599 mesh::MetaData & meta = mesh::MetaData::get(part); 00600 bool success = meta.remove_attribute(part, entity); 00601 if (!success) { 00602 std::string msg = "stk_classic::io::remove_io_part_attribute( "; 00603 msg += part.name(); 00604 msg += " ) FAILED:"; 00605 msg += " meta.remove_attribute(..) returned failure."; 00606 throw std::runtime_error( msg ); 00607 } 00608 00609 if (entity->type() == Ioss::INVALID_TYPE) { 00610 delete entity; 00611 } 00612 00613 } 00614 } 00615 00620 bool is_valid_part_field(const stk_classic::mesh::FieldBase *field, 00621 const stk_classic::mesh::EntityRank part_type, 00622 const stk_classic::mesh::Part &part, 00623 const stk_classic::mesh::Part &universal, 00624 const Ioss::Field::RoleType filter_role, 00625 bool add_all) 00626 { 00627 const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*field); 00628 00629 if (!add_all && role == NULL) { 00630 return false; 00631 } 00632 00633 if (role != NULL && *role != filter_role) 00634 return false; 00635 00636 const stk_classic::mesh::FieldBase::Restriction &res = field->restriction(part_type, part); 00637 if (res.dimension() > 0) { 00638 // The field exists on the current 'part'. Now check (for 00639 // node types only) whether the 'part' is *either* the 00640 // universal_part() *or* the field *doesn't* exist on the 00641 // universal part... 00642 // Note that for "node" type parts, the IO database has a part 00643 // (nodeblock) that corresponds to the universal_part(), so 00644 // fields defined on all nodes are output on the nodeblock and 00645 // fields defined on only a subset of the parts should be 00646 // output on that subset which maps to a nodeset. For other 00647 // part types, there is no IO entity that corresponds to a 00648 // universal part, so fields must be output on the part they 00649 // exist on. There may be a problem if we start using element 00650 // sets ..., but wait until we get to that point; current code 00651 // works with current entity set. 00652 if (part_type != node_rank(mesh::MetaData::get(part)) || part == universal) { 00653 return true; 00654 } 00655 00656 const stk_classic::mesh::FieldBase::Restriction &res_universe = field->restriction(part_type, universal); 00657 if (res_universe.dimension() <= 0) { 00658 // Field exists on current part, but not on the universal 00659 // set (and this part is not the universal part) 00660 return true; 00661 } 00662 } 00663 return false; 00664 } 00665 00669 // ======================================================================== 00670 const CellTopologyData *map_topology_ioss_to_cell(const Ioss::ElementTopology *topology) 00671 { 00678 00679 std::string name = topology->name(); 00680 int io_nodes_per_element = topology->number_nodes(); 00681 00682 const CellTopologyData *cell_topology = map_ioss_to_topology(name, io_nodes_per_element); 00683 00684 return cell_topology; 00685 } 00686 00687 std::string map_topology_cell_to_ioss( const CellTopologyData *cell_top, 00688 int spatial_dimension) 00689 { 00690 std::string extype = "unknown"; 00691 00692 if (cell_top == NULL) 00693 return extype; 00694 00695 if(strcmp(cell_top->name, "super") == 0) { 00696 std::stringstream oss; 00697 oss << "super" << cell_top->node_count; 00698 return oss.str(); 00699 } 00700 else if(strncasecmp(cell_top->name, "super", 5) == 0) { 00701 return cell_top->name; 00702 } 00703 00704 switch( cell_top->key ) { 00705 case shards::Node::key : extype.assign( "node" ); break ; 00706 case shards::Particle::key : 00707 if (spatial_dimension == 2) extype = "circle1"; 00708 else extype = "sphere1"; 00709 break ; 00710 00711 case shards::Beam<2>::key : 00712 extype = "bar2"; 00713 break ; 00714 00715 case shards::Beam<3>::key : 00716 extype = "bar3"; 00717 break ; 00718 00719 case shards::Line<2>::key : 00720 extype = "edge2"; 00721 break ; 00722 case shards::Line<3>::key : 00723 extype = "edge3"; 00724 break ; 00725 00726 case shards::ShellLine<2>::key : extype.assign( "shellline2d2" ); break ; 00727 case shards::ShellLine<3>::key : extype.assign( "shellline2d3" ); break ; 00728 00729 case shards::Triangle<3>::key : 00730 extype = "tri3"; 00731 break ; 00732 case shards::Triangle<4>::key : 00733 extype = "tri4"; 00734 break ; 00735 case shards::Triangle<6>::key : 00736 extype = "tri6"; 00737 break ; 00738 00739 case shards::ShellTriangle<3>::key : extype.assign( "trishell3" ); break ; 00740 case shards::ShellTriangle<6>::key : extype.assign( "trishell6" ); break ; 00741 00742 case shards::Quadrilateral<4>::key : 00743 extype = "quad4"; 00744 break ; 00745 case shards::Quadrilateral<8>::key : 00746 extype = "quad8"; 00747 break ; 00748 case shards::Quadrilateral<9>::key : 00749 extype = "quad9"; 00750 break ; 00751 00752 case shards::ShellQuadrilateral<4>::key : extype.assign( "shell4" ); break ; 00753 case shards::ShellQuadrilateral<8>::key : extype.assign( "shell8" ); break ; 00754 case shards::ShellQuadrilateral<9>::key : extype.assign( "shell9" ); break ; 00755 00756 case shards::Tetrahedron< 4>::key : extype.assign( "tetra4" ); break ; 00757 case shards::Tetrahedron<8>::key : extype.assign( "tetra8" ); break ; 00758 case shards::Tetrahedron<10>::key : extype.assign( "tetra10" ); break ; 00759 00760 case shards::Pyramid< 5>::key : extype.assign( "pyramid5" ); break ; 00761 case shards::Pyramid<13>::key : extype.assign( "pyramid13" ); break ; 00762 case shards::Pyramid<14>::key : extype.assign( "pyramid14" ); break ; 00763 00764 case shards::Wedge< 6>::key : extype.assign( "wedge6" ); break ; 00765 case shards::Wedge<15>::key : extype.assign( "wedge15" ); break ; 00766 case shards::Wedge<18>::key : extype.assign( "wedge18" ); break ; 00767 00768 case shards::Hexahedron< 8>::key : extype.assign( "hex8" ); break ; 00769 case shards::Hexahedron<20>::key : extype.assign( "hex20" ); break ; 00770 case shards::Hexahedron<27>::key : extype.assign( "hex27" ); break ; 00771 00772 default: 00773 std::ostringstream oss; 00774 oss << "stk_classic::io::map_topology_to_ioss( '" << cell_top->name 00775 << "' ) ERROR unmapped topology" << std::endl ; 00776 throw std::runtime_error(oss.str()); 00777 } 00778 00779 return extype ; 00780 } 00781 00782 void internal_part_processing(Ioss::GroupingEntity *entity, stk_classic::mesh::fem::FEMMetaData &meta) 00783 { 00784 internal_part_processing(entity, meta.get_meta_data(meta)); 00785 } 00786 00787 void internal_part_processing(Ioss::EntityBlock *entity, stk_classic::mesh::fem::FEMMetaData &meta) 00788 { 00789 internal_part_processing(entity, meta.get_meta_data(meta)); 00790 } 00791 00792 void internal_part_processing(Ioss::GroupingEntity *entity, stk_classic::mesh::MetaData &meta) 00793 { 00794 if (include_entity(entity)) { 00795 stk_classic::mesh::fem::FEMMetaData * fem_meta = const_cast<stk_classic::mesh::fem::FEMMetaData *>(meta.get_attribute<stk_classic::mesh::fem::FEMMetaData>()); 00796 mesh::EntityRank type = get_entity_rank(entity, meta); 00797 if (fem_meta) { 00798 stk_classic::mesh::Part & part = fem_meta->declare_part(entity->name(), type); 00799 stk_classic::io::put_io_part_attribute(part, entity); 00800 } else { 00801 stk_classic::mesh::Part & part = meta.declare_part(entity->name(), type); 00802 stk_classic::io::put_io_part_attribute(part, entity); 00803 } 00804 } 00805 } 00806 00807 void internal_part_processing(Ioss::EntityBlock *entity, stk_classic::mesh::MetaData &meta) 00808 { 00809 if (include_entity(entity)) { 00810 mesh::EntityRank type = get_entity_rank(entity, meta); 00811 stk_classic::mesh::fem::FEMMetaData * fem_meta = const_cast<stk_classic::mesh::fem::FEMMetaData *>(meta.get_attribute<stk_classic::mesh::fem::FEMMetaData>()); 00812 //const stk_classic::mesh::fem::FEMMetaData * fem_meta = meta.get_attribute<stk_classic::mesh::fem::FEMMetaData>(); 00813 stk_classic::mesh::Part * part = NULL; 00814 if( fem_meta ) 00815 part = &fem_meta->declare_part(entity->name(), type); 00816 else 00817 part = &meta.declare_part(entity->name(), type); 00818 stk_classic::io::put_io_part_attribute(*part, entity); 00819 00820 const Ioss::ElementTopology *topology = entity->topology(); 00821 // Check spatial dimension of the element topology here so we 00822 // can issue a more meaningful error message. If the 00823 // dimension is bad and we continue to the following calls, 00824 // there is an exception and we get unintelligible (to the 00825 // user) error messages. Could also do a catch... 00826 00827 if (entity->type() == Ioss::ELEMENTBLOCK) { 00828 assert(topology != NULL); 00829 if (fem_meta && (topology->spatial_dimension() < (int)fem_meta->spatial_dimension())) { 00830 // NOTE: The comparison is '<' and not '!=' since a 2D mesh 00831 // can contain a "3d" element -- a Beam is both a 2D and 00832 // 3D element... 00833 00834 std::ostringstream msg ; 00835 msg << "\n\nERROR: Element Block " << entity->name() 00836 << " contains " << topology->name() << " elements with spatial dimension " 00837 << topology->spatial_dimension() 00838 << "\n which does not match the spatial dimension of the model which is " 00839 << fem_meta->spatial_dimension() << "\n\n"; 00840 throw std::runtime_error( msg.str() ); 00841 } 00842 } 00843 00844 const CellTopologyData * const cell_topology = map_topology_ioss_to_cell(topology); 00845 // \todo IMPLEMENT Determine whether application can work 00846 // with this topology type... Perhaps map_topology_ioss_to_cell only 00847 // returns a valid topology if the application has registered 00848 // that it can handle that specific topology. 00849 00850 if (cell_topology != NULL) { 00851 if( fem_meta ) { 00852 const stk_classic::mesh::fem::CellTopology cell_topo(cell_topology); 00853 stk_classic::mesh::fem::set_cell_topology(*part, cell_topo); 00854 } 00855 stk_classic::io::set_cell_topology(*part, cell_topology); 00856 } else { 00857 // \todo IMPLEMENT handle cell_topolgy mapping error... 00858 } 00859 stk_classic::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE, *part, type); 00860 } 00861 } 00862 00863 //---------------------------------------------------------------------- 00868 void ioss_add_fields(const stk_classic::mesh::Part &part, 00869 const stk_classic::mesh::EntityRank part_type, 00870 Ioss::GroupingEntity *entity, 00871 const Ioss::Field::RoleType filter_role, 00872 const bool add_all) 00873 { 00874 const stk_classic::mesh::MetaData & meta = mesh::MetaData::get(part); 00875 const stk_classic::mesh::Part &universal = meta.universal_part(); 00876 00877 const std::vector<mesh::FieldBase*> &fields = meta.get_fields(); 00878 00879 std::vector<mesh::FieldBase *>::const_iterator I = fields.begin(); 00880 while (I != fields.end()) { 00881 const stk_classic::mesh::FieldBase *f = *I; ++I; 00882 if (stk_classic::io::is_valid_part_field(f, part_type, part, universal, filter_role, add_all)) { 00883 const stk_classic::mesh::FieldBase::Restriction &res = f->restriction(part_type, part); 00884 std::pair<std::string, Ioss::Field::BasicType> field_type; 00885 get_io_field_type(f, res, &field_type); 00886 if (field_type.second != Ioss::Field::INVALID) { 00887 size_t entity_size = entity->get_property("entity_count").get_int(); 00888 const std::string& name = f->name(); 00889 entity->field_add(Ioss::Field(name, field_type.second, field_type.first, 00890 filter_role, entity_size)); 00891 } 00892 } 00893 } 00894 } 00895 00905 void define_io_fields(Ioss::GroupingEntity *entity, 00906 Ioss::Field::RoleType role, 00907 stk_classic::mesh::Part &part, 00908 stk_classic::mesh::EntityRank part_type) 00909 { 00910 stk_classic::mesh::MetaData &meta = mesh::MetaData::get(part); 00911 00912 bool use_cartesian_for_scalar = false; 00913 if (role == Ioss::Field::ATTRIBUTE) 00914 use_cartesian_for_scalar = true; 00915 00916 Ioss::NameList names; 00917 entity->field_describe(role, &names); 00918 00919 for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) { 00920 // \todo IMPLEMENT Need a field selection mechanism and a field naming 00921 // (ioss_name -> stk_classic::name) For now, select all and give the 00922 // stk field the same name as the ioss field. 00923 00924 // Skip the attribute field that is named "attribute" 00925 if (*I == "attribute" && names.size() > 1) 00926 continue; 00927 00928 // \todo IMPLEMENT Need to determine whether these are 00929 // multi-state fields or constant, or interpolated, or ... 00930 Ioss::Field io_field = entity->get_field(*I); 00931 declare_ioss_field(meta, part_type, part, io_field, use_cartesian_for_scalar); 00932 } 00933 } 00934 00935 template <typename INT> 00936 void get_entity_list(Ioss::GroupingEntity *io_entity, 00937 stk_classic::mesh::EntityRank part_type, 00938 const stk_classic::mesh::BulkData &bulk, 00939 std::vector<stk_classic::mesh::Entity*> &entities, INT /*dummy*/) 00940 { 00941 std::vector<INT> ids ; 00942 io_entity->get_field_data("ids", ids); 00943 00944 size_t count = ids.size(); 00945 entities.reserve(count); 00946 00947 for(size_t i=0; i<count; ++i) { 00948 entities.push_back(bulk.get_entity( part_type, ids[i] )); 00949 } 00950 } 00951 00952 void get_entity_list(Ioss::GroupingEntity *io_entity, 00953 stk_classic::mesh::EntityRank part_type, 00954 const stk_classic::mesh::BulkData &bulk, 00955 std::vector<stk_classic::mesh::Entity*> &entities) 00956 { 00957 if (db_api_int_size(io_entity) == 4) { 00958 get_entity_list(io_entity, part_type, bulk, entities, (int)0); 00959 } else { 00960 get_entity_list(io_entity, part_type, bulk, entities, (int64_t)0); 00961 } 00962 } 00963 00964 void field_data_from_ioss(const stk_classic::mesh::FieldBase *field, 00965 std::vector<stk_classic::mesh::Entity*> &entities, 00966 Ioss::GroupingEntity *io_entity, 00967 const std::string &io_fld_name) 00968 { 00971 00972 if (field != NULL && io_entity->field_exists(io_fld_name)) { 00973 const Ioss::Field &io_field = io_entity->get_fieldref(io_fld_name); 00974 if (field->type_is<double>()) { 00975 internal_field_data_from_ioss(io_field, field, entities, io_entity, 00976 static_cast<double>(1.0)); 00977 } else if (field->type_is<int>()) { 00978 // Make sure the IO field type matches the STK field type. 00979 // By default, all IO fields are created of type 'double' 00980 if (db_api_int_size(io_entity) == 4) { 00981 if (io_field.get_type() != Ioss::Field::INTEGER) { 00982 Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field); 00983 tmp.reset_type(Ioss::Field::INTEGER); 00984 } 00985 internal_field_data_from_ioss(io_field, field, entities, io_entity, 00986 static_cast<int>(1)); 00987 } else { 00988 if (io_field.get_type() != Ioss::Field::INT64) { 00989 Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field); 00990 tmp.reset_type(Ioss::Field::INT64); 00991 } 00992 internal_field_data_from_ioss(io_field, field, entities, io_entity, 00993 static_cast<int64_t>(1)); 00994 } 00995 } 00996 } 00997 } 00998 00999 void field_data_to_ioss(const stk_classic::mesh::FieldBase *field, 01000 std::vector<stk_classic::mesh::Entity*> &entities, 01001 Ioss::GroupingEntity *io_entity, 01002 const std::string &io_fld_name, 01003 Ioss::Field::RoleType filter_role) 01004 { 01007 01008 if (field != NULL && io_entity->field_exists(io_fld_name)) { 01009 const Ioss::Field &io_field = io_entity->get_fieldref(io_fld_name); 01010 if (io_field.get_role() == filter_role) { 01011 if (field->type_is<double>()) { 01012 internal_field_data_to_ioss(io_field, field, entities, io_entity, 01013 static_cast<double>(1.0)); 01014 } else if (field->type_is<int>()) { 01015 if (io_field.get_type() != Ioss::Field::INTEGER) { 01016 Ioss::Field &tmp = const_cast<Ioss::Field&>(io_field); 01017 tmp.reset_type(Ioss::Field::INTEGER); 01018 } 01019 // FIX 64? 01020 internal_field_data_to_ioss(io_field, field, entities, io_entity, 01021 static_cast<int>(1)); 01022 } 01023 } 01024 } 01025 } 01026 01027 //---------------------------------------------------------------------- 01028 01029 // ---------------------------------------------------------------------- 01030 // Returns true if 'entity' should be a 'part' in the analysis mesh. 01031 // Returns false if the application is only using a subset of the 01032 // database entities and this entity is not to be used. The 01033 // "omitted" property is set by the application during parsing or 01034 // pre-mesh reading time. 01035 bool include_entity(const Ioss::GroupingEntity *entity) 01036 { 01037 assert(entity); 01038 01039 // Check whether entity has "omitted" property... 01040 bool omitted = (entity->property_exists("omitted")) && 01041 (entity->get_property("omitted").get_int() == 1); 01042 01043 return !omitted; 01044 } 01045 01046 namespace { 01047 01048 void define_side_block(stk_classic::mesh::Part &part, 01049 Ioss::SideSet *sset, 01050 stk_classic::mesh::EntityRank type, 01051 size_t side_count, int spatial_dimension) 01052 { 01053 const stk_classic::mesh::EntityRank siderank = side_rank(mesh::MetaData::get(part)); 01054 const stk_classic::mesh::EntityRank edgerank = edge_rank(mesh::MetaData::get(part)); 01055 ThrowRequire(type == siderank || type == edgerank); 01056 01057 const CellTopologyData *const side_topology = stk_classic::io::get_cell_topology(part) ? 01058 stk_classic::io::get_cell_topology(part) : 01059 stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData(); 01060 01061 if (side_topology == NULL && side_count > 0) { 01062 // Non-empty side blocks must have an associated topology 01063 std::ostringstream msg ; 01064 msg << " INTERNAL_ERROR: Part " << part.name() << " returned NULL from get_cell_topology()"; 01065 throw std::runtime_error( msg.str() ); 01066 } 01067 01068 std::string io_topo = map_topology_cell_to_ioss(side_topology, spatial_dimension); 01069 std::string element_topo_name = "unknown"; 01070 01071 // Get sideblock parent element topology quantities... 01072 // Try to decode from part name... 01073 std::vector<std::string> tokens; 01074 stk_classic::util::tokenize(part.name(), "_", tokens); 01075 if (tokens.size() >= 4) { 01076 // Name of form: "name_eltopo_sidetopo_id" or 01077 // "name_block_id_sidetopo_id" 01078 // "name" is typically "surface". 01079 const Ioss::ElementTopology *element_topo = Ioss::ElementTopology::factory(tokens[tokens.size()-3], true); 01080 if (element_topo != NULL) { 01081 element_topo_name = element_topo->name(); 01082 } 01083 } 01084 01085 Ioss::SideBlock *side_block = new Ioss::SideBlock( sset->get_database() , 01086 part.name() , 01087 io_topo, element_topo_name, side_count); 01088 assert(sset->get_side_block(part.name()) == NULL); 01089 sset->add(side_block); 01090 01091 const mesh::Field<double, mesh::ElementNode> *df = get_distribution_factor_field(part); 01092 if (df != NULL) { 01093 int nodes_per_side = side_topology->node_count; 01094 std::string storage_type = "Real["; 01095 storage_type += Ioss::Utils::to_string(nodes_per_side); 01096 storage_type += "]"; 01097 side_block->field_add(Ioss::Field("distribution_factors", Ioss::Field::REAL, storage_type, 01098 Ioss::Field::MESH, side_count)); 01099 } 01100 01101 // Add the attribute fields. 01102 ioss_add_fields(part, part_primary_entity_rank(part), side_block, Ioss::Field::ATTRIBUTE); 01103 } 01104 01105 void define_side_blocks(stk_classic::mesh::Part &part, 01106 const stk_classic::mesh::BulkData &bulk_data, 01107 Ioss::SideSet *sset, 01108 stk_classic::mesh::EntityRank type, 01109 int spatial_dimension, 01110 const stk_classic::mesh::Selector *anded_selector) 01111 { 01112 mesh::MetaData & meta = mesh::MetaData::get(part); 01113 ThrowRequire(type == face_rank(meta) || type == edge_rank(meta)); 01114 01115 const stk_classic::mesh::PartVector &blocks = part.subsets(); 01116 if (blocks.size() > 0) { 01117 for (size_t j = 0; j < blocks.size(); j++) { 01118 mesh::Part & side_block_part = *blocks[j]; 01119 stk_classic::mesh::EntityRank side_rank = side_block_part.primary_entity_rank(); 01120 mesh::Selector selector = meta.locally_owned_part() & side_block_part; 01121 if (anded_selector) selector &= *anded_selector; 01122 01123 size_t num_side = count_selected_entities(selector, bulk_data.buckets(side_rank)); 01124 01125 define_side_block(side_block_part, sset, side_rank, num_side, spatial_dimension); 01126 } 01127 } else { 01128 stk_classic::mesh::EntityRank side_rank = part.primary_entity_rank(); 01129 mesh::Selector selector = meta.locally_owned_part() & part; 01130 if (anded_selector) selector &= *anded_selector; 01131 size_t num_side = count_selected_entities(selector, bulk_data.buckets(side_rank)); 01132 define_side_block(part, sset, side_rank, num_side, spatial_dimension); 01133 } 01134 } 01135 01136 //---------------------------------------------------------------------- 01137 //---------------------------------------------------------------------- 01138 //---------------------------------------------------------------------- 01139 01140 void define_node_block(stk_classic::mesh::Part &part, 01141 const stk_classic::mesh::BulkData &bulk, 01142 Ioss::Region &io_region, 01143 const stk_classic::mesh::Selector *anded_selector) 01144 { 01145 //-------------------------------- 01146 // Set the spatial dimension: 01147 mesh::MetaData & meta = mesh::MetaData::get(part); 01148 01153 mesh::Field<double, mesh::Cartesian> *coord_field = 01154 meta.get_field<stk_classic::mesh::Field<double, mesh::Cartesian> >(std::string("coordinates")); 01155 assert(coord_field != NULL); 01156 const mesh::FieldBase::Restriction &res = coord_field->restriction(node_rank(meta), part); 01157 01161 const int spatial_dim = res.dimension() ; 01162 io_region.property_add( Ioss::Property("spatial_dimension", spatial_dim)); 01163 01164 //-------------------------------- 01165 // Create the special universal node block: 01166 01167 mesh::Selector selector = meta.locally_owned_part() | meta.globally_shared_part(); 01168 if (anded_selector) selector &= *anded_selector; 01169 01170 size_t num_nodes = count_selected_entities(selector, bulk.buckets(node_rank(meta))); 01171 01172 const std::string name("nodeblock_1"); 01173 01174 Ioss::NodeBlock * const nb = new Ioss::NodeBlock(io_region.get_database(), 01175 name, num_nodes, spatial_dim); 01176 io_region.add( nb ); 01177 01178 // Add the attribute fields. 01179 ioss_add_fields(part, part_primary_entity_rank(part), nb, Ioss::Field::ATTRIBUTE); 01180 } 01181 01182 01183 void define_element_block(stk_classic::mesh::Part &part, 01184 const stk_classic::mesh::BulkData &bulk, 01185 Ioss::Region &io_region, 01186 const stk_classic::mesh::Selector *anded_selector) 01187 { 01188 01189 mesh::MetaData & meta = mesh::MetaData::get(part); 01190 const stk_classic::mesh::EntityRank elem_rank = element_rank(meta); 01191 01192 const CellTopologyData * const cell_top = 01193 stk_classic::io::get_cell_topology(part) ? 01194 stk_classic::io::get_cell_topology(part) : 01195 stk_classic::mesh::fem::FEMMetaData::get(part).get_cell_topology(part).getCellTopologyData(); 01196 01197 if (cell_top == NULL) { 01198 std::ostringstream msg ; 01199 msg << " INTERNAL_ERROR: Part " << part.name() << " returned NULL from get_cell_topology()"; 01200 throw std::runtime_error( msg.str() ); 01201 } 01202 01203 mesh::Selector selector = meta.locally_owned_part() & part; 01204 if (anded_selector) selector &= *anded_selector; 01205 const size_t num_elems = count_selected_entities( selector, bulk.buckets(elem_rank)); 01206 01207 int spatial_dim = io_region.get_property("spatial_dimension").get_int(); 01208 01209 // Defer the counting of attributes until after we define the 01210 // element block so we can count them as we add them as fields to 01211 // the element block 01212 Ioss::ElementBlock *eb = new Ioss::ElementBlock(io_region.get_database() , 01213 part.name() , 01214 map_topology_cell_to_ioss(cell_top, spatial_dim) , 01215 num_elems); 01216 io_region.add(eb); 01217 01218 // Add the attribute fields. 01219 ioss_add_fields(part, part_primary_entity_rank(part), eb, Ioss::Field::ATTRIBUTE); 01220 } 01221 01222 void define_side_set(stk_classic::mesh::Part &part, 01223 const stk_classic::mesh::BulkData &bulk, 01224 Ioss::Region &io_region, 01225 const stk_classic::mesh::Selector *anded_selector) 01226 { 01227 const stk_classic::mesh::EntityRank si_rank = side_rank(mesh::MetaData::get(part)); 01228 01229 bool create_sideset = true; 01230 if (part.subsets().empty()) { 01231 // Only define a sideset for this part if its superset part is 01232 // not a side-containing part.. (i.e., this part is not a subset part 01233 // in a surface...) 01234 const stk_classic::mesh::PartVector &supersets = part.supersets(); 01235 for (size_t i=0; i < supersets.size(); i++) { 01236 if (is_part_io_part(*supersets[i]) && supersets[i]->primary_entity_rank() == si_rank) { 01237 create_sideset = false; 01238 break; 01239 } 01240 } 01241 } 01242 if (create_sideset) { 01243 Ioss::SideSet * const ss = new Ioss::SideSet(io_region.get_database(), part.name()); 01244 01245 io_region.add(ss); 01246 int spatial_dim = io_region.get_property("spatial_dimension").get_int(); 01247 define_side_blocks(part, bulk, ss, si_rank, spatial_dim, anded_selector); 01248 } 01249 } 01250 01251 void define_node_set(stk_classic::mesh::Part &part, 01252 const stk_classic::mesh::BulkData &bulk, 01253 Ioss::Region &io_region, 01254 const stk_classic::mesh::Selector *anded_selector) 01255 { 01256 mesh::MetaData & meta = mesh::MetaData::get(part); 01257 01258 mesh::Selector selector = ( meta.locally_owned_part() | meta.globally_shared_part() ) & part; 01259 if (anded_selector) selector &= *anded_selector; 01260 01261 const size_t num_nodes = 01262 count_selected_entities(selector, bulk.buckets(node_rank(meta))); 01263 01264 Ioss::NodeSet * const ns = 01265 new Ioss::NodeSet( io_region.get_database(), part.name(), num_nodes); 01266 io_region.add(ns); 01267 01268 // Add the attribute fields. 01269 ioss_add_fields(part, part_primary_entity_rank(part), ns, Ioss::Field::ATTRIBUTE); 01270 } 01271 } // namespace <blank> 01272 01273 struct part_compare { 01274 bool operator() (stk_classic::mesh::Part *i, stk_classic::mesh::Part *j) { return (i->name() < j->name()); } 01275 }; 01276 01277 void define_output_db(Ioss::Region & io_region , 01278 const mesh::BulkData &bulk_data, 01279 const Ioss::Region *input_region, 01280 const stk_classic::mesh::Selector *anded_selector, 01281 const bool sort_stk_parts) 01282 { 01283 const mesh::MetaData & meta_data = mesh::MetaData::get(bulk_data); 01284 01285 const stk_classic::mesh::EntityRank no_rank = node_rank(meta_data); 01286 const stk_classic::mesh::EntityRank el_rank = element_rank(meta_data); 01287 const stk_classic::mesh::EntityRank fa_rank = face_rank(meta_data); 01288 const stk_classic::mesh::EntityRank ed_rank = edge_rank(meta_data); 01289 01290 io_region.begin_mode( Ioss::STATE_DEFINE_MODEL ); 01291 01292 define_node_block(meta_data.universal_part(), bulk_data, io_region, anded_selector); 01293 01294 // All parts of the meta data: 01295 //const mesh::PartVector & all_parts = meta_data.get_parts(); 01296 const mesh::PartVector & all_parts_unsorted = meta_data.get_parts(); 01297 01298 // sort parts so they go out the same on all processors (srk: this was induced by streaming refine) 01299 mesh::PartVector all_parts = all_parts_unsorted; 01300 if (sort_stk_parts) 01301 std::sort(all_parts.begin(), all_parts.end(), part_compare()); 01302 01303 for (mesh::PartVector::const_iterator i = all_parts.begin(); 01304 i != all_parts.end(); ++i) { 01305 01306 mesh::Part * const part = *i ; 01307 01308 if (is_part_io_part(*part)) { 01309 if (invalid_rank(part->primary_entity_rank())) 01310 continue; 01311 else if (part->primary_entity_rank() == no_rank) 01312 define_node_set(*part, bulk_data, io_region, anded_selector); 01313 else if (part->primary_entity_rank() == el_rank) 01314 define_element_block(*part, bulk_data, io_region, anded_selector); 01315 else if (part->primary_entity_rank() == fa_rank) 01316 define_side_set(*part, bulk_data, io_region, anded_selector); 01317 else if (part->primary_entity_rank() == ed_rank) 01318 define_side_set(*part, bulk_data, io_region, anded_selector); 01319 } 01320 } 01321 01322 if (input_region != NULL) 01323 io_region.synchronize_id_and_name(input_region, true); 01324 01325 // for streaming refinement, each "pseudo-processor" doesn't know about others, so we pick a sort order 01326 // and use it for all pseudo-procs - the original_block_order property is used to set the order 01327 // on all procs. 01328 if (sort_stk_parts) 01329 { 01330 int offset=0; 01331 for (mesh::PartVector::const_iterator i = all_parts.begin(); 01332 i != all_parts.end(); ++i) { 01333 01334 mesh::Part * const part = *i ; 01335 01336 if (is_part_io_part(*part)) { 01337 if (invalid_rank(part->primary_entity_rank())) 01338 continue; 01339 else if (part->primary_entity_rank() == el_rank) 01340 { 01341 Ioss::GroupingEntity *element_block = io_region.get_entity(part->name()); 01342 if (element_block) 01343 { 01344 if (element_block->property_exists("original_block_order")) { 01345 element_block->property_erase("original_block_order"); 01346 } 01347 element_block->property_add(Ioss::Property("original_block_order", offset)); 01348 ++offset; 01349 } 01350 } 01351 } 01352 } 01353 } 01354 01355 io_region.end_mode( Ioss::STATE_DEFINE_MODEL ); 01356 } 01357 01358 //---------------------------------------------------------------------- 01359 01360 namespace { 01361 01362 size_t get_entities(stk_classic::mesh::Part &part, 01363 const stk_classic::mesh::BulkData &bulk, 01364 std::vector<mesh::Entity*> &entities, 01365 bool include_shared, 01366 const stk_classic::mesh::Selector *anded_selector) 01367 { 01368 mesh::MetaData & meta = mesh::MetaData::get(part); 01369 mesh::EntityRank type = part_primary_entity_rank(part); 01370 if (invalid_rank(type)) 01371 type = node_rank(meta); 01372 01373 mesh::Selector own_share = meta.locally_owned_part(); 01374 if (include_shared) 01375 own_share |= meta.globally_shared_part(); 01376 01377 mesh::Selector selector = part & own_share; 01378 if (anded_selector) selector &= *anded_selector; 01379 01380 get_selected_entities(selector, bulk.buckets(type), entities); 01381 return entities.size(); 01382 } 01383 01384 01385 template <typename INT> 01386 void write_side_data_to_ioss( Ioss::GroupingEntity & io , 01387 mesh::Part * const part , 01388 const mesh::BulkData & bulk_data, 01389 const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/ ) 01390 { 01391 //std::cout << "tmp write_side_data_to_ioss part= " << part->name() << std::endl; 01392 const mesh::MetaData & meta_data = mesh::MetaData::get(*part); 01393 01394 std::vector<mesh::Entity *> sides ; 01395 size_t num_sides = get_entities(*part, bulk_data, sides, false, anded_selector); 01396 01397 std::vector<INT> elem_side_ids; elem_side_ids.reserve(num_sides*2); 01398 01399 stk_classic::mesh::EntityRank elem_rank = element_rank(meta_data); 01400 for(size_t i=0; i<num_sides; ++i) { 01401 01402 const mesh::Entity &side = *sides[i] ; 01403 const mesh::PairIterRelation side_elem = side.relations( elem_rank ); 01404 01405 // Which element to use? 01406 // Any locally owned element that has the "correct" orientation 01407 01408 const size_t num_side_elem = side_elem.size(); 01409 01410 const mesh::Relation *rel = NULL ; 01411 01412 for ( size_t j = 0 ; j < num_side_elem && ! rel ; ++j ) { 01413 const mesh::Entity & elem = *side_elem[j].entity(); 01414 01415 if ( elem.bucket().member( meta_data.locally_owned_part() ) && 01416 (num_side_elem == 1 || stk_classic::mesh::fem::element_side_polarity(elem, side, side_elem[j].identifier())) ) { 01417 rel = &side_elem[j]; 01418 } 01419 } 01420 01421 if (rel == NULL) { // no suitable element found 01422 std::ostringstream oss; 01423 oss << "ERROR, no suitable element found"; 01424 throw std::runtime_error(oss.str()); 01425 } 01426 01427 elem_side_ids.push_back(rel->entity()->identifier()); 01428 elem_side_ids.push_back(rel->identifier() + 1) ; // Ioss is 1-based, mesh is 0-based. 01429 } 01430 01431 const size_t num_side_written = io.put_field_data("element_side",elem_side_ids); 01432 01433 if ( num_sides != num_side_written ) { 01434 std::ostringstream msg ; 01435 01436 msg << "stk_classic::io::write_side_data_to_ioss FAILED for " ; 01437 msg << io.name(); 01438 msg << " in Ioss::GroupingEntity::put_field_data:" ; 01439 msg << " num_sides = " << num_sides ; 01440 msg << " , num_side_written = " << num_side_written ; 01441 throw std::runtime_error( msg.str() ); 01442 } 01443 01444 const mesh::Field<double, mesh::ElementNode> *df = get_distribution_factor_field(*part); 01445 if (df != NULL) { 01446 field_data_to_ioss(df, sides, &io, "distribution_factors", Ioss::Field::MESH); 01447 } 01448 01449 const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields(); 01450 std::vector<mesh::FieldBase *>::const_iterator I = fields.begin(); 01451 while (I != fields.end()) { 01452 const mesh::FieldBase *f = *I ; ++I ; 01453 const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f); 01454 if (role != NULL && *role == Ioss::Field::ATTRIBUTE) { 01455 stk_classic::io::field_data_to_ioss(f, sides, &io, f->name(), Ioss::Field::ATTRIBUTE); 01456 } 01457 } 01458 } 01459 01460 //---------------------------------------------------------------------- 01461 template <typename INT> 01462 void output_node_block(Ioss::NodeBlock &nb, 01463 stk_classic::mesh::Part &part, 01464 const stk_classic::mesh::BulkData &bulk, 01465 const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/) 01466 { 01467 //---------------------------------- 01468 // Exactly one node block to obtain the nodal coordinates and ids: 01469 // Note that the "ids" field of the nodes needs to be written 01470 // before any other bulk data that uses node ids since it sets up 01471 // the global->local mapping of nodes for the output database. 01472 // Similarly for the element "ids" field related to bulk data 01473 // using element ids. 01474 std::vector<mesh::Entity *> nodes ; 01475 size_t num_nodes = get_entities(part, bulk, nodes, true, anded_selector); 01476 01477 std::vector<INT> node_ids; node_ids.reserve(num_nodes); 01478 for(size_t i=0; i<num_nodes; ++i) { 01479 const mesh::Entity & node = * nodes[i] ; 01480 node_ids.push_back(node.identifier()); 01481 } 01482 01483 size_t num_ids_written = nb.put_field_data("ids", node_ids); 01484 if ( num_nodes != num_ids_written) { 01485 std::ostringstream msg ; 01486 msg << " FAILED in Ioss::NodeBlock::put_field_data:" ; 01487 msg << " num_nodes = " << num_nodes ; 01488 msg << " , num_ids_written = " << num_ids_written ; 01489 throw std::runtime_error( msg.str() ); 01490 } 01491 01496 const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk); 01497 mesh::Field<double, mesh::Cartesian> *coord_field = 01498 meta_data.get_field<stk_classic::mesh::Field<double, mesh::Cartesian> >(std::string("coordinates")); 01499 assert(coord_field != NULL); 01500 field_data_to_ioss(coord_field, nodes, &nb, "mesh_model_coordinates", Ioss::Field::MESH); 01501 01502 const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields(); 01503 std::vector<mesh::FieldBase *>::const_iterator I = fields.begin(); 01504 while (I != fields.end()) { 01505 const mesh::FieldBase *f = *I ; ++I ; 01506 if (stk_classic::io::is_valid_part_field(f, part_primary_entity_rank(part), part, 01507 meta_data.universal_part(), Ioss::Field::ATTRIBUTE, false)) { 01508 stk_classic::io::field_data_to_ioss(f, nodes, &nb, f->name(), Ioss::Field::ATTRIBUTE); 01509 } 01510 } 01511 } 01512 01513 template <typename INT> 01514 void output_element_block(Ioss::ElementBlock *block, 01515 const stk_classic::mesh::BulkData &bulk, 01516 const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/) 01517 { 01518 const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk); 01519 const std::string& name = block->name(); 01520 mesh::Part* part = meta_data.get_part(name); 01521 01522 assert(part != NULL); 01523 std::vector<mesh::Entity *> elements; 01524 size_t num_elems = get_entities(*part, bulk, elements, false, anded_selector); 01525 01526 const CellTopologyData * cell_topo = 01527 stk_classic::io::get_cell_topology(*part) ? 01528 stk_classic::io::get_cell_topology(*part) : 01529 stk_classic::mesh::fem::FEMMetaData::get(*part).get_cell_topology(*part).getCellTopologyData(); 01530 if (cell_topo == NULL) { 01531 std::ostringstream msg ; 01532 msg << " INTERNAL_ERROR: Part " << part->name() << " returned NULL from get_cell_topology()"; 01533 throw std::runtime_error( msg.str() ); 01534 } 01535 size_t nodes_per_elem = cell_topo->node_count; 01536 01537 std::vector<INT> elem_ids; elem_ids.reserve(num_elems); 01538 std::vector<INT> connectivity; connectivity.reserve(num_elems*nodes_per_elem); 01539 01540 stk_classic::mesh::EntityRank no_rank = node_rank(meta_data); 01541 for (size_t i = 0; i < num_elems; ++i) { 01542 01543 elem_ids.push_back(elements[i]->identifier()); 01544 01545 const mesh::PairIterRelation elem_nodes = elements[i]->relations(no_rank); 01546 01547 for (size_t j = 0; j < nodes_per_elem; ++j) { 01548 connectivity.push_back(elem_nodes[j].entity()->identifier()); 01549 } 01550 } 01551 01552 const size_t num_ids_written = block->put_field_data("ids", elem_ids); 01553 const size_t num_con_written = block->put_field_data("connectivity", connectivity); 01554 01555 if ( num_elems != num_ids_written || num_elems != num_con_written ) { 01556 std::ostringstream msg ; 01557 msg << " FAILED in Ioss::ElementBlock::put_field_data:" << std::endl ; 01558 msg << " num_elems = " << num_elems << std::endl ; 01559 msg << " num_ids_written = " << num_ids_written << std::endl ; 01560 msg << " num_connectivity_written = " << num_con_written << std::endl ; 01561 throw std::runtime_error( msg.str() ); 01562 } 01563 01564 stk_classic::mesh::EntityRank elem_rank = element_rank(meta_data); 01565 const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields(); 01566 std::vector<mesh::FieldBase *>::const_iterator I = fields.begin(); 01567 while (I != fields.end()) { 01568 const mesh::FieldBase *f = *I ; ++I ; 01569 const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f); 01570 if (role != NULL && *role == Ioss::Field::ATTRIBUTE) { 01571 const mesh::FieldBase::Restriction &res = f->restriction(elem_rank, *part); 01572 if (res.dimension() > 0) { 01573 stk_classic::io::field_data_to_ioss(f, elements, block, f->name(), Ioss::Field::ATTRIBUTE); 01574 } 01575 } 01576 } 01577 } 01578 01579 template <typename INT> 01580 void output_node_set(Ioss::NodeSet *ns, const stk_classic::mesh::BulkData &bulk, 01581 const stk_classic::mesh::Selector *anded_selector, INT /*dummy*/) 01582 { 01583 const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk); 01584 const std::string& name = ns->name(); 01585 stk_classic::mesh::Part* part = meta_data.get_part(name); 01586 assert(part != NULL); 01587 01588 std::vector<stk_classic::mesh::Entity *> nodes ; 01589 size_t num_nodes = get_entities(*part, bulk, nodes, true, anded_selector); 01590 01591 std::vector<INT> node_ids; node_ids.reserve(num_nodes); 01592 for(size_t i=0; i<num_nodes; ++i) { 01593 const stk_classic::mesh::Entity & node = * nodes[i] ; 01594 node_ids.push_back(node.identifier()); 01595 } 01596 01597 size_t num_ids_written = ns->put_field_data("ids", node_ids); 01598 if ( num_nodes != num_ids_written ) { 01599 std::ostringstream msg ; 01600 msg << " FAILED in Ioss::NodeSet::put_field_data:" 01601 << " num_nodes = " << num_nodes 01602 << ", num_ids_written = " << num_ids_written; 01603 throw std::runtime_error( msg.str() ); 01604 } 01605 01606 stk_classic::mesh::Field<double> *df_field = 01607 meta_data.get_field<stk_classic::mesh::Field<double> >("distribution_factors"); 01608 if (df_field != NULL) { 01609 stk_classic::io::field_data_to_ioss(df_field, nodes, ns, "distribution_factors", Ioss::Field::MESH); 01610 } 01611 01612 const std::vector<mesh::FieldBase *> &fields = meta_data.get_fields(); 01613 std::vector<mesh::FieldBase *>::const_iterator I = fields.begin(); 01614 while (I != fields.end()) { 01615 const mesh::FieldBase *f = *I ; ++I ; 01616 const Ioss::Field::RoleType *role = stk_classic::io::get_field_role(*f); 01617 if (role != NULL && *role == Ioss::Field::ATTRIBUTE) { 01618 const mesh::FieldBase::Restriction &res = f->restriction(0, *part); 01619 if (res.dimension() > 0) { 01620 stk_classic::io::field_data_to_ioss(f, nodes, ns, f->name(), Ioss::Field::ATTRIBUTE); 01621 } 01622 } 01623 } 01624 } 01625 01626 template <typename INT> 01627 void output_side_set(Ioss::SideSet *ss, 01628 const stk_classic::mesh::BulkData &bulk, 01629 const stk_classic::mesh::Selector *anded_selector, INT dummy) 01630 { 01631 const stk_classic::mesh::MetaData & meta_data = mesh::MetaData::get(bulk); 01632 size_t block_count = ss->block_count(); 01633 for (size_t i=0; i < block_count; i++) { 01634 Ioss::SideBlock *block = ss->get_block(i); 01635 if (stk_classic::io::include_entity(block)) { 01636 stk_classic::mesh::Part * const part = meta_data.get_part(block->name()); 01637 stk_classic::io::write_side_data_to_ioss(*block, part, bulk, anded_selector, dummy); 01638 } 01639 } 01640 } 01641 01642 } // namespace <blank> 01643 01644 void write_output_db(Ioss::Region& io_region, 01645 const stk_classic::mesh::BulkData& bulk, 01646 const stk_classic::mesh::Selector *anded_selector) 01647 { 01648 const stk_classic::mesh::MetaData & meta = mesh::MetaData::get(bulk); 01649 01650 bool ints64bit = db_api_int_size(&io_region) == 8; 01651 01652 io_region.begin_mode( Ioss::STATE_MODEL ); 01653 01654 int64_t z64 = 0; 01655 int z32 = 0; 01656 01657 Ioss::NodeBlock & nb = *io_region.get_node_blocks()[0]; 01658 if (ints64bit) 01659 output_node_block(nb, meta.universal_part(), bulk, anded_selector, z64); 01660 else 01661 output_node_block(nb, meta.universal_part(), bulk, anded_selector, z32); 01662 01663 //---------------------------------- 01664 const Ioss::ElementBlockContainer& elem_blocks = io_region.get_element_blocks(); 01665 for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); 01666 it != elem_blocks.end(); ++it) { 01667 if (ints64bit) 01668 output_element_block(*it, bulk, anded_selector, z64); 01669 else 01670 output_element_block(*it, bulk, anded_selector, z32); 01671 } 01672 01673 //---------------------------------- 01674 const Ioss::NodeSetContainer& node_sets = io_region.get_nodesets(); 01675 for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin(); 01676 it != node_sets.end(); ++it) { 01677 if (ints64bit) 01678 output_node_set(*it, bulk, anded_selector, z64); 01679 else 01680 output_node_set(*it, bulk, anded_selector, z32); 01681 } 01682 01683 //---------------------------------- 01684 const Ioss::SideSetContainer& side_sets = io_region.get_sidesets(); 01685 for(Ioss::SideSetContainer::const_iterator it = side_sets.begin(); 01686 it != side_sets.end(); ++it) { 01687 if (ints64bit) 01688 output_side_set(*it, bulk, anded_selector, z64); 01689 else 01690 output_side_set(*it, bulk, anded_selector, z32); 01691 } 01692 01693 io_region.end_mode( Ioss::STATE_MODEL ); 01694 } 01695 01696 //---------------------------------------------------------------------- 01697 bool is_part_io_part(stk_classic::mesh::Part &part) 01698 { 01699 return NULL != part.attribute<Ioss::GroupingEntity>(); 01700 } 01701 01702 const stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> *get_distribution_factor_field(const stk_classic::mesh::Part &p) 01703 { 01704 return p.attribute<stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> >(); 01705 } 01706 01707 void set_distribution_factor_field(stk_classic::mesh::Part &p, 01708 const stk_classic::mesh::Field<double, stk_classic::mesh::ElementNode> &df_field) 01709 { 01710 stk_classic::mesh::MetaData &m = mesh::MetaData::get(p); 01711 m.declare_attribute_no_delete(p,&df_field); 01712 } 01713 01714 const Ioss::Field::RoleType* get_field_role(const stk_classic::mesh::FieldBase &f) 01715 { 01716 return f.attribute<Ioss::Field::RoleType>(); 01717 } 01718 01719 void set_field_role(stk_classic::mesh::FieldBase &f, const Ioss::Field::RoleType &role) 01720 { 01721 Ioss::Field::RoleType *my_role = new Ioss::Field::RoleType(role); 01722 stk_classic::mesh::MetaData &m = mesh::MetaData::get(f); 01723 const Ioss::Field::RoleType *check = m.declare_attribute_with_delete(f, my_role); 01724 if ( check != my_role ) { 01725 if (*check != *my_role) { 01726 std::ostringstream msg ; 01727 msg << " FAILED in IossBridge -- set_field_role:" 01728 << " The role type had already been set to " << *check 01729 << ", so it is not possible to change it to " << *my_role; 01730 throw std::runtime_error( msg.str() ); 01731 } 01732 delete my_role; 01733 } 01734 } 01735 01736 }//namespace io 01737 }//namespace stk_classic 01738