41#include <boost/algorithm/string.hpp>
54 const std::shared_ptr<EquationSystem> &pEquation,
const ParamMap &pParams)
55 :
Filter(pSession, pEquation)
60 auto it = pParams.find(
"OutputFile");
61 if (it == pParams.end())
67 ASSERTL0(it->second.length() > 0,
"Empty parameter 'OutputFile'.");
73 it = pParams.find(
"Composites");
74 ASSERTL0(it != pParams.end(),
"Missing parameter 'Composites'.");
75 ASSERTL0(it->second.length() > 0,
"Empty parameter 'Composites'.");
77 std::vector<std::string> splitComposite;
79 boost::token_compress_on);
84 size_t first = comp.find_first_of(
'[') + 1;
85 size_t last = comp.find_last_of(
']') - 1;
86 auto tmpString = comp.substr(first, last - first + 1);
88 std::vector<unsigned int> tmpVec;
91 ASSERTL0(parseGood && !tmpVec.empty(),
92 "Unable to read composite regions index range for "
101 it = pParams.find(
"OutputPrecision");
102 if (it == pParams.end())
108 ASSERTL0(it->second.length() > 0,
"Empty parameter 'OutputPrecision'.");
109 precision = std::stoi(it->second);
113 auto equationSys =
m_equ.lock();
114 ASSERTL0(equationSys,
"Weak pointer expired");
118 m_comm = pSession->GetComm();
119 if (
m_comm->GetRank() == 0)
123 m_outFile.setf(std::ios::scientific, std::ios::floatfield);
131 std::string varName = equationSys->GetVariable(j);
132 m_outFile <<
" " + compName +
"_" + varName +
"_integral";
139 it = pParams.find(
"OutputFrequency");
140 if (it == pParams.end())
146 ASSERTL0(it->second.length() > 0,
"Empty parameter 'OutputFrequency'.");
161 auto expList = pFields[0]->GetExp();
162 auto meshGraph = pFields[0]->GetGraph();
164 for (
size_t i = 0; i < expList->size(); ++i)
166 auto exp = (*expList)[i];
171 std::map<size_t, size_t> geomIdToTraceId;
172 auto trace = pFields[0]->GetTrace()->GetExp();
173 for (
size_t i = 0; i < trace->size(); ++i)
175 auto exp = (*trace)[i];
176 geomIdToTraceId[exp->GetGeom()->GetGlobalID()] = i;
180 auto composites = pFields[0]->GetGraph()->GetComposites();
181 size_t meshDim = pFields[0]->GetGraph()->GetMeshDimension();
186 if (composites.find(
m_compVector[i][0]) == composites.end())
191 std::vector<std::shared_ptr<SpatialDomains::Geometry>> geomVec =
194 composites[
m_compVector[i][0]]->m_geomVec[0]->GetShapeDim();
197 std::vector<size_t> compGeomIds;
200 ASSERTL0(composites.find(compNum) != composites.end(),
201 "In FilterIntegral defined composite C[" +
202 std::to_string(compNum) +
203 "] does not exist in the mesh.")
205 auto compGeom = composites[compNum]->m_geomVec;
207 for (
auto &geom : compGeom)
209 compGeomIds.emplace_back(geom->GetGlobalID());
214 dim == compGeom[0]->GetShapeDim(),
215 "Differing geometry dimensions specified in FilterIntegral '" +
219 std::vector<std::pair<LocalRegions::ExpansionSharedPtr, int>>
220 tmpCompExp(compGeomIds.size());
224 if (dim == pFields[0]->GetShapeDimension())
226 for (
size_t j = 0; j < compGeomIds.size(); ++j)
228 tmpCompExp[j] = std::make_pair(
237 else if (meshDim == 3 && dim == 2)
239 for (
size_t j = 0; j < compGeomIds.size(); ++j)
242 (*trace)[geomIdToTraceId[compGeomIds[j]]];
244 std::dynamic_pointer_cast<LocalRegions::Expansion2D>(exp);
247 std::dynamic_pointer_cast<LocalRegions::Expansion>(
248 exp2D->GetLeftAdjacentElementExp());
249 int leftAdjElmtFace = exp2D->GetLeftAdjacentElementTrace();
251 tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtFace);
254 else if (meshDim == 2 && dim == 1)
256 for (
size_t j = 0; j < compGeomIds.size(); ++j)
259 (*trace)[geomIdToTraceId[compGeomIds[j]]];
261 std::dynamic_pointer_cast<LocalRegions::Expansion1D>(exp);
264 std::dynamic_pointer_cast<LocalRegions::Expansion>(
265 exp1D->GetLeftAdjacentElementExp());
266 int leftAdjElmtEdge = exp1D->GetLeftAdjacentElementTrace();
268 tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtEdge);
274 "FilterIntegral: Only composite dimensions equal to or "
275 "one lower than the mesh dimension are supported.")
296 if (
m_comm->GetRank() == 0)
306 phys = pFields[i]->GetPhys();
315 size_t dim = compExp[0].first->GetGeom()->GetShapeDim();
316 size_t meshDim = pFields[i]->GetGraph()->GetMeshDimension();
321 for (
auto &expPair : compExp)
324 auto exp = expPair.first;
328 size_t offset = pFields[i]->GetPhys_Offset(
330 input = exp->Integral(phys + offset);
332 else if (meshDim == 3 && dim == 2)
335 exp->GetTracePhysVals(expPair.second, exp, phys,
340 ->GetExp(exp->GetGeom()->GetTid(expPair.second))
341 ->Integral(facePhys);
343 else if (meshDim == 2 && dim == 1)
346 exp->GetTracePhysVals(expPair.second, exp, phys,
351 ->GetExp(exp->GetGeom()->GetTid(expPair.second))
352 ->Integral(edgePhys);
357 "FilterIntegral: Only composite dimensions "
358 "equal to or one lower than the mesh "
359 "dimension are supported.")
363 c += fabs(sum) >= fabs(input) ? (sum - t) + input
372 if (
m_comm->GetRank() == 0)
379 if (
m_comm->GetRank() == 0)
393 if (
m_comm->GetRank() == 0)
#define ASSERTL0(condition, msg)
NekDouble Evaluate() const
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
LibUtilities::SessionReaderSharedPtr m_session
const std::weak_ptr< EquationSystem > m_equ
std::map< std::string, std::string > ParamMap
std::map< int, std::vector< std::pair< LocalRegions::ExpansionSharedPtr, int > > > m_compExpMap
Map of composite ID to vector of expansions an face/edge local ID.
void v_Update(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
Calculate integral over requested composites.
std::map< size_t, size_t > m_geomElmtIdToExpId
Mapping from geometry ID to expansion ID.
static FilterSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation, const std::map< std::string, std::string > &pParams)
Creates an instance of this class.
size_t m_outputFrequency
Frequency to write to output data file in timesteps.
size_t m_numVariables
Number of fields to perform integral on.
std::ofstream m_outFile
Out file.
bool v_IsTimeDependent() final
Returns true as filter depends on time.
LibUtilities::CommSharedPtr m_comm
Global communicator.
static std::string className
Name of the class.
void v_Finalise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
This is a time-dependent filter.
std::vector< std::vector< unsigned int > > m_compVector
Vector of vector of composites IDs as integers.
SOLVER_UTILS_EXPORT FilterIntegral(const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation, const ParamMap &pParams)
Constructs the integral filter and parses filter options, opens file.
std::vector< std::string > m_splitCompString
Vector of composite IDs as a single string.
void v_Initialise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
Parse composite list and geometric entities to integrate over.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Expansion > ExpansionSharedPtr
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
FilterFactory & GetFilterFactory()