42template<
class real_type>
43void shift(
bool& negative, real_type & x,
dg::bc bc, real_type x0, real_type x1)
48 real_type N0 = floor((x-x0)/(x1-x0));
49 x =
x == x1 ? x0 :
x - N0*(x1-x0);
52 while( (x<x0) || (x>x1) )
76template<
class real_type>
77std::vector<real_type> legendre( real_type xn,
unsigned n)
79 assert( xn <= 1. && xn >= -1.);
80 std::vector<real_type> px(n);
83 for(
unsigned u=0; u<
n; u++)
84 px[u] = (u%2 == 0) ? +1. : -1.;
88 for(
unsigned i=0; i<
n; i++)
97 for(
unsigned i=1; i<
n-1; i++)
98 px[i+1] = ((real_type)(2*i+1)*xn*px[i]-(real_type)i*px[i-1])/(real_type)(i+1);
105template<
class real_type>
106std::vector<real_type> lagrange( real_type x,
const std::vector<real_type>& xi)
108 unsigned n = xi.size();
109 std::vector<real_type> l( n , 1.);
110 for(
unsigned i=0; i<
n; i++)
111 for(
unsigned k=0; k<
n; k++)
114 l[i] *= (
x-xi[k])/(xi[i]-xi[k]);
119template<
class real_type>
120void choose_1d_abscissas( real_type X,
121 unsigned points_per_line,
double lx,
122 const thrust::host_vector<real_type>& abs,
dg::bc bcx,
123 thrust::host_vector<int>& cols,
124 thrust::host_vector<real_type>& px
133 auto it = std::lower_bound( abs.begin(), abs.end(), X);
136 if( fabs( X - *it) < 1e-13)
137 idxX = it - abs.begin();
138 if( it != abs.begin() and fabs( X - *(it-1)) < 1e-13)
139 idxX = (it - abs.begin())-1;
142 cols.assign(1, idxX );
147 std::vector<real_type> xs( points_per_line, 0);
148 cols.resize( points_per_line, 0);
149 switch( points_per_line)
152 if( it == abs.begin())
154 else if( it == abs.end())
155 cols[0] = it - abs.begin() - 1;
158 if ( fabs(X - *it) < fabs( X - *(it-1)))
159 cols[0] = it - abs.begin();
161 cols[0] = it - abs.begin() -1;
164 case 2:
if( it == abs.begin())
169 xs[1] = *(abs.end() -1)-
lx;;
170 cols[0] = 0, cols[1] = abs.end()-abs.begin()-1;
181 else if( it == abs.end())
185 xs[0] = *(abs.begin())+
lx;
187 cols[0] = 0, cols[1] = it-abs.begin()-1;
195 cols[0] = it-abs.begin()-1;
202 cols[0] = it - abs.begin() - 1;
206 case 4:
if( it <= abs.begin() +1)
210 xs[0] = *abs.begin(), cols[0] = 0;
211 xs[1] = *(abs.begin()+1), cols[1] = 1;
212 xs[2] = it == abs.begin() ? *(abs.end() -2) -
lx: *(abs.begin()+2);
213 cols[2] = it == abs.begin() ? abs.end()-abs.begin() -2 : 2;
214 xs[3] = *(abs.end() -1) -
lx;
215 cols[3] = abs.end()-abs.begin() -1;
220 xs[0] = *it, xs[1] = *(it+1);
221 xs[2] = *(it+2), xs[3] = *(it+3);
222 cols[0] = 0, cols[1] = 1;
223 cols[2] = 2, cols[3] = 3;
226 else if( it >= abs.end() -1)
230 xs[0] = *abs.begin()+
lx, cols[0] = 0;
231 xs[1] = it == abs.end() ? *(abs.begin()+1) +
lx : *(abs.end() -3) ;
232 cols[1] = it == abs.end() ? 1 : abs.end()-abs.begin()-3 ;
233 xs[2] = *(abs.end() - 2), cols[2] = abs.end()-abs.begin()-2;
234 xs[3] = *(abs.end() - 1), cols[3] = abs.end()-abs.begin()-1;
239 xs[0] = *(it-4), xs[1] = *(it-3);
240 xs[2] = *(it-2), xs[3] = *(it-1);
241 cols[0] = it - abs.begin() - 4;
249 xs[0] = *(it-2), xs[1] = *(it-1);
250 xs[2] = *(it ), xs[3] = *(it+1);
251 cols[0] = it - abs.begin() - 2;
258 px = detail::lagrange( X, xs);
261template<
class real_type>
262void interpolation_row(
dg::space sp, real_type X,
263 const RealGrid1d<real_type>& g,
dg::bc bcx,
264 thrust::host_vector<int>& cols,
265 thrust::host_vector<real_type>& vals)
267 bool negative =
false;
268 detail::shift( negative, X, bcx, g.x0(), g.x1());
271 real_type xnn = (X-g.x0())/g.h();
272 unsigned nn = (unsigned)floor(xnn);
274 real_type xn = 2.*xnn - (real_type)(2*nn+1);
283 for(
unsigned k=0; k<g.nx(); k++)
287 if( fabs( xn - gauss_nodesx[k]) < 1e-13)
288 idxX = nn*g.nx() + k;
293 std::vector<real_type> px = detail::legendre( xn, g.n());
297 std::vector<real_type> pxF(px.size(), 0);
298 std::vector<real_type>
forward =
300 for(
unsigned l=0; l<g.n(); l++)
301 for(
unsigned k=0; k<g.n(); k++)
302 pxF[l]+= px[k]*forward[k*g.n() + l];
305 for (
unsigned l=0; l<g.n(); l++)
307 cols.push_back( nn*g.n() + l);
308 vals.push_back( negative ? -px[l] : px[l]);
313 cols.push_back( idxX);
314 vals.push_back( negative ? -1. : 1.);
320template<
class host_vector,
class real_type>
323 const host_vector& x,
324 const RealGrid1d<real_type>& g,
327 thrust::host_vector<real_type> values;
328 thrust::host_vector<int> row_offsets;
329 thrust::host_vector<int> column_indices;
330 auto ptr =
x.begin();
331 row_offsets.push_back(0);
332 for(
unsigned i=0; i<
x.size(); i++)
334 interpolation_row( sp, *ptr, g, bcx, column_indices, values);
335 row_offsets.push_back( values.size());
338 return {
x.size(), g.size(), row_offsets, column_indices, values};
342template<
class host_vector1,
class host_vector2 >
344 const host_vector1& x,
345 const host_vector2& abs,
352 thrust::host_vector<real_type> values;
353 thrust::host_vector<int> row_offsets;
354 thrust::host_vector<int> column_indices;
355 unsigned points_per_line = 1;
356 if( method ==
"nearest")
358 else if( method ==
"linear")
360 else if( method ==
"cubic")
363 throw std::runtime_error(
"Interpolation method "+method+
" not recognized!\n");
364 if( abs.size() < points_per_line)
365 throw std::runtime_error(
"There must be more points to interpolate\n");
366 auto ptr =
x.begin();
367 row_offsets.push_back(0);
368 thrust::host_vector<int> cols;
369 thrust::host_vector<real_type> px;
370 for(
unsigned i=0; i<
x.size(); i++)
372 row_offsets.push_back(row_offsets[i]);
375 bool negative =
false;
376 detail::shift( negative, X, bcx, x0, x1);
381 detail::choose_1d_abscissas( X,
382 points_per_line, x1-x0, abs, bcx, cols, px);
385 for (
unsigned l=0; l<px.size(); l++)
388 column_indices.push_back( cols[l]);
389 values.push_back(negative ? -px[l] : px[l]);
392 return {
x.size(), abs.size(), row_offsets, column_indices, values};
444template<
class RecursiveHostVector,
class real_type,
size_t Nd>
446 const RecursiveHostVector& x,
448 std::array<dg::bc, Nd> bcx,
449 std::string method =
"dg")
452 std::array<dg::SparseMatrix<int,real_type,thrust::host_vector>,Nd> axes;
453 for(
unsigned u=0; u<Nd; u++)
455 if(
x[u].size() !=
x[0].size())
463 axes[u] = detail::interpolation1d(
x[u], g.
abscissas(u),
bcx[u], g.
p(u), g.
q(u), method);
466 for(
unsigned u=1; u<Nd; u++)
491template<
class host_vector,
class real_type,
typename = std::enable_if_t<dg::is_vector_v<host_vector>>>
493 const host_vector& x,
496 std::string method =
"dg")
501 std::array<dg::bc,1>{
bcx}, method);
525template<
class host_vector,
class real_type>
527 const host_vector& x,
528 const host_vector&
y,
531 std::string method =
"dg")
563template<
class host_vector,
class real_type>
565 const host_vector& x,
566 const host_vector&
y,
567 const host_vector&
z,
570 std::string method =
"dg")
597template<
class real_type,
size_t Nd>
603 for(
unsigned u=0; u<Nd; u++)
605 if( g_new.
p(u) < g_old.
p(u))
606 std::cerr <<
"ERROR: New grid boundary number "<<u<<
" with value p "<<g_new.
p(u)<<
" lies outside old grid "<<g_old.
p(u)<<
" "<<g_old.
p(u)-g_new.
p(u)<<
"\n";
607 assert( g_new.
p(u) >= g_old.
p(u));
608 if( g_new.
q(u) > g_old.
q(u))
609 std::cerr <<
"ERROR: New grid boundary number "<<u<<
" with value q "<<g_new.
q(u)<<
" lies outside old grid "<<g_old.
q(u)<<
" "<<g_old.
q(u)-g_new.
q(u)<<
"\n";
610 assert( g_new.
q(u) <= g_old.
q(u));
612 std::array<dg::SparseMatrix<int,real_type,thrust::host_vector>,Nd> axes;
613 for(
unsigned u=0; u<Nd; u++)
618 g_old.
grid(u), g_old.
bc(u));
622 axes[u] = detail::interpolation1d( g_new.
abscissas(u),
627 for(
unsigned u=1; u<Nd; u++)
655template<
class host_vector,
class real_type>
658 const host_vector& v,
663 assert( v.size() == g.
size());
664 thrust::host_vector<real_type> vals;
665 thrust::host_vector<int> cols;
666 create::detail::interpolation_row( sp,
x, g,
bcx, cols, vals);
669 for(
unsigned j=0; j<vals.size(); j++)
670 value += v[cols[j]]*vals[j];
693template<
class host_vector,
class real_type>
696 const host_vector& v,
697 real_type x, real_type
y,
701 assert( v.size() == g.
size());
702 thrust::host_vector<real_type> valsx;
703 thrust::host_vector<int> colsx;
704 create::detail::interpolation_row( sp,
x, g.
gx(),
bcx, colsx, valsx);
705 thrust::host_vector<real_type> valsy;
706 thrust::host_vector<int> colsy;
707 create::detail::interpolation_row( sp,
y, g.
gy(),
bcy, colsy, valsy);
710 for(
unsigned i=0; i<valsy.size(); i++)
711 for(
unsigned j=0; j<valsx.size(); j++)
712 value += v[colsy[i]*g.
shape(0) + colsx[j]]*valsx[j]*valsy[i];
class intended for the use in throw statements
Definition exceptions.h:83
small class holding a stringstream
Definition exceptions.h:29
Function discretization routines.
#define _ping_
Definition exceptions.h:12
Some utility functions for the dg::evaluate routines.
bc
Switch between boundary conditions.
Definition enums.h:15
space
Space of DG coefficients.
Definition enums.h:164
@ NEU_DIR
Neumann on left, Dirichlet on right boundary.
Definition enums.h:19
@ PER
periodic boundaries
Definition enums.h:16
@ NEU
Neumann on both boundaries.
Definition enums.h:20
@ DIR
homogeneous dirichlet boundaries
Definition enums.h:17
@ DIR_NEU
Dirichlet on left, Neumann on right boundary.
Definition enums.h:18
@ xspace
Configuration space "nodal values".
Definition enums.h:166
@ lspace
DG Polynomial space "modal values".
Definition enums.h:165
@ forward
forward derivative (cell to the right and current cell)
Definition enums.h:98
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition tensor_traits.h:45
real_type interpolate(dg::space sp, const host_vector &v, real_type x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU)
Interpolate a vector on a single point on a 1d Grid.
Definition interpolation.h:656
dg::SparseMatrix< int, real_type, thrust::host_vector > interpolation(const RecursiveHostVector &x, const aRealTopology< real_type, Nd > &g, std::array< dg::bc, Nd > bcx, std::string method="dg")
Create interpolation matrix of a list of points in given grid.
Definition interpolation.h:445
dg::SparseMatrix< int, T, thrust::host_vector > tensorproduct_cols(const dg::SparseMatrix< int, T, thrust::host_vector > &lhs, const dg::SparseMatrix< int, T, thrust::host_vector > &rhs)
Form the tensor (Kronecker) product between two matrices in the column index
Definition xspacelib.h:89
SquareMatrix< T > tensorproduct(const SquareMatrix< T > &op1, const SquareMatrix< T > &op2)
Form the tensor product between two operators.
Definition operator_tensor.h:25
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
static std::vector< real_type > abscissas(unsigned n)
Return Gauss-Legendre nodes on the interval [-1,1].
Definition dlt.h:27
static std::vector< real_type > forward(unsigned n)
Return forward DLT trafo matrix.
Definition dlt.h:195
The simplest implementation of aRealTopology.
Definition grid.h:710
A CSR formatted sparse matrix.
Definition sparsematrix.h:102
A vector view class, usable in dg functions.
Definition view.h:45
An abstract base class for Nd-dimensional dG grids.
Definition grid.h:95
RealGrid< real_type, 1 > gy() const
Equivalent to grid(1)
Definition grid.h:360
real_type q(unsigned u=0) const
Get right boundary point for axis u.
Definition grid.h:253
RealGrid< real_type, 1 > gx() const
Equivalent to grid(0)
Definition grid.h:354
unsigned size() const
The total number of points.
Definition grid.h:532
host_vector abscissas(unsigned u=0) const
Construct grid abscissas of the u axis.
Definition grid.h:128
RealGrid< real_type, 1 > grid(unsigned u) const
Get axis u as a 1d grid.
Definition grid.h:274
real_type p(unsigned u=0) const
Get left boundary point for axis u.
Definition grid.h:250
dg::bc bc(unsigned u=0) const
Get boundary condition for axis u.
Definition grid.h:268
unsigned shape(unsigned u=0) const
the total number of points of an axis
Definition grid.h:114
Useful typedefs of commonly used types.