44 namespace LibUtilities
57 std::vector<NekDouble> freeParams) :
59 m_name(
"FractionalInTime")
67 "FractionalInTime Time integration scheme bad order: " +
68 std::to_string(order));
71 freeParams.size() == 1 ||
72 freeParams.size() == 2 ||
73 freeParams.size() == 6,
74 "FractionalInTime Time integration scheme invalid number "
75 "of free parameters, expected zero, one <alpha>, "
76 "two <alpha, base>, or "
77 "six <alpha, base, nQuadPts, sigma, mu0, nu> received " +
78 std::to_string(freeParams.size()));
80 if( freeParams.size() >= 1 )
85 if( freeParams.size() >= 2 )
90 if( freeParams.size() == 6 )
94 m_mu0 = freeParams[4];
110 boost::ignore_unused(op);
139 for(
unsigned int m=0; m<=
m_order; ++m )
143 for(
unsigned int i=0; i<
m_nvars; ++i )
147 for (
unsigned int j=0; j<
m_npoints; ++j )
166 for(
unsigned int i=0; i<
m_nvars; ++i )
178 for(
unsigned int m=1, m_1=0; m<
m_order; ++m, ++m_1 )
187 for(
unsigned int m=1; m<=
m_order; ++m )
191 for(
unsigned int n=0; n<m; ++n )
231 for(
unsigned int j=2; j<=m; ++j )
233 for(
unsigned int i=0; i<m; ++i )
235 m_Ahats[m][j-1][i] = pow( (1-j), i );
239 ASSERTL1(
false,
"No matrix inverse.");
250 for(
unsigned int i=0; i<
m_order; ++i )
252 for(
unsigned int j=0; j<
m_order; ++j )
260 for (
int l=0; l<
m_Lmax; ++l)
276 boost::ignore_unused(delta_t);
279 "Delta T has changed which is not permitted." );
282 int timeStep = timestep + 1;
286 for (
int l=0; l<
m_Lmax; ++l)
298 for (
int l=0; l<
L; ++l)
320 m_u[m][i][j] =
m_u[m-1][i][j];
354 for (
int i=0; i<
m_Lmax; ++i)
369 const int unsigned base)
const
371 return (counter+1) % base;
380 const unsigned int l )
const
382 unsigned int L = ceil(
log(l/2.0) /
log(base));
384 if( l % (
unsigned int)(2 * pow(base,
L)) == 0 )
401 const unsigned int m )
408 for(
unsigned int i=0; i<
L-1; ++i )
410 m_qml[i] = floor(m / pow(base, i+1) ) - 1;
425 const unsigned int m )
442 for(
unsigned int i=1; i<
L; ++i )
476 for(
unsigned int q=0; q<nQuadPts; ++q )
481 lamb[q] = sigma + mu * th * std::complex<NekDouble>(1./tan(th), nu);
483 w[q] = std::complex<NekDouble>(0, -1./
NekDouble(nQuadPts)) *
484 mu * std::complex<NekDouble>(1./tan(th) - th/(sin(th)*sin(th)), nu);
489 if( nQuadPts % 2 == 1 )
491 unsigned int q = (nQuadPts+1) / 2;
493 lamb[q] = std::complex<NekDouble>(sigma + mu, 0);
495 w[q] = std::complex<NekDouble>(nu * mu / nQuadPts, 0);
540 instance.
index = index;
552 for(
unsigned int q=0; q<
m_nvars; ++q )
560 for(
unsigned int i=0; i<
m_npoints; ++i )
571 instance.
stage_ind = std::pair<int, int>(0, 0);
589 instance.
cstash_ind = std::pair<int, int>(0, 0);
600 instance.
fstash_ind = std::pair<int, int>(0, 0);
638 for(
unsigned int m=1; m<=
m_order+1; ++m )
642 for(
unsigned int n=0; n<m; ++n )
654 As[m][0][0] = 0.; As[m][0][1] = 1.;
655 As[m][1][0] = 1.; As[m][1][1] = -1.;
659 As[m][0][0] = 0.; As[m][0][1] = 1.; As[m][0][2] = 0;
660 As[m][1][0] = 1./2.; As[m][1][1] = 0.; As[m][1][2] = -1./2.;
661 As[m][2][0] = 1./2.; As[m][2][1] = -1.; As[m][2][2] = 1./2.;
665 As[m][0][0] = 0.; As[m][0][1] = 1.;
666 As[m][0][2] = 0.; As[m][0][3] = 0.;
668 As[m][1][0] = 1./3.; As[m][1][1] = 1./2.;
669 As[m][1][2] = -1.; As[m][1][3] = 1./6.;
671 As[m][2][0] = 1./2.; As[m][2][1] = -1.;
672 As[m][2][2] = 1./2.; As[m][2][3] = 0.;
674 As[m][3][0] = 1./6.; As[m][3][1] = -1./2.;
675 As[m][3][2] = 1./2.; As[m][3][3] = -1./6.;
679 As[m][0][0] = 0.; As[m][0][1] = 1.;
680 As[m][0][2] = 0.; As[m][0][3] = 0.; As[m][0][4] = 0.;
682 As[m][1][0] = 1./4.; As[m][1][1] = 5./6.;
683 As[m][1][2] = -3./2.; As[m][1][3] = 1./2.; As[m][1][4] = -1./12.;
685 As[m][2][0] = 11./24.; As[m][2][1] = -5./6.;
686 As[m][2][2] = 1./4.; As[m][2][3] = 1./6.; As[m][2][4] = -1./24.;
688 As[m][3][0] = 1./4.; As[m][3][1] = -5./6.;
689 As[m][3][2] = 1.; As[m][3][3] = -1./2.; As[m][3][4] = 1./12.;
691 As[m][4][0] = 1./24.; As[m][4][1] = -1./6.;
692 As[m][4][2] = 1./4.; As[m][4][3] = -1./6.; As[m][4][4] = 1./24.;
700 ASSERTL1(
false,
"No matrix inverse.");
722 instance.
E[q] = exp(instance.
z[q] *
m_deltaT);
727 for(
unsigned int m=0; m<
m_order+1; ++m )
735 1. / instance.
z[q] * (exp(instance.
z[q] *
m_deltaT) - 1.0);
737 instance.
Eh[m][q] = -1./instance.
z[q] +
747 for(
unsigned int m=0; m<=
m_order; ++m )
753 for(
unsigned int i=0; i<=
m_order; ++i )
755 instance.
AtEh[m][q] +=
803 for(
unsigned int i=0; i<
m_nvars; ++i )
805 for(
unsigned int j=0; j<
m_npoints; ++j )
841 for(
unsigned int m=0; m<
m_order; ++m )
845 for(
unsigned int i=0; i<
m_nvars; ++i )
847 for(
unsigned int j=0; j<
m_npoints; ++j )
862 const unsigned int tauml,
870 pow(instance.
z[q], -
m_alpha) * instance.
w[q];
873 for(
unsigned int i=0; i<
m_nvars; ++i )
875 for(
unsigned int j=0; j<
m_npoints; ++j )
884 if(
m_uInt[i][j].real() < 1e8 )
914 for(
unsigned int m=0; m<=order; ++m )
918 instance.
AtEh[m][q] = 0;
920 for(
unsigned int i=0; i<=order; ++i )
922 instance.
AtEh[m][q] +=
923 instance.
As[order+1][m][i] * instance.
Eh[i][q];
934 for(
unsigned int m=0; m<=order; ++m )
938 for(
unsigned int i=0; i<
m_nvars; ++i )
940 for(
unsigned int j=0; j<
m_npoints; ++j )
946 y[i][j][q] *= instance.
E[q];
949 y[i][j][q] +=
m_F[i][j] * instance.
AtEh[m][q];
989 for(
unsigned int i=0; i<
m_nvars; ++i )
991 for(
unsigned int j=0; j<
m_npoints; ++j )
1018 for(
unsigned int i=0; i<
m_nvars; ++i )
1020 for(
unsigned int j=0; j<
m_npoints; ++j )
1037 instance.
fsandbox_ind = std::pair<int,int>(timeStep, timeStep);
1047 os <<
"Time Integration Scheme: " <<
GetFullName() << std::endl
1048 <<
" Alpha " <<
m_alpha << std::endl
1049 <<
" Base " <<
m_base << std::endl
1050 <<
" Number of instances " <<
m_Lmax << std::endl
1051 <<
" Number of quadature points " <<
m_nQuadPts << std::endl
1052 <<
" Talbot Parameter: sigma " <<
m_sigma << std::endl
1053 <<
" Talbot Parameter: mu0 " <<
m_mu0 << std::endl
1054 <<
" Talbot Parameter: nu " <<
m_nu << std::endl;
1059 os <<
"Time Integration Scheme: " <<
GetFullName() << std::endl
1060 <<
" Alpha " <<
m_alpha << std::endl
1061 <<
" Base " <<
m_base << std::endl
1062 <<
" Number of instances " <<
m_Lmax << std::endl
1063 <<
" Number of quadature points " <<
m_nQuadPts << std::endl
1064 <<
" Talbot Parameter: sigma " <<
m_sigma << std::endl
1065 <<
" Talbot Parameter: mu0 " <<
m_mu0 << std::endl
1066 <<
" Talbot Parameter: nu " <<
m_nu << std::endl;
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Class for fractional-in-time integration.
unsigned int modIncrement(const unsigned int counter, const unsigned int base) const
Method that increments the counter then performs mod calculation.
virtual LUE void print(std::ostream &os) const
Worker method to print details on the integration scheme.
void updateStage(const unsigned int timeStep, Instance &instance)
Method to rearrange of staging/stashing for current time.
virtual LUE void printFull(std::ostream &os) const
void integralClassInitialize(const unsigned int index, Instance &instance) const
Method to initialize the integral class.
unsigned int computeQML(const unsigned int base, const unsigned int m)
Method to compute the demarcation integers q_{m, ell}.
Array< OneD, int > m_taus
unsigned int m_maxTimeSteps
unsigned int computeL(const unsigned int base, const unsigned int m) const
Method to compute the smallest integer L such that base < 2.
void timeAdvance(const unsigned int timeStep, const TimeIntegrationSchemeOperators &op, Instance &instance, ComplexTripleArray &y)
Method to get the solution to y' = z*y + f(u), using an exponential integrator with implicit order (m...
ComplexSingleArray m_expFactor
virtual LUE void InitializeScheme(const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time, const TimeIntegrationSchemeOperators &op)
Worker method to initialize the integration scheme.
ComplexDoubleArray m_uInt
virtual LUE ConstDoubleArray & TimeIntegrate(const int timestep, const NekDouble delta_t, const TimeIntegrationSchemeOperators &op)
Worker method that performs the time integration.
unsigned int computeTaus(const unsigned int base, const unsigned int m)
Method to compute the demarcation interval marker tau_{m, ell}.
void talbotQuadrature(const unsigned int nQuadPts, const NekDouble mu, const NekDouble nu, const NekDouble sigma, ComplexSingleArray &lamb, ComplexSingleArray &w) const
Method to compute the quadrature rule over Tablot contour.
void advanceSandbox(const unsigned int timeStep, const TimeIntegrationSchemeOperators &op, Instance &instance)
Method to update sandboxes to the current time.
Array< OneD, Instance > m_integral_classes
FractionalInTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
Constructor.
void finalIncrement(const unsigned int timeStep, const TimeIntegrationSchemeOperators &op)
Method to approximate the integral.
void integralContribution(const unsigned int timeStep, const unsigned int tauml, const Instance &instance)
Method to get the integral contribution over [taus(i+1) taus(i)]. Stored in m_uInt.
std::vector< NekDouble > m_freeParams
Base class for time integration schemes.
virtual LUE std::string GetFullName() const
Binds a set of functions for use by time integration schemes.
void DoOdeRhs(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
AT< AT< NekDouble > > DoubleArray
AT< AT< std::complex< NekDouble > > > ComplexDoubleArray
AT< NekDouble > SingleArray
AT< std::complex< NekDouble > > ComplexSingleArray
AT< AT< AT< NekDouble > > > TripleArray
std::shared_ptr< FractionalInTimeIntegrationScheme > FractionalInTimeIntegrationSchemeSharedPtr
AT< AT< AT< std::complex< NekDouble > > > > ComplexTripleArray
std::ostream & operator<<(std::ostream &os, const BasisKey &rhs)
The above copyright notice and this permission notice shall be included.
scalarT< T > log(scalarT< T > in)
ComplexTripleArray fstash_y
std::pair< int, int > fsandbox_ind
ComplexTripleArray csandbox_y
ComplexTripleArray cstash_y
std::pair< int, int > fstash_ind
std::pair< int, int > cstash_ind
ComplexTripleArray stage_y
std::pair< int, int > csandbox_ind
int fsandbox_stashincrement
ComplexTripleArray fsandbox_y
std::pair< int, int > stage_ind