[cig-commits] [commit] master: Added stress recording to QuakeLib (7c2cb32)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Tue Dec 2 13:56:09 PST 2014


Repository : https://github.com/geodynamics/vq

On branch  : master
Link       : https://github.com/geodynamics/vq/compare/06902a05cf4d70bc94c85d1c195c073d4e74cdad...c935dfd33f870a081b6c01cce97a060ad1cbdbda

>---------------------------------------------------------------

commit 7c2cb323f0dda50ef82704172dbf344c6278d06e
Author: Eric Heien <emheien at ucdavis.edu>
Date:   Wed Nov 26 00:38:53 2014 -0800

    Added stress recording to QuakeLib


>---------------------------------------------------------------

7c2cb323f0dda50ef82704172dbf344c6278d06e
 quakelib/src/QuakeLibIO.cpp | 419 ++++++++++++++++++++++++++++++++++++++++++++
 quakelib/src/QuakeLibIO.h   | 142 +++++++++++++++
 src/io/ReadModelFile.cpp    |   2 +-
 3 files changed, 562 insertions(+), 1 deletion(-)

diff --git a/quakelib/src/QuakeLibIO.cpp b/quakelib/src/QuakeLibIO.cpp
index 2822234..720fb0d 100644
--- a/quakelib/src/QuakeLibIO.cpp
+++ b/quakelib/src/QuakeLibIO.cpp
@@ -2828,6 +2828,425 @@ int quakelib::ModelEventSet::read_file_ascii(const std::string &event_file_name,
     return 0;
 }
 
+// ********************************************************************************************
+
+void quakelib::ModelStress::read_ascii(std::istream &in_stream, const unsigned int num_records) {
+    for (unsigned int i=0; i<num_records; ++i) {
+        std::stringstream   ss(next_line(in_stream));
+        StressData     new_stress_rec;
+        ss >> new_stress_rec._element_id;
+        ss >> new_stress_rec._shear_stress;
+        ss >> new_stress_rec._normal_stress;
+        // Put the stress record on the list
+        _data.push_back(new_stress_rec);
+    }
+}
+
+void quakelib::ModelStress::write_ascii(std::ostream &out_stream) const {
+    std::vector<StressData>::const_iterator it;
+
+    for (it=_data.begin(); it!=_data.end(); ++it) {
+        out_stream << it->_element_id << " ";
+        out_stream << it->_shear_stress << " ";
+        out_stream << it->_normal_stress;
+
+        next_line(out_stream);
+    }
+}
+
+#ifdef HDF5_FOUND
+void quakelib::ModelStress::setup_stress_hdf5(const hid_t &data_file) {
+    std::vector<FieldDesc>  descs;
+    size_t                  num_fields;
+    unsigned int            i;
+    StressData              blank_data;
+    herr_t                  res;
+
+    // Set up the section table definition
+    descs.clear();
+    ModelStress::get_field_descs(descs);
+    num_fields = descs.size();
+    char **field_names = new char *[num_fields];
+    char **field_details = new char *[num_fields];
+    size_t *field_offsets = new size_t[num_fields];
+    hid_t *field_types = new hid_t[num_fields];
+    size_t *field_sizes = new size_t[num_fields];
+
+    for (i=0; i<num_fields; ++i) {
+        field_names[i] = new char[descs[i].name.length()+1];
+        strncpy(field_names[i], descs[i].name.c_str(), descs[i].name.length());
+        field_names[i][descs[i].name.length()] = '\0';
+        field_details[i] = new char[descs[i].details.length()+1];
+        strncpy(field_details[i], descs[i].details.c_str(), descs[i].details.length());
+        field_details[i][descs[i].details.length()] = '\0';
+        field_offsets[i] = descs[i].offset;
+        field_types[i] = descs[i].type;
+        field_sizes[i] = descs[i].size;
+    }
+
+    // Create the sweep table
+    res = H5TBmake_table("Stress Table",
+                         data_file,
+                         ModelStress::hdf5_table_name().c_str(),
+                         num_fields,
+                         0,
+                         sizeof(StressData),
+                         (const char **)field_names,
+                         field_offsets,
+                         field_types,
+                         100,
+                         &blank_data,
+                         0,
+                         NULL);
+
+    if (res < 0) exit(-1);
+
+    // Add the details of each field as an attribute
+    for (i=0; i<num_fields; ++i) {
+        std::stringstream   ss;
+        ss << "FIELD_" << i << "_DETAILS";
+        res = H5LTset_attribute_string(data_file, ModelStress::hdf5_table_name().c_str(), ss.str().c_str(), field_details[i]);
+
+        if (res < 0) exit(-1);
+    }
+
+    // Free memory for HDF5 related data
+    for (i=0; i<num_fields; ++i) delete field_names[i];
+
+    delete field_names;
+
+    for (i=0; i<num_fields; ++i) delete field_details[i];
+
+    delete field_details;
+    delete field_offsets;
+    delete field_types;
+    delete field_sizes;
+}
+
+void quakelib::ModelStress::append_stress_hdf5(const hid_t &data_file) const {
+    std::vector<FieldDesc>                  descs;
+    std::vector<StressData>::const_iterator it;
+    herr_t                      res;
+    unsigned int                i;
+
+    // Set up the section table definition
+    descs.clear();
+    ModelStress::get_field_descs(descs);
+    size_t num_fields = descs.size();
+    size_t num_stress_recs = _data.size();
+    size_t *field_offsets = new size_t[num_fields];
+    size_t *field_sizes = new size_t[num_fields];
+
+    for (i=0; i<num_fields; ++i) {
+        field_offsets[i] = descs[i].offset;
+        field_sizes[i] = descs[i].size;
+    }
+
+    // Fill in the data for the sections
+    StressData *stress_data = new StressData[num_stress_recs];
+
+    for (i=0,it=_data.begin(); it!=_data.end(); ++i,++it) {
+        memcpy(&(stress_data[i]), &(*it), sizeof(StressData));
+    }
+
+    // Create the section table
+    res = H5TBappend_records(data_file,
+                             ModelStress::hdf5_table_name().c_str(),
+                             num_stress_recs,
+                             sizeof(StressData),
+                             field_offsets,
+                             field_sizes,
+                             stress_data);
+
+    if (res < 0) exit(-1);
+
+    // Free memory for HDF5 related data
+    delete stress_data;
+
+    delete field_offsets;
+    delete field_sizes;
+}
+#endif
+
+void quakelib::ModelStress::write_ascii_header(std::ostream &out_stream) {
+    std::vector<FieldDesc>                  descs;
+    std::vector<FieldDesc>::const_iterator  dit;
+
+    // Write section header
+    ModelStress::get_field_descs(descs);
+
+    for (dit=descs.begin(); dit!=descs.end(); ++dit) {
+        out_stream << "# " << dit->name << ": " << dit->details << "\n";
+    }
+
+    out_stream << "# ";
+
+    for (dit=descs.begin(); dit!=descs.end(); ++dit) {
+        out_stream << dit->name << " ";
+    }
+
+    out_stream << "\n";
+}
+
+void quakelib::ModelStress::get_field_descs(std::vector<quakelib::FieldDesc> &descs) {
+    FieldDesc       field_desc;
+
+    // Stress state table definition
+    field_desc.name = "element_id";
+    field_desc.details = "ID number of the element corresponding to the stress values.";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressData, _element_id);
+    field_desc.type = H5T_NATIVE_UINT;
+    field_desc.size = sizeof(unsigned int);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "shear_stress";
+    field_desc.details = "Shear stress on the element (Pascals).";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressData, _shear_stress);
+    field_desc.type = H5T_NATIVE_FLOAT;
+    field_desc.size = sizeof(float);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "normal_stress";
+    field_desc.details = "Normal stress on the element (Pascals).";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressData, _normal_stress);
+    field_desc.type = H5T_NATIVE_FLOAT;
+    field_desc.size = sizeof(float);
+#endif
+    descs.push_back(field_desc);
+}
+
+// ********************************************************************************************
+
+void quakelib::ModelStressState::write_ascii_header(std::ostream &out_stream) {
+    std::vector<FieldDesc>                  descs;
+    std::vector<FieldDesc>::const_iterator  dit;
+
+    // Write section header
+    ModelStressState::get_field_descs(descs);
+
+    for (dit=descs.begin(); dit!=descs.end(); ++dit) {
+        out_stream << "# " << dit->name << ": " << dit->details << "\n";
+    }
+
+    out_stream << "# ";
+
+    for (dit=descs.begin(); dit!=descs.end(); ++dit) {
+        out_stream << dit->name << " ";
+    }
+
+    out_stream << "\n";
+}
+
+#ifdef HDF5_FOUND
+void quakelib::ModelStressState::setup_stress_state_hdf5(const hid_t &data_file) {
+    std::vector<FieldDesc>  descs;
+    unsigned int            i;
+    StressDataTime          blank_data;
+    herr_t                  res;
+
+    // Set up the section table definition
+    descs.clear();
+    ModelStressState::get_field_descs(descs);
+    size_t num_fields = descs.size();
+    char **field_names = new char *[num_fields];
+    char **field_details = new char *[num_fields];
+    size_t *field_offsets = new size_t[num_fields];
+    hid_t *field_types = new hid_t[num_fields];
+    size_t *field_sizes = new size_t[num_fields];
+
+    for (i=0; i<num_fields; ++i) {
+        field_names[i] = new char[descs[i].name.length()+1];
+        strncpy(field_names[i], descs[i].name.c_str(), descs[i].name.length());
+        field_names[i][descs[i].name.length()] = '\0';
+        field_details[i] = new char[descs[i].details.length()+1];
+        strncpy(field_details[i], descs[i].details.c_str(), descs[i].details.length());
+        field_details[i][descs[i].details.length()] = '\0';
+        field_offsets[i] = descs[i].offset;
+        field_types[i] = descs[i].type;
+        field_sizes[i] = descs[i].size;
+    }
+
+    // Create the sweep table
+    res = H5TBmake_table("Stress State Table",
+                         data_file,
+                         ModelStressState::hdf5_table_name().c_str(),
+                         num_fields,
+                         0,
+                         sizeof(StressDataTime),
+                         (const char **)field_names,
+                         field_offsets,
+                         field_types,
+                         100,
+                         &blank_data,
+                         0,
+                         NULL);
+
+    if (res < 0) exit(-1);
+
+    // Add the details of each field as an attribute
+    for (i=0; i<num_fields; ++i) {
+        std::stringstream   ss;
+        ss << "FIELD_" << i << "_DETAILS";
+        res = H5LTset_attribute_string(data_file, ModelStressState::hdf5_table_name().c_str(), ss.str().c_str(), field_details[i]);
+
+        if (res < 0) exit(-1);
+    }
+
+    // Free memory for HDF5 related data
+    for (i=0; i<num_fields; ++i) delete field_names[i];
+
+    delete field_names;
+
+    for (i=0; i<num_fields; ++i) delete field_details[i];
+
+    delete field_details;
+    delete field_offsets;
+    delete field_types;
+    delete field_sizes;
+}
+
+void quakelib::ModelStressState::append_stress_state_hdf5(const hid_t &data_file) const {
+    std::vector<FieldDesc>                  descs;
+    std::vector<StressData>::const_iterator it;
+    herr_t                      res;
+    unsigned int                i;
+
+    // Set up the section table definition
+    descs.clear();
+    ModelStressState::get_field_descs(descs);
+    size_t num_fields = descs.size();
+    size_t *field_offsets = new size_t[num_fields];
+    size_t *field_sizes = new size_t[num_fields];
+
+    for (i=0; i<num_fields; ++i) {
+        field_offsets[i] = descs[i].offset;
+        field_sizes[i] = descs[i].size;
+    }
+
+    // Add to the stress state table
+    res = H5TBappend_records(data_file,
+                             ModelStressState::hdf5_table_name().c_str(),
+                             1,
+                             sizeof(StressDataTime),
+                             field_offsets,
+                             field_sizes,
+                             &_times);
+
+    if (res < 0) exit(-1);
+
+    // Free memory for HDF5 related data
+    delete field_offsets;
+    delete field_sizes;
+}
+#endif
+
+void quakelib::ModelStressState::read_ascii(std::istream &in_stream) {
+    std::stringstream   ss(next_line(in_stream));
+    ss >> _times._year;
+    ss >> _times._event_num;
+    ss >> _times._sweep_num;
+    ss >> _times._start_rec;
+    ss >> _times._end_rec;
+}
+
+void quakelib::ModelStressState::write_ascii(std::ostream &out_stream) const {
+    out_stream << _times._year << " ";
+    out_stream << _times._event_num << " ";
+    out_stream << _times._sweep_num << " ";
+    out_stream << _times._start_rec << " ";
+    out_stream << _times._end_rec;
+
+    next_line(out_stream);
+}
+
+void quakelib::ModelStressState::get_field_descs(std::vector<quakelib::FieldDesc> &descs) {
+    FieldDesc       field_desc;
+
+    // Stress state table definition
+    field_desc.name = "year";
+    field_desc.details = "Simulation time this stress state was recorded (years).";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressDataTime, _year);
+    field_desc.type = H5T_NATIVE_FLOAT;
+    field_desc.size = sizeof(float);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "event_num";
+    field_desc.details = "Event number this stress state corresponds to.";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressDataTime, _event_num);
+    field_desc.type = H5T_NATIVE_UINT;
+    field_desc.size = sizeof(unsigned int);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "sweep_num";
+    field_desc.details = "Sweep number this stress state corresponds to.";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressDataTime, _sweep_num);
+    field_desc.type = H5T_NATIVE_UINT;
+    field_desc.size = sizeof(unsigned int);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "start_rec";
+    field_desc.details = "Starting record of stress values for this time.";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressDataTime, _start_rec);
+    field_desc.type = H5T_NATIVE_UINT;
+    field_desc.size = sizeof(unsigned int);
+#endif
+    descs.push_back(field_desc);
+
+    field_desc.name = "end_rec";
+    field_desc.details = "Ending record of stress values for this time.";
+#ifdef HDF5_FOUND
+    field_desc.offset = HOFFSET(StressDataTime, _end_rec);
+    field_desc.type = H5T_NATIVE_UINT;
+    field_desc.size = sizeof(unsigned int);
+#endif
+    descs.push_back(field_desc);
+}
+
+int quakelib::ModelStressSet::read_file_ascii(const std::string &stress_index_file_name, const std::string &stress_file_name) {
+    std::ifstream   stress_ind_file, stress_file;
+    ModelSweeps     file_sweeps;
+
+    // Try to open the stress index file
+    stress_ind_file.open(stress_index_file_name.c_str());
+
+    if (!stress_ind_file.is_open()) return -1;
+
+    // Try to open the stress file
+    stress_file.open(stress_file_name.c_str());
+
+    if (!stress_file.is_open()) return -1;
+
+    // Keep going until we hit the end of either file
+    while (!stress_ind_file.eof() && !stress_file.eof()) {
+        ModelStressState    new_stress_state;
+        ModelStress         new_stresses;
+        new_stress_state.read_ascii(stress_ind_file);
+        unsigned int num_recs = new_stress_state.getNumStressRecords();
+        new_stresses.read_ascii(stress_file, num_recs);
+        new_stress_state.setStresses(new_stresses);
+
+        if (!stress_ind_file.eof() && !stress_file.eof()) _states.push_back(new_stress_state);
+    }
+
+    // Close the files
+    stress_ind_file.close();
+    stress_file.close();
+
+    return 0;
+}
+
 namespace quakelib {
     std::ostream &operator<<(std::ostream &os, const ModelSweeps &ms) {
         os << "SWEEPS(" << ms._sweeps.size() << ")";
diff --git a/quakelib/src/QuakeLibIO.h b/quakelib/src/QuakeLibIO.h
index e7bf438..440d52e 100644
--- a/quakelib/src/QuakeLibIO.h
+++ b/quakelib/src/QuakeLibIO.h
@@ -998,6 +998,148 @@ namespace quakelib {
 
             int read_file_ascii(const std::string &event_file_name, const std::string &sweep_file_name);
     };
+
+    /*!
+     The stress state of an element in the model at a specified time in the simulation.
+     32-bit floats are used to save space since there may be vast amounts of stress
+     data output and high precision is not needed for analysis.
+     */
+    struct StressData {
+        //! The ID of the element
+        UIndex          _element_id;
+
+        //! Shear and normal stress on the element at this time
+        float          _shear_stress, _normal_stress;
+    };
+
+    /*!
+     ModelStress is the stress state of the model at a specified point in time.
+     */
+    class ModelStress : public ModelIO {
+        private:
+            std::vector<StressData>     _data;
+
+        public:
+            ModelStress(void) {
+                _data.clear();
+            }
+
+            //! Get the total number of blocks that failed in this event.
+            unsigned int size(void) const {
+                return _data.size();
+            };
+
+            void clear(void) {
+                _data.clear();
+            }
+
+#ifdef HDF5_FOUND
+            static std::string hdf5_table_name(void) {
+                return "stresses";
+            };
+            static void setup_stress_hdf5(const hid_t &data_file);
+            void append_stress_hdf5(const hid_t &data_file) const;
+#endif
+            static void get_field_descs(std::vector<FieldDesc> &descs);
+            static void write_ascii_header(std::ostream &out_stream);
+
+            void read_ascii(std::istream &in_stream, const unsigned int num_records);
+            void write_ascii(std::ostream &out_stream) const;
+
+            friend std::ostream &operator<<(std::ostream &os, const ModelStress &ms);
+    };
+
+    struct StressDataTime {
+        //! The year of the stress data
+        float           _year;
+
+        //! The event and sweep of the stress data (if applicable)
+        UIndex          _event_num, _sweep_num;
+
+        //! Starting and ending index of the actual stress entries
+        UIndex          _start_rec, _end_rec;
+    };
+
+    /*!
+     ModelStressState is the stress state of the model at a specified point in time, including information specifying the time.
+     */
+    class ModelStressState : public ModelIO {
+        private:
+            ModelStress         _stress;
+
+            StressDataTime      _times;
+
+        public:
+            ModelStressState(void) {
+                clear();
+            }
+
+            void clear(void) {
+                _stress.clear();
+                _times._year = nan("");
+                _times._event_num = UNDEFINED_EVENT_ID;
+                _times._sweep_num = UNDEFINED_EVENT_ID;
+                _times._start_rec = UNDEFINED_EVENT_ID;
+                _times._end_rec = UNDEFINED_EVENT_ID;
+            }
+
+#ifdef HDF5_FOUND
+            static std::string hdf5_table_name(void) {
+                return "stress_state";
+            };
+            static void setup_stress_state_hdf5(const hid_t &data_file);
+            void append_stress_state_hdf5(const hid_t &data_file) const;
+#endif
+            static void get_field_descs(std::vector<FieldDesc> &descs);
+            static void write_ascii_header(std::ostream &out_stream);
+
+            void setStresses(const ModelStress &new_stresses) {
+                _stress = new_stresses;
+            };
+
+            unsigned int getNumStressRecords(void) const {
+                return _times._end_rec - _times._start_rec;
+            };
+
+            void read_ascii(std::istream &in_stream);
+            void write_ascii(std::ostream &out_stream) const;
+
+            friend std::ostream &operator<<(std::ostream &os, const ModelStressState &mss);
+    };
+
+    class ModelStressSet {
+        private:
+            std::vector<ModelStressState>   _states;
+
+        public:
+            typedef std::vector<ModelStressState>::iterator         iterator;
+            typedef std::vector<ModelStressState>::const_iterator   const_iterator;
+
+            iterator begin(void) {
+                return _states.begin();
+            };
+            iterator end(void) {
+                return _states.end();
+            };
+
+            unsigned int size(void) const {
+                return _states.size();
+            }
+
+            ModelStressState &operator[](const unsigned int ind) throw(std::out_of_range) {
+                if (ind >= _states.size()) throw std::out_of_range("ModelStressSet[]");
+
+                return _states[ind];
+            };
+
+            const ModelStressState &operator[](const unsigned int ind) const throw(std::out_of_range) {
+                if (ind >= _states.size()) throw std::out_of_range("ModelStressSet[]");
+
+                return _states[ind];
+            };
+
+            int read_file_ascii(const std::string &stress_index_file_name, const std::string &stress_file_name);
+    };
 }
 
 #endif
diff --git a/src/io/ReadModelFile.cpp b/src/io/ReadModelFile.cpp
index 42e8936..e426ddd 100644
--- a/src/io/ReadModelFile.cpp
+++ b/src/io/ReadModelFile.cpp
@@ -93,6 +93,6 @@ void ReadModelFile::init(SimFramework *_sim) {
         new_block.setInitNormalStress(0);
         new_block.setDynamicVal(sim->getDynamic());
 
-        BlockID new_id = sim->addBlock(new_block);
+        sim->addBlock(new_block);
     }
 }



More information about the CIG-COMMITS mailing list