Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added: save anasols to HDF5 #517

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/SIM/SIMbase.C
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "AlgEqSystem.h"
#include "LinSolParams.h"
#include "EigSolver.h"
#include "ExprFunctions.h"
#include "GlbNorm.h"
#include "GlbL2projector.h"
#include "ElmNorm.h"
Expand Down Expand Up @@ -2400,3 +2401,64 @@ void SIMbase::dumpEqSys ()
utl::zero_print_tol = old_tol;
}
}


std::map<std::string, std::string> SIMbase::getAnaSolDefinitions () const
{
std::map<std::string, std::string> result;

if (mySol) {
size_t nf = this->getNoFields(0);

if (nf == 1) // Scalar solution
{
const EvalFunction* pSol = dynamic_cast<const EvalFunction*>(mySol->getScalarSol());
if (pSol)
result.insert(std::make_pair(myProblem->getField1Name(0,"Exact"), pSol->asString()));

const VecFuncExpr* sSol = dynamic_cast<const VecFuncExpr*>(mySol->getScalarSecSol());
if (sSol)
for (size_t i = 1; i <= this->getNoSpaceDim(); ++i)
result.insert(std::make_pair(myProblem->getField2Name(i-1,"Exact"),sSol->asString(i)));
}
else
{
const VecFuncExpr* vSol = dynamic_cast<const VecFuncExpr*>(mySol->getVectorSol());
size_t idx = 0;
if (vSol) {
for (; idx < this->getNoSpaceDim(); ++idx)
result.insert(std::make_pair(myProblem->getField1Name(idx,"Exact"),vSol->asString(idx+1)));
}
size_t scalSol = 0;
while (mySol->getScalarSol(scalSol)) {
const EvalFunction* pSol = dynamic_cast<const EvalFunction*>(mySol->getScalarSol(scalSol));
if (pSol)
result.insert(std::make_pair(myProblem->getField1Name(idx++,"Exact"), pSol->asString()));
++scalSol;
}

idx = 0;
const STensorFuncExpr* stSol = dynamic_cast<const STensorFuncExpr*>(mySol->getStressSol());
if (stSol)
for (size_t i = 1; i <= stSol->dim(); ++i, ++idx)
result.insert(std::make_pair(myProblem->getField2Name(idx,"Exact"),stSol->asString(i)));

const TensorFuncExpr* tSol = dynamic_cast<const TensorFuncExpr*>(mySol->getVectorSecSol());
if (tSol)
for (size_t i = 1; i <= tSol->dim(); ++i, ++idx)
result.insert(std::make_pair(myProblem->getField2Name(idx,"Exact"),tSol->asString(i)));

scalSol = 0;
while (mySol->getScalarSecSol(scalSol)) {
const VecFuncExpr* sSol = dynamic_cast<const VecFuncExpr*>(mySol->getScalarSecSol(scalSol));
if (sSol) {
for (size_t i = 1; i <= this->getNoSpaceDim(); ++i, ++idx)
result.insert(std::make_pair(myProblem->getField2Name(idx,"Exact"),sSol->asString(i)));
}
++scalSol;
}
}
}

return result;
}
3 changes: 3 additions & 0 deletions src/SIM/SIMbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,9 @@ class SIMbase : public SIMadmin, public SIMdependency
//! \brief Returns whether a dual solution is available or not.
virtual bool haveDualSol() const { return dualField ? true : false; }

//! \brief Returns analytic solutions as their string definitions if possible.
std::map<std::string, std::string> getAnaSolDefinitions() const;

//! \brief Returns a pointer to a norm integrand object for this simulator.
//! \note The object is allocated dynamically and has therefore to be
//! manually deleted before the variable receiving the pointer value goes
Expand Down
2 changes: 1 addition & 1 deletion src/Utility/ExprFunctions.C
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Real EvalFunc::deriv (Real x) const
}


EvalFunction::EvalFunction (const char* function) : gradient{}, dgradient{}
EvalFunction::EvalFunction (const char* function) : gradient{}, dgradient{}, definition(function)
{
try {
#ifdef USE_OPENMP
Expand Down
9 changes: 9 additions & 0 deletions src/Utility/ExprFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class EvalFunction : public RealFunc
//! \brief Set an additional parameter in the function.
void setParam(const std::string& name, double value);

//! \brief Returns function string.
const std::string& asString() const { return definition; }

protected:
//! \brief Non-implemented copy constructor to disallow copying.
EvalFunction(const EvalFunction&) = delete;
Expand All @@ -133,6 +136,8 @@ class EvalFunction : public RealFunc

//! \brief Cleans up the allocated data.
void cleanup();

std::string definition; //!< Function definition, used for serialization purposes.
};


Expand Down Expand Up @@ -201,6 +206,10 @@ class EvalMultiFunction : public ParentFunc, public EvalFunctions
func->setParam(name, value);
}

//! \brief Returns function string for component.
//! \param idx 1-based index for component to return.
const std::string& asString(size_t idx) const { return p[idx-1]->asString(); }

protected:
//! \brief Sets the number of spatial dimensions (default implementation).
void setNoDims() { ParentFunc::ncmp = nsd = p.size(); }
Expand Down
41 changes: 41 additions & 0 deletions src/Utility/HDF5Writer.C
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,9 @@ void HDF5Writer::writeSIM (int level, const DataEntry& entry,
}
}

if (sim->haveAnaSol())
this->writeAnaSol(sim->getAnaSolDefinitions(), sim->getName());

delete norm;
for (hid_t g : group)
if (g != -1)
Expand Down Expand Up @@ -783,3 +786,41 @@ bool HDF5Writer::writeLog (const std::string& data, const std::string& name)
return false;
#endif
}


bool HDF5Writer::writeAnaSol (const std::map<std::string,std::string>& aSols,
const std::string& name)
{
if (aSols.empty())
return true;

#ifdef HAS_HDF5
hid_t group;
if (!checkGroupExistence(m_file,"/anasol")) {
group = H5Gcreate2(m_file,"/anasol",0,H5P_DEFAULT,H5P_DEFAULT);
H5Gclose(group);
}

std::stringstream str;
str << "/anasol/" << name;

if (checkGroupExistence(m_file,str.str().c_str()))
group = H5Gopen2(m_file,str.str().c_str(),H5P_DEFAULT);
else
group = H5Gcreate2(m_file,str.str().c_str(),0,H5P_DEFAULT,H5P_DEFAULT);

int rank = 0;
#ifdef HAVE_MPI
MPI_Comm_rank(*m_adm.getCommunicator(), &rank);
#endif

for (const auto& it : aSols)
this->writeArray(group,it. first, -1,
rank == 0 ? it.second.size() : 0, it.second.data(), H5T_NATIVE_CHAR);

H5Gclose(group);
return true;
#else
return false;
#endif
}
6 changes: 6 additions & 0 deletions src/Utility/HDF5Writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ class HDF5Writer : public DataWriter, public HDF5Base
//! \param name Name of log
virtual bool writeLog(const std::string& data, const std::string& name);

//! \brief Write analytical solutions to file.
//! \param aSol Map of functions
//! \param name Name of simulator
bool writeAnaSol(const std::map<std::string, std::string>& aSols,
const std::string& name);

#ifdef HAS_HDF5
protected:
//! \brief Internal helper function writing a data array to file.
Expand Down