Nektar++
Loading...
Searching...
No Matches
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.
 

Protected Attributes

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

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 646 of file FileSolution.cpp.

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

612{
613 DNekMatSharedPtr loc_mat;
614 DNekBlkMatSharedPtr BlkMatrix;
615
616 Array<OneD, unsigned int> nrows(nexp);
617 Array<OneD, unsigned int> ncols(nexp);
618
619 nrows = Array<OneD, unsigned int>(nexp, m_slices);
620 ncols = Array<OneD, unsigned int>(nexp, m_slices);
621
622 MatrixStorage blkmatStorage = eDIAGONAL;
623 BlkMatrix = MemoryManager<DNekBlkMat>::AllocateSharedPtr(nrows, ncols,
624 blkmatStorage);
625
626 const LibUtilities::PointsKey Pkey(m_slices,
628 const LibUtilities::BasisKey BK(LibUtilities::eFourier, m_slices, Pkey);
629 StdRegions::StdSegExp StdSeg(BK);
630
631 StdRegions::StdMatrixKey matkey(StdRegions::eFwdTrans,
632 StdSeg.DetShapeType(), StdSeg);
633
634 loc_mat = StdSeg.GetStdMatrix(matkey);
635
636 // set up array of block matrices.
637 for (int i = 0; i < nexp; ++i)
638 {
639 BlkMatrix->SetBlock(i, i, loc_mat);
640 }
641
642 return BlkMatrix;
643}
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

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 795 of file FileSolution.cpp.

796{
797 return m_timeStart;
798}

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 452 of file FileSolution.cpp.

456{
457 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
458 std::vector<std::vector<NekDouble>> FieldData;
459
460 int numexp = pFields[0]->GetExpSize();
461 Array<OneD, int> ElementGIDs(numexp);
462
463 // Define list of global element ids
464 for (int i = 0; i < numexp; ++i)
465 {
466 ElementGIDs[i] = pFields[0]->GetExp(i)->GetGeom()->GetGlobalID();
467 }
468
469 // Get Homogeneous
472 fld->Import(pInfile, FieldDef, FieldData,
474
475 int nFileVar = FieldDef[0]->m_fields.size();
476 for (int j = 0; j < nFileVar; ++j)
477 {
478 std::string var = FieldDef[0]->m_fields[j];
479 if (!m_variableMap.count(var))
480 {
481 continue;
482 }
483 int ncoeffs = pFields[m_variableMap[var]]->GetNcoeffs();
484 Array<OneD, NekDouble> tmp_coeff(ncoeffs, 0.);
485 for (int i = 0; i < FieldDef.size(); ++i)
486 {
487 pFields[m_variableMap[var]]->ExtractDataToCoeffs(
488 FieldDef[i], FieldData[i], FieldDef[i]->m_fields[j], tmp_coeff);
489 }
490 Vmath::Vcopy(ncoeffs, &tmp_coeff[0], 1,
491 &m_interp[m_variableMap[var]][pSlice * ncoeffs], 1);
492 }
493
494 LibUtilities::FieldMetaDataMap fieldMetaDataMap;
495 fld->ImportFieldMetaData(pInfile, fieldMetaDataMap);
496 // check to see if time defined
497 if (fieldMetaDataMap != LibUtilities::NullFieldMetaDataMap)
498 {
499 auto iter = fieldMetaDataMap.find("Time");
500 if (iter != fieldMetaDataMap.end())
501 {
502 params["time"] = std::stod(iter->second);
503 }
504 }
505}
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 339 of file FileSolution.cpp.

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

521{
522 // doesnot have this variable
523 if (!m_interp.count(v))
524 {
525 return;
526 }
527 // one slice, steady solution
528 int npoints = m_interp[v].size() / m_slices;
529 if (m_slices == 1)
530 {
531 Vmath::Vcopy(npoints, &m_interp[v][0], 1, &outarray[0], 1);
532 return;
533 }
534 // unsteady solution
535 time -= m_timeStart;
536 if (m_isperiodic && time > m_period)
537 {
538 time = fmod(time, m_period);
539 if (time < 0.)
540 {
541 time += m_period;
542 }
543 }
544 if (m_interporder < 1)
545 {
546 NekDouble BetaT = 2 * M_PI * fmod(time, m_period) / m_period;
547 NekDouble phase;
548 Array<OneD, NekDouble> auxiliary(npoints);
549
550 Vmath::Vcopy(npoints, &m_interp[v][0], 1, &outarray[0], 1);
551 Vmath::Svtvp(npoints, cos(0.5 * m_slices * BetaT),
552 &m_interp[v][npoints], 1, &outarray[0], 1, &outarray[0],
553 1);
554
555 for (int i = 2; i < m_slices; i += 2)
556 {
557 phase = (i >> 1) * BetaT;
558
559 Vmath::Svtvp(npoints, cos(phase), &m_interp[v][i * npoints], 1,
560 &outarray[0], 1, &outarray[0], 1);
561 Vmath::Svtvp(npoints, -sin(phase), &m_interp[v][(i + 1) * npoints],
562 1, &outarray[0], 1, &outarray[0], 1);
563 }
564 }
565 else
566 {
567 NekDouble x = time;
568 x = x / m_period * (m_slices - 1);
569 int ix = x;
570 if (ix < 0)
571 {
572 ix = 0;
573 }
574 if (ix > m_slices - 2)
575 {
576 ix = m_slices - 2;
577 }
578 int padleft = std::max(0, m_interporder / 2 - 1);
579 if (padleft > ix)
580 {
581 padleft = ix;
582 }
583 int padright = m_interporder - 1 - padleft;
584 if (padright > m_slices - 1 - ix)
585 {
586 padright = m_slices - 1 - ix;
587 }
588 padleft = m_interporder - 1 - padright;
589 Array<OneD, NekDouble> coeff(m_interporder, 1.);
590 for (int i = 0; i < m_interporder; ++i)
591 {
592 for (int j = 0; j < m_interporder; ++j)
593 {
594 if (i != j)
595 {
596 coeff[i] *= (x - ix + padleft - (NekDouble)j) /
597 ((NekDouble)i - (NekDouble)j);
598 }
599 }
600 }
601 Vmath::Zero(npoints, &outarray[0], 1);
602 for (int i = ix - padleft; i < ix + padright + 1; ++i)
603 {
604 Vmath::Svtvp(npoints, coeff[i - ix + padleft],
605 &m_interp[v][i * npoints], 1, &outarray[0], 1,
606 &outarray[0], 1);
607 }
608 }
609}
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 507 of file FileSolution.cpp.

510{
511 if (!m_variableMap.count(variable))
512 {
513 return;
514 }
515 InterpolateField(m_variableMap[variable], outarray, time);
516}
void InterpolateField(const std::string variable, Array< OneD, NekDouble > &outarray, NekDouble time)

References InterpolateField(), and m_variableMap.

Referenced by InterpolateField().

Friends And Related Symbol 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().