Skip to content

Commit 80b0cc8

Browse files
committed
draft for SSV
1 parent 3e91599 commit 80b0cc8

11 files changed

+264
-29
lines changed

Apps/Common/SIMSolver.h

+15-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "TimeStep.h"
2020
#include "HDF5Restart.h"
2121
#include "HDF5Writer.h"
22+
#include "HDF5WriterSSV.h"
2223
#include "tinyxml.h"
2324

2425

@@ -47,17 +48,23 @@ template<class T1> class SIMSolverStat : public SIMadmin
4748
//! \param[in] hdf5file The file to save to
4849
//! \param[in] modelAdm Process administrator to use
4950
//! \param[in] saveInterval The stride in the output file
51+
//! \param[in] ssv Enable SSV writer
5052
void handleDataOutput(const std::string& hdf5file,
5153
const ProcessAdm& modelAdm,
52-
int saveInterval = 1)
54+
int saveInterval = 1,
55+
bool vis = true,
56+
bool ssv = false)
5357
{
5458
if (IFEM::getOptions().discretization == ASM::Spectral && !hdf5file.empty())
5559
IFEM::cout <<"\n ** HDF5 output is available for spline/lagrangian discretization"
5660
<<" only. Deactivating...\n"<< std::endl;
57-
else
61+
else if (vis || ssv)
5862
{
5963
exporter = new DataExporter(true,saveInterval);
60-
exporter->registerWriter(new HDF5Writer(hdf5file,modelAdm));
64+
if (vis)
65+
exporter->registerWriter(new HDF5Writer(hdf5file,modelAdm));
66+
if (ssv)
67+
exporter->registerWriter(new HDF5WriterSSV(hdf5file,modelAdm));
6168
S1.registerFields(*exporter);
6269
IFEM::registerCallback(*exporter);
6370
}
@@ -169,15 +176,18 @@ template<class T1> class SIMSolver : public SIMSolverStat<T1>
169176
//! \param[in] modelAdm Process administrator to use
170177
//! \param[in] saveInterval The stride in the output file
171178
//! \param[in] restartInterval The stride in the restart file
179+
//! \param[in] ssv Enable SSV writer
172180
void handleDataOutput(const std::string& hdf5file,
173181
const ProcessAdm& modelAdm,
174182
int saveInterval = 1,
175-
int restartInterval = 0)
183+
int restartInterval = 0,
184+
bool vis = true,
185+
bool ssv = false)
176186
{
177187
if (restartInterval > 0)
178188
restartAdm = new HDF5Restart(hdf5file+"_restart",modelAdm,restartInterval);
179189

180-
this->SIMSolverStat<T1>::handleDataOutput(hdf5file, modelAdm, saveInterval);
190+
this->SIMSolverStat<T1>::handleDataOutput(hdf5file, modelAdm, saveInterval, vis, ssv);
181191
}
182192

183193
//! \brief Serialize internal state for restarting purposes.

src/SIM/SIMoptions.C

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ SIMoptions::SIMoptions ()
5252
nViz[0] = nViz[1] = nViz[2] = 2;
5353

5454
printPid = 0;
55+
saveHDF5viz = true;
56+
saveHDF5ssv = false;
5557
}
5658

5759

@@ -174,6 +176,9 @@ bool SIMoptions::parseOutputTag (const TiXmlElement* elem)
174176
}
175177
else // use the default output file name
176178
hdf5 = "(default)";
179+
180+
utl::getAttribute(elem,"ssv",saveHDF5ssv);
181+
utl::getAttribute(elem,"viz",saveHDF5viz);
177182
}
178183

179184
else if (!strcasecmp(elem->Value(),"primarySolOnly"))

src/SIM/SIMoptions.h

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class SIMoptions
9191
bool pSolOnly; //!< If \e true, don't save secondary solution variables
9292
bool saveNorms;//!< If \e true, save element norms
9393
bool saveLog; //!< If \e true, export the log
94+
bool saveHDF5viz; //!< If \e true, save HDF5 visualization file
95+
bool saveHDF5ssv; //!< If \e true, save HDF5 SSV file
9496

9597
std::string hdf5; //!< Prefix for HDF5-file
9698
std::string vtf; //!< Prefix for VTF-file

src/Utility/DataExporter.C

+4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
121121

122122
for (DataWriter* writer : m_writers) {
123123
writer->openFile(m_level);
124+
for (const DataEntry& it : m_entry)
125+
if (it.second.field == SIM)
126+
writer->prepare(m_level,it,geometryUpdated,it.second.prefix);
127+
124128
for (const DataEntry& it : m_entry) {
125129
if (!it.second.data)
126130
return false;

src/Utility/DataExporter.h

+10
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ class DataWriter
189189
//! \param[in] level Level we just wrote to the file
190190
virtual void closeFile(int level) = 0;
191191

192+
//! \brief Prepare writer for writing a time level.
193+
//! \param[in] level The time level to write the data at
194+
//! \param[in] entry The DataEntry describing the vector
195+
//! \param[in] geometryUpdated Whether or not geometries should be written
196+
//! \param[in] prefix Field name prefix
197+
//! \details Used by SVV where we have to preallocate datasets
198+
virtual bool prepare(int level, const DataEntry& entry,
199+
bool geometryUpdated, const std::string& prefix)
200+
{ return true; }
201+
192202
//! \brief Writes a vector to file.
193203
//! \param[in] level The time level to write the vector at
194204
//! \param[in] entry The DataEntry describing the vector

src/Utility/HDF5Base.C

+23-9
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,40 @@ HDF5Base::HDF5Base (const std::string& name, const ProcessAdm& adm)
3535
}
3636

3737

38-
bool HDF5Base::openFile (unsigned int flags)
38+
bool HDF5Base::openFile (unsigned int flags, bool latest)
3939
{
4040
#ifdef HAS_HDF5
4141
if (m_file != -1)
4242
return true;
4343

44+
hid_t acc_tpl = H5P_DEFAULT;
45+
bool acc_tpl_alloc = false;
46+
if (latest
47+
#ifdef HAVE_MPI
48+
&& m_adm.getProcId() == 0 || !m_adm.dd.isPartitioned()
49+
#endif
50+
) {
51+
acc_tpl = H5Pcreate(H5P_FILE_ACCESS);
52+
acc_tpl_alloc = true;
53+
}
54+
4455
#ifdef HAVE_MPI
45-
hid_t acc_tpl;
4656
if (m_adm.dd.isPartitioned()) {
4757
if (m_adm.getProcId() != 0)
4858
return true;
49-
acc_tpl = H5P_DEFAULT;
5059
} else {
5160
MPI_Info info = MPI_INFO_NULL;
52-
acc_tpl = H5Pcreate(H5P_FILE_ACCESS);
61+
if (!acc_tpl_alloc) {
62+
acc_tpl = H5Pcreate(H5P_FILE_ACCESS);
63+
acc_tpl_alloc = true;
64+
}
5365
H5Pset_fapl_mpio(acc_tpl, *m_adm.getCommunicator(), info);
5466
}
55-
#else
56-
hid_t acc_tpl = H5P_DEFAULT;
5767
#endif
5868

69+
if (latest)
70+
H5Pset_libver_bounds(acc_tpl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
71+
5972
if (flags == H5F_ACC_TRUNC)
6073
m_file = H5Fcreate(m_hdf5_name.c_str(),flags,H5P_DEFAULT,acc_tpl);
6174
else
@@ -64,13 +77,14 @@ bool HDF5Base::openFile (unsigned int flags)
6477
if (m_file < 0)
6578
{
6679
std::cerr <<" *** HDF5Base: Failed to open "<< m_hdf5_name << std::endl;
80+
if (acc_tpl_alloc)
81+
H5Pclose(acc_tpl);
6782
return false;
6883
}
6984

70-
#ifdef HAVE_MPI
71-
if (!m_adm.dd.isPartitioned())
85+
if (acc_tpl_alloc)
7286
H5Pclose(acc_tpl);
73-
#endif
87+
7488
return true;
7589
#else
7690
return false;

src/Utility/HDF5Base.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class HDF5Base
3939
protected:
4040
//! \brief Opens the HDF5 file.
4141
//! \param[in] flag Mode to open file using
42-
bool openFile(unsigned int flag);
42+
//! \param[in] latest If true, open using latest version
43+
bool openFile(unsigned int flag, bool latest = false);
4344
//! \brief Closes the HDF5 file.
4445
void closeFile();
4546

src/Utility/HDF5Writer.C

+28-13
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,18 @@ void HDF5Writer::writeArray(hid_t group, const std::string& name, int patch,
168168
space = H5Screate_simple(1,&siz,nullptr);
169169
std::stringstream str;
170170
str << patch;
171-
set = H5Dcreate2(group1,str.str().c_str(),
172-
type,space,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
171+
if (checkGroupExistence(group1,str.str().c_str()))
172+
set = H5Dopen2(group1,str.str().c_str(),H5P_DEFAULT);
173+
else
174+
set = H5Dcreate2(group1,str.str().c_str(),
175+
type,space,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
173176
} else {
174177
space = H5Screate_simple(1,&siz,nullptr);
175-
set = H5Dcreate2(group,name.c_str(),
176-
type,space,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
178+
if (checkGroupExistence(group,name.c_str()))
179+
set = H5Dopen2(group,name.c_str(),H5P_DEFAULT);
180+
else
181+
set = H5Dcreate2(group,name.c_str(),
182+
type,space,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT);
177183
}
178184
if (len > 0) {
179185
hid_t file_space = H5Dget_space(set);
@@ -185,6 +191,7 @@ void HDF5Writer::writeArray(hid_t group, const std::string& name, int patch,
185191
H5Sclose(mem_space);
186192
H5Sclose(file_space);
187193
}
194+
H5Dflush(set);
188195
H5Dclose(set);
189196
H5Sclose(space);
190197
if (group1 != -1)
@@ -241,6 +248,14 @@ void HDF5Writer::writeBasis (int level, const DataEntry& entry,
241248

242249
void HDF5Writer::writeSIM (int level, const DataEntry& entry,
243250
bool geometryUpdated, const std::string& prefix)
251+
{
252+
this->writeSIMInt(level, entry, geometryUpdated, prefix, false);
253+
}
254+
255+
256+
void HDF5Writer::writeSIMInt (int level, const DataEntry& entry,
257+
bool geometryUpdated,
258+
const std::string& prefix, bool noData)
244259
{
245260
if (!entry.second.enabled || !entry.second.data || entry.second.data2.empty())
246261
return;
@@ -336,7 +351,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
336351
(!(results & DataExporter::REDUNDANT) || sim->getGlobalProcessID() == 0)) // we own the patch
337352
{
338353
ASMbase* pch = sim->getPatch(loc);
339-
if (results & DataExporter::PRIMARY && !sol->empty()) {
354+
if (results & DataExporter::PRIMARY && !sol->empty() && !noData) {
340355
Vector psol;
341356
size_t ndof1 = sim->extractPatchSolution(*sol,psol,pch,entry.second.ncmps,
342357
usedescription ? 1 : 0);
@@ -357,7 +372,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
357372
i+1, ndof1, data, H5T_NATIVE_DOUBLE);
358373
}
359374

360-
if (results & DataExporter::SECONDARY && !sol->empty()) {
375+
if (results & DataExporter::SECONDARY && !sol->empty() && !noData) {
361376
Matrix field;
362377
SIM::SolutionMode mode = prob->getMode();
363378
const_cast<SIMbase*>(sim)->setMode(SIM::RECOVERY);
@@ -369,7 +384,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
369384
i+1, field.cols(), field.getRow(j+1).ptr(), H5T_NATIVE_DOUBLE);
370385
}
371386

372-
if (proj)
387+
if (proj && !noData)
373388
for (size_t p = 0; p < proj->size(); ++p) {
374389
if (proj->at(p).empty())
375390
continue;
@@ -394,7 +409,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
394409
i+1, field.cols(), field.getRow(j+1).ptr(), H5T_NATIVE_DOUBLE);
395410
}
396411

397-
if (results & DataExporter::NORMS && eNorm) {
412+
if (results & DataExporter::NORMS && eNorm && !noData) {
398413
Matrix patchEnorm;
399414
sim->extractPatchElmRes(*eNorm,patchEnorm,loc-1);
400415
for (size_t j = 1, l = 1; l < eNorm->rows(); j++)
@@ -405,7 +420,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
405420
i+1, patchEnorm.cols(), patchEnorm.getRow(l++).ptr(), H5T_NATIVE_DOUBLE);
406421
}
407422

408-
if (results & DataExporter::EIGENMODES) {
423+
if (results & DataExporter::EIGENMODES && !noData) {
409424
size_t iMode = 0;
410425
const std::vector<Mode>* modes = static_cast<const std::vector<Mode>*>(entry.second.data2.front());
411426
for (const Mode& mode : *modes)
@@ -440,7 +455,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
440455
else // must write empty dummy records for the other patches
441456
{
442457
double dummy=0.0;
443-
if (results & DataExporter::PRIMARY) {
458+
if (results & DataExporter::PRIMARY && !noData) {
444459
if (usedescription)
445460
writeArray(group.front(), entry.second.description,
446461
i+1, 0, &dummy, H5T_NATIVE_DOUBLE);
@@ -453,18 +468,18 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
453468
i+1, 0, &dummy, H5T_NATIVE_DOUBLE);
454469
}
455470

456-
if (results & DataExporter::SECONDARY)
471+
if (results & DataExporter::SECONDARY && !noData)
457472
for (size_t j = 0; j < prob->getNoFields(2); j++)
458473
writeArray(group.front(), prefix+prob->getField2Name(j),
459474
i+1, 0, &dummy,H5T_NATIVE_DOUBLE);
460475

461-
if (proj)
476+
if (proj && !noData)
462477
for (size_t p = 0; p < proj->size(); p++)
463478
for (size_t j = 0; j < prob->getNoFields(2); j++)
464479
writeArray(group.front(), m_prefix[p]+" "+prob->getField2Name(j),
465480
i+1, 0, &dummy,H5T_NATIVE_DOUBLE);
466481

467-
if (results & DataExporter::NORMS && eNorm)
482+
if (results & DataExporter::NORMS && eNorm && !noData)
468483
for (size_t j = 1; j <= norm->getNoFields(0); j++)
469484
for (size_t k = 1; k <= norm->getNoFields(j); k++)
470485
if (norm->hasElementContributions(j,k))

src/Utility/HDF5Writer.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ class HDF5Writer : public DataWriter, public HDF5Base
9999

100100
#ifdef HAS_HDF5
101101
protected:
102+
//! \brief Writes data from a SIM to file.
103+
//! \param[in] level The time level to write the data at
104+
//! \param[in] entry The DataEntry describing the data to write
105+
//! \param[in] geometryUpdated Whether or not geometries should be written
106+
//! \param[in] prefix Field name prefix
107+
//! \param[in] noData True to not write data (only open groups)
108+
//!
109+
//! \details If prefix is non-empty and we are asked to dump secondary
110+
//! solutions, we assume they come from different projections
111+
//! \sa SIMbase::project
112+
void writeSIMInt(int level, const DataEntry& entry,
113+
bool geometryUpdated, const std::string& prefix, bool noData);
114+
102115
//! \brief Internal helper function writing a data array to file.
103116
//! \param[in] group The HDF5 group to write data into
104117
//! \param[in] name The name of the array
@@ -120,7 +133,6 @@ class HDF5Writer : public DataWriter, public HDF5Base
120133
int basis, int level, bool redundant = false,
121134
bool l2g = false);
122135

123-
private:
124136
unsigned int m_flag; //!< The file flags to open HDF5 file with
125137
#endif
126138
};

0 commit comments

Comments
 (0)