Beispiel #1
0
void Ioss::ParallelUtils::global_array_minmax(double *local_minmax, size_t count, Ioss::ParallelUtils::MinMax which) const
{
#ifdef HAVE_MPI
  if (parallel_size() > 1 && count > 0) {
    if (Ioss::SerializeIO::isEnabled() && Ioss::SerializeIO::inBarrier()) {
      std::ostringstream errmsg;
      errmsg << "Attempting mpi while in barrier owned by " << Ioss::SerializeIO::getOwner();
      IOSS_ERROR(errmsg);
    }

    std::vector<double> maxout(count);

    MPI_Op oper;
    if (which == DO_MAX)
      oper = MPI_MAX;
    else
      oper = MPI_MIN;

    const int success = MPI_Allreduce((void*)&local_minmax[0], &maxout[0],
				      static_cast<int>(count),
				      MPI_DOUBLE, oper, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::global_array_minmax - MPI_Allreduce failed";
      IOSS_ERROR(errmsg);
    }
    // Now copy back into passed in array...
    for (size_t i=0; i < count; i++) {
      local_minmax[i] = maxout[i];
    }
  }
#endif
}
Beispiel #2
0
int64_t Ioex::SuperElement::internal_get_field_data(const Ioss::Field& field,
				      void *data, size_t data_size) const
{
  size_t num_to_get = field.verify(data_size);
  assert(num_to_get == numDOF * numDOF);
  
  if (field.get_name() == "Kr") {
    int status = nc_get_array(filePtr, "Kr", (double*)data);
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load stiffness matrix field 'Kr' from file '"
	     << fileName << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "Mr") {
    int status = nc_get_array(filePtr, "Mr", (double*)data);
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load mass matrix field 'Mr' from file '"
	     << fileName << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else {
    std::cerr << "WARNING: " << type() << " '" << name()
	      << "'. Unknown input field '" << field.get_name() << "'";
    return -4;
  }
  return num_to_get;
}
Beispiel #3
0
unsigned int Ioss::ParallelUtils::global_minmax(unsigned int local_minmax, Ioss::ParallelUtils::MinMax which) const
{
  unsigned int minmax = local_minmax;

#ifdef HAVE_MPI
  if (parallel_size() > 1) {
    if (Ioss::SerializeIO::isEnabled() && Ioss::SerializeIO::inBarrier()) {
      std::ostringstream errmsg;
      errmsg << "Attempting mpi while in barrier owned by " << Ioss::SerializeIO::getOwner();
      IOSS_ERROR(errmsg);
    }
    static unsigned int inbuf[1], outbuf[1];
    inbuf[0] = local_minmax;

    MPI_Op oper;
    if (which == DO_MAX)
      oper = MPI_MAX;
    else
      oper = MPI_MIN;

    const int success = MPI_Allreduce((void*)&inbuf[0], &outbuf[0], 1,
				      MPI_UNSIGNED, oper, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::global_minmax - MPI_Allreduce failed";
      IOSS_ERROR(errmsg);
    }
    minmax = outbuf[0];
  }
#endif
  return minmax;
}
Beispiel #4
0
void Ioss::ParallelUtils::global_count(const Int64Vector &local_counts, Int64Vector &global_counts) const
{
  // Vector 'local_counts' contains the number of objects
  // local to this processor.  On exit, global_counts
  // contains the total number of objects on all processors.
  // Assumes that ordering is the same on all processors
  global_counts.resize(local_counts.size());
#ifdef HAVE_MPI
  if (local_counts.size() > 0 && parallel_size() > 1) {
    if (Ioss::SerializeIO::isEnabled() && Ioss::SerializeIO::inBarrier()) {
      std::ostringstream errmsg;
      errmsg << "Attempting mpi while in barrier owned by " << Ioss::SerializeIO::getOwner();
      IOSS_ERROR(errmsg);
    }
    const int success = MPI_Allreduce((void*)&local_counts[0], &global_counts[0],
				      static_cast<int>(local_counts.size()),
				      MPI_LONG_LONG_INT, MPI_SUM, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg  << "Ioss::ParallelUtils::global_count - MPI_Allreduce failed";
      IOSS_ERROR(errmsg);
    }
  } else {
    // Serial run, just copy local to global...
    std::copy(local_counts.begin(), local_counts.end(), global_counts.begin());
  }
#else
  std::copy(local_counts.begin(), local_counts.end(), global_counts.begin());
#endif
}
SerializeIO::SerializeIO(
  const DatabaseIO *database_io,
  int		    manual_owner_processor)
  : m_databaseIO(database_io),
    m_activeFallThru(s_owner != -1)

{

  const Ioss::ParallelUtils util = m_databaseIO->util();
  if (s_rank == -1) {
    s_rank = util.parallel_rank();
    s_size = util.parallel_size();
    if (s_groupFactor != 0) {
      s_groupRank = s_rank/s_groupFactor;
      s_groupSize = (s_size - 1)/s_groupFactor + 1;
    }
  }

  m_manualOwner = (manual_owner_processor == -1 || s_groupFactor == 0) ? -1 : manual_owner_processor/s_groupFactor;

  if (m_activeFallThru) {
    if (m_manualOwner != -1 && m_manualOwner != s_owner) {
      std::ostringstream errmsg;
      errmsg << "Attempting to replace manual ownership from " << s_owner << " to " << m_manualOwner;
      IOSS_ERROR(errmsg);
    }
  }

  else if (s_groupFactor > 0) {
    if (m_manualOwner == -1) {
#ifdef HAVE_MPI
      do {
	MPI_Barrier(util.communicator());
      } while (++s_owner != s_groupRank);
#endif
      m_databaseIO->openDatabase();
    }
    else {
      if (s_owner != -1 && m_manualOwner != s_owner) {
	std::ostringstream errmsg;
	errmsg << "Attempting to replace manual ownership from " << s_owner << " to " << m_manualOwner;
	IOSS_ERROR(errmsg);
      }
      s_owner = m_manualOwner;
    }
  }
  else {
    s_owner = s_groupRank;
}
}
Beispiel #6
0
std::string Ioss::VariableType::numeric_label(int which, int ncomp, const std::string &name)
{
  char digits[8];
  // Create a format for our use...
  char format[5];
  if (ncomp <          10)
    std::strcpy(format, "%01d");
  else if (ncomp <    100)
    std::strcpy(format, "%02d");
  else if (ncomp <   1000)
    std::strcpy(format, "%03d");
  else if (ncomp <  10000)
    std::strcpy(format, "%04d");
  else if (ncomp < 100000)
    std::strcpy(format, "%05d");
  else {
    std::ostringstream errmsg;
    errmsg << "ERROR: Variable '" << name << "' has " << ncomp
	   << " components which is larger than the current maximum"
	   << " of 100,000. Please contact developer.\n";
    IOSS_ERROR(errmsg);
  }

  std::sprintf(digits, format, which);
  return std::string(digits);
}
Beispiel #7
0
const Ioss::VariableType* Ioss::VariableType::factory(const std::string& raw_name, int copies)
{
  Ioss::VariableType* inst = NULL;
  std::string name = Ioss::Utils::lowercase(raw_name);
  Ioss::VariableTypeMap::iterator iter = registry().find(name);
  if (iter == registry().end()) {
    bool can_construct = build_variable_type(name);
    if (can_construct) {
      iter = registry().find(name);
      assert(iter != registry().end());
      inst = (*iter).second;
    } else {
      std::ostringstream errmsg;
      errmsg << "FATAL: The variable type '" << raw_name << "' is not supported.\n";
      IOSS_ERROR(errmsg);
    }
  } else {
    inst = (*iter).second;
  }

  if (copies != 1) {
    inst = CompositeVariableType::composite_variable_type(inst, copies);
  }
  assert(inst != NULL);
  return inst;
}
Beispiel #8
0
  void DatabaseIO::create_groups(const std::string &property_name, EntityType type,
                                 const std::string &type_name, const T *set_type)
  {
    if (!properties.exists(property_name)) {
      return;
    }

    std::string              prop   = properties.get(property_name).get_string();
    std::vector<std::string> groups = tokenize(prop, ":");
    for (auto &group : groups) {
      std::vector<std::string> group_spec = tokenize(group, ",");

      // group_spec should contain the name of the new group as
      // the first location and the members of the group as subsequent
      // locations.  OK to have a single member
      if (group_spec.size() < 2) {
        std::ostringstream errmsg;
        errmsg << "ERROR: Invalid " << type_name << " group specification '" << group << "'\n"
               << "       Correct syntax is 'new_group,member1,...,memberN' and "
                  "their must "
               << "       be at least 1 member of the group";
        IOSS_ERROR(errmsg);
      }

      create_group(type, type_name, group_spec, set_type);
    }
  }
Beispiel #9
0
Ioss::EntityBlock::EntityBlock(Ioss::DatabaseIO *io_database, const std::string &my_name,
                               const std::string &entity_type, size_t entity_count)
    : Ioss::GroupingEntity(io_database, my_name, entity_count), idOffset(0)

{
  // The 'true' means it is ok for the factory to return
  // nullptr.  This is done here just so we can output a better
  // error message.
  topology_ = ElementTopology::factory(entity_type, true);
  if (topology_ == nullptr) {
    std::ostringstream errmsg;
    errmsg << "ERROR: The topology type '" << entity_type << "' is not supported"
           << " on " << name() << " in file " << io_database->get_filename();
    IOSS_ERROR(errmsg);
  }

  if (topology()->master_element_name() != entity_type && topology()->name() != entity_type) {
    // Maintain original element type on output database if possible.
    properties.add(Ioss::Property("original_topology_type", entity_type));
  }

  properties.add(Ioss::Property(this, "topology_node_count", Ioss::Property::INTEGER));
  properties.add(Ioss::Property(this, "topology_type", Ioss::Property::STRING));
  fields.add(Ioss::Field("connectivity", field_int_type(), topology_->name(), Ioss::Field::MESH,
                         entity_count));

  // Returns connectivity in local id space
  fields.add(Ioss::Field("connectivity_raw", field_int_type(), topology()->name(),
                         Ioss::Field::MESH, entity_count));
}
Beispiel #10
0
void Ioss::ParallelUtils::attribute_reduction( const int length , char buffer[]) const
{
#ifdef HAVE_MPI
  if ( 1 < parallel_size() ) {
    assert( sizeof(char) == 1 );

    char * const recv_buf = new char[ length ];

    std::memset( recv_buf , 0 , length );

    const int success =
      MPI_Allreduce( buffer , recv_buf , length , MPI_BYTE , MPI_BOR , communicator_);

    if ( MPI_SUCCESS != success ) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::attribute_reduction - MPI_Allreduce failed";
      IOSS_ERROR(errmsg);
    }

    std::memcpy( buffer , recv_buf , length );

    delete[] recv_buf ;
  }
#endif
}
Beispiel #11
0
  void DatabaseIO::create_path(const std::string &filename) const
  {
    bool               error_found = false;
    std::ostringstream errmsg;

    if (myProcessor == 0) {
      Ioss::FileInfo file = Ioss::FileInfo(filename);
      std::string    path = file.pathname();

      const int mode = 0777; // Users umask will be applied to this.

      auto iter = path.begin();
      while (iter != path.end() && !error_found) {
        iter                  = std::find(iter, path.end(), '/');
        std::string path_root = std::string(path.begin(), iter);

        if (iter != path.end()) {
          ++iter; // Skip past the '/'
        }

        if (path_root.empty()) { // Path started with '/'
          continue;
        }

        struct stat st;
        if (stat(path_root.c_str(), &st) != 0) {
          if (mkdir(path_root.c_str(), mode) != 0 && errno != EEXIST) {
            errmsg << "ERROR: Cannot create directory '" << path_root
                   << "' : " << std::strerror(errno) << "\n";
            error_found = true;
          }
        }
        else if (!S_ISDIR(st.st_mode)) {
          errno = ENOTDIR;
          errmsg << "ERROR: Path '" << path_root << "' is not a directory.\n";
          error_found = true;
        }
      }
    }
    else {
      // Give the other processors something to say in case there is an error.
      errmsg << "ERROR: Could not create path. See processor 0 output for more "
                "details.\n";
    }

    // Sync all processors with error status...
    // All processors but 0 will have error_found=false
    // Processor 0 will have error_found = true or false depending on path
    // result.
    int is_error = error_found ? 1 : 0;
    error_found  = (util().global_minmax(is_error, Ioss::ParallelUtils::DO_MAX) == 1);

    if (error_found) {
      IOSS_ERROR(errmsg);
    }
  }
Beispiel #12
0
Ioss::Property Ioss::PropertyManager::get(const std::string& property_name) const
{
  PropMapType::const_iterator iter = properties.find(property_name);
  if (iter == properties.end()) {
    std::ostringstream errmsg;
    errmsg << "ERROR: Could not find property '" << property_name << "'\n";
    IOSS_ERROR(errmsg);
  }
  return (*iter).second;
}
Beispiel #13
0
Ioss::Transform* Factory::create(const std::string& type)
{
  Ioss::Transform *transform = NULL;
  FactoryMap::iterator iter = registry()->find(type);
  if (iter == registry()->end()) {
    if (registry()->size() == 0) {
      std::ostringstream errmsg;
      errmsg << "FATAL: No transformations have been registered.\n"
	     << "       Was Iotr::Initializer::initialize() called?\n\n";
      IOSS_ERROR(errmsg);
    } else {
      std::ostringstream errmsg;
      errmsg << "FATAL: The transform named '" << type
	     << "' is not supported.\n";
      IOSS_ERROR(errmsg);
    }
  } else {
    Factory* factory = (*iter).second;
    transform = factory->make(type);
  }
  return transform;
}
void Ioss::Map::build_reverse_map(int64_t num_to_get, int64_t offset)
{
  // Stored as a sorted vector of <global_id, local_id> pairs...
  // To build incrementally:
  // 0. PRE: reverseElementMap is sorted, size >= 0.
  // 1. Build vector of current ids. -- new_ids
  // 2. Sort that vector.
  // 3. Copy reverseElementMap to old_ids, empty reverseElementMap.
  // 4. Merge old_ids and new_ids to reverseElementMap.
  // 5. Check for duplicate global_ids...

  // Build a vector containing the current ids...
  ReverseMapContainer new_ids(num_to_get);
  for (int64_t i=0; i < num_to_get; i++) {
    int64_t local_id = offset + i + 1;
    new_ids[i] = std::make_pair(map[local_id], local_id);

    if (map[local_id] <= 0) {
      std::ostringstream errmsg;
      errmsg << "\nERROR: " << entityType << " map detected non-positive global id " << map[local_id]
	     << " for " << entityType << " with local id " << local_id
	     << " on processor " << myProcessor << ".\n";
      IOSS_ERROR(errmsg);
    }
  }

  // Sort that vector...
  std::sort(new_ids.begin(), new_ids.end(), IdPairCompare());

  int64_t new_id_min = new_ids.empty() ? 0 : new_ids.front().first;
  int64_t old_id_max = reverse.empty() ? 0 : reverse.back().first;
  if (new_id_min > old_id_max) {
    reverse.insert(reverse.end(), new_ids.begin(), new_ids.end());
  } else {
    // Copy reverseElementMap to old_ids, empty reverseElementMap.
    ReverseMapContainer old_ids;
    old_ids.swap(reverse);
    assert(reverse.empty());
    
    // Merge old_ids and new_ids to reverseElementMap.
    reverse.reserve(old_ids.size() + new_ids.size());
    std::merge(old_ids.begin(), old_ids.end(),
	       new_ids.begin(), new_ids.end(),
	       std::inserter(reverse, reverse.begin()), IdPairCompare());
    
  }
  // Check for duplicate ids...
#ifndef NDEBUG
  verify_no_duplicate_ids(reverse);
#endif
}
Beispiel #15
0
void Ioss::Map::set_map(INT *ids, size_t count, size_t offset)
{
  for (size_t i=0; i < count; i++) {
    ssize_t local_id = offset + i + 1;
    map[local_id] = ids[i];
    if (local_id != ids[i]) {
      map[0] = 1;
    }
    if (ids[i] <= 0) {
      std::ostringstream errmsg;
      errmsg << "\nERROR: " << entityType << " mapping routines detected non-positive global id " << ids[i]
	     << " for local id " << local_id << ".\n";
      IOSS_ERROR(errmsg);
    }
  }
}
void Ioss::Map::verify_no_duplicate_ids(std::vector<Ioss::IdPair> &reverse_map)
{
  // Check for duplicate ids...
  auto dup = std::adjacent_find(reverse_map.begin(),
				reverse_map.end(),
				IdPairEqual());

  if (dup != reverse_map.end()) {
    auto other = dup+1;
    std::ostringstream errmsg;
    errmsg << "\nERROR: Duplicate " << entityType << " global id detected on processor "
	   << myProcessor << ", filename '" << filename << "'.\n"
	   << "       Global id " << (*dup).first
	   << " assigned to local " << entityType << "s "
	   << (*dup).second << " and "
	   << (*other).second << ".\n";
    IOSS_ERROR(errmsg);
  }
}
Beispiel #17
0
Ioss::ElementTopology* Ioss::ElementTopology::factory(const std::string& type, bool ok_to_fail)
{
  std::string ltype = Ioss::Utils::lowercase(type);
  
  Ioss::ElementTopology* inst = nullptr;
  Ioss::ElementTopologyMap::iterator iter = registry().find(ltype);

  if (iter == registry().end()) {
    std::string base1 = "super";
    if (ltype.find(base1) == 0) {
      // A super element can have a varying number of nodes.  Create
      // an IO element type for this super element. The node count
      // should be encoded in the 'type' as 'super42' for a 42-node
      // superelement.

      Ioss::Super::make_super(ltype);
      iter = registry().find(ltype);
    }
    else {
      // See if 'type' contains a '-'.  Some codes create their
      // own topologies by adding a "-something" onto the end of a
      // standard topology.
      size_t dash = ltype.find('-');
      if (dash != std::string::npos) {
        std::string sub_type = ltype.substr(0, dash);
        iter = registry().find(sub_type);
      }
    }
  }

  if (iter == registry().end()) {
    if (!ok_to_fail) {
      std::ostringstream errmsg;
      errmsg << "ERROR: The topology type '" << type << "' is not supported.";
      IOSS_ERROR(errmsg);
    }
  } else {
    inst = (*iter).second;
  }
  return inst;
}
Beispiel #18
0
int64_t Ioss::Map::global_to_local(int64_t global, bool must_exist) const
{
  int64_t local = global;
  if (map[0] == 1) {
    RMapI iter = std::lower_bound(reverse.begin(), reverse.end(), global, IdPairCompare());
    if (iter != reverse.end() && iter->first == global)
      local = iter->second;
    else
      local = 0;
  } else if (!must_exist && global > (int64_t)map.size()-1) {
    local = 0;
  }
  if (local > (int64_t)map.size()-1 || (local <= 0  && must_exist)) {
    std::ostringstream errmsg;
    errmsg << "ERROR: Ioss Mapping routines detected " << entityType << " with global id equal to " << global
	   << " returns a local id of " << local
	   << " which is invalid. This should not happen, please report.\n";
    IOSS_ERROR(errmsg);
      }
  return local;
}
Beispiel #19
0
void Ioss::ParallelUtils::gather(int64_t my_value, std::vector<int64_t> &result) const
{
  if (parallel_rank() == 0) {
    result.resize(parallel_size());
  }
#ifdef HAVE_MPI
  if (parallel_size() > 1) {
    const int success = MPI_Gather((void*)&my_value,  1, MPI_LONG_LONG_INT,
				   (void*)&result[0], 1, MPI_LONG_LONG_INT,
				   0, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::gather - MPI_Gather failed";
      IOSS_ERROR(errmsg);
    }
  } else {
    result[0] = my_value;
  }
#else
  result[0] = my_value;
#endif
}
Beispiel #20
0
void Ioss::ParallelUtils::gather(std::vector<int64_t> &my_values, std::vector<int64_t> &result) const
{
  size_t count = my_values.size();
  if (parallel_rank() == 0) {
    result.resize(count * parallel_size());
  }
#ifdef HAVE_MPI
  if (parallel_size() > 1) {
    const int success = MPI_Gather((void*)TOPTR(my_values),  count, MPI_LONG_LONG_INT,
				   (void*)TOPTR(result), count, MPI_LONG_LONG_INT,
				   0, communicator_);
    if (success !=  MPI_SUCCESS) {
      std::ostringstream errmsg;
      errmsg << "Ioss::ParallelUtils::gather - MPI_Gather failed";
      IOSS_ERROR(errmsg);
    }
  } else {
    std::copy(my_values.begin(), my_values.end(), result.begin());
  }
#else
  std::copy(my_values.begin(), my_values.end(), result.begin());
#endif
}
Beispiel #21
0
  void DatabaseIO::initialize(const Ioss::Region * /*region*/) const
  {
    if (!initialized_) {
      assert(layout_ == nullptr);
      assert(legend_ == nullptr);

      DatabaseIO *new_this = const_cast<DatabaseIO *>(this);

      if (properties.exists("FIELD_SEPARATOR")) {
        new_this->separator_ = properties.get("FIELD_SEPARATOR").get_string();
      }

      if (properties.exists("FILE_FORMAT")) {
        std::string format = properties.get("FILE_FORMAT").get_string();
        if (Ioss::Utils::case_strcmp(format, "spyhis") == 0) {
          new_this->fileFormat = SPYHIS;
        }
      }

      bool append = open_create_behavior() == Ioss::DB_APPEND;

      // Try to open file...
      new_this->logStream = nullptr;
      if (util().parallel_rank() == 0) {
        new_this->logStream = open_stream(get_filename(), &(new_this->streamNeedsDelete), append);

        if (new_this->logStream == nullptr) {
          std::ostringstream errmsg;
          errmsg << "ERROR: Could not create heartbeat file '" << get_filename() << "'\n";
          IOSS_ERROR(errmsg);
        }
      }

      // Pull variables from the regions property data...
      if (properties.exists("TIME_STAMP_FORMAT")) {
        new_this->tsFormat = properties.get("TIME_STAMP_FORMAT").get_string();
      }

      if (properties.exists("SHOW_TIME_STAMP")) {
        bool show_time_stamp = properties.get("SHOW_TIME_STAMP").get_int() == 1;
        if (!show_time_stamp) {
          new_this->tsFormat = "";
        }
      }

      if (properties.exists("PRECISION")) {
        new_this->precision_ = properties.get("PRECISION").get_int();
      }

      if (properties.exists("FIELD_WIDTH")) {
        new_this->fieldWidth_ = properties.get("FIELD_WIDTH").get_int();
      }
      else {
        // +1.xxxxxxe+00 The x count is the precision the "+1.e+00" is the 7
        new_this->fieldWidth_ = precision_ + 7;
      }

      if (properties.exists("SHOW_LABELS")) {
        new_this->showLabels = (properties.get("SHOW_LABELS").get_int() == 1);
      }

      if (properties.exists("SHOW_LEGEND")) {
        new_this->showLegend =
            (properties.get("SHOW_LEGEND").get_int() == 1 && !new_this->appendOutput);
      }

      if (properties.exists("SHOW_TIME_FIELD")) {
        new_this->addTimeField = (properties.get("SHOW_TIME_FIELD").get_int() == 1);
      }

      if (fileFormat == SPYHIS) {
        new_this->addTimeField = true;
        new_this->showLegend   = true;
        new_this->showLabels   = false;
        new_this->tsFormat     = "";
      }

      if (showLegend) {
        new_this->legend_ = new Layout(false, precision_, separator_, fieldWidth_);
        if (!tsFormat.empty()) {
          new_this->legend_->add_literal("+");
          new_this->legend_->add_literal(time_stamp(tsFormat));
          new_this->legend_->add_literal(" ");
        }

        if (addTimeField) {
          if (fileFormat == SPYHIS) {
            new_this->legend_->add_legend("TIME");
          }
          else {
            new_this->legend_->add_legend("Time");
          }
        }
      }
      new_this->initialized_ = true;
    }
  }
Beispiel #22
0
  DatabaseIO::DatabaseIO(Region *region, std::string filename, DatabaseUsage db_usage,
                         MPI_Comm communicator, const PropertyManager &props)
      : properties(props), commonSideTopology(nullptr), DBFilename(std::move(filename)),
        dbState(STATE_INVALID), isParallel(false), myProcessor(0),
        cycleCount(0), overlayCount(0), timeScaleFactor(1.0), splitType(SPLIT_BY_TOPOLOGIES),
        dbUsage(db_usage), dbIntSizeAPI(USE_INT32_API), lowerCaseVariableNames(true),
        util_(communicator), region_(region), isInput(is_input_event(db_usage)),
        isParallelConsistent(true),
        singleProcOnly(db_usage == WRITE_HISTORY || db_usage == WRITE_HEARTBEAT ||
                       SerializeIO::isEnabled()),
        doLogging(false), useGenericCanonicalName(false)
  {
    isParallel  = util_.parallel_size() > 1;
    myProcessor = util_.parallel_rank();

    // Check environment variable IOSS_PROPERTIES. If it exists, parse
    // the contents and add to the 'properties' map.

    std::string env_props;
    if (util_.get_environment("IOSS_PROPERTIES", env_props, isParallel)) {
      // env_props string should be of the form
      // "PROP1=VALUE1:PROP2=VALUE2:..."
      std::vector<std::string> prop_val = tokenize(env_props, ":");

      for (auto &elem : prop_val) {
        std::vector<std::string> property = tokenize(elem, "=");
        if (property.size() != 2) {
          std::ostringstream errmsg;
          errmsg << "ERROR: Invalid property specification found in "
                    "IOSS_PROPERTIES environment variable\n"
                 << "       Found '" << elem << "' which is not of the correct PROPERTY=VALUE form";
          IOSS_ERROR(errmsg);
        }
        std::string prop      = Utils::uppercase(property[0]);
        std::string value     = property[1];
        std::string up_value  = Utils::uppercase(value);
        bool        all_digit = value.find_first_not_of("0123456789") == std::string::npos;

        if (myProcessor == 0) {
          std::cerr << "IOSS: Adding property '" << prop << "' with value '" << value << "'\n";
        }
        if (all_digit) {
          int int_value = std::strtol(value.c_str(), nullptr, 10);
          properties.add(Property(prop, int_value));
        }
        else if (up_value == "TRUE" || up_value == "YES") {
          properties.add(Property(prop, 1));
        }
        else if (up_value == "FALSE" || up_value == "NO") {
          properties.add(Property(prop, 0));
        }
        else {
          properties.add(Property(prop, value));
        }
      }
    }

    if (properties.exists("INTEGER_SIZE_API")) {
      int isize = properties.get("INTEGER_SIZE_API").get_int();
      if (isize == 8) {
        set_int_byte_size_api(Ioss::USE_INT64_API);
      }
    }

    {
      bool logging;
      if (Utils::check_set_bool_property(properties, "LOGGING", logging)) {
        set_logging(logging);
      }
    }

    Utils::check_set_bool_property(properties, "LOWER_CASE_VARIABLE_NAMES", lowerCaseVariableNames);
    Utils::check_set_bool_property(properties, "USE_GENERIC_CANONICAL_NAMES",
                                   useGenericCanonicalName);

    {
      bool consistent;
      if (Utils::check_set_bool_property(properties, "PARALLEL_CONSISTENCY", consistent)) {
        set_parallel_consistency(consistent);
      }
    }

    if (!is_input()) {
      // Create full path to the output file at this point if it doesn't
      // exist...
      create_path(DBFilename);
    }
  }
Beispiel #23
0
  int64_t DatabaseIO::put_field_internal(const Ioss::Region* region, const Ioss::Field& field,
				     void *data, size_t data_size) const
  {
    initialize(region);
    Ioss::Field::RoleType role = field.get_role();
    int64_t num_to_get = field.verify(data_size);

    if ((role == Ioss::Field::TRANSIENT || role == Ioss::Field::REDUCTION) &&
	num_to_get == 1) {

      int ncomp = field.transformed_storage()->component_count();

      if (legend_ != NULL && layout_ != NULL) {
	if (ncomp == 1) {
	  legend_->add_legend(field.get_name());
	}
	else {
	  const Ioss::VariableType *var_type = field.transformed_storage();
	  for (int i=0; i < ncomp; i++) {
	    std::string var_name = var_type->label_name(field.get_name(), i+1, '_');
	    legend_->add_legend(var_name);
	  }
	}
      }

      if (field.get_type() == Ioss::Field::STRING) {
	// Assume that if layout_ is NULL, then we want special one-line output.
	if (layout_ == NULL) {
	  Layout layout(false, 0, separator_, fieldWidth_);
	  layout.add_literal("-");
	  layout.add_literal(time_stamp(tsFormat));
	  layout.add_literal(" ");
	  layout.add_literal(*(std::string*)data);
	  if (logStream != NULL)
	    *logStream << layout << std::endl;
	} else {
	  layout_->add(field.get_name(), *(std::string*)data);
	}
      } else {
	if (layout_ == NULL) {
	  std::ostringstream errmsg;
	  errmsg << "INTERNAL ERROR: Unexpected NULL layout.\n";
	  IOSS_ERROR(errmsg);
	}
	if (field.get_type() == Ioss::Field::INTEGER) {
	  assert(field.transformed_count() == 1);

	  int *i_data = (int*)data;
	  std::vector<int> idata(ncomp);
	  for (int i=0; i < ncomp; i++) {
	    idata[i] = i_data[i];
	  }
	  layout_->add(field.get_name(), idata);
	} else {
	  std::vector<double> rdata(ncomp);
	  double *r_data = (double*)data;
	  for (int i=0; i < ncomp; i++) {
	    rdata[i] = r_data[i];
	  }
	  layout_->add(field.get_name(), rdata);
	}
      }
    } else {
      std::ostringstream errmsg;
      errmsg << "ERROR: Can not handle non-TRANSIENT or non-REDUCTION fields on regions.\n";
      IOSS_ERROR(errmsg);
    }
    return num_to_get;
  }
Beispiel #24
0
Ioex::SuperElement::SuperElement(std::string filename, const std::string &my_name)
    : Ioss::GroupingEntity(nullptr, my_name, 1), fileName(std::move(filename)), numDOF(0),
      num_nodes(0), numEIG(0), num_dim(0), filePtr(-1)
{

  // For now, we will open the raw netcdf file here and parse the
  // dimensions. This is probably not how this should be done long
  // term, but is better than putting netcdf calls in application...

  // Check that file specified by filename exists...
  // Add working directory if needed.
  std::string local_filename = fileName;

  int status = nc_open(local_filename.c_str(), NC_NOWRITE, &filePtr);
  if (status != NC_NOERR) {
    std::ostringstream errmsg;
    errmsg << "ERROR: Failed to open superelement file '" << local_filename << "'.";
    IOSS_ERROR(errmsg);
  }

  // At this point have a valid netcdf file handle.
  // Read some dimensions to determine size of Mass and Stiffness
  // matrix.
  nc_get_dimension(filePtr, "NumDof", "number of degrees of freedom", &numDOF);

  nc_get_dimension(filePtr, "num_nodes", "number of nodes", &num_nodes);

  nc_get_dimension(filePtr, "NumEig", "number of eigenvalues", &numEIG);

  nc_get_dimension(filePtr, "num_dim", "number of dimensions", &num_dim);

  size_t num_constraints = 0;
  nc_get_dimension(filePtr, "NumConstraints", "number of interface dof", &num_constraints);
  assert(num_constraints == numDOF - numEIG);

  // Add the standard properties...
  properties.add(Ioss::Property(this, "numDOF", Ioss::Property::INTEGER));
  if (num_nodes > 0) {
    properties.add(Ioss::Property(this, "num_nodes", Ioss::Property::INTEGER));
  }
  properties.add(Ioss::Property(this, "numEIG", Ioss::Property::INTEGER));

  properties.add(Ioss::Property(this, "numDIM", Ioss::Property::INTEGER));

  properties.add(Ioss::Property(this, "numConstraints", Ioss::Property::INTEGER));

  // Add the standard fields...
  if (num_nodes > 0) {
    fields.add(Ioss::Field("coordx", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, num_nodes));
    fields.add(Ioss::Field("coordy", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, num_nodes));
    fields.add(Ioss::Field("coordz", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, num_nodes));
    fields.add(
        Ioss::Field("node_num_map", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, num_nodes));
    fields.add(Ioss::Field("cbmap", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH,
                           2 * num_nodes * num_dim));
  }

  fields.add(Ioss::Field("Kr", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, numDOF * numDOF));

  fields.add(Ioss::Field("Mr", Ioss::Field::REAL, SCALAR(), Ioss::Field::MESH, numDOF * numDOF));

  // There are additional properties and fields on the netcdf file,
  // but for now we only need "Kr" and "Mr"
}
Beispiel #25
0
int64_t Ioex::SuperElement::internal_get_field_data(const Ioss::Field &field, void *data,
                                                    size_t data_size) const
{
  size_t num_to_get = field.verify(data_size);

  if (field.get_name() == "cbmap") {
    assert(num_to_get == 2 * num_nodes * num_dim);
    int status = nc_get_array(filePtr, "cbmap", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load coodintate data field 'cbmap' from file '" << fileName
             << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "node_num_map") {
    assert(num_to_get == num_nodes);
    int status = nc_get_array(filePtr, "node_num_map", reinterpret_cast<double *>(data));

    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load coodintate data field 'node_num_map' from file '" << fileName
             << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "coordx") {
    assert(num_to_get == num_nodes);
    int status = nc_get_array(filePtr, "coordx", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load coodintate data field 'coordx' from file '" << fileName
             << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "coordy") {
    assert(num_to_get == num_nodes);
    int status = nc_get_array(filePtr, "coordy", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load coodintate data field 'coordy' from file '" << fileName
             << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "coordz") {
    assert(num_to_get == num_nodes);
    int status = nc_get_array(filePtr, "coordz", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load coodintate data field 'coordz' from file '" << fileName
             << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "Kr") {
    assert(num_to_get == numDOF * numDOF);
    int status = nc_get_array(filePtr, "Kr", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load stiffness matrix field 'Kr' from file '" << fileName << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else if (field.get_name() == "Mr") {
    assert(num_to_get == numDOF * numDOF);
    int status = nc_get_array(filePtr, "Mr", reinterpret_cast<double *>(data));
    if (status != 0) {
      std::ostringstream errmsg;
      errmsg << "ERROR: Could not load mass matrix field 'Mr' from file '" << fileName << "'.";
      IOSS_ERROR(errmsg);
    }
  }
  else {
    std::cerr << "WARNING: " << type() << " '" << name() << "'. Unknown input field '"
              << field.get_name() << "'";
    return -4;
  }
  return num_to_get;
}