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

#include <FileSolution.h>

Public Member Functions

void InitObject (const std::string functionName, LibUtilities::SessionReaderSharedPtr pSession, const Array< OneD, const MultiRegions::ExpListSharedPtr > pFields, std::set< std::string > &variables, std::map< std::string, int > &series, std::map< std::string, NekDouble > &time)
 
void InterpolateField (const std::string variable, Array< OneD, NekDouble > &outarray, NekDouble time)
 
void InterpolateField (const int v, Array< OneD, NekDouble > &outarray, const NekDouble time)
 
NekDouble GetStartTime ()
 

Protected Member Functions

DNekBlkMatSharedPtr GetFloquetBlockMatrix (int nexp)
 
 FileFieldInterpolator ()=default
 
 ~FileFieldInterpolator ()=default
 
void DFT (const std::string file, const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const bool timefromfile)
 
void ImportFldBase (std::string pInfile, const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, int slice, std::map< std::string, NekDouble > &params)
 Import Base flow. More...
 

Protected Attributes

LibUtilities::SessionReaderSharedPtr m_session
 
int m_start
 number of slices More...
 
int m_skip
 
int m_slices
 
NekDouble m_timeStart
 period length More...
 
NekDouble m_period
 
int m_isperiodic
 
int m_interporder
 
std::map< int, Array< OneD, NekDouble > > m_interp
 interpolation vector More...
 
std::map< std::string, int > m_variableMap
 variables More...
 

Friends

class MemoryManager< FileFieldInterpolator >
 

Detailed Description

Definition at line 53 of file FileSolution.h.

Constructor & Destructor Documentation

◆ FileFieldInterpolator()

Nektar::SolverUtils::FileFieldInterpolator::FileFieldInterpolator ( )
protecteddefault

◆ ~FileFieldInterpolator()

Nektar::SolverUtils::FileFieldInterpolator::~FileFieldInterpolator ( )
protecteddefault

Member Function Documentation

◆ DFT()

void Nektar::SolverUtils::FileFieldInterpolator::DFT ( const std::string  file,
const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
const bool  timefromfile 
)
protected

Definition at line 639 of file FileSolution.cpp.

643{
644 for (auto it : m_variableMap)
645 {
646 int ncoeffs = pFields[it.second]->GetNcoeffs();
647 m_interp[it.second] = Array<OneD, NekDouble>(ncoeffs * m_slices, 0.0);
648 }
649
650 // Import the slides into auxiliary vector
651 // The base flow should be stored in the form "filename_%d.ext"
652 // A subdirectory can also be included, such as "dir/filename_%d.ext"
653 size_t found = file.find("%d");
654 std::map<std::string, NekDouble> params;
655 if (found != std::string::npos)
656 {
657 ASSERTL0(file.find("%d", found + 1) == std::string::npos,
658 "There are more than one '%d'.");
659 int nstart = m_start;
660 std::vector<NekDouble> times;
661 for (int i = 0; i < m_slices; ++i)
662 {
663 int filen = nstart + i * m_skip;
664 auto fmt = boost::format(file) % filen;
665 ImportFldBase(fmt.str(), pFields, i, params);
666 if (m_session->GetComm()->GetRank() == 0)
667 {
668 std::cout << "read base flow file " << fmt.str() << std::endl;
669 }
670 if (timefromfile && params.count("time"))
671 {
672 times.push_back(params["time"]);
673 }
674 }
675 if (timefromfile && times.size() == m_slices && m_slices > 1)
676 {
677 m_timeStart = times[0];
678 if (m_interporder < 1)
679 {
680 m_period = m_slices * (times[m_slices - 1] - times[0]) /
681 (m_slices - 1.);
682 }
683 else
684 {
685 m_period = times[m_slices - 1] - times[0];
686 }
687 }
688 }
689 else if (m_slices == 1)
690 {
691 ImportFldBase(file.c_str(), pFields, 0, params);
692 }
693 else
694 {
695 ASSERTL0(
696 false,
697 "Since N_slices is specified, the filename provided for function "
698 "'BaseFlow' must include exactly one instance of the format "
699 "specifier '%d', to index the time-slices.");
700 }
701
702 if (!m_isperiodic || m_slices == 1)
703 {
704 return;
705 }
706
707 // Discrete Fourier Transform of the fields
708 for (auto it : m_interp)
709 {
710 int npoints = pFields[it.first]->GetNcoeffs();
711#ifdef NEKTAR_USING_FFTW
712
713 // Discrete Fourier Transform using FFTW
714 Array<OneD, NekDouble> fft_in(npoints * m_slices);
715 Array<OneD, NekDouble> fft_out(npoints * m_slices);
716
717 Array<OneD, NekDouble> m_tmpIN(m_slices);
718 Array<OneD, NekDouble> m_tmpOUT(m_slices);
719
720 // Shuffle the data
721 for (int j = 0; j < m_slices; ++j)
722 {
723 Vmath::Vcopy(npoints, &(it.second)[j * npoints], 1, &(fft_in[j]),
724 m_slices);
725 }
726
728 m_slices);
729
730 // FFT Transform
731 for (int i = 0; i < npoints; i++)
732 {
733 m_FFT->FFTFwdTrans(m_tmpIN = fft_in + i * m_slices,
734 m_tmpOUT = fft_out + i * m_slices);
735 }
736
737 // Reshuffle data
738 for (int s = 0; s < m_slices; ++s)
739 {
740 Vmath::Vcopy(npoints, &fft_out[s], m_slices,
741 &(it.second)[s * npoints], 1);
742 }
743
744 Vmath::Zero(fft_in.size(), &fft_in[0], 1);
745 Vmath::Zero(fft_out.size(), &fft_out[0], 1);
746#else
747 // Discrete Fourier Transform using MVM
748 DNekBlkMatSharedPtr blkmat;
749 blkmat = GetFloquetBlockMatrix(npoints);
750
751 int nrows = blkmat->GetRows();
752 int ncols = blkmat->GetColumns();
753
754 Array<OneD, NekDouble> sortedinarray(ncols);
755 Array<OneD, NekDouble> sortedoutarray(nrows);
756
757 // Shuffle the data
758 for (int j = 0; j < m_slices; ++j)
759 {
760 Vmath::Vcopy(npoints, &(it.second)[j * npoints], 1,
761 &(sortedinarray[j]), m_slices);
762 }
763
764 // Create NekVectors from the given data arrays
765 NekVector<NekDouble> in(ncols, sortedinarray, eWrapper);
766 NekVector<NekDouble> out(nrows, sortedoutarray, eWrapper);
767
768 // Perform matrix-vector multiply.
769 out = (*blkmat) * in;
770
771 // Reshuffle data
772 for (int s = 0; s < m_slices; ++s)
773 {
774 Vmath::Vcopy(npoints, &sortedoutarray[s], m_slices,
775 &(it.second)[s * npoints], 1);
776 }
777
778 for (int r = 0; r < sortedinarray.size(); ++r)
779 {
780 sortedinarray[0] = 0;
781 sortedoutarray[0] = 0;
782 }
783
784#endif
785 }
786}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
LibUtilities::SessionReaderSharedPtr m_session
Definition: FileSolution.h:74
std::map< std::string, int > m_variableMap
variables
Definition: FileSolution.h:87
void ImportFldBase(std::string pInfile, const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, int slice, std::map< std::string, NekDouble > &params)
Import Base flow.
std::map< int, Array< OneD, NekDouble > > m_interp
interpolation vector
Definition: FileSolution.h:85
DNekBlkMatSharedPtr GetFloquetBlockMatrix(int nexp)
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:65
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:77
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::eWrapper, CellMLToNektar.pycml::format, GetFloquetBlockMatrix(), Nektar::LibUtilities::GetNektarFFTFactory(), ImportFldBase(), m_interp, m_interporder, m_isperiodic, m_period, m_session, m_skip, m_slices, m_start, m_timeStart, m_variableMap, Vmath::Vcopy(), and Vmath::Zero().

Referenced by InitObject().

◆ GetFloquetBlockMatrix()

DNekBlkMatSharedPtr Nektar::SolverUtils::FileFieldInterpolator::GetFloquetBlockMatrix ( int  nexp)
protected

Definition at line 604 of file FileSolution.cpp.

605{
606 DNekMatSharedPtr loc_mat;
607 DNekBlkMatSharedPtr BlkMatrix;
608
609 Array<OneD, unsigned int> nrows(nexp);
610 Array<OneD, unsigned int> ncols(nexp);
611
612 nrows = Array<OneD, unsigned int>(nexp, m_slices);
613 ncols = Array<OneD, unsigned int>(nexp, m_slices);
614
615 MatrixStorage blkmatStorage = eDIAGONAL;
616 BlkMatrix = MemoryManager<DNekBlkMat>::AllocateSharedPtr(nrows, ncols,
617 blkmatStorage);
618
619 const LibUtilities::PointsKey Pkey(m_slices,
621 const LibUtilities::BasisKey BK(LibUtilities::eFourier, m_slices, Pkey);
622 StdRegions::StdSegExp StdSeg(BK);
623
624 StdRegions::StdMatrixKey matkey(StdRegions::eFwdTrans,
625 StdSeg.DetShapeType(), StdSeg);
626
627 loc_mat = StdSeg.GetStdMatrix(matkey);
628
629 // set up array of block matrices.
630 for (int i = 0; i < nexp; ++i)
631 {
632 BlkMatrix->SetBlock(i, i, loc_mat);
633 }
634
635 return BlkMatrix;
636}
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:74
@ eFourier
Fourier Expansion .
Definition: BasisType.h:55
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Nektar::StdRegions::StdExpansion::DetShapeType(), Nektar::eDIAGONAL, Nektar::LibUtilities::eFourier, Nektar::LibUtilities::eFourierEvenlySpaced, Nektar::StdRegions::eFwdTrans, Nektar::StdRegions::StdExpansion::GetStdMatrix(), and m_slices.

Referenced by DFT().

◆ GetStartTime()

NekDouble Nektar::SolverUtils::FileFieldInterpolator::GetStartTime ( )

Definition at line 788 of file FileSolution.cpp.

789{
790 return m_timeStart;
791}

References m_timeStart.

◆ ImportFldBase()

void Nektar::SolverUtils::FileFieldInterpolator::ImportFldBase ( std::string  pInfile,
const Array< OneD, const MultiRegions::ExpListSharedPtr > &  pFields,
int  pSlice,
std::map< std::string, NekDouble > &  params 
)
protected

Import Base flow.

Import field from infile and load into m_fields. This routine will also perform a BwdTrans to ensure data is in both the physical and coefficient storage.

Parameters
pInFileFilename to read.
pFieldsArray of expansion lists

Definition at line 445 of file FileSolution.cpp.

449{
450 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
451 std::vector<std::vector<NekDouble>> FieldData;
452
453 int numexp = pFields[0]->GetExpSize();
454 Array<OneD, int> ElementGIDs(numexp);
455
456 // Define list of global element ids
457 for (int i = 0; i < numexp; ++i)
458 {
459 ElementGIDs[i] = pFields[0]->GetExp(i)->GetGeom()->GetGlobalID();
460 }
461
462 // Get Homogeneous
465 fld->Import(pInfile, FieldDef, FieldData,
467
468 int nFileVar = FieldDef[0]->m_fields.size();
469 for (int j = 0; j < nFileVar; ++j)
470 {
471 std::string var = FieldDef[0]->m_fields[j];
472 if (!m_variableMap.count(var))
473 {
474 continue;
475 }
476 int ncoeffs = pFields[m_variableMap[var]]->GetNcoeffs();
477 Array<OneD, NekDouble> tmp_coeff(ncoeffs, 0.);
478 for (int i = 0; i < FieldDef.size(); ++i)
479 {
480 pFields[m_variableMap[var]]->ExtractDataToCoeffs(
481 FieldDef[i], FieldData[i], FieldDef[i]->m_fields[j], tmp_coeff);
482 }
483 Vmath::Vcopy(ncoeffs, &tmp_coeff[0], 1,
484 &m_interp[m_variableMap[var]][pSlice * ncoeffs], 1);
485 }
486
487 LibUtilities::FieldMetaDataMap fieldMetaDataMap;
488 fld->ImportFieldMetaData(pInfile, fieldMetaDataMap);
489 // check to see if time defined
490 if (fieldMetaDataMap != LibUtilities::NullFieldMetaDataMap)
491 {
492 auto iter = fieldMetaDataMap.find("Time");
493 if (iter != fieldMetaDataMap.end())
494 {
495 params["time"] = std::stod(iter->second);
496 }
497 }
498}
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:223
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:322
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:50
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:51

References Nektar::LibUtilities::FieldIO::CreateForFile(), m_interp, m_session, m_variableMap, Nektar::LibUtilities::NullFieldMetaDataMap, and Vmath::Vcopy().

Referenced by DFT().

◆ InitObject()

void Nektar::SolverUtils::FileFieldInterpolator::InitObject ( const std::string  functionName,
LibUtilities::SessionReaderSharedPtr  pSession,
const Array< OneD, const MultiRegions::ExpListSharedPtr pFields,
std::set< std::string > &  variables,
std::map< std::string, int > &  series,
std::map< std::string, NekDouble > &  time 
)

Definition at line 332 of file FileSolution.cpp.

338{
339 m_session = pSession;
340 for (size_t i = 0; i < m_session->GetVariables().size(); ++i)
341 {
342 std::string var = m_session->GetVariable(i);
343 if (variables.count(var))
344 {
345 ASSERTL0(m_session->DefinesFunction(functionName, var) &&
346 (m_session->GetFunctionType(functionName, var) ==
348 functionName + "(" + var + ") is not defined as a file.");
349 m_variableMap[var] = i;
350 }
351 }
352
353 if (series.count("start"))
354 {
355 m_start = series["start"];
356 }
357 else
358 {
359 m_start = 0;
360 }
361
362 if (series.count("skip"))
363 {
364 m_skip = series["skip"];
365 }
366 else
367 {
368 m_skip = 1;
369 }
370
371 if (series.count("slices"))
372 {
373 m_slices = series["slices"];
374 }
375 else
376 {
377 m_slices = 1;
378 }
379
380 if (series.count("order"))
381 {
382 m_interporder = series["order"];
383 }
384 else
385 {
386 m_interporder = 0;
387 }
388
389 if (series.count("isperiodic"))
390 {
391 m_isperiodic = series["isperiodic"];
392 }
393 else
394 {
395 m_isperiodic = 1;
396 }
397
398 bool timefromfile = false;
399 if (times.count("period"))
400 {
401 m_period = times["period"];
402 }
403 else if (m_slices > 1)
404 {
405 timefromfile = true;
406 }
407 if (times.count("start"))
408 {
409 m_timeStart = times["start"];
410 }
411 else
412 {
413 m_timeStart = 0.;
414 }
415
416 if (m_session->GetComm()->GetRank() == 0)
417 {
418 std::cout << "baseflow info : interpolation order " << m_interporder
419 << ", period " << m_period << ", periodicity ";
420 if (m_isperiodic)
421 {
422 std::cout << "yes\n";
423 }
424 else
425 {
426 std::cout << "no\n";
427 }
428 std::cout << "baseflow info : files from " << m_start << " to "
429 << (m_start + (m_slices - 1) * m_skip) << " (skip " << m_skip
430 << ") with " << (m_slices - (m_interporder > 1))
431 << " time intervals" << std::endl;
432 }
433
434 std::string file = m_session->GetFunctionFilename("Solution", 0);
435 DFT(file, pFields, timefromfile);
436}
void DFT(const std::string file, const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const bool timefromfile)

References ASSERTL0, DFT(), Nektar::LibUtilities::eFunctionTypeFile, m_interporder, m_isperiodic, m_period, m_session, m_skip, m_slices, m_start, m_timeStart, and m_variableMap.

◆ InterpolateField() [1/2]

void Nektar::SolverUtils::FileFieldInterpolator::InterpolateField ( const int  v,
Array< OneD, NekDouble > &  outarray,
const NekDouble  time 
)

Definition at line 511 of file FileSolution.cpp.

514{
515 // doesnot have this variable
516 if (!m_interp.count(v))
517 {
518 return;
519 }
520 // one slice, steady solution
521 int npoints = m_interp[v].size() / m_slices;
522 if (m_slices == 1)
523 {
524 Vmath::Vcopy(npoints, &m_interp[v][0], 1, &outarray[0], 1);
525 return;
526 }
527 // unsteady solution
528 time -= m_timeStart;
529 if (m_isperiodic && time > m_period)
530 {
531 time = fmod(time, m_period);
532 if (time < 0.)
533 {
534 time += m_period;
535 }
536 }
537 if (m_interporder < 1)
538 {
539 NekDouble BetaT = 2 * M_PI * fmod(time, m_period) / m_period;
540 NekDouble phase;
541 Array<OneD, NekDouble> auxiliary(npoints);
542
543 Vmath::Vcopy(npoints, &m_interp[v][0], 1, &outarray[0], 1);
544 Vmath::Svtvp(npoints, cos(0.5 * m_slices * BetaT),
545 &m_interp[v][npoints], 1, &outarray[0], 1, &outarray[0],
546 1);
547
548 for (int i = 2; i < m_slices; i += 2)
549 {
550 phase = (i >> 1) * BetaT;
551
552 Vmath::Svtvp(npoints, cos(phase), &m_interp[v][i * npoints], 1,
553 &outarray[0], 1, &outarray[0], 1);
554 Vmath::Svtvp(npoints, -sin(phase), &m_interp[v][(i + 1) * npoints],
555 1, &outarray[0], 1, &outarray[0], 1);
556 }
557 }
558 else
559 {
560 NekDouble x = time;
561 x = x / m_period * (m_slices - 1);
562 int ix = x;
563 if (ix < 0)
564 {
565 ix = 0;
566 }
567 if (ix > m_slices - 2)
568 {
569 ix = m_slices - 2;
570 }
571 int padleft = std::max(0, m_interporder / 2 - 1);
572 if (padleft > ix)
573 {
574 padleft = ix;
575 }
576 int padright = m_interporder - 1 - padleft;
577 if (padright > m_slices - 1 - ix)
578 {
579 padright = m_slices - 1 - ix;
580 }
581 padleft = m_interporder - 1 - padright;
582 Array<OneD, NekDouble> coeff(m_interporder, 1.);
583 for (int i = 0; i < m_interporder; ++i)
584 {
585 for (int j = 0; j < m_interporder; ++j)
586 {
587 if (i != j)
588 {
589 coeff[i] *= (x - ix + padleft - (NekDouble)j) /
590 ((NekDouble)i - (NekDouble)j);
591 }
592 }
593 }
594 Vmath::Zero(npoints, &outarray[0], 1);
595 for (int i = ix - padleft; i < ix + padright + 1; ++i)
596 {
597 Vmath::Svtvp(npoints, coeff[i - ix + padleft],
598 &m_interp[v][i * npoints], 1, &outarray[0], 1,
599 &outarray[0], 1);
600 }
601 }
602}
double NekDouble
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition: Vmath.hpp:396

References m_interp, m_interporder, m_isperiodic, m_period, m_slices, m_timeStart, Vmath::Svtvp(), Vmath::Vcopy(), and Vmath::Zero().

◆ InterpolateField() [2/2]

void Nektar::SolverUtils::FileFieldInterpolator::InterpolateField ( const std::string  variable,
Array< OneD, NekDouble > &  outarray,
NekDouble  time 
)

Definition at line 500 of file FileSolution.cpp.

503{
504 if (!m_variableMap.count(variable))
505 {
506 return;
507 }
508 InterpolateField(m_variableMap[variable], outarray, time);
509}
void InterpolateField(const std::string variable, Array< OneD, NekDouble > &outarray, NekDouble time)

References InterpolateField(), and m_variableMap.

Referenced by InterpolateField().

Friends And Related Function Documentation

◆ MemoryManager< FileFieldInterpolator >

friend class MemoryManager< FileFieldInterpolator >
friend

Definition at line 52 of file FileSolution.h.

Member Data Documentation

◆ m_interp

std::map<int, Array<OneD, NekDouble> > Nektar::SolverUtils::FileFieldInterpolator::m_interp
protected

interpolation vector

Definition at line 85 of file FileSolution.h.

Referenced by DFT(), ImportFldBase(), and InterpolateField().

◆ m_interporder

int Nektar::SolverUtils::FileFieldInterpolator::m_interporder
protected

Definition at line 83 of file FileSolution.h.

Referenced by DFT(), InitObject(), and InterpolateField().

◆ m_isperiodic

int Nektar::SolverUtils::FileFieldInterpolator::m_isperiodic
protected

Definition at line 82 of file FileSolution.h.

Referenced by DFT(), InitObject(), and InterpolateField().

◆ m_period

NekDouble Nektar::SolverUtils::FileFieldInterpolator::m_period
protected

Definition at line 81 of file FileSolution.h.

Referenced by DFT(), InitObject(), and InterpolateField().

◆ m_session

LibUtilities::SessionReaderSharedPtr Nektar::SolverUtils::FileFieldInterpolator::m_session
protected

Definition at line 74 of file FileSolution.h.

Referenced by DFT(), ImportFldBase(), and InitObject().

◆ m_skip

int Nektar::SolverUtils::FileFieldInterpolator::m_skip
protected

Definition at line 77 of file FileSolution.h.

Referenced by DFT(), and InitObject().

◆ m_slices

int Nektar::SolverUtils::FileFieldInterpolator::m_slices
protected

Definition at line 78 of file FileSolution.h.

Referenced by DFT(), GetFloquetBlockMatrix(), InitObject(), and InterpolateField().

◆ m_start

int Nektar::SolverUtils::FileFieldInterpolator::m_start
protected

number of slices

Definition at line 76 of file FileSolution.h.

Referenced by DFT(), and InitObject().

◆ m_timeStart

NekDouble Nektar::SolverUtils::FileFieldInterpolator::m_timeStart
protected

period length

Definition at line 80 of file FileSolution.h.

Referenced by DFT(), GetStartTime(), InitObject(), and InterpolateField().

◆ m_variableMap

std::map<std::string, int> Nektar::SolverUtils::FileFieldInterpolator::m_variableMap
protected

variables

Definition at line 87 of file FileSolution.h.

Referenced by DFT(), ImportFldBase(), InitObject(), and InterpolateField().