Discontinuous Galerkin Library
#include "dg/algorithm.h"
fast_interpolation.h
Go to the documentation of this file.
1#pragma once
2
3#include <thrust/host_vector.h>
4#include "dg/backend/memory.h"
6#include "dg/enums.h"
7#include "dg/blas.h"
8#include "grid.h"
9#include "interpolation.h"
10#include "projection.h"
11#ifdef MPI_VERSION
12#include "mpi_grid.h"
13#endif //MPI_VERSION
14
15
16
21namespace dg
22{
23
34template <class MatrixType, class ContainerType>
36{
44 MultiMatrix( int dimension): inter_(dimension), temp_(dimension-1 > 0 ? dimension-1 : 0 ){}
45
46 template<class OtherMatrix, class OtherContainer, class ... Params>
48 unsigned dimsM = src.get_matrices().size();
49 unsigned dimsT = src.get_temp().size();
50 inter_.resize( dimsM);
51 temp_.resize( dimsT);
52 for( unsigned i=0; i<dimsM; i++)
53 inter_[i] = src.get_matrices()[i];
54 for( unsigned i=0; i<dimsT; i++)
55 dg::assign( src.get_temp()[i].data(), temp_[i].data(), std::forward<Params>(ps)...);
56
57 }
58 template<class ...Params>
59 void construct( Params&& ...ps){
60 *this = MultiMatrix( std::forward<Params>(ps)...);
61 }
62
63
64 template<class ContainerType0, class ContainerType1>
65 void symv( const ContainerType0& x, ContainerType1& y) const{ symv( 1., x,0,y);}
66 template<class ContainerType0, class ContainerType1>
67 void symv(real_type alpha, const ContainerType0& x, real_type beta, ContainerType1& y) const
68 {
69 int dims = inter_.size();
70 if( dims == 1)
71 {
72 dg::blas2::symv( alpha, inter_[0], x, beta, y);
73 return;
74 }
75 dg::blas2::symv( inter_[0], x,temp_[0].data());
76 for( int i=1; i<dims-1; i++)
77 dg::blas2::symv( inter_[i], temp_[i-1].data(), temp_[i].data());
78 dg::blas2::symv( alpha, inter_[dims-1], temp_[dims-2].data(), beta, y);
79 }
80 std::vector<Buffer<ContainerType> >& get_temp(){ return temp_;}
81 const std::vector<Buffer<ContainerType> >& get_temp()const{ return temp_;}
82 std::vector<MatrixType>& get_matrices(){ return inter_;}
83 const std::vector<MatrixType>& get_matrices()const{ return inter_;}
84 private:
85 std::vector<MatrixType > inter_;
86 std::vector<Buffer<ContainerType> > temp_;
87};
88
90template <class M, class V>
91struct TensorTraits<MultiMatrix<M, V> >
92{
93 using value_type = get_value_type<V>;
94 using tensor_category = SelfMadeMatrixTag;
95};
96
97namespace detail
98{
99//pay attention that left and right must have correct sizes
100template<class real_type>
101MultiMatrix< dg::HMatrix_t<real_type>, dg::HVec_t<real_type> > multiply( const dg::HMatrix_t<real_type>& left, const dg::HMatrix_t<real_type>& right)
102{
103 MultiMatrix< dg::HMatrix_t<real_type>, dg::HVec_t<real_type> > matrix(2);
104 if( right.total_num_rows() != left.total_num_cols())
105 throw Error( Message(_ping_)<< "left and right cannot be multiplied due to wrong sizes" << left.total_num_cols() << " vs "<<right.total_num_rows());
106 matrix.get_matrices()[0] = right;
107 matrix.get_matrices()[1] = left;
108 thrust::host_vector<real_type> vec( right.total_num_rows());
109 matrix.get_temp()[0] = Buffer<dg::HVec_t<real_type>>(vec);
110 return matrix;
111}
112template<class real_type>
113void set_right_size( dg::HMatrix_t<real_type>& left, const dg::HMatrix_t<real_type>& right)
114{
115 left.set_right_size(right.num_rows*right.n*right.right_size);
116}
117#ifdef MPI_VERSION
118// MHMatrix must have non-null communicator
119template<class real_type>
120MultiMatrix< dg::MHMatrix_t<real_type>, dg::MHVec_t<real_type> > multiply( const dg::MHMatrix_t<real_type>& left, const dg::MHMatrix_t<real_type>& right)
121{
122 MultiMatrix< dg::MHMatrix_t<real_type>, dg::MHVec_t<real_type> > matrix(2);
123 matrix.get_matrices()[0] = right;
124 matrix.get_matrices()[1] = left;
125 thrust::host_vector<real_type> vec( right.inner_matrix().total_num_rows());
126 matrix.get_temp()[0] = Buffer<dg::MHVec_t<real_type>>({vec, left.collective().communicator()});
127 return matrix;
128}
129template<class real_type>
130void set_right_size( dg::MHMatrix_t<real_type>& left, const dg::MHMatrix_t<real_type>& right)
131{
132 const HMatrix_t<real_type>& in = right.inner_matrix();
133 unsigned right_size = in.num_rows*in.n*in.right_size;
134 left.inner_matrix().set_right_size(right_size);
135 left.outer_matrix().right_size = right_size;
136}
137#endif
138} //namespace detail
139
141
142namespace create
143{
151
169template<class real_type>
170dg::HMatrix_t<real_type> fast_interpolation( const RealGrid1d<real_type>& t, unsigned multiplyn, unsigned multiplyNx)
171{
172 unsigned n=t.n();
173 dg::RealGrid1d<real_type> g_old( -1., 1., n, 1);
174 dg::RealGrid1d<real_type> g_new( -1., 1., n*multiplyn, multiplyNx);
175 cusp::coo_matrix<int, real_type, cusp::host_memory> interpolX = dg::create::interpolation( g_new, g_old);
176 EllSparseBlockMat<real_type> iX( multiplyn*multiplyNx*t.N(), t.N(), 1, multiplyNx*multiplyn, t.n());
177 for( unsigned k=0; k<multiplyNx*multiplyn; k++)
178 for( unsigned i=0; i<n; i++)
179 for( unsigned j=0; j<n; j++)
180 iX.data[(k*n+i)*n+j] = interpolX.values[(k*n+i)*n+j];
181 for( unsigned i=0; i<multiplyNx*multiplyn*t.N(); i++)
182 {
183 iX.cols_idx[i] = i/(multiplyNx*multiplyn);
184 iX.data_idx[i] = i%(multiplyNx*multiplyn);
185 }
186 return iX;
187}
188
206template<class real_type>
207dg::HMatrix_t<real_type> fast_projection( const RealGrid1d<real_type>& t, unsigned dividen, unsigned divideNx)
208{
209 if( t.N()%divideNx != 0) throw Error( Message(_ping_)<< "Nx and divideNx don't match: Nx: " << t.N()<< " divideNx "<< (unsigned)divideNx);
210 if( t.n()%dividen != 0) throw Error( Message(_ping_)<< "n and dividen don't match: n: " << t.n()<< " dividen "<< (unsigned)dividen);
211 unsigned n=t.n()/dividen;
212 dg::RealGrid1d<real_type> g_old( -1., 1., n*dividen, divideNx);
213 dg::RealGrid1d<real_type> g_new( -1., 1., n, 1);
214 dg::HVec w1d = dg::create::weights( g_old);
215 dg::HVec v1d = dg::create::inv_weights( g_new);
216 cusp::coo_matrix<int, real_type, cusp::host_memory> projectX, tmp;
217 //Here, we cannot use create::projection because that would remove explicit zeros!!
218 tmp = dg::create::interpolation( g_old, g_new);
219 cusp::transpose( tmp, projectX);
220 EllSparseBlockMat<real_type> pX( t.N()/divideNx, t.N()*dividen, divideNx*dividen, divideNx*dividen, n);
221 for( unsigned k=0; k<divideNx; k++)
222 for( unsigned l=0; l<dividen; l++)
223 for( unsigned i=0; i<n; i++)
224 for( unsigned j=0; j<n; j++)
225 {
226 pX.data[((k*dividen+l)*n+i)*n+j] = projectX.values[((i*divideNx+k)*dividen + l)*n+j];
227 pX.data[((k*dividen+l)*n+i)*n+j] *= v1d[i]*w1d[l*n+j];
228 }
229 for( unsigned i=0; i<t.N()/divideNx; i++)
230 for( unsigned d=0; d<divideNx*dividen; d++)
231 {
232 pX.cols_idx[i*divideNx*dividen+d] = i*divideNx*dividen+d;
233 pX.data_idx[i*divideNx*dividen+d] = d;
234 }
235 return pX;
236}
237
261template<class real_type>
263{
264 EllSparseBlockMat<real_type> A( t.N(), t.N(), 1, 1, t.n());
265 if( opx.size() != t.n())
266 throw Error( Message(_ping_)<< "Operator must have same n as grid!");
267 dg::assign( opx.data(), A.data);
268 for( unsigned i=0; i<t.N(); i++)
269 {
270 A.cols_idx[i] = i;
271 A.data_idx[i] = 0;
272 }
273 return A;
274}
275
278template<class real_type>
279dg::HMatrix_t<real_type> fast_interpolation( enum coo3d direction, const aRealTopology2d<real_type>& t, unsigned multiplyn, unsigned multiplyNx)
280{
281 if( direction == dg::coo3d::x)
282 {
283 auto trafo = dg::create::fast_interpolation( t.gx(), multiplyn,multiplyNx);
284 trafo.set_left_size ( t.ny()*t.Ny());
285 return trafo;
286 }
287 auto trafo = dg::create::fast_interpolation( t.gy(), multiplyn,multiplyNx);
288 trafo.set_right_size ( t.nx()*t.Nx());
289 return trafo;
290}
291
294template<class real_type>
295dg::HMatrix_t<real_type> fast_projection( enum coo3d direction, const aRealTopology2d<real_type>& t, unsigned dividen, unsigned divideNx)
296{
297 if( direction == dg::coo3d::x)
298 {
299 auto trafo = dg::create::fast_projection( t.gx(), dividen,divideNx);
300 trafo.set_left_size ( t.ny()*t.Ny());
301 return trafo;
302 }
303 auto trafo = dg::create::fast_projection( t.gy(), dividen,divideNx);
304 trafo.set_right_size ( t.nx()*t.Nx());
305 return trafo;
306}
307
310template<class real_type>
312{
313 if( direction == dg::coo3d::x)
314 {
315 auto trafo = fast_transform( opx, t.gx());
316 trafo.set_left_size ( t.ny()*t.Ny());
317 return trafo;
318 }
319 auto trafo = fast_transform( opx, t.gy());
320 trafo.set_right_size ( t.nx()*t.Nx());
321 return trafo;
322}
323
326template<class real_type>
327dg::HMatrix_t<real_type> fast_interpolation( enum coo3d direction, const aRealTopology3d<real_type>& t, unsigned multiplyn, unsigned multiplyNx)
328{
329 if( direction == dg::coo3d::x)
330 {
331 auto trafo = fast_interpolation( t.gx(), multiplyn, multiplyNx);
332 trafo.set_left_size ( t.ny()*t.Ny()*t.nz()*t.Nz());
333 return trafo;
334 }
335 if( direction == dg::coo3d::y)
336 {
337 auto trafo = fast_interpolation( t.gy(), multiplyn, multiplyNx);
338 trafo.set_left_size ( t.nz()*t.Nz());
339 trafo.set_right_size ( t.nx()*t.Nx());
340 return trafo;
341 }
342 auto trafo = fast_interpolation( t.gz(), multiplyn, multiplyNx);
343 trafo.set_right_size ( t.nx()*t.Nx()*t.ny()*t.Ny());
344 return trafo;
345}
346
349template<class real_type>
350dg::HMatrix_t<real_type> fast_projection( enum coo3d direction, const aRealTopology3d<real_type>& t, unsigned dividen, unsigned divideNx)
351{
352 if( direction == dg::coo3d::x)
353 {
354 auto trafo = fast_projection( t.gx(), dividen, divideNx);
355 trafo.set_left_size ( t.ny()*t.Ny()*t.nz()*t.Nz());
356 return trafo;
357 }
358 if( direction == dg::coo3d::y)
359 {
360 auto trafo = fast_projection( t.gy(), dividen, divideNx);
361 trafo.set_left_size ( t.nz()*t.Nz());
362 trafo.set_right_size ( t.nx()*t.Nx());
363 return trafo;
364 }
365 auto trafo = fast_projection( t.gz(), dividen, divideNx);
366 trafo.set_right_size ( t.nx()*t.Nx()*t.ny()*t.Ny());
367 return trafo;
368}
369
372template<class real_type>
374{
375 if( direction == dg::coo3d::x)
376 {
377 auto trafo = fast_transform( opx, t.gx());
378 trafo.set_left_size ( t.ny()*t.Ny()*t.nz()*t.Nz());
379 return trafo;
380 }
381 if( direction == dg::coo3d::y)
382 {
383 auto trafo = fast_transform( opx, t.gy());
384 trafo.set_left_size ( t.nz()*t.Nz());
385 trafo.set_right_size ( t.nx()*t.Nx());
386 return trafo;
387 }
388 auto trafo = fast_transform( opx, t.gz());
389 trafo.set_right_size ( t.nx()*t.Nx()*t.ny()*t.Ny());
390 return trafo;
391}
392
393
394#ifdef MPI_VERSION
396namespace detail
397{
398template<class real_type>
399MHMatrix_t<real_type> elevate_no_comm( const HMatrix_t<real_type>& local, MPI_Comm comm)
400{
402}
403
404}//namespace detail
406
409template<class real_type>
410dg::MHMatrix_t<real_type> fast_interpolation( enum coo3d direction, const aRealMPITopology2d<real_type>& t, unsigned multiplyn, unsigned multiplyNx)
411{
412 return detail::elevate_no_comm( dg::create::fast_interpolation( direction, t.local(), multiplyn, multiplyNx), t.communicator());
413}
416template<class real_type>
417dg::MHMatrix_t<real_type> fast_projection( enum coo3d direction, const aRealMPITopology2d<real_type>& t, unsigned dividen, unsigned divideNx)
418{
419 return detail::elevate_no_comm( dg::create::fast_projection( direction, t.local(), dividen, divideNx), t.communicator());
420}
423template<class real_type>
425{
426 return detail::elevate_no_comm( dg::create::fast_transform( direction, opx, t.local()), t.communicator());
427}
428
431template<class real_type>
432dg::MHMatrix_t<real_type> fast_interpolation( enum coo3d direction, const aRealMPITopology3d<real_type>& t, unsigned multiplyn, unsigned multiplyNx)
433{
434 return detail::elevate_no_comm( dg::create::fast_interpolation( direction, t.local(), multiplyn, multiplyNx), t.communicator());
435}
438template<class real_type>
439dg::MHMatrix_t<real_type> fast_projection( enum coo3d direction, const aRealMPITopology3d<real_type>& t, unsigned dividen, unsigned divideNx)
440{
441 return detail::elevate_no_comm( dg::create::fast_projection( direction, t.local(), dividen, divideNx), t.communicator());
442}
445template<class real_type>
447{
448 return detail::elevate_no_comm( dg::create::fast_transform( direction, opx, t.local()), t.communicator());
449}
450#endif //MPI_VERSION
451
454template<class Topology>
455auto fast_interpolation( const Topology& t, unsigned multiplyn, unsigned multiplyNx, unsigned multiplyNy)
456{
457 auto interX = dg::create::fast_interpolation( dg::coo3d::x, t, multiplyn,multiplyNx);
458 auto interY = dg::create::fast_interpolation( dg::coo3d::y, t, multiplyn,multiplyNy);
459 dg::detail::set_right_size( interY, interX);
460 return dg::detail::multiply( interY, interX);
461}
462
465template<class Topology>
466auto fast_projection( const Topology& t, unsigned dividen, unsigned divideNx, unsigned divideNy)
467{
468 auto interX = dg::create::fast_projection( dg::coo3d::x, t, dividen, divideNx);
469 auto interY = dg::create::fast_projection( dg::coo3d::y, t, dividen, divideNy);
470 dg::detail::set_right_size( interY, interX);
471 return dg::detail::multiply( interY, interX);
472}
475template<class Topology>
477{
478 auto interX = dg::create::fast_transform( dg::coo3d::x, opx, t);
479 auto interY = dg::create::fast_transform( dg::coo3d::y, opy, t);
480 return dg::detail::multiply( interY, interX);
481}
483
484}//namespace create
485
496template<class real_type>
497thrust::host_vector<real_type> forward_transform( const thrust::host_vector<real_type>& in, const aRealTopology2d<real_type>& g)
498{
499 thrust::host_vector<real_type> out(in.size(), 0);
500 auto forward = create::fast_transform( g.dltx().forward(),
501 g.dlty().forward(), g);
502 dg::blas2::symv( forward, in, out);
503 return out;
504}
505
506}//namespace dg
class intended for the use in throw statements
Definition: exceptions.h:83
small class holding a stringstream
Definition: exceptions.h:29
unsigned size() const
Size n of the Operator.
Definition: operator.h:113
const std::vector< value_type > & data() const
access underlying data
Definition: operator.h:130
enums
#define _ping_
Definition: exceptions.h:12
base topology classes
void assign(const from_ContainerType &from, ContainerType &to, Params &&... ps)
Generic way to assign the contents of a from_ContainerType object to a ContainerType object optionall...
Definition: blas1.h:665
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
Definition: blas2.h:287
coo3d
3d contra- and covariant coordinates
Definition: enums.h:177
direction
Direction of a discrete derivative.
Definition: enums.h:97
@ y
y direction
@ x
x direction
@ forward
forward derivative (cell to the right and current cell)
Definition: enums.h:98
@ y
y direction
@ x
x direction
MPI_Vector< thrust::host_vector< real_type > > weights(const aRealMPITopology2d< real_type > &g)
Nodal weight coefficients.
Definition: mpi_weights.h:22
MPI_Vector< thrust::host_vector< real_type > > inv_weights(const aRealMPITopology2d< real_type > &g)
inverse nodal weight coefficients
Definition: mpi_weights.h:29
dg::HMatrix_t< real_type > fast_transform(dg::Operator< real_type > opx, const RealGrid1d< real_type > &t)
Create a block-diagonal matrix.
Definition: fast_interpolation.h:262
dg::HMatrix_t< real_type > fast_interpolation(const RealGrid1d< real_type > &t, unsigned multiplyn, unsigned multiplyNx)
Create interpolation matrix for integer multipliers.
Definition: fast_interpolation.h:170
cusp::coo_matrix< int, real_type, cusp::host_memory > interpolation(const thrust::host_vector< real_type > &x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU, std::string method="dg")
Create interpolation matrix.
Definition: interpolation.h:254
dg::HMatrix_t< real_type > fast_projection(const RealGrid1d< real_type > &t, unsigned dividen, unsigned divideNx)
Create projecton matrix for integer dividers.
Definition: fast_interpolation.h:207
thrust::host_vector< real_type > forward_transform(const thrust::host_vector< real_type > &in, const aRealTopology2d< real_type > &g)
Transform a vector from dg::xspace (nodal values) to dg::lspace (modal values)
Definition: fast_interpolation.h:497
void transpose(unsigned nx, unsigned ny, const ContainerType &in, ContainerType &out)
Transpose vector.
Definition: average_dispatch.h:26
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition: tensor_traits.h:38
thrust::host_vector< T > HVec_t
Host Vector.
Definition: typedefs.h:18
thrust::host_vector< double > HVec
Host Vector.
Definition: typedefs.h:19
1D, 2D and 3D interpolation matrix creation functions
MPI Grid objects.
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Creation of projection matrices.
Coo Sparse Block Matrix format.
Definition: sparseblockmat.h:179
Ell Sparse Block Matrix format.
Definition: sparseblockmat.h:46
int total_num_cols() const
total number of columns is num_cols*n*left_size*right_size
Definition: sparseblockmat.h:82
thrust::host_vector< int > data_idx
has the same size as cols_idx and contains indices into the data array, i.e. the block number
Definition: sparseblockmat.h:128
int num_rows
number of block rows, each row contains blocks
Definition: sparseblockmat.h:130
void set_right_size(int new_right_size)
Set right_size = new_right_size; set_default_range();
Definition: sparseblockmat.h:110
thrust::host_vector< value_type > data
The data array is of size n*n*num_different_blocks and contains the blocks. The first block is contai...
Definition: sparseblockmat.h:126
int total_num_rows() const
total number of rows is num_rows*n*left_size*right_size
Definition: sparseblockmat.h:78
thrust::host_vector< int > cols_idx
is of size num_rows*num_blocks_per_line and contains the column indices % n into the vector
Definition: sparseblockmat.h:127
int n
each block has size n*n
Definition: sparseblockmat.h:133
int right_size
size of the right Kronecker delta (is e.g 1 for a x - derivative)
Definition: sparseblockmat.h:135
mpi Vector class
Definition: mpi_vector.h:32
Struct that applies given matrices one after the other.
Definition: fast_interpolation.h:36
MultiMatrix(const MultiMatrix< OtherMatrix, OtherContainer > &src, Params &&... ps)
Definition: fast_interpolation.h:47
void symv(real_type alpha, const ContainerType0 &x, real_type beta, ContainerType1 &y) const
Definition: fast_interpolation.h:67
std::vector< Buffer< ContainerType > > & get_temp()
Definition: fast_interpolation.h:80
void construct(Params &&...ps)
Definition: fast_interpolation.h:59
std::vector< MatrixType > & get_matrices()
Definition: fast_interpolation.h:82
get_value_type< ContainerType > real_type
Definition: fast_interpolation.h:37
const std::vector< Buffer< ContainerType > > & get_temp() const
Definition: fast_interpolation.h:81
const std::vector< MatrixType > & get_matrices() const
Definition: fast_interpolation.h:83
void symv(const ContainerType0 &x, ContainerType1 &y) const
Definition: fast_interpolation.h:65
MultiMatrix()
Definition: fast_interpolation.h:38
MultiMatrix(int dimension)
reserve space for dimension matrices and dimension-1 ContainerTypes
Definition: fast_interpolation.h:44
Communicator for asynchronous nearest neighbor communication.
Definition: mpi_vector.h:181
1D grid
Definition: grid.h:80
unsigned n() const
number of polynomial coefficients
Definition: grid.h:141
unsigned N() const
number of cells
Definition: grid.h:135
Distributed memory matrix class, asynchronous communication.
Definition: mpi_matrix.h:65
const LocalMatrixInner & inner_matrix() const
Read access to the inner matrix.
Definition: mpi_matrix.h:96
const LocalMatrixOuter & outer_matrix() const
Read access to the outer matrix.
Definition: mpi_matrix.h:100
const Collective & collective() const
Read access to the communication object.
Definition: mpi_matrix.h:104
NotATensorTag tensor_category
Definition: tensor_traits.h:33
void value_type
Definition: tensor_traits.h:32
2D MPI abstract grid class
Definition: mpi_grid.h:45
const RealGrid2d< real_type > & local() const
Return a non-MPI grid local for the calling process.
Definition: mpi_grid.h:252
MPI_Comm communicator() const
Return mpi cartesian communicator that is used in this grid.
Definition: mpi_grid.h:138
3D MPI Grid class
Definition: mpi_grid.h:329
MPI_Comm communicator() const
Return mpi cartesian communicator that is used in this grid.
Definition: mpi_grid.h:459
const RealGrid3d< real_type > & local() const
Return a non-MPI grid local for the calling process.
Definition: mpi_grid.h:560
An abstract base class for two-dimensional grids.
Definition: grid.h:277
const DLT< real_type > & dltx() const
discrete legendre trafo
Definition: grid.h:372
const DLT< real_type > & dlty() const
discrete legendre transformation in y
Definition: grid.h:374
const RealGrid1d< real_type > & gy() const
The y-axis grid.
Definition: grid.h:379
unsigned ny() const
number of polynomial coefficients in y
Definition: grid.h:340
unsigned Nx() const
number of cells in x
Definition: grid.h:346
const RealGrid1d< real_type > & gx() const
The x-axis grid.
Definition: grid.h:377
unsigned nx() const
number of polynomial coefficients in x
Definition: grid.h:338
unsigned Ny() const
number of cells in y
Definition: grid.h:352
An abstract base class for three-dimensional grids.
Definition: grid.h:523
const RealGrid1d< real_type > & gz() const
The z-axis grid.
Definition: grid.h:664
unsigned nz() const
number of polynomial coefficients in z
Definition: grid.h:616
unsigned Nx() const
number of points in x
Definition: grid.h:622
unsigned ny() const
number of polynomial coefficients in y
Definition: grid.h:614
const RealGrid1d< real_type > & gx() const
The x-axis grid.
Definition: grid.h:660
const RealGrid1d< real_type > & gy() const
The y-axis grid.
Definition: grid.h:662
unsigned Ny() const
number of points in y
Definition: grid.h:628
unsigned Nz() const
number of points in z
Definition: grid.h:634
unsigned nx() const
number of polynomial coefficients in x
Definition: grid.h:612
Useful typedefs of commonly used types.