Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Private Attributes | Friends | List of all members
Nektar::SolverUtils::FilterIntegral Class Reference

#include <FilterIntegral.h>

Inheritance diagram for Nektar::SolverUtils::FilterIntegral:
[legend]

Public Member Functions

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. More...
 
SOLVER_UTILS_EXPORT ~FilterIntegral () override=default
 Default destructor. More...
 
- Public Member Functions inherited from Nektar::SolverUtils::Filter
SOLVER_UTILS_EXPORT Filter (const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation)
 
virtual SOLVER_UTILS_EXPORT ~Filter ()
 
SOLVER_UTILS_EXPORT void Initialise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
 
SOLVER_UTILS_EXPORT void Update (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
 
SOLVER_UTILS_EXPORT void Finalise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
 
SOLVER_UTILS_EXPORT bool IsTimeDependent ()
 
SOLVER_UTILS_EXPORT std::string SetupOutput (const std::string ext, const ParamMap &pParams)
 
SOLVER_UTILS_EXPORT std::string SetupOutput (const std::string ext, const std::string inname)
 
SOLVER_UTILS_EXPORT void SetUpdateOnInitialise (bool flag)
 

Static Public Member Functions

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. More...
 

Static Public Attributes

static std::string className
 Name of the class. More...
 

Protected Member Functions

void v_Initialise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
 Parse composite list and geometric entities to integrate over. More...
 
void v_Update (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
 Calculate integral over requested composites. More...
 
void v_Finalise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time) final
 This is a time-dependent filter. More...
 
bool v_IsTimeDependent () final
 Returns true as filter depends on time. More...
 
- Protected Member Functions inherited from Nektar::SolverUtils::Filter
virtual void v_Initialise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)=0
 
virtual void v_Update (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)=0
 
virtual void v_Finalise (const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)=0
 
virtual bool v_IsTimeDependent ()=0
 
virtual SOLVER_UTILS_EXPORT std::string v_SetupOutput (const std::string ext, const ParamMap &pParams)
 
virtual SOLVER_UTILS_EXPORT std::string v_SetupOutput (const std::string ext, const std::string inname)
 

Private Attributes

size_t m_index = 0
 
size_t m_outputFrequency
 Frequency to write to output data file in timesteps. More...
 
size_t m_numVariables
 Number of fields to perform integral on. More...
 
std::ofstream m_outFile
 Out file. More...
 
LibUtilities::CommSharedPtr m_comm
 Global communicator. More...
 
std::vector< std::string > m_splitCompString
 Vector of composite IDs as a single string. More...
 
std::vector< std::vector< unsigned int > > m_compVector
 Vector of vector of composites IDs as integers. More...
 
std::map< size_t, size_t > m_geomElmtIdToExpId
 Mapping from geometry ID to expansion ID. More...
 
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. More...
 

Friends

class MemoryManager< FilterIntegral >
 

Additional Inherited Members

- Public Types inherited from Nektar::SolverUtils::Filter
typedef std::map< std::string, std::string > ParamMap
 
- Protected Attributes inherited from Nektar::SolverUtils::Filter
LibUtilities::SessionReaderSharedPtr m_session
 
const std::weak_ptr< EquationSystemm_equ
 
bool m_updateOnInitialise = true
 

Detailed Description

Definition at line 42 of file FilterIntegral.h.

Constructor & Destructor Documentation

◆ FilterIntegral()

Nektar::SolverUtils::FilterIntegral::FilterIntegral ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::shared_ptr< EquationSystem > &  pEquation,
const ParamMap pParams 
)

Constructs the integral filter and parses filter options, opens file.

Initialise the filter and parse the session file parameters.

Definition at line 52 of file FilterIntegral.cpp.

55 : Filter(pSession, pEquation)
56{
57 std::string outName;
58 std::string ext = ".int";
59 outName = Filter::SetupOutput(ext, pParams);
60
61 // Composites (to calculate integrals on)
62 auto it = pParams.find("Composites");
63 ASSERTL0(it != pParams.end(), "Missing parameter 'Composites'.");
64 ASSERTL0(it->second.length() > 0, "Empty parameter 'Composites'.");
65
66 std::vector<std::string> splitComposite;
67 boost::split(m_splitCompString, it->second, boost::is_any_of(","),
68 boost::token_compress_on);
69
70 for (auto &comp : m_splitCompString)
71 {
72 boost::trim(comp);
73 size_t first = comp.find_first_of('[') + 1;
74 size_t last = comp.find_last_of(']') - 1;
75 auto tmpString = comp.substr(first, last - first + 1);
76
77 std::vector<unsigned int> tmpVec;
78 bool parseGood = ParseUtils::GenerateSeqVector(tmpString, tmpVec);
79
80 ASSERTL0(parseGood && !tmpVec.empty(),
81 "Unable to read composite regions index range for "
82 "FilterIntegral: " +
83 comp);
84
85 m_compVector.emplace_back(tmpVec);
86 }
87
88 // OutputPrecision
89 size_t precision;
90 it = pParams.find("OutputPrecision");
91 if (it == pParams.end())
92 {
93 precision = 7;
94 }
95 else
96 {
97 ASSERTL0(it->second.length() > 0, "Empty parameter 'OutputPrecision'.");
98 precision = std::stoi(it->second);
99 }
100
101 // Lock equation system pointer
102 auto equationSys = m_equ.lock();
103 ASSERTL0(equationSys, "Weak pointer expired");
104
105 m_numVariables = equationSys->GetNvariables();
106
107 m_comm = pSession->GetComm();
108 if (m_comm->GetRank() == 0)
109 {
110 m_outFile.open(outName);
111 ASSERTL0(m_outFile.good(), "Unable to open: '" + outName + "'");
112 m_outFile.setf(std::ios::scientific, std::ios::floatfield);
113 m_outFile.precision(precision);
114 m_outFile << "#Time";
115
116 for (auto &compName : m_splitCompString)
117 {
118 for (size_t j = 0; j < m_numVariables; ++j)
119 {
120 std::string varName = equationSys->GetVariable(j);
121 m_outFile << " " + compName + "_" + varName + "_integral";
122 }
123 }
124 m_outFile << std::endl;
125 }
126
127 // OutputFrequency
128 it = pParams.find("OutputFrequency");
129 if (it == pParams.end())
130 {
132 }
133 else
134 {
135 ASSERTL0(it->second.length() > 0, "Empty parameter 'OutputFrequency'.");
136 LibUtilities::Equation equ(m_session->GetInterpreter(), it->second);
137 m_outputFrequency = round(equ.Evaluate());
138 }
139}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
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.
Definition: ParseUtils.cpp:104
SOLVER_UTILS_EXPORT std::string SetupOutput(const std::string ext, const ParamMap &pParams)
Definition: Filter.h:139
LibUtilities::SessionReaderSharedPtr m_session
Definition: Filter.h:93
const std::weak_ptr< EquationSystem > m_equ
Definition: Filter.h:94
SOLVER_UTILS_EXPORT Filter(const LibUtilities::SessionReaderSharedPtr &pSession, const std::shared_ptr< EquationSystem > &pEquation)
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.
LibUtilities::CommSharedPtr m_comm
Global communicator.
std::vector< std::vector< unsigned int > > m_compVector
Vector of vector of composites IDs as integers.
std::vector< std::string > m_splitCompString
Vector of composite IDs as a single string.

References ASSERTL0, Nektar::LibUtilities::Equation::Evaluate(), Nektar::ParseUtils::GenerateSeqVector(), m_comm, m_compVector, Nektar::SolverUtils::Filter::m_equ, m_numVariables, m_outFile, m_outputFrequency, Nektar::SolverUtils::Filter::m_session, m_splitCompString, and Nektar::SolverUtils::Filter::SetupOutput().

◆ ~FilterIntegral()

SOLVER_UTILS_EXPORT Nektar::SolverUtils::FilterIntegral::~FilterIntegral ( )
overridedefault

Default destructor.

Member Function Documentation

◆ create()

static FilterSharedPtr Nektar::SolverUtils::FilterIntegral::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const std::shared_ptr< EquationSystem > &  pEquation,
const std::map< std::string, std::string > &  pParams 
)
inlinestatic

Creates an instance of this class.

Definition at line 48 of file FilterIntegral.h.

52 {
54 pSession, pEquation, pParams);
55 return p;
56 }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< Filter > FilterSharedPtr
A shared pointer to a Driver object.
Definition: Filter.h:52

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and CellMLToNektar.cellml_metadata::p.

◆ v_Finalise()

void Nektar::SolverUtils::FilterIntegral::v_Finalise ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
finalprotectedvirtual

This is a time-dependent filter.

Closes the output data file

Parameters
pFieldsField data
timeCurrent time

Implements Nektar::SolverUtils::Filter.

Definition at line 379 of file FilterIntegral.cpp.

383{
384 if (m_comm->GetRank() == 0)
385 {
386 m_outFile.close();
387 }
388}

References m_comm, and m_outFile.

◆ v_Initialise()

void Nektar::SolverUtils::FilterIntegral::v_Initialise ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
finalprotectedvirtual

Parse composite list and geometric entities to integrate over.

Initialises the integral filter and stores the composite expansions in m_compExpMap for all composites specified in the XML file

Parameters
pFieldsField data
timeCurrent time

Implements Nektar::SolverUtils::Filter.

Definition at line 144 of file FilterIntegral.cpp.

147{
148
149 // Create map from element ID -> expansion list ID
150 auto expList = pFields[0]->GetExp();
151 auto meshGraph = pFields[0]->GetGraph();
152
153 for (size_t i = 0; i < expList->size(); ++i)
154 {
155 auto exp = (*expList)[i];
156 m_geomElmtIdToExpId[exp->GetGeom()->GetGlobalID()] = i;
157 }
158
159 // Create a map from geom ID -> trace expansion list ID
160 std::map<size_t, size_t> geomIdToTraceId;
161 auto trace = pFields[0]->GetTrace()->GetExp();
162 for (size_t i = 0; i < trace->size(); ++i)
163 {
164 auto exp = (*trace)[i];
165 geomIdToTraceId[exp->GetGeom()->GetGlobalID()] = i;
166 }
167
168 // Get comp list dimension from first composite & element
169 auto composites = pFields[0]->GetGraph()->GetComposites();
170 size_t meshDim = pFields[0]->GetGraph()->GetMeshDimension();
171
172 for (int i = 0; i < m_compVector.size(); ++i)
173 {
174 // Check composite is present in the rank
175 if (composites.find(m_compVector[i][0]) == composites.end())
176 {
177 continue;
178 }
179
180 std::vector<std::shared_ptr<SpatialDomains::Geometry>> geomVec =
181 composites[m_compVector[i][0]]->m_geomVec;
182 size_t dim =
183 composites[m_compVector[i][0]]->m_geomVec[0]->GetShapeDim();
184
185 // Vector of all geometry IDs contained within the composite list
186 std::vector<size_t> compGeomIds;
187 for (auto compNum : m_compVector[i])
188 {
189 ASSERTL0(composites.find(compNum) != composites.end(),
190 "In FilterIntegral defined composite C[" +
191 std::to_string(compNum) +
192 "] does not exist in the mesh.")
193
194 auto compGeom = composites[compNum]->m_geomVec;
195
196 for (auto &geom : compGeom)
197 {
198 compGeomIds.emplace_back(geom->GetGlobalID());
199 }
200
201 // Only check first element in each comp for dimension
202 ASSERTL0(
203 dim == compGeom[0]->GetShapeDim(),
204 "Differing geometry dimensions specified in FilterIntegral '" +
205 m_splitCompString[i] + "'.");
206 }
207
208 std::vector<std::pair<LocalRegions::ExpansionSharedPtr, int>>
209 tmpCompExp(compGeomIds.size());
210
211 // If dimension of composite == dimension of mesh then we only need the
212 // expansion of the element
213 if (dim == pFields[0]->GetShapeDimension())
214 {
215 for (size_t j = 0; j < compGeomIds.size(); ++j)
216 {
217 tmpCompExp[j] = std::make_pair(
218 (*expList)[m_geomElmtIdToExpId[compGeomIds[j]]], -1);
219 }
220 }
221 // however if the dimension is less we need the expansion of the element
222 // containing the global composite geometry and the face/edge local ID
223 // within that. 3D mesh -> 2D, 2D -> 1D.
224 // @TODO: Restructure with the new dimension independent functions
225 // and check all is correct with this filter.
226 else if (meshDim == 3 && dim == 2)
227 {
228 for (size_t j = 0; j < compGeomIds.size(); ++j)
229 {
231 (*trace)[geomIdToTraceId[compGeomIds[j]]];
233 std::dynamic_pointer_cast<LocalRegions::Expansion2D>(exp);
234
235 LocalRegions::ExpansionSharedPtr leftAdjElmtExp =
236 std::dynamic_pointer_cast<LocalRegions::Expansion>(
237 exp2D->GetLeftAdjacentElementExp());
238 int leftAdjElmtFace = exp2D->GetLeftAdjacentElementTrace();
239
240 tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtFace);
241 }
242 }
243 else if (meshDim == 2 && dim == 1)
244 {
245 for (size_t j = 0; j < compGeomIds.size(); ++j)
246 {
248 (*trace)[geomIdToTraceId[compGeomIds[j]]];
250 std::dynamic_pointer_cast<LocalRegions::Expansion1D>(exp);
251
252 LocalRegions::ExpansionSharedPtr leftAdjElmtExp =
253 std::dynamic_pointer_cast<LocalRegions::Expansion>(
254 exp1D->GetLeftAdjacentElementExp());
255 int leftAdjElmtEdge = exp1D->GetLeftAdjacentElementTrace();
256
257 tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtEdge);
258 }
259 }
260 else
261 {
262 ASSERTL0(false,
263 "FilterIntegral: Only composite dimensions equal to or "
264 "one lower than the mesh dimension are supported.")
265 }
266
267 m_compExpMap[i] = tmpCompExp;
268 }
270 {
271 v_Update(pFields, time);
272 }
273}
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.
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:66
std::shared_ptr< Expansion2D > Expansion2DSharedPtr
Definition: Expansion1D.h:46
std::shared_ptr< Expansion1D > Expansion1DSharedPtr
Definition: Expansion1D.h:50

References ASSERTL0, m_compExpMap, m_compVector, m_geomElmtIdToExpId, m_splitCompString, Nektar::SolverUtils::Filter::m_updateOnInitialise, and v_Update().

◆ v_IsTimeDependent()

bool Nektar::SolverUtils::FilterIntegral::v_IsTimeDependent ( )
finalprotectedvirtual

Returns true as filter depends on time.

Implements Nektar::SolverUtils::Filter.

Definition at line 390 of file FilterIntegral.cpp.

391{
392 return true;
393}

◆ v_Update()

void Nektar::SolverUtils::FilterIntegral::v_Update ( const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const NekDouble time 
)
finalprotectedvirtual

Calculate integral over requested composites.

Performs the integration on the stored composite expansions and outputs in to the output data file

Parameters
pFieldsField data
timeCurrent time

Implements Nektar::SolverUtils::Filter.

Definition at line 278 of file FilterIntegral.cpp.

281{
282 if (m_index++ % m_outputFrequency > 0)
283 {
284 return;
285 }
286
287 if (m_comm->GetRank() == 0)
288 {
289 m_outFile << time;
290 }
291
292 for (size_t j = 0; j < m_compVector.size(); ++j)
293 {
294 for (size_t i = 0; i < m_numVariables; ++i)
295 {
296 Array<OneD, const NekDouble> phys;
297 phys = pFields[i]->GetPhys();
298
299 NekDouble sum = 0.0;
300 NekDouble c = 0.0;
301
302 // Check if composite is on the rank
303 if (m_compExpMap.find(j) != m_compExpMap.end())
304 {
305 auto compExp = m_compExpMap[j];
306 size_t dim = compExp[0].first->GetGeom()->GetShapeDim();
307 size_t meshDim = pFields[i]->GetGraph()->GetMeshDimension();
308
309 // Evaluate integral using improved Kahan–Babuška summation
310 // algorithm to reduce numerical error from adding floating
311 // points
312 for (auto &expPair : compExp)
313 {
314 NekDouble input = 0;
315 auto exp = expPair.first;
316
317 if (meshDim == dim)
318 {
319 size_t offset = pFields[i]->GetPhys_Offset(
320 m_geomElmtIdToExpId[exp->GetGeom()->GetGlobalID()]);
321 input = exp->Integral(phys + offset);
322 }
323 else if (meshDim == 3 && dim == 2)
324 {
325 Array<OneD, NekDouble> facePhys;
326 exp->GetTracePhysVals(expPair.second, exp, phys,
327 facePhys);
328 input =
329 pFields[i]
330 ->GetTrace()
331 ->GetExp(exp->GetGeom()->GetTid(expPair.second))
332 ->Integral(facePhys);
333 }
334 else if (meshDim == 2 && dim == 1)
335 {
336 Array<OneD, NekDouble> edgePhys;
337 exp->GetTracePhysVals(expPair.second, exp, phys,
338 edgePhys);
339 input =
340 pFields[i]
341 ->GetTrace()
342 ->GetExp(exp->GetGeom()->GetTid(expPair.second))
343 ->Integral(edgePhys);
344 }
345 else
346 {
347 ASSERTL0(false,
348 "FilterIntegral: Only composite dimensions "
349 "equal to or one lower than the mesh "
350 "dimension are supported.")
351 }
352
353 NekDouble t = sum + input;
354 c += fabs(sum) >= fabs(input) ? (sum - t) + input
355 : (input - t) + sum;
356 sum = t;
357 }
358 }
359
360 // Sum integral values from all ranks
361 Array<OneD, NekDouble> sumArray(1, sum + c);
362 m_comm->AllReduce(sumArray, LibUtilities::ReduceSum);
363 if (m_comm->GetRank() == 0)
364 {
365 m_outFile << " " << sumArray[0];
366 }
367 }
368 }
369
370 if (m_comm->GetRank() == 0)
371 {
372 m_outFile << std::endl;
373 }
374}
double NekDouble

References ASSERTL0, m_comm, m_compExpMap, m_compVector, m_geomElmtIdToExpId, m_index, m_numVariables, m_outFile, m_outputFrequency, and Nektar::LibUtilities::ReduceSum.

Referenced by v_Initialise().

Friends And Related Function Documentation

◆ MemoryManager< FilterIntegral >

friend class MemoryManager< FilterIntegral >
friend

Definition at line 1 of file FilterIntegral.h.

Member Data Documentation

◆ className

std::string Nektar::SolverUtils::FilterIntegral::className
static
Initial value:
=
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
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.
FilterFactory & GetFilterFactory()

Name of the class.

Definition at line 59 of file FilterIntegral.h.

◆ m_comm

LibUtilities::CommSharedPtr Nektar::SolverUtils::FilterIntegral::m_comm
private

Global communicator.

Definition at line 115 of file FilterIntegral.h.

Referenced by FilterIntegral(), v_Finalise(), and v_Update().

◆ m_compExpMap

std::map<int, std::vector<std::pair<LocalRegions::ExpansionSharedPtr, int> > > Nektar::SolverUtils::FilterIntegral::m_compExpMap
private

Map of composite ID to vector of expansions an face/edge local ID.

Definition at line 124 of file FilterIntegral.h.

Referenced by v_Initialise(), and v_Update().

◆ m_compVector

std::vector<std::vector<unsigned int> > Nektar::SolverUtils::FilterIntegral::m_compVector
private

Vector of vector of composites IDs as integers.

Definition at line 119 of file FilterIntegral.h.

Referenced by FilterIntegral(), v_Initialise(), and v_Update().

◆ m_geomElmtIdToExpId

std::map<size_t, size_t> Nektar::SolverUtils::FilterIntegral::m_geomElmtIdToExpId
private

Mapping from geometry ID to expansion ID.

Definition at line 121 of file FilterIntegral.h.

Referenced by v_Initialise(), and v_Update().

◆ m_index

size_t Nektar::SolverUtils::FilterIntegral::m_index = 0
private

Definition at line 107 of file FilterIntegral.h.

Referenced by v_Update().

◆ m_numVariables

size_t Nektar::SolverUtils::FilterIntegral::m_numVariables
private

Number of fields to perform integral on.

Definition at line 111 of file FilterIntegral.h.

Referenced by FilterIntegral(), and v_Update().

◆ m_outFile

std::ofstream Nektar::SolverUtils::FilterIntegral::m_outFile
private

Out file.

Definition at line 113 of file FilterIntegral.h.

Referenced by FilterIntegral(), v_Finalise(), and v_Update().

◆ m_outputFrequency

size_t Nektar::SolverUtils::FilterIntegral::m_outputFrequency
private

Frequency to write to output data file in timesteps.

Definition at line 109 of file FilterIntegral.h.

Referenced by FilterIntegral(), and v_Update().

◆ m_splitCompString

std::vector<std::string> Nektar::SolverUtils::FilterIntegral::m_splitCompString
private

Vector of composite IDs as a single string.

Definition at line 117 of file FilterIntegral.h.

Referenced by FilterIntegral(), and v_Initialise().