Discontinuous Galerkin Library
#include "dg/algorithm.h"
projection.h
Go to the documentation of this file.
1#pragma once
2#include <vector>
3#include <cusp/coo_matrix.h>
4#include <cusp/transpose.h>
5#include "grid.h"
6#include "interpolation.h"
7#include "weights.h"
8#include "fem.h"
9
14namespace dg{
17
27template<class T>
28T gcd( T a, T b)
29{
30 T r2 = std::max(a,b);
31 T r1 = std::min(a,b);
32 while( r1!=0)
33 {
34 r2 = r2%r1;
35 std::swap( r1, r2);
36 }
37 return r2;
38}
39
49template<class T>
50T lcm( T a, T b)
51{
52 T g = gcd( a,b);
53 return a/g*b;
54}
55
56namespace create{
57
65template<class real_type>
66cusp::coo_matrix< int, real_type, cusp::host_memory> diagonal( const thrust::host_vector<real_type>& diagonal)
67{
68 unsigned size = diagonal.size();
69 cusp::coo_matrix<int, real_type, cusp::host_memory> W( size, size, size);
70 for( unsigned i=0; i<size; i++)
71 {
72 W.row_indices[i] = W.column_indices[i] = i;
73 W.values[i] = diagonal[i];
74 }
75 return W;
76}
77
78
103template<class real_type>
104cusp::coo_matrix< int, real_type, cusp::host_memory> projection( const RealGrid1d<real_type>& g_new, const RealGrid1d<real_type>& g_old, std::string method = "dg")
105{
106 if( g_old.N() % g_new.N() != 0) std::cerr << "# ATTENTION: you project between incompatible grids!! old N: "<<g_old.N()<<" new N: "<<g_new.N()<<"\n";
107 if( g_old.n() < g_new.n()) std::cerr << "# ATTENTION: you project between incompatible grids!! old n: "<<g_old.n()<<" new n: "<<g_new.n()<<"\n";
108 //form the adjoint
109 cusp::coo_matrix<int, real_type, cusp::host_memory> Wf =
111 cusp::coo_matrix<int, real_type, cusp::host_memory> Vc =
113 cusp::coo_matrix<int, real_type, cusp::host_memory> temp = interpolation( g_old, g_new, method), A;
114 cusp::transpose( temp, A);
116 cusp::multiply( A, Wf, temp);
117 cusp::multiply( Vc, temp, A);
118 A.sort_by_row_and_column();
119 return A;
120}
121
122
124template<class real_type>
125cusp::coo_matrix< int, real_type, cusp::host_memory> projection( const aRealTopology2d<real_type>& g_new, const aRealTopology2d<real_type>& g_old, std::string method = "dg")
126{
127 cusp::csr_matrix<int, real_type, cusp::host_memory> projectX = projection( g_new.gx(), g_old.gx(), method);
128 cusp::csr_matrix<int, real_type, cusp::host_memory> projectY = projection( g_new.gy(), g_old.gy(), method);
129 return dg::tensorproduct( projectY, projectX);
130}
131
133template<class real_type>
134cusp::coo_matrix< int, real_type, cusp::host_memory> projection( const aRealTopology3d<real_type>& g_new, const aRealTopology3d<real_type>& g_old, std::string method = "dg")
135{
136 cusp::csr_matrix<int, real_type, cusp::host_memory> projectX = projection( g_new.gx(), g_old.gx(), method);
137 cusp::csr_matrix<int, real_type, cusp::host_memory> projectY = projection( g_new.gy(), g_old.gy(), method);
138 cusp::csr_matrix<int, real_type, cusp::host_memory> projectZ = projection( g_new.gz(), g_old.gz(), method);
139 return dg::tensorproduct( projectZ, dg::tensorproduct( projectY, projectX));
140}
141
164template<class real_type>
165cusp::coo_matrix< int, real_type, cusp::host_memory> transformation( const aRealTopology3d<real_type>& g_new, const aRealTopology3d<real_type>& g_old)
166{
167 Grid3d g_lcm( Grid1d( g_new.x0(), g_new.x1(), lcm( g_new.nx(), g_old.nx()), lcm( g_new.Nx(), g_old.Nx())),
168 Grid1d( g_new.y0(), g_new.y1(), lcm( g_new.ny(), g_old.ny()), lcm( g_new.Ny(), g_old.Ny())),
169 Grid1d( g_new.z0(), g_new.z1(), lcm( g_new.nz(), g_old.nz()), lcm( g_new.Nz(), g_old.Nz())));
170 cusp::coo_matrix< int, real_type, cusp::host_memory> Q = create::interpolation( g_lcm, g_old);
171 cusp::coo_matrix< int, real_type, cusp::host_memory> P = create::projection( g_new, g_lcm), Y;
172 cusp::multiply( P, Q, Y);
173 Y.sort_by_row_and_column();
174 return Y;
175}
176
178template<class real_type>
179cusp::coo_matrix< int, real_type, cusp::host_memory> transformation( const aRealTopology2d<real_type>& g_new, const aRealTopology2d<real_type>& g_old)
180{
181 Grid2d g_lcm( Grid1d( g_new.x0(), g_new.x1(), lcm( g_new.nx(), g_old.nx()), lcm( g_new.Nx(), g_old.Nx())),
182 Grid1d( g_new.y0(), g_new.y1(), lcm( g_new.ny(), g_old.ny()), lcm( g_new.Ny(), g_old.Ny())));
183 cusp::coo_matrix< int, real_type, cusp::host_memory> Q = create::interpolation( g_lcm, g_old);
184 cusp::coo_matrix< int, real_type, cusp::host_memory> P = create::projection( g_new, g_lcm), Y;
185 cusp::multiply( P, Q, Y);
186 Y.sort_by_row_and_column();
187 return Y;
188}
190template<class real_type>
191cusp::coo_matrix< int, real_type, cusp::host_memory> transformation( const RealGrid1d<real_type>& g_new, const RealGrid1d<real_type>& g_old)
192{
193 RealGrid1d<real_type> g_lcm(g_new.x0(), g_new.x1(), lcm(g_new.n(), g_old.n()), lcm(g_new.N(), g_old.N()));
194 cusp::coo_matrix< int, real_type, cusp::host_memory> Q = create::interpolation( g_lcm, g_old);
195 cusp::coo_matrix< int, real_type, cusp::host_memory> P = create::projection( g_new, g_lcm), Y;
196 cusp::multiply( P, Q, Y);
197 Y.sort_by_row_and_column();
198 return Y;
199}
203
213template<class real_type>
215{
216 unsigned n=g.n();
217 dg::RealGrid1d<real_type> g_old( -1., 1., n, 1);
218 dg::RealGrid1d<real_type> g_new( -1., 1., 1, n);
219 auto block = dg::create::transformation( g_new, g_old);
220 dg::Operator<real_type> op(n, 0.);
221 for( unsigned i=0; i<block.num_entries; i++)
222 op( block.row_indices[i], block.column_indices[i]) = block.values[i];
223
225}
226
228template<class real_type>
230{
231 auto transformX = backproject( g.gx());
232 auto transformY = backproject( g.gy());
233 return dg::tensorproduct( transformY, transformX);
234}
235
237template<class real_type>
239{
240 auto transformX = backproject( g.gx());
241 auto transformY = backproject( g.gy());
242 auto transformZ = backproject( g.gz());
243 return dg::tensorproduct( transformZ, dg::tensorproduct(transformY, transformX));
244}
245
256template<class real_type>
258{
259 unsigned n=g.n();
260 dg::RealGrid1d<real_type> g_old( -1., 1., n, 1);
261 dg::RealGrid1d<real_type> g_new( -1., 1., 1, n);
262 auto block = dg::create::transformation( g_new, g_old);
263 dg::Operator<real_type> op(n, 0.);
264 for( unsigned i=0; i<block.num_entries; i++)
265 op( block.row_indices[i], block.column_indices[i]) = block.values[i];
266
268}
269
271template<class real_type>
273{
274 //create equidistant backward transformation
275 auto transformX = inv_backproject( g.gx());
276 auto transformY = inv_backproject( g.gy());
277 return dg::tensorproduct( transformY, transformX);
278}
279
281template<class real_type>
283{
284 auto transformX = inv_backproject( g.gx());
285 auto transformY = inv_backproject( g.gy());
286 auto transformZ = inv_backproject( g.gz());
287 return dg::tensorproduct( transformZ, dg::tensorproduct(transformY, transformX));
288}
289
291
292}//namespace create
293}//namespace dg
base topology classes
dg::Operator< T > invert(const dg::Operator< T > &in)
Alias for dg::create::inverse. Compute inverse of square matrix.
Definition: operator.h:695
dg::RealGrid1d< double > Grid1d
Definition: grid.h:887
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
cusp::coo_matrix< int, real_type, cusp::host_memory > diagonal(const thrust::host_vector< real_type > &diagonal)
Create a diagonal matrix.
Definition: projection.h:66
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
cusp::coo_matrix< int, real_type, cusp::host_memory > transformation(const aRealTopology3d< real_type > &g_new, const aRealTopology3d< real_type > &g_old)
Create a transformation matrix between two grids.
Definition: projection.h:165
dg::MIHMatrix_t< real_type > projection(const aRealMPITopology2d< real_type > &g_new, const aRealMPITopology2d< real_type > &g_old, std::string method="dg")
Create a projection between two grids.
Definition: mpi_projection.h:247
Operator< T > tensorproduct(const Operator< T > &op1, const Operator< T > &op2)
Form the tensor product between two operators.
Definition: operator_tensor.h:27
T gcd(T a, T b)
Greatest common divisor.
Definition: projection.h:28
T lcm(T a, T b)
Least common multiple.
Definition: projection.h:50
void transpose(unsigned nx, unsigned ny, const ContainerType &in, ContainerType &out)
Transpose vector.
Definition: average_dispatch.h:26
dg::IHMatrix_t< real_type > backproject(const RealGrid1d< real_type > &g)
Create a matrix that projects values to an equidistant grid.
Definition: projection.h:214
dg::IHMatrix_t< real_type > inv_backproject(const RealGrid1d< real_type > &g)
Create a matrix that transforms values from an equidistant grid back to a dg grid.
Definition: projection.h:257
cusp::csr_matrix< int, real_type, cusp::host_memory > IHMatrix_t
Definition: typedefs.h:37
1D, 2D and 3D interpolation matrix creation functions
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
1D grid
Definition: grid.h:80
unsigned n() const
number of polynomial coefficients
Definition: grid.h:141
real_type x1() const
right boundary
Definition: grid.h:117
unsigned N() const
number of cells
Definition: grid.h:135
real_type x0() const
left boundary
Definition: grid.h:111
The simplest implementation of aRealTopology3d.
Definition: grid.h:844
An abstract base class for two-dimensional grids.
Definition: grid.h:277
real_type x0() const
Left boundary in x.
Definition: grid.h:288
real_type y1() const
Right boundary in y.
Definition: grid.h:306
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
real_type y0() const
left boundary in y
Definition: grid.h:300
unsigned Nx() const
number of cells in x
Definition: grid.h:346
real_type x1() const
Right boundary in x.
Definition: grid.h:294
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
real_type y0() const
left boundary in y
Definition: grid.h:547
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
real_type x0() const
left boundary in x
Definition: grid.h:534
real_type y1() const
right boundary in y
Definition: grid.h:553
const RealGrid1d< real_type > & gy() const
The y-axis grid.
Definition: grid.h:662
real_type z0() const
left boundary in z
Definition: grid.h:560
real_type x1() const
right boundary in x
Definition: grid.h:540
unsigned Ny() const
number of points in y
Definition: grid.h:628
real_type z1() const
right boundary in z
Definition: grid.h:566
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
Creation functions for integration weights and their inverse.