Changed: [extract|inject]PatchSolution signature + some HDF5Writer cleaning
This commit is contained in:
parent
f94a20126a
commit
607c9771cf
@ -27,28 +27,25 @@ static bool compute(Vector& result, const SIMbase& model,
|
|||||||
{
|
{
|
||||||
result.resize(model.getNoElms());
|
result.resize(model.getNoElms());
|
||||||
|
|
||||||
for (int l = 0; l < model.getNoPatches(); l++) {
|
for (int idx = 1; idx <= model.getNoPatches(); idx++) {
|
||||||
Vector locvec;
|
ASMbase* pch = model.getPatch(idx,true);
|
||||||
int loc = model.getLocalPatchIndex(l+1);
|
if (!pch) continue;
|
||||||
if (loc == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
model.extractPatchSolution(displacement,locvec,loc-1);
|
Vector locvec;
|
||||||
const ASMbase* pch = model.getPatch(loc);
|
|
||||||
if (!displacement.empty()) {
|
if (!displacement.empty()) {
|
||||||
model.extractPatchSolution(displacement,locvec,loc-1);
|
model.extractPatchSolution(displacement,locvec,pch);
|
||||||
const_cast<ASMbase*>(pch)->updateCoords(locvec);
|
pch->updateCoords(locvec);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iel = 0;
|
int iel = 0;
|
||||||
IntMat::const_iterator elm_it = pch->begin_elm();
|
size_t nel = pch->getNoElms(true);
|
||||||
for (size_t e = 1; elm_it != pch->end_elm(); ++elm_it, ++e)
|
for (size_t e = 1; e <= nel; e++)
|
||||||
if ((iel = pch->getElmID(e)) > 0)
|
if ((iel = pch->getElmID(e)) > 0)
|
||||||
result(iel) = func(*pch,e);
|
result(iel) = func(*pch,e);
|
||||||
|
|
||||||
if (!displacement.empty()) {
|
if (!displacement.empty()) {
|
||||||
locvec *= -1;
|
locvec *= -1.0;
|
||||||
const_cast<ASMbase*>(pch)->updateCoords(locvec);
|
pch->updateCoords(locvec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1361,7 +1361,7 @@ bool SIMbase::solutionNorms (const TimeDomain& time,
|
|||||||
norm->setProjectedFields(f, k);
|
norm->setProjectedFields(f, k);
|
||||||
projOfs += ndof;
|
projOfs += ndof;
|
||||||
} else
|
} else
|
||||||
this->extractPatchSolution(ssol[k],norm->getProjection(k),lp-1,nCmp,1);
|
this->extractPatchSolution(ssol[k],norm->getProjection(k),pch,nCmp,1);
|
||||||
|
|
||||||
if (mySol)
|
if (mySol)
|
||||||
mySol->initPatch(pch->idx);
|
mySol->initPatch(pch->idx);
|
||||||
@ -1396,7 +1396,7 @@ bool SIMbase::solutionNorms (const TimeDomain& time,
|
|||||||
norm->setProjectedFields(f, k);
|
norm->setProjectedFields(f, k);
|
||||||
projOfs += ndof;
|
projOfs += ndof;
|
||||||
} else
|
} else
|
||||||
this->extractPatchSolution(ssol[k],norm->getProjection(k),i,nCmp,1);
|
this->extractPatchSolution(ssol[k],norm->getProjection(k),myModel[i],nCmp,1);
|
||||||
|
|
||||||
if (mySol)
|
if (mySol)
|
||||||
mySol->initPatch(myModel[i]->idx);
|
mySol->initPatch(myModel[i]->idx);
|
||||||
@ -1860,10 +1860,9 @@ bool SIMbase::projectAnaSol (Vector& ssol,
|
|||||||
|
|
||||||
|
|
||||||
size_t SIMbase::extractPatchSolution (const Vector& sol, Vector& vec,
|
size_t SIMbase::extractPatchSolution (const Vector& sol, Vector& vec,
|
||||||
int pindx, unsigned char nndof,
|
const ASMbase* pch, unsigned char nndof,
|
||||||
unsigned char basis) const
|
unsigned char basis) const
|
||||||
{
|
{
|
||||||
ASMbase* pch = pindx >= 0 ? this->getPatch(pindx+1) : nullptr;
|
|
||||||
if (!pch || sol.empty()) return 0;
|
if (!pch || sol.empty()) return 0;
|
||||||
|
|
||||||
if (basis != 0 && nndof != 0 &&
|
if (basis != 0 && nndof != 0 &&
|
||||||
@ -1881,10 +1880,9 @@ size_t SIMbase::extractPatchSolution (const Vector& sol, Vector& vec,
|
|||||||
|
|
||||||
|
|
||||||
bool SIMbase::injectPatchSolution (Vector& sol, const Vector& vec,
|
bool SIMbase::injectPatchSolution (Vector& sol, const Vector& vec,
|
||||||
int pindx, unsigned char nndof,
|
const ASMbase* pch, unsigned char nndof,
|
||||||
unsigned char basis) const
|
unsigned char basis) const
|
||||||
{
|
{
|
||||||
ASMbase* pch = pindx >= 0 ? this->getPatch(pindx+1) : nullptr;
|
|
||||||
if (!pch) return false;
|
if (!pch) return false;
|
||||||
|
|
||||||
if (basis > 0 && nndof > 0 &&
|
if (basis > 0 && nndof > 0 &&
|
||||||
|
@ -566,21 +566,23 @@ public:
|
|||||||
//! \brief Extracts a local solution vector for a specified patch.
|
//! \brief Extracts a local solution vector for a specified patch.
|
||||||
//! \param[in] sol Global primary solution vector in DOF-order
|
//! \param[in] sol Global primary solution vector in DOF-order
|
||||||
//! \param[out] vec Local solution vector associated with specified patch
|
//! \param[out] vec Local solution vector associated with specified patch
|
||||||
//! \param[in] pindx Local patch index to extract solution vector for
|
//! \param[in] pch The patch to extract solution vector for
|
||||||
//! \param[in] nndof Number of DOFs per node (optional)
|
//! \param[in] nndof Number of DOFs per node (optional)
|
||||||
//! \param[in] basis Basis to extract for (optional)
|
//! \param[in] basis Basis to extract for (optional)
|
||||||
//! \return Total number of DOFs in the patch (first basis only if mixed)
|
//! \return Total number of DOFs in the patch (first basis only if mixed)
|
||||||
size_t extractPatchSolution(const Vector& sol, Vector& vec, int pindx,
|
size_t extractPatchSolution(const Vector& sol, Vector& vec,
|
||||||
|
const ASMbase* pch,
|
||||||
unsigned char nndof = 0,
|
unsigned char nndof = 0,
|
||||||
unsigned char basis = 0) const;
|
unsigned char basis = 0) const;
|
||||||
|
|
||||||
//! \brief Injects a patch-wise solution vector into the global vector.
|
//! \brief Injects a patch-wise solution vector into the global vector.
|
||||||
//! \param sol Global primary solution vector in DOF-order
|
//! \param sol Global primary solution vector in DOF-order
|
||||||
//! \param[in] vec Local solution vector associated with specified patch
|
//! \param[in] vec Local solution vector associated with specified patch
|
||||||
//! \param[in] pindx Local patch index to inject solution vector for
|
//! \param[in] pch The patch to inject solution vector for
|
||||||
//! \param[in] nndof Number of DOFs per node (optional)
|
//! \param[in] nndof Number of DOFs per node (optional)
|
||||||
//! \param[in] basis Basis to inject for (optional)
|
//! \param[in] basis Basis to inject for (optional)
|
||||||
bool injectPatchSolution(Vector& sol, const Vector& vec, int pindx,
|
bool injectPatchSolution(Vector& sol, const Vector& vec,
|
||||||
|
const ASMbase* pch,
|
||||||
unsigned char nndof = 0,
|
unsigned char nndof = 0,
|
||||||
unsigned char basis = 0) const;
|
unsigned char basis = 0) const;
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ int SIMoutput::writeGlvS1 (const Vector& psol, int iStep, int& nBlock,
|
|||||||
|
|
||||||
if (msgLevel > 1)
|
if (msgLevel > 1)
|
||||||
IFEM::cout <<"Writing primary solution for patch "
|
IFEM::cout <<"Writing primary solution for patch "
|
||||||
<< pch->idx << std::endl;
|
<< pch->idx+1 << std::endl;
|
||||||
|
|
||||||
// Evaluate primary solution variables
|
// Evaluate primary solution variables
|
||||||
|
|
||||||
@ -851,25 +851,25 @@ bool SIMoutput::writeGlvP (const Vector& ssol, int iStep, int& nBlock,
|
|||||||
|
|
||||||
Vector::const_iterator ssolIt = ssol.begin();
|
Vector::const_iterator ssolIt = ssol.begin();
|
||||||
int geomID = myGeomID;
|
int geomID = myGeomID;
|
||||||
for (size_t i = 0; i < myModel.size(); i++)
|
for (ASMbase* pch : myModel)
|
||||||
{
|
{
|
||||||
if (myModel[i]->empty()) continue; // skip empty patches
|
if (pch->empty()) continue; // skip empty patches
|
||||||
|
|
||||||
if (msgLevel > 1)
|
if (msgLevel > 1)
|
||||||
IFEM::cout <<"Writing projected solution for patch "<< i+1 << std::endl;
|
IFEM::cout <<"Writing projected solution for patch "
|
||||||
|
<< pch->idx+1 << std::endl;
|
||||||
|
|
||||||
if (this->fieldProjections())
|
if (this->fieldProjections())
|
||||||
{
|
{
|
||||||
size_t nval = nComp*myModel[i]->getNoProjectionNodes();
|
size_t nval = nComp*pch->getNoProjectionNodes();
|
||||||
lovec.resize(nval);
|
lovec = RealArray(ssolIt,ssolIt+nval);
|
||||||
std::copy(ssolIt,ssolIt+nval,lovec.begin());
|
|
||||||
ssolIt += nval;
|
ssolIt += nval;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->extractPatchSolution(ssol,lovec,i,nComp,1);
|
this->extractPatchSolution(ssol,lovec,pch,nComp,1);
|
||||||
|
|
||||||
// Evaluate the solution variables at the visualization points
|
// Evaluate the solution variables at the visualization points
|
||||||
if (!myModel[i]->evalProjSolution(field,lovec,opt.nViz,nComp))
|
if (!pch->evalProjSolution(field,lovec,opt.nViz,nComp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t j = 1; // Write out to VTF-file as scalar fields
|
size_t j = 1; // Write out to VTF-file as scalar fields
|
||||||
|
@ -131,6 +131,7 @@ TEST(TestSIM3D, ProjectSolutionMixed)
|
|||||||
TEST(TestSIM, InjectPatchSolution)
|
TEST(TestSIM, InjectPatchSolution)
|
||||||
{
|
{
|
||||||
TestProjectSIM<SIM2D> sim({1,1});
|
TestProjectSIM<SIM2D> sim({1,1});
|
||||||
|
ASMbase* pch = sim.getPatch(1);
|
||||||
|
|
||||||
Vector sol(2*sim.getNoNodes(1) + sim.getNoNodes(2));
|
Vector sol(2*sim.getNoNodes(1) + sim.getNoNodes(2));
|
||||||
Vector lsol(2*sim.getNoNodes(1));
|
Vector lsol(2*sim.getNoNodes(1));
|
||||||
@ -139,7 +140,7 @@ TEST(TestSIM, InjectPatchSolution)
|
|||||||
lsol[2*i] = lsol[2*i+1] = i+1;
|
lsol[2*i] = lsol[2*i+1] = i+1;
|
||||||
|
|
||||||
ASSERT_TRUE(sim.addMixedMADOF(1, 2));
|
ASSERT_TRUE(sim.addMixedMADOF(1, 2));
|
||||||
sim.injectPatchSolution(sol, lsol, 0, 2, 1);
|
sim.injectPatchSolution(sol, lsol, pch, 2, 1);
|
||||||
for (i = ofs = 0; i < sim.getNoNodes(1); i++, ofs += 2) {
|
for (i = ofs = 0; i < sim.getNoNodes(1); i++, ofs += 2) {
|
||||||
EXPECT_FLOAT_EQ(sol[ofs], i+1);
|
EXPECT_FLOAT_EQ(sol[ofs], i+1);
|
||||||
EXPECT_FLOAT_EQ(sol[ofs+1], i+1);
|
EXPECT_FLOAT_EQ(sol[ofs+1], i+1);
|
||||||
@ -153,7 +154,7 @@ TEST(TestSIM, InjectPatchSolution)
|
|||||||
for (i = 0; i < sim.getNoNodes(2); i++)
|
for (i = 0; i < sim.getNoNodes(2); i++)
|
||||||
lsol2[2*i] = lsol2[2*i+1] = i+1;
|
lsol2[2*i] = lsol2[2*i+1] = i+1;
|
||||||
|
|
||||||
sim.injectPatchSolution(sol2, lsol2, 0, 2, 2);
|
sim.injectPatchSolution(sol2, lsol2, pch, 2, 2);
|
||||||
for (i = ofs = 0; i < sim.getNoNodes(1); i++, ofs++)
|
for (i = ofs = 0; i < sim.getNoNodes(1); i++, ofs++)
|
||||||
EXPECT_FLOAT_EQ(sol2[ofs], 0);
|
EXPECT_FLOAT_EQ(sol2[ofs], 0);
|
||||||
|
|
||||||
|
@ -288,31 +288,24 @@ void HDF5Writer::writeVector(int level, const DataEntry& entry)
|
|||||||
if (!entry.second.enabled)
|
if (!entry.second.enabled)
|
||||||
return;
|
return;
|
||||||
#ifdef HAS_HDF5
|
#ifdef HAS_HDF5
|
||||||
|
int redundant = entry.second.results & DataExporter::REDUNDANT;
|
||||||
int rank = 0;
|
int rank = 0;
|
||||||
#ifdef HAVE_MPI
|
#ifdef HAVE_MPI
|
||||||
if (entry.second.results & DataExporter::REDUNDANT)
|
if (redundant)
|
||||||
MPI_Comm_rank(*m_adm.getCommunicator(), &rank);
|
MPI_Comm_rank(*m_adm.getCommunicator(), &rank);
|
||||||
#endif
|
#endif
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << level;
|
str << level;
|
||||||
hid_t group = H5Gopen2(m_file,str.str().c_str(),H5P_DEFAULT);
|
hid_t group = H5Gopen2(m_file,str.str().c_str(),H5P_DEFAULT);
|
||||||
|
|
||||||
if (entry.second.field == DataExporter::VECTOR) {
|
if (entry.second.field == DataExporter::VECTOR) {
|
||||||
Vector* vector = (Vector*)entry.second.data;
|
Vector* dvec = (Vector*)entry.second.data;
|
||||||
if (!(entry.second.results & DataExporter::REDUNDANT) || rank == 0)
|
int len = !redundant || rank == 0 ? dvec->size() : 0;
|
||||||
writeArray(level,entry.first,vector->size(),vector->data(),H5T_NATIVE_DOUBLE);
|
this->writeArray(level,entry.first,len,dvec->data(),H5T_NATIVE_DOUBLE);
|
||||||
if ((entry.second.results & DataExporter::REDUNDANT) && rank != 0) {
|
}
|
||||||
double dummy;
|
else if (entry.second.field == DataExporter::INTVECTOR) {
|
||||||
writeArray(group,entry.first,0,&dummy,H5T_NATIVE_DOUBLE);
|
std::vector<int>* ivec = (std::vector<int>*)entry.second.data;
|
||||||
}
|
int len = !redundant || rank == 0 ? ivec->size() : 0;
|
||||||
} else if (entry.second.field == DataExporter::INTVECTOR) {
|
this->writeArray(group,entry.first,len,ivec->data(),H5T_NATIVE_INT);
|
||||||
std::vector<int>* data = (std::vector<int>*)entry.second.data;
|
|
||||||
if (!(entry.second.results & DataExporter::REDUNDANT) || rank == 0)
|
|
||||||
writeArray(group,entry.first,data->size(),&data->front(),H5T_NATIVE_INT);
|
|
||||||
if ((entry.second.results & DataExporter::REDUNDANT) && rank != 0) {
|
|
||||||
int dummy;
|
|
||||||
writeArray(group,entry.first,0,&dummy,H5T_NATIVE_INT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
H5Gclose(group);
|
H5Gclose(group);
|
||||||
#endif
|
#endif
|
||||||
@ -347,65 +340,45 @@ bool HDF5Writer::readVector(int level, const std::string& name,
|
|||||||
void HDF5Writer::writeBasis (int level, const DataEntry& entry,
|
void HDF5Writer::writeBasis (int level, const DataEntry& entry,
|
||||||
const std::string& prefix)
|
const std::string& prefix)
|
||||||
{
|
{
|
||||||
if (!entry.second.enabled)
|
if (!entry.second.enabled || !entry.second.data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SIMbase* sim = static_cast<SIMbase*>(const_cast<void*>(entry.second.data));
|
const SIMbase* sim = static_cast<const SIMbase*>(entry.second.data);
|
||||||
if (!sim)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string basisname;
|
this->writeBasis(sim, prefix+sim->getName()+"-1", 1, level,
|
||||||
if (prefix.empty())
|
entry.second.results & DataExporter::REDUNDANT);
|
||||||
basisname = sim->getName()+"-1";
|
|
||||||
else
|
|
||||||
basisname = prefix+sim->getName()+"-1";
|
|
||||||
|
|
||||||
writeBasis(sim,basisname,1,level,
|
|
||||||
entry.second.results & DataExporter::REDUNDANT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
||||||
bool geometryUpdated, const std::string& prefix)
|
bool geometryUpdated, const std::string& prefix)
|
||||||
{
|
{
|
||||||
if (!entry.second.enabled)
|
if (!entry.second.enabled || !entry.second.data || !entry.second.data2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SIMbase* sim = static_cast<SIMbase*>(const_cast<void*>(entry.second.data));
|
const SIMbase* sim = static_cast<const SIMbase*>(entry.second.data);
|
||||||
const Vector* sol = static_cast<const Vector*>(entry.second.data2);
|
const Vector* sol = static_cast<const Vector*>(entry.second.data2);
|
||||||
if (!sim || !sol) return;
|
const int results = abs(entry.second.results);
|
||||||
|
|
||||||
std::string basisname;
|
if (level == 0 || geometryUpdated || (results & DataExporter::GRID)) {
|
||||||
if (prefix.empty())
|
this->writeBasis(sim,prefix+sim->getName()+"-1",1,level);
|
||||||
basisname = sim->getName()+"-1";
|
|
||||||
else
|
|
||||||
basisname = prefix+sim->getName()+"-1";
|
|
||||||
|
|
||||||
if (level == 0 || geometryUpdated || (abs(entry.second.results) & DataExporter::GRID)) {
|
|
||||||
writeBasis(sim,basisname,1,level);
|
|
||||||
if (sim->mixedProblem())
|
if (sim->mixedProblem())
|
||||||
for (size_t b=2; b <= sim->getNoBasis(); ++b) {
|
for (size_t b=2; b <= sim->getNoBasis(); ++b) {
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << sim->getName() << "-" << b;
|
str << sim->getName() << "-" << b;
|
||||||
writeBasis(sim,str.str(),b,level);
|
this->writeBasis(sim,str.str(),b,level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix eNorm;
|
Matrix eNorm;
|
||||||
Vectors gNorm;
|
Vectors gNorm;
|
||||||
if (abs(entry.second.results) & DataExporter::NORMS)
|
if (results & DataExporter::NORMS)
|
||||||
sim->solutionNorms(*sol,eNorm,gNorm);
|
const_cast<SIMbase*>(sim)->solutionNorms(*sol,eNorm,gNorm);
|
||||||
|
|
||||||
NormBase* norm = sim->getNormIntegrand();
|
|
||||||
|
|
||||||
#ifdef HAS_HDF5
|
#ifdef HAS_HDF5
|
||||||
|
NormBase* norm = sim->getNormIntegrand();
|
||||||
const IntegrandBase* prob = sim->getProblem();
|
const IntegrandBase* prob = sim->getProblem();
|
||||||
int results = entry.second.results;
|
bool usedescription = entry.second.results < 0;
|
||||||
bool usedescription=false;
|
|
||||||
if (results < 0) {
|
|
||||||
results = -results;
|
|
||||||
usedescription = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t j, k, l;
|
size_t j, k, l;
|
||||||
for (int i = 0; i < sim->getNoPatches(); ++i) {
|
for (int i = 0; i < sim->getNoPatches(); ++i) {
|
||||||
@ -419,23 +392,24 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
else
|
else
|
||||||
group2 = H5Gcreate2(m_file,str.str().c_str(),0,H5P_DEFAULT,H5P_DEFAULT);
|
group2 = H5Gcreate2(m_file,str.str().c_str(),0,H5P_DEFAULT,H5P_DEFAULT);
|
||||||
int loc = sim->getLocalPatchIndex(i+1);
|
int loc = sim->getLocalPatchIndex(i+1);
|
||||||
if (loc > 0 && (!(abs(results) & DataExporter::REDUNDANT) ||
|
if (loc > 0 && (!(results & DataExporter::REDUNDANT) ||
|
||||||
sim->getGlobalProcessID() == 0)) // we own the patch
|
sim->getGlobalProcessID() == 0)) // we own the patch
|
||||||
{
|
{
|
||||||
if (abs(results) & DataExporter::PRIMARY) {
|
ASMbase* pch = sim->getPatch(loc);
|
||||||
|
if (results & DataExporter::PRIMARY) {
|
||||||
Vector psol;
|
Vector psol;
|
||||||
int ncmps = entry.second.ncmps;
|
int ncmps = entry.second.ncmps;
|
||||||
if (entry.second.results < 0) { // field assumed to be on basis 1 for now
|
if (entry.second.results < 0) { // field assumed to be on basis 1 for now
|
||||||
size_t ndof1 = sim->extractPatchSolution(*sol, psol, loc-1, ncmps, 1);
|
size_t ndof1 = sim->extractPatchSolution(*sol,psol,pch,ncmps,1);
|
||||||
writeArray(group2, entry.second.description,
|
writeArray(group2, entry.second.description,
|
||||||
ndof1, psol.ptr(), H5T_NATIVE_DOUBLE);
|
ndof1, psol.ptr(), H5T_NATIVE_DOUBLE);
|
||||||
} else {
|
} else {
|
||||||
size_t ndof1 = sim->extractPatchSolution(*sol,psol,loc-1,ncmps);
|
size_t ndof1 = sim->extractPatchSolution(*sol,psol,pch,ncmps);
|
||||||
if (sim->mixedProblem())
|
if (sim->mixedProblem())
|
||||||
{
|
{
|
||||||
size_t ofs = 0;
|
size_t ofs = 0;
|
||||||
for (size_t b=1; b <= sim->getNoBasis(); ++b) {
|
for (size_t b=1; b <= sim->getNoBasis(); ++b) {
|
||||||
ndof1 = sim->getPatch(loc)->getNoNodes(b)*sim->getPatch(loc)->getNoFields(b);
|
ndof1 = pch->getNoNodes(b)*pch->getNoFields(b);
|
||||||
writeArray(group2,prefix+prob->getField1Name(10+b),ndof1,
|
writeArray(group2,prefix+prob->getField1Name(10+b),ndof1,
|
||||||
psol.ptr()+ofs,H5T_NATIVE_DOUBLE);
|
psol.ptr()+ofs,H5T_NATIVE_DOUBLE);
|
||||||
ofs += ndof1;
|
ofs += ndof1;
|
||||||
@ -449,16 +423,16 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(results) & DataExporter::SECONDARY) {
|
if (results & DataExporter::SECONDARY) {
|
||||||
Matrix field;
|
Matrix field;
|
||||||
if (prefix.empty()) {
|
if (prefix.empty()) {
|
||||||
sim->setMode(SIM::RECOVERY);
|
const_cast<SIMbase*>(sim)->setMode(SIM::RECOVERY);
|
||||||
sim->extractPatchSolution(Vectors(1,*sol), loc-1);
|
sim->extractPatchSolution(Vectors(1,*sol), loc-1);
|
||||||
sim->evalSecondarySolution(field,loc-1);
|
sim->evalSecondarySolution(field,loc-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Vector locvec;
|
Vector locvec;
|
||||||
sim->extractPatchSolution(*sol,locvec,loc-1,prob->getNoFields(2));
|
sim->extractPatchSolution(*sol,locvec,pch,prob->getNoFields(2));
|
||||||
field.resize(prob->getNoFields(2),locvec.size()/prob->getNoFields(2));
|
field.resize(prob->getNoFields(2),locvec.size()/prob->getNoFields(2));
|
||||||
field.fill(locvec.ptr());
|
field.fill(locvec.ptr());
|
||||||
}
|
}
|
||||||
@ -467,7 +441,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
field.getRow(j+1).ptr(),H5T_NATIVE_DOUBLE);
|
field.getRow(j+1).ptr(),H5T_NATIVE_DOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(results) & DataExporter::NORMS && norm) {
|
if (results & DataExporter::NORMS && norm) {
|
||||||
Matrix patchEnorm;
|
Matrix patchEnorm;
|
||||||
sim->extractPatchElmRes(eNorm,patchEnorm,loc-1);
|
sim->extractPatchElmRes(eNorm,patchEnorm,loc-1);
|
||||||
for (j = l = 1; j <= norm->getNoFields(0); j++)
|
for (j = l = 1; j <= norm->getNoFields(0); j++)
|
||||||
@ -478,13 +452,13 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
patchEnorm.cols(),patchEnorm.getRow(l++).ptr(),
|
patchEnorm.cols(),patchEnorm.getRow(l++).ptr(),
|
||||||
H5T_NATIVE_DOUBLE);
|
H5T_NATIVE_DOUBLE);
|
||||||
}
|
}
|
||||||
if (abs(results) & DataExporter::EIGENMODES) {
|
if (results & DataExporter::EIGENMODES) {
|
||||||
const std::vector<Mode>* vec2 = static_cast<const std::vector<Mode>* >(entry.second.data2);
|
const std::vector<Mode>* vec2 = static_cast<const std::vector<Mode>*>(entry.second.data2);
|
||||||
const std::vector<Mode>& vec = static_cast<const std::vector<Mode>& >(*vec2);
|
const std::vector<Mode>& vec = static_cast<const std::vector<Mode>&>(*vec2);
|
||||||
H5Gclose(group2);
|
H5Gclose(group2);
|
||||||
for (k = 0; k < vec.size(); ++k) {
|
for (k = 0; k < vec.size(); ++k) {
|
||||||
Vector psol;
|
Vector psol;
|
||||||
size_t ndof1 = sim->extractPatchSolution(vec[k].eigVec,psol,loc-1);
|
size_t ndof1 = sim->extractPatchSolution(vec[k].eigVec,psol,pch);
|
||||||
std::stringstream name;
|
std::stringstream name;
|
||||||
name << entry.second.description << "-" << k+1;
|
name << entry.second.description << "-" << k+1;
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
@ -514,7 +488,7 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
else // must write empty dummy records for the other patches
|
else // must write empty dummy records for the other patches
|
||||||
{
|
{
|
||||||
double dummy;
|
double dummy;
|
||||||
if (abs(results) & DataExporter::PRIMARY) {
|
if (results & DataExporter::PRIMARY) {
|
||||||
if (entry.second.results < 0) {
|
if (entry.second.results < 0) {
|
||||||
writeArray(group2, entry.second.description,
|
writeArray(group2, entry.second.description,
|
||||||
0, &dummy, H5T_NATIVE_DOUBLE);
|
0, &dummy, H5T_NATIVE_DOUBLE);
|
||||||
@ -530,11 +504,11 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
0, &dummy, H5T_NATIVE_DOUBLE);
|
0, &dummy, H5T_NATIVE_DOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(results) & DataExporter::SECONDARY)
|
if (results & DataExporter::SECONDARY)
|
||||||
for (j = 0; j < prob->getNoFields(2); j++)
|
for (j = 0; j < prob->getNoFields(2); j++)
|
||||||
writeArray(group2,prefix+prob->getField2Name(j),0,&dummy,H5T_NATIVE_DOUBLE);
|
writeArray(group2,prefix+prob->getField2Name(j),0,&dummy,H5T_NATIVE_DOUBLE);
|
||||||
|
|
||||||
if (abs(results) & DataExporter::NORMS && norm)
|
if (results & DataExporter::NORMS && norm)
|
||||||
for (j = l = 1; j <= norm->getNoFields(0); j++)
|
for (j = l = 1; j <= norm->getNoFields(0); j++)
|
||||||
for (k = 1; k <= norm->getNoFields(j); k++)
|
for (k = 1; k <= norm->getNoFields(j); k++)
|
||||||
if (norm->hasElementContributions(j,k))
|
if (norm->hasElementContributions(j,k))
|
||||||
@ -544,29 +518,23 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
|
|||||||
}
|
}
|
||||||
H5Gclose(group2);
|
H5Gclose(group2);
|
||||||
}
|
}
|
||||||
|
delete norm;
|
||||||
#else
|
#else
|
||||||
std::cout << "HDF5Writer: compiled without HDF5 support, no data written" << std::endl;
|
std::cout << "HDF5Writer: compiled without HDF5 support, no data written" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
delete norm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HDF5Writer::writeKnotspan (int level, const DataEntry& entry,
|
void HDF5Writer::writeKnotspan (int level, const DataEntry& entry,
|
||||||
const std::string& prefix)
|
const std::string& prefix)
|
||||||
{
|
{
|
||||||
SIMbase* sim = static_cast<SIMbase*>(const_cast<void*>(entry.second.data));
|
const SIMbase* sim = static_cast<const SIMbase*>(entry.second.data);
|
||||||
const Vector* sol = static_cast<const Vector*>(entry.second.data2);
|
const Vector* sol = static_cast<const Vector*>(entry.second.data2);
|
||||||
if (!sim || !sol) return;
|
if (!sim || !sol) return;
|
||||||
|
|
||||||
Matrix infield(1,sol->size());
|
Matrix infield(1,sol->size());
|
||||||
infield.fillRow(1,sol->ptr());
|
infield.fillRow(1,sol->ptr());
|
||||||
|
|
||||||
std::string basisname;
|
|
||||||
if (prefix.empty())
|
|
||||||
basisname = sim->getName()+"-1";
|
|
||||||
else
|
|
||||||
basisname = prefix+sim->getName()+"-1";
|
|
||||||
|
|
||||||
#ifdef HAS_HDF5
|
#ifdef HAS_HDF5
|
||||||
for (int i = 0; i < sim->getNoPatches(); ++i) {
|
for (int i = 0; i < sim->getNoPatches(); ++i) {
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
@ -600,7 +568,7 @@ void HDF5Writer::writeKnotspan (int level, const DataEntry& entry,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HDF5Writer::writeBasis (SIMbase* sim, const std::string& name,
|
void HDF5Writer::writeBasis (const SIMbase* sim, const std::string& name,
|
||||||
int basis, int level, bool redundant)
|
int basis, int level, bool redundant)
|
||||||
{
|
{
|
||||||
#ifdef HAS_HDF5
|
#ifdef HAS_HDF5
|
||||||
@ -792,27 +760,22 @@ bool HDF5Writer::writeRestartData(int level, const DataExporter::SerializeData&
|
|||||||
pid = m_adm.getProcId();
|
pid = m_adm.getProcId();
|
||||||
ptot = m_adm.getNoProcs();
|
ptot = m_adm.getNoProcs();
|
||||||
#endif
|
#endif
|
||||||
for (int p = 0; p < ptot; ++p) {
|
for (int p = 0; p < ptot; p++)
|
||||||
for (auto& it : data) {
|
for (const std::pair<std::string,std::string>& it : data) {
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << level << '/' << p;
|
str << level << '/' << p;
|
||||||
|
|
||||||
int group;
|
int group;
|
||||||
if (checkGroupExistence(m_restart_file,str.str().c_str()))
|
if (checkGroupExistence(m_restart_file,str.str().c_str()))
|
||||||
group = H5Gopen2(m_restart_file,str.str().c_str(),H5P_DEFAULT);
|
group = H5Gopen2(m_restart_file,str.str().c_str(),H5P_DEFAULT);
|
||||||
else
|
else
|
||||||
group = H5Gcreate2(m_restart_file,str.str().c_str(),0,H5P_DEFAULT,H5P_DEFAULT);
|
group = H5Gcreate2(m_restart_file,str.str().c_str(),0,H5P_DEFAULT,H5P_DEFAULT);
|
||||||
|
|
||||||
if (!H5Lexists(group, it.first.c_str(), 0)) {
|
if (!H5Lexists(group, it.first.c_str(), 0)) {
|
||||||
if (pid == p)
|
int len = pid == p ? it.second.size() : 0;
|
||||||
writeArray(group, it.first, it.second.size(), it.second.data(), H5T_NATIVE_CHAR);
|
writeArray(group, it.first, len, it.second.data(), H5T_NATIVE_CHAR);
|
||||||
else
|
|
||||||
writeArray(group, it.first, 0, nullptr, H5T_NATIVE_CHAR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
H5Gclose(group);
|
H5Gclose(group);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
H5Fclose(m_restart_file);
|
H5Fclose(m_restart_file);
|
||||||
m_restart_file = 0;
|
m_restart_file = 0;
|
||||||
#else
|
#else
|
||||||
@ -823,11 +786,8 @@ bool HDF5Writer::writeRestartData(int level, const DataExporter::SerializeData&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \brief A struct holding the context for a restart.
|
//! \brief Convenience type for restart IO.
|
||||||
struct read_restart_ctx {
|
typedef std::pair<HDF5Writer*,DataExporter::SerializeData*> read_restart_ctx;
|
||||||
HDF5Writer* w; //!< HDF5 reader/writer to use
|
|
||||||
DataExporter::SerializeData* data; //!< The serialized data
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_HDF5
|
#ifdef HAS_HDF5
|
||||||
@ -837,11 +797,8 @@ static herr_t read_restart_data(hid_t group_id, const char* member_name, void* d
|
|||||||
|
|
||||||
char* c;
|
char* c;
|
||||||
int len;
|
int len;
|
||||||
ctx->w->readArray(group_id, member_name, len, c);
|
ctx->first->readArray(group_id,member_name,len,c);
|
||||||
std::string tmp;
|
ctx->second->insert(std::make_pair(std::string(member_name),std::string(c,len)));
|
||||||
tmp.resize(len);
|
|
||||||
tmp.assign(c, len);
|
|
||||||
ctx->data->insert(std::make_pair(std::string(member_name),tmp));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -863,16 +820,14 @@ int HDF5Writer::readRestartData(DataExporter::SerializeData& data, int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << '/' << level << '/'
|
str << '/' << level << '/';
|
||||||
#ifdef HAVE_MPI
|
#ifdef HAVE_MPI
|
||||||
<< m_adm.getProcId();
|
str << m_adm.getProcId();
|
||||||
#else
|
#else
|
||||||
<< 0;
|
str << 0;
|
||||||
#endif
|
#endif
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
read_restart_ctx ctx;
|
read_restart_ctx ctx(this,&data);
|
||||||
ctx.w = this;
|
|
||||||
ctx.data = &data;
|
|
||||||
int it = H5Giterate(m_file, str.str().c_str(), &idx, read_restart_data, &ctx);
|
int it = H5Giterate(m_file, str.str().c_str(), &idx, read_restart_data, &ctx);
|
||||||
closeFile(0);
|
closeFile(0);
|
||||||
return it < 0 ? it : level;
|
return it < 0 ? it : level;
|
||||||
|
@ -31,12 +31,12 @@ class HDF5Writer : public DataWriter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! \brief The constructor opens a named HDF5-file.
|
//! \brief The constructor opens a named HDF5-file.
|
||||||
//! \param[in] name The name (filename without extension) of data file
|
//! \param[in] name The name (without extension) of the data file
|
||||||
//! \param[in] adm The process administrator
|
//! \param[in] adm The process administrator
|
||||||
//! \param[in] append Whether to append to or overwrite an existing file
|
//! \param[in] append Whether to append to or overwrite an existing file
|
||||||
//! \param[in] keepopen Whether to always keep the HDF5 open
|
//! \param[in] keepopen Whether to always keep the HDF5 open
|
||||||
HDF5Writer(const std::string& name, const ProcessAdm& adm, bool append = false,
|
HDF5Writer(const std::string& name, const ProcessAdm& adm,
|
||||||
bool keepopen = false);
|
bool append = false, bool keepopen = false);
|
||||||
|
|
||||||
//! \brief Empty destructor.
|
//! \brief Empty destructor.
|
||||||
virtual ~HDF5Writer() {}
|
virtual ~HDF5Writer() {}
|
||||||
@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
//! \brief Opens the file at a given time level.
|
//! \brief Opens the file at a given time level.
|
||||||
//! \param[in] level The requested time level
|
//! \param[in] level The requested time level
|
||||||
virtual void openFile(int level) { openFile(level, false); }
|
virtual void openFile(int level) { this->openFile(level,false); }
|
||||||
|
|
||||||
//! \brief Opens the file at a given time level.
|
//! \brief Opens the file at a given time level.
|
||||||
//! \param[in] level The requested time level
|
//! \param[in] level The requested time level
|
||||||
@ -70,7 +70,7 @@ public:
|
|||||||
|
|
||||||
//! \brief Writes data from a SIM to file.
|
//! \brief Writes data from a SIM to file.
|
||||||
//! \param[in] level The time level to write the data at
|
//! \param[in] level The time level to write the data at
|
||||||
//! \param[in] entry The DataEntry describing the vector
|
//! \param[in] entry The DataEntry describing the data to write
|
||||||
//! \param[in] geometryUpdated Whether or not geometries should be written
|
//! \param[in] geometryUpdated Whether or not geometries should be written
|
||||||
//! \param[in] prefix Field name prefix
|
//! \param[in] prefix Field name prefix
|
||||||
//!
|
//!
|
||||||
@ -82,7 +82,7 @@ public:
|
|||||||
|
|
||||||
//! \brief Writes nodal forces to file.
|
//! \brief Writes nodal forces to file.
|
||||||
//! \param[in] level The time level to write the data at
|
//! \param[in] level The time level to write the data at
|
||||||
//! \param[in] entry The DataEntry describing the vector
|
//! \param[in] entry The DataEntry describing the data to write
|
||||||
virtual void writeNodalForces(int level, const DataEntry& entry);
|
virtual void writeNodalForces(int level, const DataEntry& entry);
|
||||||
|
|
||||||
//! \brief Writes knot span field to file.
|
//! \brief Writes knot span field to file.
|
||||||
@ -92,7 +92,7 @@ public:
|
|||||||
virtual void writeKnotspan(int level, const DataEntry& entry,
|
virtual void writeKnotspan(int level, const DataEntry& entry,
|
||||||
const std::string& prefix);
|
const std::string& prefix);
|
||||||
|
|
||||||
//! \brief Write a basis to file
|
//! \brief Writes a basis to file.
|
||||||
//! \param[in] level The time level to write the basis at
|
//! \param[in] level The time level to write the basis at
|
||||||
//! \param[in] entry The DataEntry describing the basis
|
//! \param[in] entry The DataEntry describing the basis
|
||||||
//! \param[in] prefix Prefix for basis
|
//! \param[in] prefix Prefix for basis
|
||||||
@ -140,26 +140,26 @@ public:
|
|||||||
//! \param[in] basisName Check for a particular basis
|
//! \param[in] basisName Check for a particular basis
|
||||||
bool hasGeometries(int level, const std::string& basisName = "");
|
bool hasGeometries(int level, const std::string& basisName = "");
|
||||||
|
|
||||||
//! \brief Write restart data.
|
//! \brief Writes restart data to file.
|
||||||
//! \param level Level to write data at
|
//! \param[in] level Level to write data at
|
||||||
//! \param data Data to write
|
//! \param[in] data Data to write
|
||||||
bool writeRestartData(int level, const DataExporter::SerializeData& data);
|
bool writeRestartData(int level, const DataExporter::SerializeData& data);
|
||||||
|
|
||||||
//! \brief Read restart data from file.
|
//! \brief Reads restart data from file.
|
||||||
//! \param data The map to store data in
|
//! \param[out] data The map to store data in
|
||||||
//! \param level Level to read (-1 to read last level in file)
|
//! \param[in] level Level to read (-1 to read last level in file)
|
||||||
//! \returns Negative value on error, else restart level loaded
|
//! \returns Negative value on error, else restart level loaded
|
||||||
int readRestartData(DataExporter::SerializeData& data, int level = -1);
|
int readRestartData(DataExporter::SerializeData& data, int level = -1);
|
||||||
|
|
||||||
//! \brief Internal helper function. Reads an array into an array of chars.
|
//! \brief Internal helper function reading into an array of chars.
|
||||||
//! \param[in] group The HDF5 group to read data from
|
//! \param[in] group The HDF5 group to read data from
|
||||||
//! \param[in] name The name of the array
|
//! \param[in] name The name of the array
|
||||||
//! \param[in] len The length of the data to read
|
//! \param[out] len The length of the data read
|
||||||
//! \param[out] data The array to read data into
|
//! \param[out] data The array to read data into
|
||||||
void readArray(int group, const std::string& name, int& len, char*& data);
|
void readArray(int group, const std::string& name, int& len, char*& data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Internal helper function. Writes a data array to HDF5 file.
|
//! \brief Internal helper function writing a data array to file.
|
||||||
//! \param[in] group The HDF5 group to write data into
|
//! \param[in] group The HDF5 group to write data into
|
||||||
//! \param[in] name The name of the array
|
//! \param[in] name The name of the array
|
||||||
//! \param[in] len The length of the array
|
//! \param[in] len The length of the array
|
||||||
@ -168,30 +168,30 @@ protected:
|
|||||||
void writeArray(int group, const std::string& name,
|
void writeArray(int group, const std::string& name,
|
||||||
int len, const void* data, int type);
|
int len, const void* data, int type);
|
||||||
|
|
||||||
//! \brief Internal helper function. Writes a SIM's basis (geometry) to file.
|
//! \brief Internal helper function writing a SIM's basis (geometry) to file.
|
||||||
//! \param[in] SIM The SIM we want to write basis for
|
//! \param[in] SIM The SIM we want to write basis for
|
||||||
//! \param[in] name The name of the basis
|
//! \param[in] name The name of the basis
|
||||||
//! \param[in] basis 1/2 Write primary or secondary basis from SIM
|
//! \param[in] basis 1/2 Write primary or secondary basis from SIM
|
||||||
//! \param[in] level The time level to write the basis at
|
//! \param[in] level The time level to write the basis at
|
||||||
//! \param[in] redundant Whether or not basis is redundant across processes
|
//! \param[in] redundant Whether or not basis is redundant across processes
|
||||||
void writeBasis(SIMbase* SIM, const std::string& name, int basis,
|
void writeBasis(const SIMbase* SIM, const std::string& name,
|
||||||
int level, bool redundant=false);
|
int basis, int level, bool redundant = false);
|
||||||
|
|
||||||
//! \brief Internal helper function. Reads an array into a array of doubles.
|
//! \brief Internal helper function reading into an array of doubles.
|
||||||
//! \param[in] group The HDF5 group to read data from
|
//! \param[in] group The HDF5 group to read data from
|
||||||
//! \param[in] name The name of the array
|
//! \param[in] name The name of the array
|
||||||
//! \param[in] len The length of the data to read
|
//! \param[out] len The length of the data read
|
||||||
//! \param[out] data The array to read data into
|
//! \param[out] data The array to read data into
|
||||||
void readArray(int group, const std::string& name, int& len, double*& data);
|
void readArray(int group, const std::string& name, int& len, double*& data);
|
||||||
|
|
||||||
//! \brief Internal helper function. Reads an array into a array of integers.
|
//! \brief Internal helper function reading into an array of integers.
|
||||||
//! \param[in] group The HDF5 group to read data from
|
//! \param[in] group The HDF5 group to read data from
|
||||||
//! \param[in] name The name of the array
|
//! \param[in] name The name of the array
|
||||||
//! \param[in] len The length of the data to read
|
//! \param[out] len The length of the data read
|
||||||
//! \param[out] data The array to read data into
|
//! \param[out] data The array to read data into
|
||||||
void readArray(int group, const std::string& name, int& len, int*& data);
|
void readArray(int group, const std::string& name, int& len, int*& data);
|
||||||
|
|
||||||
//! \brief Internal helper function. Checks if a group exists in the file.
|
//! \brief Internal helper function checking if a group exists in the file.
|
||||||
//! \param[in] parent The HDF5 group of the parent
|
//! \param[in] parent The HDF5 group of the parent
|
||||||
//! \param[in] group The name of the group to check for
|
//! \param[in] group The name of the group to check for
|
||||||
//! \return \e true if group exists, otherwise \e false
|
//! \return \e true if group exists, otherwise \e false
|
||||||
|
Loading…
Reference in New Issue
Block a user