void extract_sideset_data_from_io(std::vector<IdAndSideSet> &sidesetData)
 {
     stk::mesh::BulkData &bulk = this->bulk_data();
     Ioss::Region *region = m_input_files[m_active_mesh_index]->get_input_io_region().get();
     for ( const Ioss::SideSet * sset : region->get_sidesets() )
         add_ioss_sideset_to_stk_sideset_with_sideset_id(bulk, sset, sidesetData);
 }
void process_input_request(Ioss::Region &region,
                           stk::mesh::BulkData &bulk,
                           int step)
{
    region.begin_state(step);

    // Special processing for nodeblock (all nodes in model)...
    const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk);

    // ??? Get field data from nodeblock...
    get_field_data(bulk, meta.universal_part(), stk::topology::NODE_RANK,
                   region.get_node_blocks()[0], Ioss::Field::TRANSIENT);

    const stk::mesh::PartVector & all_parts = meta.get_parts();
    for ( stk::mesh::PartVector::const_iterator
            ip = all_parts.begin(); ip != all_parts.end(); ++ip ) {

        stk::mesh::Part * const part = *ip;

        const stk::mesh::EntityRank part_rank = part->primary_entity_rank();

        // Check whether this part should be output to results database.
        if (stk::io::is_part_io_part(*part)) {
            // Get Ioss::GroupingEntity corresponding to this part...
            Ioss::GroupingEntity *entity = region.get_entity(part->name());
            if (entity != NULL) {
                if (entity->type() == Ioss::SIDESET) {
                    Ioss::SideSet *sset = dynamic_cast<Ioss::SideSet*>(entity);
                    assert(sset != NULL);
                    int block_count = sset->block_count();
                    for (int i=0; i < block_count; i++) {
                        Ioss::SideBlock *side_block = sset->get_block(i);
                        /// \todo REFACTOR Need filtering mechanism.
                        get_field_data(bulk, *part,
                                       part_rank,
                                       side_block, Ioss::Field::TRANSIENT);
                    }
                } else {
                    get_field_data(bulk, *part,
                                   part_rank,
                                   entity, Ioss::Field::TRANSIENT);
                }
            } else {
                /// \todo IMPLEMENT handle error... Possibly an assert since
                /// I think the corresponding entity should always exist...
            }
        }
    }

    region.end_state(step);
}
// ========================================================================
// Bulk Data
// ========================================================================
void process_nodeblocks(Ioss::Region &region, stk::mesh::BulkData &bulk)
{
    // This must be called after the "process_element_blocks" call
    // since there may be nodes that exist in the database that are
    // not part of the analysis mesh due to subsetting of the element
    // blocks.

    const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
    assert(node_blocks.size() == 1);

    Ioss::NodeBlock *nb = node_blocks[0];

    std::vector<stk::mesh::Entity> nodes;
    stk::io::get_entity_list(nb, stk::topology::NODE_RANK, bulk, nodes);

    /** \todo REFACTOR Application would probably store this field
     * (and others) somewhere after the declaration instead of
     * looking it up each time it is needed.
     */
    const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk);
    stk::mesh::Field<double,stk::mesh::Cartesian> *coord_field =
        meta.get_field<stk::mesh::Field<double,stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates");

    stk::io::field_data_from_ioss(bulk, coord_field, nodes, nb, "mesh_model_coordinates");
}
// ========================================================================
void process_elementblocks(Ioss::Region &region, stk::mesh::BulkData &bulk)
{
    const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();

    for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
            it != elem_blocks.end(); ++it) {
        Ioss::ElementBlock *entity = *it;

        if (stk::io::include_entity(entity)) {
            const std::string &name = entity->name();
            const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk);
            stk::mesh::Part* const part = meta.get_part(name);
            STKIORequire(part != NULL);

            const stk::topology topo = part->topology();
            if (topo == stk::topology::INVALID_TOPOLOGY) {
                std::ostringstream msg ;
                msg << " INTERNAL_ERROR: Part " << part->name() << " returned INVALID from get_topology()";
                throw std::runtime_error( msg.str() );
            }

            std::vector<int> elem_ids ;
            std::vector<int> connectivity ;

            entity->get_field_data("ids", elem_ids);
            entity->get_field_data("connectivity", connectivity);

            size_t element_count = elem_ids.size();
            int nodes_per_elem = topo.num_nodes();

            stk::mesh::EntityIdVector connectivity2(nodes_per_elem);

            std::vector<int>::const_iterator connBegin = connectivity.begin();
            std::vector<stk::mesh::Entity> elements(element_count);
            for(size_t i=0; i<element_count; ++i, connBegin += nodes_per_elem) {
                std::copy(connBegin, connBegin + nodes_per_elem, connectivity2.begin());
                elements[i] = stk::mesh::declare_element(bulk, *part, elem_ids[i], connectivity2);
            }

            // For this example, we are just taking all attribute fields
            // found on the io database and populating fields on the
            // corresponding mesh part.  In practice, would probably be
            // selective about which attributes to use...
            Ioss::NameList names;
            entity->field_describe(Ioss::Field::ATTRIBUTE, &names);
            for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) {
                if (*I == "attribute" && names.size() > 1)
                    continue;
                stk::mesh::FieldBase *field = meta.get_field<stk::mesh::FieldBase>(stk::topology::ELEMENT_RANK, *I);
                stk::io::field_data_from_ioss(bulk, field, elements, entity, *I);

            }
        }
    }
}
// ========================================================================
void process_sidesets(Ioss::Region &region, stk::mesh::BulkData &bulk)
{
    const Ioss::SideSetContainer& side_sets = region.get_sidesets();

    for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
            it != side_sets.end(); ++it) {
        Ioss::SideSet *entity = *it;

        if (stk::io::include_entity(entity)) {
            process_surface_entity(entity, bulk);
        }
    }
}
// ========================================================================
void process_sidesets(Ioss::Region &region, stk::mesh::MetaData &meta)
{
    const stk::mesh::EntityRank side_rank = meta.side_rank();

    const Ioss::SideSetContainer& side_sets = region.get_sidesets();
    stk::io::default_part_processing(side_sets, meta, side_rank);

    for(Ioss::SideSetContainer::const_iterator it = side_sets.begin();
            it != side_sets.end(); ++it) {
        Ioss::SideSet *entity = *it;

        if (stk::io::include_entity(entity)) {
            process_surface_entity(entity, meta, side_rank);
        }
    }
}
// ========================================================================
void process_nodesets(Ioss::Region &region, stk::mesh::BulkData &bulk)
{
    // Should only process nodes that have already been defined via the element
    // blocks connectivity lists.
    const Ioss::NodeSetContainer& node_sets = region.get_nodesets();

    for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
            it != node_sets.end(); ++it) {
        Ioss::NodeSet *entity = *it;

        if (stk::io::include_entity(entity)) {
            const std::string & name = entity->name();
            const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk);
            stk::mesh::Part* const part = meta.get_part(name);
            STKIORequire(part != NULL);
            stk::mesh::PartVector add_parts( 1 , part );

            std::vector<int> node_ids ;
            int node_count = entity->get_field_data("ids", node_ids);

            std::vector<stk::mesh::Entity> nodes(node_count);
            for(int i=0; i<node_count; ++i) {
                nodes[i] = bulk.get_entity( stk::topology::NODE_RANK, node_ids[i] );
                if (bulk.is_valid(nodes[i])) {
                    bulk.declare_entity(stk::topology::NODE_RANK, node_ids[i], add_parts );
                }
            }

            /** \todo REFACTOR Application would probably store this field
             * (and others) somewhere after the declaration instead of
             * looking it up each time it is needed.
             */
            stk::mesh::Field<double> *df_field =
                meta.get_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors");

            if (df_field != NULL) {
                stk::io::field_data_from_ioss(bulk, df_field, nodes, entity, "distribution_factors");
            }
        }
    }
}
// ========================================================================
void process_nodesets(Ioss::Region &region, stk::mesh::MetaData &meta)
{
    const Ioss::NodeSetContainer& node_sets = region.get_nodesets();
    stk::io::default_part_processing(node_sets, meta, stk::topology::NODE_RANK);

    /** \todo REFACTOR should "distribution_factor" be a default field
     * that is automatically declared on all objects that it exists
     * on as is done in current framework?
     */
    stk::mesh::Field<double> & distribution_factors_field =
        meta.declare_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors");

    /** \todo REFACTOR How to associate distribution_factors field
     * with the nodeset part if a node is a member of multiple
     * nodesets
     */

    for(Ioss::NodeSetContainer::const_iterator it = node_sets.begin();
            it != node_sets.end(); ++it) {
        Ioss::NodeSet *entity = *it;

        if (stk::io::include_entity(entity)) {
            stk::mesh::Part* const part = meta.get_part(entity->name());
            STKIORequire(part != NULL);
            STKIORequire(entity->field_exists("distribution_factors"));

            stk::mesh::put_field(distribution_factors_field, *part);

            /** \todo IMPLEMENT truly handle fields... For this case we
             * are just defining a field for each transient field that is
             * present in the mesh...
             */
            stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
                                      *part,
                                      part->primary_entity_rank() ) ;
        }
    }
}
// ========================================================================
void process_elementblocks(Ioss::Region &region, stk::mesh::MetaData &meta)
{
    const stk::mesh::EntityRank element_rank = stk::topology::ELEMENT_RANK;

    const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks();
    stk::io::default_part_processing(elem_blocks, meta, element_rank);

    // Parts were created above, now handle element block specific
    // information (topology, attributes, ...);
    for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin();
            it != elem_blocks.end(); ++it) {
        Ioss::ElementBlock *entity = *it;

        if (stk::io::include_entity(entity)) {
            stk::mesh::Part* const part = meta.get_part(entity->name());
            STKIORequire(part != NULL);

            const stk::mesh::EntityRank part_rank = part->primary_entity_rank();

            // Element Block attributes (if any)...
            /** \todo IMPLEMENT truly handle attribute fields... For this
             * case we are just defining a field for each attribute field
             * that is present in the mesh...
             */
            stk::io::define_io_fields(entity, Ioss::Field::ATTRIBUTE,
                                      *part,
                                      part_rank);

            /** \todo IMPLEMENT truly handle fields... For this case we
             * are just defining a field for each transient field that is
             * present in the mesh...
             */
            stk::io::define_io_fields(entity, Ioss::Field::TRANSIENT,
                                      *part,
                                      part_rank);
        }
    }
}
// ========================================================================
void process_nodeblocks(Ioss::Region &region, stk::mesh::MetaData &meta)
{
    const Ioss::NodeBlockContainer& node_blocks = region.get_node_blocks();
    assert(node_blocks.size() == 1);

    Ioss::NodeBlock *nb = node_blocks[0];

    assert(nb->field_exists("mesh_model_coordinates"));
    Ioss::Field coordinates = nb->get_field("mesh_model_coordinates");
    int spatial_dim = coordinates.transformed_storage()->component_count();

    stk::mesh::Field<double,stk::mesh::Cartesian> & coord_field =
        meta.declare_field<stk::mesh::Field<double,stk::mesh::Cartesian> >(stk::topology::NODE_RANK, "coordinates");

    stk::mesh::put_field( coord_field, meta.universal_part(),
                          spatial_dim);

    /** \todo IMPLEMENT truly handle fields... For this case we are
     * just defining a field for each transient field that is present
     * in the mesh...
     */
    stk::io::define_io_fields(nb, Ioss::Field::TRANSIENT, meta.universal_part(),stk::topology::NODE_RANK);
}
示例#11
0
void
Albany::IossSTKMeshStruct::setFieldAndBulkData(
                                               const Teuchos::RCP<const Epetra_Comm>& comm,
                                               const Teuchos::RCP<Teuchos::ParameterList>& params,
                                               const unsigned int neq_,
                                               const AbstractFieldContainer::FieldContainerRequirements& req,
                                               const Teuchos::RCP<Albany::StateInfoStruct>& sis,
                                               const unsigned int worksetSize)
{
  this->SetupFieldData(comm, neq_, req, sis, worksetSize);

  *out << "IOSS-STK: number of node sets = " << nsPartVec.size() << std::endl;
  *out << "IOSS-STK: number of side sets = " << ssPartVec.size() << std::endl;

  metaData->commit();

  // Restart index to read solution from exodus file.
  int index = params->get("Restart Index",-1); // Default to no restart
  double res_time = params->get<double>("Restart Time",-1.0); // Default to no restart
  Ioss::Region *region = mesh_data->m_input_region;

  /*
   * The following code block reads a single mesh on PE 0, then distributes the mesh across
   * the other processors. stk_rebalance is used, which requires Zoltan
   *
   * This code is only compiled if ALBANY_MPI and ALBANY_ZOLTAN are true
   */

#ifdef ALBANY_ZOLTAN // rebalance needs Zoltan

  if(useSerialMesh){

    bulkData->modification_begin();

    if(comm->MyPID() == 0){ // read in the mesh on PE 0

      stk::io::process_mesh_bulk_data(region, *bulkData);

      // Read solution from exodus file.
      if (index >= 0) { // User has specified a time step to restart at
        *out << "Restart Index set, reading solution index : " << index << std::endl;
        stk::io::input_mesh_fields(region, *bulkData, index);
        m_restartDataTime = region->get_state_time(index);
        m_hasRestartSolution = true;
      }
      else if (res_time >= 0) { // User has specified a time to restart at
        *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
        stk::io::input_mesh_fields(region, *bulkData, res_time);
        m_restartDataTime = res_time;
        m_hasRestartSolution = true;
      }
      else {

        *out << "Neither restart index or time are set. Not reading solution data from exodus file"<< std::endl;

      }
    }

    bulkData->modification_end();

  } // End UseSerialMesh - reading mesh on PE 0

  else 
#endif

    /*
     * The following code block reads a single mesh when Albany is compiled serially, or a
     * Nemspread fileset if ALBANY_MPI is true.
     *
     */

  { // running in Serial or Parallel read from Nemspread files

    stk::io::populate_bulk_data(*bulkData, *mesh_data);

    if (!usePamgen)  {

      // Read solution from exodus file.
      if (index >= 0) { // User has specified a time step to restart at
        *out << "Restart Index set, reading solution index : " << index << std::endl;
        stk::io::process_input_request(*mesh_data, *bulkData, index);
        m_restartDataTime = region->get_state_time(index);
        m_hasRestartSolution = true;
      }
      else if (res_time >= 0) { // User has specified a time to restart at
        *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
        stk::io::process_input_request(*mesh_data, *bulkData, res_time);
        m_restartDataTime = res_time;
        m_hasRestartSolution = true;
      }
      else {
        *out << "Restart Index not set. Not reading solution from exodus (" 
             << index << ")"<< std::endl;

      }
    }

    bulkData->modification_end();

  } // End Parallel Read - or running in serial

  if(m_hasRestartSolution){

    Teuchos::Array<std::string> default_field;
    default_field.push_back("solution");
    Teuchos::Array<std::string> restart_fields =
      params->get<Teuchos::Array<std::string> >("Restart Fields", default_field);

    // Get the fields to be used for restart

    // See what state data was initialized from the stk::io request
    // This should be propagated into stk::io
    const Ioss::ElementBlockContainer& elem_blocks = region->get_element_blocks();

    /*
    // Uncomment to print what fields are in the exodus file
    Ioss::NameList exo_fld_names;
    elem_blocks[0]->field_describe(&exo_fld_names);
    for(std::size_t i = 0; i < exo_fld_names.size(); i++){
    *out << "Found field \"" << exo_fld_names[i] << "\" in exodus file" << std::endl;
    }
    */

    for (std::size_t i=0; i<sis->size(); i++) {
      Albany::StateStruct& st = *((*sis)[i]);

      if(elem_blocks[0]->field_exists(st.name))

        for(std::size_t j = 0; j < restart_fields.size(); j++)

          if(boost::iequals(st.name, restart_fields[j])){

            *out << "Restarting from field \"" << st.name << "\" found in exodus file." << std::endl;
            st.restartDataAvailable = true;
            break;

          }
    }
  }

//  coordinates_field = metaData->get_field<VectorFieldType>(std::string("coordinates"));
//#ifdef ALBANY_FELIX
//  surfaceHeight_field = metaData->get_field<ScalarFieldType>(std::string("surface height"));
//#endif

  // Refine the mesh before starting the simulation if indicated
  uniformRefineMesh(comm);

  // Rebalance the mesh before starting the simulation if indicated
  rebalanceInitialMesh(comm);

  // Build additional mesh connectivity needed for mesh fracture (if indicated)
  computeAddlConnectivity();

}