66// Maintainer:
77// Created: Thu Jun 18 23:16:11 2015 (-0400)
88// Version:
9- // Last-Updated: Sun Dec 20 23:20:19 2015 (-0500)
10- // By: subha
11- // Update #: 49
9+ // Last-Updated: Sat Jan 29 2022
10+ // By: bhalla
11+ // Update #: 50
1212// URL:
1313// Keywords:
1414// Compatibility:
2222//
2323
2424// Change log:
25- //
25+ // Jan 2022: Many changes added
2626//
2727//
2828//
4949#include " hdf5.h"
5050#include " hdf5_hl.h"
5151
52+ #include < fstream>
5253#include < ctime>
5354#include < deque>
54-
5555#include " ../basecode/header.h"
5656#include " ../utility/utility.h"
5757#include " ../utility/strutil.h"
@@ -67,8 +67,11 @@ extern template herr_t writeScalarAttr(hid_t file_id, string path, double value)
6767
6868const char * const EVENTPATH = " /data/event" ;
6969const char * const UNIFORMPATH = " /data/uniform" ;
70+ const char * const STATICPATH = " /data/static" ;
7071const char * const MODELTREEPATH = " /model/modeltree" ;
72+ const char * const MODELFILEPATH = " /model/modelfile" ;
7173const char * const MAPUNIFORMSRC = " /map/uniform" ;
74+ const char * const MAPSTATICSRC = " /map/static" ;
7275const char * const MAPEVENTSRC = " /map/event" ;
7376
7477string iso_time (time_t * t)
@@ -99,10 +102,16 @@ const Cinfo * NSDFWriter::initCinfo()
99102
100103 static ValueFinfo <NSDFWriter, string > modelRoot (
101104 " modelRoot" ,
102- " The moose element tree root to be saved under /model/modeltree" ,
105+ " The moose element tree root to be saved under /model/modeltree. If blank, nothing is saved. Default: root object, '/' " ,
103106 &NSDFWriter::setModelRoot,
104107 &NSDFWriter::getModelRoot);
105108
109+ static ValueFinfo <NSDFWriter, string > modelFileNames (
110+ " modelFileNames" ,
111+ " Comma separated list of model files to save into the NSDF file." ,
112+ &NSDFWriter::setModelFiles,
113+ &NSDFWriter::getModelFiles);
114+
106115 static DestFinfo process (
107116 " process" ,
108117 " Handle process calls. Collects data in buffer and if number of steps"
@@ -125,7 +134,8 @@ const Cinfo * NSDFWriter::initCinfo()
125134 processShared, sizeof ( processShared ) / sizeof ( Finfo* ));
126135
127136 static Finfo * finfos[] = {
128- &eventInputFinfo,
137+ &eventInputFinfo, // FieldElementFinfo
138+ &modelFileNames, // ValueFinfo
129139 &proc,
130140 };
131141
@@ -267,19 +277,37 @@ void NSDFWriter::openUniformData(const Eref &eref)
267277 create the DS for uniform data.
268278 */
269279void NSDFWriter::createUniformMap ()
280+ {
281+ innerCreateMaps ( MAPUNIFORMSRC );
282+ }
283+
284+ /* *
285+ create the DS for static data.
286+ */
287+ void NSDFWriter::createStaticMap ()
288+ {
289+ innerCreateMaps ( MAPSTATICSRC );
290+ }
291+
292+
293+ /* *
294+ Generic call for create the DS for static/uniform data
295+ */
296+ void NSDFWriter::innerCreateMaps ( const char * const mapSrcStr )
270297{
271298 // Create the container for all the DS
272- // TODO: make a common function like `mkdir -p` to avoid repeating this
273299 htri_t exists;
274300 herr_t status;
275- hid_t uniformMapContainer = require_group (filehandle_, MAPUNIFORMSRC );
301+ hid_t uniformMapContainer = require_group (filehandle_, mapSrcStr );
276302 // Create the DS themselves
277303 for (map< string, vector < unsigned int > >::iterator ii = classFieldToSrcIndex_.begin ();
278304 ii != classFieldToSrcIndex_.end (); ++ii){
279305 vector < string > pathTokens;
280306 moose::tokenize (ii->first , " /" , pathTokens);
281307 string className = pathTokens[0 ];
282308 string fieldName = pathTokens[1 ];
309+ if (mapSrcStr == MAPSTATICSRC ) // Hack. for now only static field is coords
310+ fieldName = " coords" ;
283311 hid_t container = require_group (uniformMapContainer, className);
284312 char ** sources = (char **)calloc (ii->second .size (), sizeof (char *));
285313 for (unsigned int jj = 0 ; jj < ii->second .size (); ++jj){
@@ -291,9 +319,6 @@ void NSDFWriter::createUniformMap()
291319 status = H5Tset_size (memtype, H5T_VARIABLE);
292320 assert (status >= 0 );
293321 status = H5Dwrite (ds, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, sources);
294- #ifndef NDEBUG
295- cout << " Write dataset: status=" << status << endl;
296- #endif
297322 assert (status >= 0 );
298323 for (unsigned int jj = 0 ; jj < ii->second .size (); ++jj){
299324 free (sources[jj]);
@@ -534,9 +559,12 @@ void NSDFWriter::reinit(const Eref& eref, const ProcPtr proc)
534559 writeScalarAttr< double >(it->second , " dt" , proc->dt );
535560 }
536561 openEventData (eref);
562+ writeModelFiles ();
537563 writeModelTree ();
538564 createUniformMap ();
565+ createStaticMap ();
539566 createEventMap ();
567+ writeStaticCoords ();
540568 steps_ = 0 ;
541569}
542570
@@ -627,9 +655,97 @@ string NSDFWriter::getModelRoot() const
627655 return modelRoot_;
628656}
629657
658+ void NSDFWriter::setModelFiles (string value)
659+ {
660+ modelFileNames_.clear ();
661+ moose::tokenize ( value, " , " , modelFileNames_);
662+ }
663+
664+ string NSDFWriter::getModelFiles () const
665+ {
666+ string ret = " " ;
667+ string spacer = " " ;
668+ for ( auto s = modelFileNames_.begin (); s!= modelFileNames_.end (); ++s) {
669+ ret += spacer + *s;
670+ spacer = " ," ;
671+ }
672+ return ret;
673+ }
674+
675+ void NSDFWriter::writeStaticCoords ()
676+ {
677+ hid_t staticObjContainer = require_group (filehandle_, STATICPATH );
678+ for (map< string, vector < unsigned int > >::iterator ii = classFieldToSrcIndex_.begin (); ii != classFieldToSrcIndex_.end (); ++ii){
679+ vector < string > pathTokens;
680+ moose::tokenize (ii->first , " /" , pathTokens);
681+ string className = pathTokens[0 ];
682+ string fieldName = " coords" ; // pathTokens[1] is not relevant.
683+ hid_t container = require_group (staticObjContainer, className);
684+ double * buffer = (double *)calloc (ii->second .size () * 7 , sizeof (double ));
685+ // Ugly class checking stuff here: Both have a coord field
686+ if ( className.find ( " Pool" ) != string::npos ||
687+ className.find ( " Compartment" ) != string::npos ) {
688+ for (unsigned int jj = 0 ; jj < ii->second .size (); ++jj) {
689+ vector< double > coords = Field< vector< double > >::get ( src_[ii->second [jj]], fieldName.c_str () );
690+ if ( coords.size () == 11 ) { // For SpineMesh
691+ for ( unsigned int kk = 0 ; kk < 6 ; ++kk) {
692+ buffer[jj * 7 + kk] = coords[kk];
693+ }
694+ buffer[jj * 7 + 6 ] = coords[9 ]; // head Dia
695+ } else if ( coords.size () == 4 ) { // for EndoMesh
696+ for ( unsigned int kk = 0 ; kk < 3 ; ++kk) {
697+ buffer[jj * 7 + kk] = coords[kk];
698+ buffer[jj * 7 + kk+3 ] = coords[kk];
699+ }
700+ buffer[jj * 7 + 6 ] = coords[3 ];
701+ } else if ( coords.size () >= 7 ) { // For NeuroMesh
702+ for ( unsigned int kk = 0 ; kk < 7 ; ++kk) {
703+ buffer[jj * 7 + kk] = coords[kk];
704+ }
705+ }
706+ }
707+ } else { // Want to check for things like Ca in an elec compt...
708+ for (unsigned int jj = 0 ; jj < ii->second .size (); ++jj) {
709+ for ( unsigned int kk = 0 ; kk < 7 ; ++kk) {
710+ buffer[jj * 7 + kk] = 0.0 ;
711+ }
712+ }
713+ }
714+ hsize_t dims[2 ];
715+ dims[0 ] = ii->second .size ();
716+ dims[1 ] = 7 ;
717+ hid_t memspace = H5Screate_simple (2 , dims, NULL );
718+ hid_t dataspace = H5Screate_simple (2 , dims, NULL );
719+ hid_t dataset = H5Dcreate2 (container, fieldName.c_str (), H5T_NATIVE_DOUBLE, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
720+ hid_t filespace = H5Dget_space (dataset);
721+ herr_t status = H5Dwrite (dataset, H5T_NATIVE_DOUBLE, memspace, filespace, H5P_DEFAULT, buffer);
722+ if ( status < 0 ) {
723+ cout << " Error: Failed to write coords as static entry\n " ;
724+ }
725+ }
726+ }
727+
728+ void NSDFWriter::writeModelFiles ()
729+ {
730+ for ( const string& fName : modelFileNames_ ) {
731+ // string fPath = MODELFILEPATH + string("/") + fName;
732+ string fPath = MODELFILEPATH;
733+ std::ifstream f ( fName );
734+ auto ss = ostringstream{};
735+ if ( f.is_open () ) {
736+ ss << f.rdbuf ();
737+ hid_t fGroup = require_group (filehandle_, fPath );
738+ writeScalarAttr<string>(fGroup , fName , ss.str ());
739+ } else {
740+ cout << " Warning: NSDFWriter::writeModelFiles Could not open file '" << fName << " '/n" ;
741+ }
742+ }
743+ }
630744
631745void NSDFWriter::writeModelTree ()
632746{
747+ if (modelRoot_ == " " )
748+ return ;
633749 vector< string > tokens;
634750 ObjId mRoot (modelRoot_);
635751 string rootPath = MODELTREEPATH + string (" /" ) + mRoot .element ()->getName ();
0 commit comments