Extension: Geometries
#include "dg/geometries/geometries.h"
curvilinear.h
Go to the documentation of this file.
1#pragma once
2
3#include "dg/algorithm.h"
4#include "generator.h"
5
6namespace dg
7{
8namespace geo
9{
10
62
65{
66 unsigned n;
67 unsigned N;
69};
70
71
73template<class real_type>
75namespace detail
76{
77template<class host_vector>
78dg::SparseTensor<host_vector> square( const dg::SparseTensor<host_vector >& jac, const host_vector& R, bool orthogonal)
79{
80 std::vector<host_vector> values( 5, R);
81 {
82 dg::blas1::scal( values[0], 0); //0
83 dg::blas1::pointwiseDot( 1., jac.value(0,0), jac.value(0,0), 1., jac.value(0,1), jac.value(0,1), 0., values[1]); //xx
84 dg::blas1::pointwiseDot( 1., jac.value(1,0), jac.value(1,0), 1., jac.value(1,1), jac.value(1,1), 0., values[2]); //yy
85 dg::blas1::pointwiseDot( values[3], values[3], values[3]);
86 dg::blas1::pointwiseDivide( 1., values[3], values[3]); //pp == 1/R^2
87
88 dg::blas1::pointwiseDot( 1., jac.value(0,0), jac.value(1,0), 1., jac.value(0,1), jac.value(1,1), 0., values[4]); //xy
89 }
90 SparseTensor<host_vector> metric(values[0]); //unit tensor
91 metric.values().pop_back(); //remove the one
92 metric.idx(0,0) = 1; metric.values().push_back( values[1]);
93 metric.idx(1,1) = 2; metric.values().push_back( values[2]);
94 metric.idx(2,2) = 3; metric.values().push_back( values[3]);
95 if( !orthogonal)
96 {
97 metric.idx(1,0) = metric.idx(0,1) = 4;
98 metric.values().push_back( values[4]);
99 }
100 return metric;
101}
102}//namespace detail
104
105//when we make a 3d grid with eta and phi swapped the metric structure and the transformation changes
106//In practise it can only be orthogonal due to the projection tensor in the elliptic operator
107
111template<class real_type>
113{
119 dg::aRealGeometry2d<real_type>( {0, generator.width(), tx.n, tx.N, tx.b}, {0., generator.height(), ty.n, ty.N, ty.b}), m_handle(generator)
120 {
121 construct( tx.n, tx.N, ty.n, ty.N);
122 }
123
129
131 const aRealGenerator2d<real_type>& generator() const{return *m_handle;}
132 virtual RealCurvilinearGrid2d* clone()const override final{return new RealCurvilinearGrid2d(*this);}
133 private:
134 virtual void do_set(unsigned nx, unsigned Nx, unsigned ny, unsigned Ny) override final
135 {
137 construct( nx, Nx, ny, Ny);
138 }
139 void construct( unsigned nx, unsigned Nx, unsigned ny, unsigned Ny);
140 virtual SparseTensor<thrust::host_vector<real_type> > do_compute_jacobian( ) const override final{
141 return m_jac;
142 }
143 virtual SparseTensor<thrust::host_vector<real_type>> do_compute_metric( ) const override final{
144 return m_metric;
145 }
146 virtual std::vector<thrust::host_vector<real_type>> do_compute_map()const override final{return m_map;}
148 std::vector<thrust::host_vector<real_type>> m_map;
150};
151
152
158template<class real_type>
160{
162
166
169 dg::aRealProductGeometry3d<real_type>( {0, generator.width(), tx.n, tx.N, tx.b}, {0., generator.height(), ty.n, ty.N, ty.b},gz), m_handle(generator)
170 {
171 m_map.resize(3);
172 constructPerp( this->nx(), this->Nx(), this->ny(), this->Ny());
173 constructParallel(this->nz(), this->Nz());
174 }
175
176
178 const aRealGenerator2d<real_type> & generator() const{return *m_handle;}
179 virtual RealCurvilinearProductGrid3d* clone()const override final{return new RealCurvilinearProductGrid3d(*this);}
180 private:
181 virtual RealCurvilinearGrid2d<real_type>* do_perp_grid() const override final;
182 virtual void do_set( unsigned nx, unsigned Nx, unsigned ny, unsigned Ny,unsigned nz,unsigned Nz) override final{
184 if( !( nx == this->nx() && Nx == this->Nx() && ny == this->ny() && Ny == this->Ny() ) )
185 constructPerp( nx, Nx, ny,Ny);
186 constructParallel(nz,Nz);
187 }
188 //construct phi and lift rest to 3d
189 void constructParallel(unsigned nz,unsigned Nz)
190 {
191 m_map[2]=dg::evaluate(dg::cooZ3d, *this);
192 unsigned size = this->size();
193 unsigned size2d = this->nx()*this->ny()*this->Nx()*this->Ny();
194 //resize for 3d values
195 for( unsigned r=0; r<6;r++)
196 m_jac.values()[r].resize(size);
197 m_map[0].resize(size);
198 m_map[1].resize(size);
199 //lift to 3D grid
200 for( unsigned k=1; k<nz*Nz; k++)
201 for( unsigned i=0; i<size2d; i++)
202 {
203 for(unsigned r=0; r<6; r++)
204 m_jac.values()[r][k*size2d+i] = m_jac.values()[r][(k-1)*size2d+i];
205 m_map[0][k*size2d+i] = m_map[0][(k-1)*size2d+i];
206 m_map[1][k*size2d+i] = m_map[1][(k-1)*size2d+i];
207 }
208 }
209 //construct 2d plane
210 void constructPerp( unsigned nx, unsigned Nx, unsigned ny, unsigned Ny)
211 {
212 dg::Grid1d gX1d( this->x0(), this->x1(), nx, Nx);
213 dg::Grid1d gY1d( this->y0(), this->y1(), ny, Ny);
214 thrust::host_vector<real_type> x_vec = dg::evaluate( dg::cooX1d, gX1d);
215 thrust::host_vector<real_type> y_vec = dg::evaluate( dg::cooX1d, gY1d);
216 m_jac = SparseTensor< thrust::host_vector<real_type>>( x_vec);//unit tensor
217 m_jac.values().resize( 6);
218 m_handle->generate( x_vec, y_vec, m_map[0], m_map[1], m_jac.values()[2], m_jac.values()[3], m_jac.values()[4], m_jac.values()[5]);
219 m_jac.idx(0,0) = 2, m_jac.idx(0,1) = 3, m_jac.idx(1,0)=4, m_jac.idx(1,1) = 5;
220 }
221 virtual SparseTensor<thrust::host_vector<real_type> > do_compute_jacobian( ) const override final{
222 return m_jac;
223 }
224 virtual SparseTensor<thrust::host_vector<real_type> > do_compute_metric( ) const override final
225 {
226 return detail::square( m_jac, m_map[0], m_handle->isOrthogonal());
227 }
228 virtual std::vector<thrust::host_vector<real_type> > do_compute_map()const override final{return m_map;}
229 std::vector<thrust::host_vector<real_type> > m_map;
230 SparseTensor<thrust::host_vector<real_type> > m_jac;
232};
233
236#ifndef MPI_VERSION
237namespace x{
240}
241#endif
242
245template<class real_type>
247 dg::aRealGeometry2d<real_type>( g.gx(), g.gy() ), m_handle(g.generator())
248{
249 g.set( this->nx(), this->Nx(), this->ny(), this->Ny(), 1, 1); //shouldn't trigger 2d grid generator
250 m_map=g.map();
251 m_jac=g.jacobian();
252 m_metric=g.metric();
253 // we rely on the fact that the 3d grid uses square to compute its metric
254 // so the (2,2) entry is value 3 that we need to set to 1 (for the
255 // create::volume function to work properly)
256 dg::blas1::copy( 1., m_metric.values()[3]);
257 m_map.pop_back();
258}
259template<class real_type>
260void RealCurvilinearGrid2d<real_type>::construct( unsigned nx, unsigned Nx, unsigned ny, unsigned Ny)
261{
262 RealCurvilinearProductGrid3d<real_type> g( *m_handle, {nx,Nx,this->bcx()}, {ny,Ny,this->bcy()}, {0., 2.*M_PI, 1,1});
263 *this = RealCurvilinearGrid2d<real_type>(g);
264}
265template<class real_type>
266typename RealCurvilinearProductGrid3d<real_type>::perpendicular_grid* RealCurvilinearProductGrid3d<real_type>::do_perp_grid() const { return new typename RealCurvilinearProductGrid3d<real_type>::perpendicular_grid(*this);}
268
269}//namespace geo
270}//namespace dg
#define M_PI
static DG_DEVICE double cooX1d(double x)
static DG_DEVICE double cooZ3d(double x, double y, double z)
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
void scal(ContainerType &x, get_value_type< ContainerType > alpha)
void pointwiseDivide(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
void pointwiseDot(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
thrust::host_vector< real_type > evaluate(UnaryOp f, const RealGrid1d< real_type > &g)
@ square
closed flux surfaces centered around an O-point and bordered by a square with four X-points in the co...
CurvilinearGrid2d CurvilinearGrid2d
Definition: curvilinear.h:238
CurvilinearProductGrid3d CurvilinearProductGrid3d
Definition: curvilinear.h:239
int idx(unsigned i, unsigned j) const
std::vector< container > & values()
const container & value(size_t i, size_t j) const
SparseTensor< thrust::host_vector< real_type > > jacobian() const
SparseTensor< thrust::host_vector< real_type > > metric() const
std::vector< thrust::host_vector< real_type > > map() const
unsigned n() const
unsigned ny() const
unsigned Nx() const
virtual void do_set(unsigned new_nx, unsigned new_Nx, unsigned new_ny, unsigned new_Ny)=0
unsigned nx() const
unsigned Ny() const
real_type y0() const
unsigned size() const
const RealGrid1d< real_type > & gz() const
unsigned nz() const
unsigned Nx() const
unsigned ny() const
real_type x0() const
real_type y1() const
virtual void do_set(unsigned new_nx, unsigned new_Nx, unsigned new_ny, unsigned new_Ny, unsigned new_nz, unsigned new_Nz)=0
unsigned n() const
void set(unsigned new_n, unsigned new_Nx, unsigned new_Ny, unsigned new_Nz)
real_type x1() const
unsigned Ny() const
unsigned Nz() const
unsigned nx() const
A two-dimensional grid based on curvilinear coordinates.
Definition: curvilinear.h:113
RealCurvilinearGrid2d(const aRealGenerator2d< real_type > &generator, unsigned n, unsigned Nx, unsigned Ny, dg::bc bcx=dg::DIR, bc bcy=dg::PER)
Construct a 2D grid.
Definition: curvilinear.h:115
const aRealGenerator2d< real_type > & generator() const
read access to the generator
Definition: curvilinear.h:131
RealCurvilinearGrid2d(const aRealGenerator2d< real_type > &generator, Topology1d tx, Topology1d ty)
Construct the computational space as the product of two 1d grids.
Definition: curvilinear.h:118
virtual RealCurvilinearGrid2d * clone() const override final
Definition: curvilinear.h:132
RealCurvilinearGrid2d(RealCurvilinearProductGrid3d< real_type > g)
Explicitly convert 3d product grid to the perpendicular grid.
A 2x1 curvilinear product space grid.
Definition: curvilinear.h:160
const aRealGenerator2d< real_type > & generator() const
read access to the generator
Definition: curvilinear.h:178
RealCurvilinearProductGrid3d(const aRealGenerator2d< real_type > &generator, unsigned n, unsigned Nx, unsigned Ny, unsigned Nz, bc bcx=dg::DIR, bc bcy=dg::PER, bc bcz=dg::PER)
Construct a 3D grid.
Definition: curvilinear.h:164
virtual RealCurvilinearProductGrid3d * clone() const override final
Definition: curvilinear.h:179
RealCurvilinearGrid2d< real_type > perpendicular_grid
Definition: curvilinear.h:161
RealCurvilinearProductGrid3d(const aRealGenerator2d< real_type > &generator, Topology1d tx, Topology1d ty, RealGrid1d< real_type > gz)
Construct the computational space as the product of three 1d grids.
Definition: curvilinear.h:168
Helper class for construction.
Definition: curvilinear.h:65
unsigned n
Definition: curvilinear.h:66
bc b
Definition: curvilinear.h:68
unsigned N
Definition: curvilinear.h:67
The abstract generator base class.
Definition: generator.h:20