Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
projection.h
Go to the documentation of this file.
1#pragma once
2#include <vector>
3#include <numeric> // lcm and gcd
4#include "grid.h"
5#include "interpolation.h"
6#include "weights.h"
7#include "fem.h"
8
13namespace dg{
14
15namespace create{
18
26template<class real_type>
28{
29 unsigned size = diagonal.size();
30 thrust::host_vector<int> A_row_offsets(size+1), A_column_indices( size);
31 thrust::host_vector<real_type> A_values( size);
32
33 A_row_offsets[0] = 0;
34 for( unsigned i=0; i<size; i++)
35 {
36 A_row_offsets[i+1] = i+1;
37 A_column_indices[i] = i;
38 A_values[i] = diagonal[i];
39 }
40 return { size, size, A_row_offsets, A_column_indices, A_values};
41}
42
43
70template<class real_type, size_t Nd>
72 const aRealTopology<real_type,Nd>& g_new,
73 const aRealTopology<real_type,Nd>& g_old, std::string method = "dg")
74{
75 // These tests cannot pass for MPI
76 //for( unsigned u=0; u<Nd; u++)
77 //{
78 // if( fabs(g_new.h(u) / g_old.h(u) -round(g_new.h(u) / g_old.h(u))) > 1e-13)
79 // throw dg::Error( dg::Message(_ping_)
80 // << "# ATTENTION: you project between incompatible grids!! old h: "
81 // <<g_old.h(u)<<" new h: "<<g_new.h(u)<<"\n");
82 // // Check that boundaries of old grid conincide with cell boundaries of new
83 // real_type fp = (g_old.p(u) - g_new.p(u) ) / g_new.h(u); // must be integer
84 // if( fabs(fp - round( fp)) > 1e-13 and method == "dg")
85 // throw dg::Error( dg::Message(_ping_)
86 // << "# ATTENTION: you project between incompatible grids!! old p: "
87 // <<g_old.p(u)<<" new p: "<<g_new.p(u)<<" fp "<<fp<<"\n");
88 // real_type fq = (g_old.q(u) - g_new.p(u) ) / g_new.h(u); // must be integer
89 // if( fabs(fq - round( fq)) > 1e-13 and method == "dg")
90 // throw dg::Error( dg::Message(_ping_)
91 // << "# ATTENTION: you project between incompatible grids!! old q: "
92 // <<g_old.q(u)<<" new p: "<<g_new.p(u)<<" fq "<<fq<<"\n");
93 // if( g_old.n(u) < g_new.n(u))
94 // throw dg::Error( dg::Message(_ping_)
95 // << "# ATTENTION: you project between incompatible grids!! old n: "
96 // <<g_old.n(u)<<" new n: "<<g_new.n(u)<<"\n");
97 //}
98 //form the adjoint
99 auto w_old = dg::create::weights( g_old);
100 auto v_new = dg::create::inv_weights( g_new);
101 auto project = interpolation( g_old, g_new, method).transpose();
102 for( unsigned row=0; row<project.num_rows(); row++)
103 for ( int jj = project.row_offsets()[row]; jj < project.row_offsets()[row+1]; jj++)
104 {
105 int col = project.column_indices()[jj];
106 // Note that w_old is multiplied before v_new (keeps results backwards reproducible)
107 project.values()[jj] = v_new[row] * ( project.values()[jj]* w_old[col]);
108 }
109 return project;
110}
111
134template<class real_type, size_t Nd>
136 const aRealTopology<real_type,Nd>& g_new,
137 const aRealTopology<real_type,Nd>& g_old)
138{
139 std::array<unsigned, Nd> n_lcm{}, N_lcm{};
140 for( unsigned u=0; u<Nd; u++)
141 {
142 n_lcm [u] = std::lcm( g_new.n(u), g_old.n(u));
143 N_lcm [u] = std::lcm( g_new.N(u), g_old.N(u));
144 }
145 RealGrid<real_type, Nd> g_lcm ( g_new.get_p(), g_new.get_q(), n_lcm, N_lcm, g_new.get_bc());
146 return create::projection( g_new, g_lcm)*create::interpolation( g_lcm, g_old);
147}
148
151namespace detail
152{
153template<class real_type>
154dg::SquareMatrix<real_type> square_backproject( const RealGrid1d<real_type>& g)
155{
156 unsigned n=g.n();
157 dg::RealGrid1d<real_type> g_old( -1., 1., n, 1);
158 dg::RealGrid1d<real_type> g_new( -1., 1., 1, n);
159 auto block = dg::create::transformation( g_new, g_old);
161 for( unsigned i=0; i<block.num_rows(); i++)
162 for( unsigned j=block.row_offsets()[i]; j<(unsigned)block.row_offsets()[i+1]; j++)
163 op( i, block.column_indices()[j]) = block.values()[j];
164 return op;
165}
166}
168
171
183template<class real_type, size_t Nd>
185{
186 std::array<dg::IHMatrix_t<real_type>,Nd> matrix;
187 for( unsigned u=0; u<Nd; u++)
188 {
190 detail::square_backproject( g.grid(u)));
191 }
192 for( unsigned u=1; u<Nd; u++)
194 return matrix[0];
195}
196
206template<class real_type, size_t Nd>
208{
209 std::array<dg::IHMatrix_t<real_type>,Nd> matrix;
210 for( unsigned u=0; u<Nd; u++)
211 {
213 dg::invert( detail::square_backproject( g.grid(u))) );
214 }
215 for( unsigned u=1; u<Nd; u++)
217 return matrix[0];
218}
219
221
222}//namespace create
223}//namespace dg
A square nxn matrix.
Definition operator.h:31
const double matrix
base topology classes
auto inv_weights(const Topology &g)
Inverse nodal weight coefficients.
Definition weights.h:107
auto weights(const Topology &g)
Nodal weight coefficients.
Definition weights.h:62
dg::MIHMatrix_t< typename MPITopology::value_type > projection(const MPITopology &g_new, const MPITopology &g_old, std::string method="dg")
Create a projection between two grids.
Definition mpi_projection.h:288
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, real_type, thrust::host_vector > diagonal(const thrust::host_vector< real_type > &diagonal)
Create a diagonal matrix.
Definition projection.h:27
dg::SparseMatrix< int, real_type, thrust::host_vector > transformation(const aRealTopology< real_type, Nd > &g_new, const aRealTopology< real_type, Nd > &g_old)
Create a transformation matrix between two grids.
Definition projection.h:135
dg::SquareMatrix< T > invert(const dg::SquareMatrix< T > &in)
Compute inverse of square matrix (alias for dg::create::inverse)
Definition operator.h:690
SquareMatrix< T > tensorproduct(const SquareMatrix< T > &op1, const SquareMatrix< T > &op2)
Form the tensor product between two operators.
Definition operator_tensor.h:25
dg::IHMatrix_t< real_type > inv_backproject(const aRealTopology< real_type, Nd > &g)
Create a matrix that transforms values from an equidistant grid back to a dg grid.
Definition projection.h:207
dg::IHMatrix_t< real_type > backproject(const aRealTopology< real_type, Nd > &g)
Create a matrix that projects values to an equidistant grid.
Definition projection.h:184
Interpolation matrix creation functions.
const double n
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
The simplest implementation of aRealTopology.
Definition grid.h:710
A CSR formatted sparse matrix.
Definition sparsematrix.h:102
An abstract base class for Nd-dimensional dG grids.
Definition grid.h:95
std::array< real_type, Nd > get_q() const
Get right boundary point .
Definition grid.h:207
std::array< dg::bc, Nd > get_bc() const
Get boundary condition for all axes.
Definition grid.h:240
unsigned n(unsigned u=0) const
Get number of polynomial coefficients for axis u.
Definition grid.h:262
std::array< real_type, Nd > get_p() const
Get left boundary point .
Definition grid.h:202
RealGrid< real_type, 1 > grid(unsigned u) const
Get axis u as a 1d grid.
Definition grid.h:274
unsigned N(unsigned u=0) const
Get number of cells for axis u.
Definition grid.h:265
Creation functions for integration weights and their inverse.