Commit 3d654e6d authored by incardon's avatar incardon

Added stencil grid + documentation

parent 18e16905
...@@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file. ...@@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
- Raw reader for grid (see ...) - Raw reader for grid (see ...)
- A way to specify names for proeprties and select properties to write - A way to specify names for proeprties and select properties to write
- Ghost put on grid - Ghost put on grid
- getDomainIterator stencil for faster stencil codes iterators
- Agebraic multigrid solvers interface for linear systems
### Fixed ### Fixed
- Installation of PETSC in case with MUMPS try without MUMPS - Installation of PETSC in case with MUMPS try without MUMPS
...@@ -22,9 +24,11 @@ All notable changes to this project will be documented in this file. ...@@ -22,9 +24,11 @@ All notable changes to this project will be documented in this file.
- Bug in VTK writer binary: long int are not supported removing output - Bug in VTK writer binary: long int are not supported removing output
- Bug in FDScheme in the constructor with stencil bigger than one - Bug in FDScheme in the constructor with stencil bigger than one
- Bug Fixed Memory leak in petsc solver - Bug Fixed Memory leak in petsc solver
- Bug Performance bug in the grid iterator
### Changed ### Changed
- CellList types has changed - CellList types has changed (one additional template parameter)
- Gris iterator types has changes (one additional template parameter)
## [0.8.0] 28 February 2016 ## [0.8.0] 28 February 2016
......
...@@ -140,6 +140,9 @@ int main(int argc, char* argv[]) ...@@ -140,6 +140,9 @@ int main(int argc, char* argv[])
double uFactor = deltaT * du/(spacing[x]*spacing[x]); double uFactor = deltaT * du/(spacing[x]*spacing[x]);
double vFactor = deltaT * dv/(spacing[x]*spacing[x]); double vFactor = deltaT * dv/(spacing[x]*spacing[x]);
timer tot_sim;
tot_sim.start();
for (size_t i = 0; i < timeSteps; ++i) for (size_t i = 0; i < timeSteps; ++i)
{ {
if (i % 300 == 0) if (i % 300 == 0)
...@@ -199,6 +202,9 @@ int main(int argc, char* argv[]) ...@@ -199,6 +202,9 @@ int main(int argc, char* argv[])
} }
} }
tot_sim.stop();
std::cout << "Total simulation: " << tot_sim.getwct() << std::endl;
//! \cond [time stepping] \endcond //! \cond [time stepping] \endcond
/*! /*!
......
...@@ -116,19 +116,19 @@ typedef grid_dist_id<3,float,aggregate<float[3]>> grid_type; ...@@ -116,19 +116,19 @@ typedef grid_dist_id<3,float,aggregate<float[3]>> grid_type;
typedef vector_dist<3,float,aggregate<float[3],float[3],float[3],float[3],float[3]>> particles_type; typedef vector_dist<3,float,aggregate<float[3],float[3],float[3],float[3],float[3]>> particles_type;
// radius of the torus // radius of the torus
float ringr1 = 5.0/4.0; float ringr1 = 1.0;
// radius of the core of the torus // radius of the core of the torus
float ringr2 = 0.5; float sigma = 1.0/3.523;
// Reynold number // Reynold number
float tgtre = 10000.0; float tgtre = 7500.0;
// Noise factor for the ring vorticity on z // Noise factor for the ring vorticity on z
float ringnz = 0.00009; float ringnz = 0.01;
// Kinematic viscosity // Kinematic viscosity
float nu = 0.0001535; float nu = 1.0/tgtre;
// Time step // Time step
float dt = 0.006; float dt = 0.025;
// All the properties by index // All the properties by index
constexpr unsigned int vorticity = 0; constexpr unsigned int vorticity = 0;
...@@ -225,13 +225,13 @@ void init_ring(grid_type & gr, const Box<3,float> & domain) ...@@ -225,13 +225,13 @@ void init_ring(grid_type & gr, const Box<3,float> & domain)
for (size_t i = 0 ; i < nk ; i++) for (size_t i = 0 ; i < nk ; i++)
{ {
ak[i] = 0.0/*rand()/RAND_MAX*/; ak[i] = rand()/RAND_MAX;
bk[i] = 0.0/*rand()/RAND_MAX*/; bk[i] = rand()/RAND_MAX;
} }
// We calculate the circuitation gamma // We calculate the circuitation gamma
float gamma = nu * tgtre; float gamma = nu * tgtre;
float rinv2 = 1.0f/(ringr2*ringr2); float rinv2 = 1.0f/(sigma*sigma);
float max_vorticity = gamma*rinv2/M_PI; float max_vorticity = gamma*rinv2/M_PI;
// We go through the grid to initialize the vortex // We go through the grid to initialize the vortex
...@@ -247,27 +247,20 @@ void init_ring(grid_type & gr, const Box<3,float> & domain) ...@@ -247,27 +247,20 @@ void init_ring(grid_type & gr, const Box<3,float> & domain)
float tz = (key.get(z)-2)*gr.spacing(z) + domain.getLow(z); float tz = (key.get(z)-2)*gr.spacing(z) + domain.getLow(z);
float theta1 = atan2((ty-2.5f),(tz-2.5f)); float theta1 = atan2((ty-2.5f),(tz-2.5f));
float noise = 0.0f; float noise = 0.0f;
for (int kk=1 ; kk < nk; kk++) // for (int kk=1 ; kk < nk; kk++)
noise = noise + sin(kk*(theta1+2.0f*M_PI*ak[kk])) + cos(kk*(theta1+2.0f*M_PI*bk[kk])); // noise = noise + sin(kk*(theta1+2.0f*M_PI*ak[kk])) + cos(kk*(theta1+2.0f*M_PI*bk[kk]));
float rad1r = sqrt((ty-2.5f)*(ty-2.5f) + (tz-2.5f)*(tz-2.5f)) - ringr1*(1.0f + ringnz * noise); float rad1r = sqrt((ty-2.5f)*(ty-2.5f) + (tz-2.5f)*(tz-2.5f)) - ringr1*(1.0f + ringnz * noise);
float rad1t = tx - 2.5f; float rad1t = tx - 1.0f;
float rad1sq = rad1r*rad1r + rad1t*rad1t; float rad1sq = rad1r*rad1r + rad1t*rad1t;
float radstr = -exp(-rad1sq*rinv2)*rinv2*gamma/M_PI; float radstr = -exp(-rad1sq*rinv2)*rinv2*gamma/M_PI;
gr.template get<vorticity>(key_d)[x] = 0.0f; gr.template get<vorticity>(key_d)[x] = 0.0f;
gr.template get<vorticity>(key_d)[y] = -radstr * cos(theta1); gr.template get<vorticity>(key_d)[y] = -radstr * cos(theta1);
gr.template get<vorticity>(key_d)[z] = radstr * sin(theta1); gr.template get<vorticity>(key_d)[z] = radstr * sin(theta1);
/* theta1 = atan2((ty-2.5f),(tz-2.5f));
rad1r = sqrt((ty-2.5f)*(ty-2.5f) + (tz-2.5f)*(tz-2.5f)) + ringr1*(1.0f + ringnz * noise);
rad1t = tx - 2.5f;
rad1sq = rad1r*rad1r + rad1t*rad1t;
float rad1sqTILDA = rad1sq*rinv2;
radstr = exp(-rad1sqTILDA)*rinv2*gamma/M_PI;
gr.template get<vorticity>(key_d)[x] = 0.0f;
gr.template get<vorticity>(key_d)[y] = gr.template get<vorticity>(key_d)[y] + radstr * cos(theta1);
gr.template get<vorticity>(key_d)[z] = gr.template get<vorticity>(key_d)[z] - radstr * sin(theta1);*/
++it; ++it;
} }
...@@ -494,8 +487,6 @@ void helmotz_hodge_projection(grid_type & gr, const Box<3,float> & domain) ...@@ -494,8 +487,6 @@ void helmotz_hodge_projection(grid_type & gr, const Box<3,float> & domain)
// Set the maximum number of iterations // Set the maximum number of iterations
solver.setMaxIter(500); solver.setMaxIter(500);
solver.log_monitor();
timer tm_solve; timer tm_solve;
tm_solve.start(); tm_solve.start();
...@@ -704,7 +695,6 @@ void comp_vel(Box<3,float> & domain, grid_type & g_vort,grid_type & g_vel, petsc ...@@ -704,7 +695,6 @@ void comp_vel(Box<3,float> & domain, grid_type & g_vort,grid_type & g_vel, petsc
solver.setSolver(KSPBCGS); solver.setSolver(KSPBCGS);
solver.setAbsTol(0.01); solver.setAbsTol(0.01);
solver.setMaxIter(500); solver.setMaxIter(500);
solver.log_monitor();
// Get the sparse matrix that represent the left-hand-side // Get the sparse matrix that represent the left-hand-side
// of the equation // of the equation
...@@ -1153,7 +1143,7 @@ int main(int argc, char* argv[]) ...@@ -1153,7 +1143,7 @@ int main(int argc, char* argv[])
openfpm_init(&argc,&argv); openfpm_init(&argc,&argv);
// Domain, a rectangle // Domain, a rectangle
Box<3,float> domain({0.0,0.0,0.0},{22.0,5.0,5.0}); Box<3,float> domain({0.0,0.0,0.0},{22.0,5.57,5.57});
// Ghost (Not important in this case but required) // Ghost (Not important in this case but required)
Ghost<3,long int> g(2); Ghost<3,long int> g(2);
...@@ -1239,7 +1229,7 @@ int main(int argc, char* argv[]) ...@@ -1239,7 +1229,7 @@ int main(int argc, char* argv[])
} }
// Time Integration // Time Integration
for ( ; i < 10 ; i++) for ( ; i < 10001 ; i++)
{ {
// do step 4-5-6-7 // do step 4-5-6-7
do_step(particles,g_vort,g_vel,g_dvort,domain,inte,phi_s); do_step(particles,g_vort,g_vel,g_dvort,domain,inte,phi_s);
...@@ -1258,6 +1248,9 @@ int main(int argc, char* argv[]) ...@@ -1258,6 +1248,9 @@ int main(int argc, char* argv[])
inte.template p2m<vorticity,vorticity>(particles,g_vort); inte.template p2m<vorticity,vorticity>(particles,g_vort);
g_vort.template ghost_put<add_,vorticity>(); g_vort.template ghost_put<add_,vorticity>();
// helmotz-hodge projection
helmotz_hodge_projection(g_vort,domain);
remesh(particles,g_vort,domain); remesh(particles,g_vort,domain);
// print the step number // print the step number
......
openfpm_data @ 8ac02bf2
Subproject commit dfaf8538f94caf51229ec40bc51af23ad8bea934 Subproject commit 8ac02bf29a070237ca028a9ecddbd7ed81a4457d
openfpm_io @ bcc455d1
Subproject commit 223f739a00a1d92034e71b1aa821f244c68f4ced Subproject commit bcc455d1dd01285b2f5f78497566720e7d8c0bf5
openfpm_numerics @ 58c0aea7
Subproject commit 43a521cb99e7859af4392e70e0eb6196646f31d4 Subproject commit 58c0aea7c21597e43967f700b54db58fe90b941e
...@@ -1895,7 +1895,7 @@ ENABLE_PREPROCESSING = YES ...@@ -1895,7 +1895,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and # the macro expansion is limited to the macros specified with the PREDEFINED and
...@@ -1903,7 +1903,7 @@ MACRO_EXPANSION = NO ...@@ -1903,7 +1903,7 @@ MACRO_EXPANSION = NO
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES the includes files in the # If the SEARCH_INCLUDES tag is set to YES the includes files in the
# INCLUDE_PATH will be searched if a #include is found. # INCLUDE_PATH will be searched if a #include is found.
...@@ -1935,7 +1935,7 @@ INCLUDE_FILE_PATTERNS = ...@@ -1935,7 +1935,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = PREDEFINED = HAVE_PETSC
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The
......
openfpm_vcluster @ 09caef4a
Subproject commit 7030e7f76e5d80a297e4cc9b2d4f3ad98beb8d0f Subproject commit 09caef4afa48f5b4013328562b388821be422993
...@@ -1388,12 +1388,9 @@ public: ...@@ -1388,12 +1388,9 @@ public:
/*! \brief Get the domain Cells /*! \brief Get the domain Cells
* *
* It perform a linearization of the domain cells using the extension provided in gs * It return all the cells-id that are inside the processor-domain
* *
* * \return the cells id inside the domain
* \param shift Cell padding
* \param cell_shift where the domain cell start
* \param gs grid extension
* *
*/ */
openfpm::vector<size_t> & getDomainCells() openfpm::vector<size_t> & getDomainCells()
...@@ -1401,15 +1398,26 @@ public: ...@@ -1401,15 +1398,26 @@ public:
return domain_nn_calculator_cart<dim>::getDomainCells(); return domain_nn_calculator_cart<dim>::getDomainCells();
} }
/*! \brief Get the CRS domain Cells /*! \brief Get the CRS domain Cells with normal neighborhood
*
* In case of symmetric interaction the neighborhood cells of
* a cell is different
*
* \verbatim
Symmetric Normal
* * * * * *
X * * X *
* * *
\endverbatim
* *
* It perform a linearization of the domain cells using the extension provided in gs
* *
* In case of CRS scheme some cells has the symmetric neighborhood
* some others has more complex neighborhood. This function return
* all the cells with normal neighborhood
* *
* \param shift Cell padding * \return the cell-id of the cells inside the processor-domain with normal neighborhood
* \param cell_shift where the domain cell start
* \param gs grid extension
* \param loc_box processor sub-domains
* *
*/ */
openfpm::vector<size_t> & getCRSDomainCells() openfpm::vector<size_t> & getCRSDomainCells()
...@@ -1430,13 +1438,8 @@ public: ...@@ -1430,13 +1438,8 @@ public:
/*! \brief Get the CRS anomalous cells /*! \brief Get the CRS anomalous cells
* *
* This function include also a linearization of the indexes * This function return the anomalous cells
* *
* \param shift Shifting point
* \param cell_shift where the processor cell-list start (In case of symmetric)
* exist one global cell-list, but each processor span only one
* part of it
* \param gs grid extension
* *
* \return the anomalous cells with neighborhood * \return the anomalous cells with neighborhood
* *
......
...@@ -506,7 +506,9 @@ public: ...@@ -506,7 +506,9 @@ public:
/*! \brief Copy the object /*! \brief Copy the object
* *
* \param object to copy * \param pm object to copy
*
* \return itself
* *
*/ */
const Parmetis<Graph> & operator=(const Parmetis<Graph> & pm) const Parmetis<Graph> & operator=(const Parmetis<Graph> & pm)
...@@ -523,7 +525,9 @@ public: ...@@ -523,7 +525,9 @@ public:
/*! \brief Copy the object /*! \brief Copy the object
* *
* \param object to copy * \param pm object to copy
*
* \return itself
* *
*/ */
const Parmetis<Graph> & operator=(Parmetis<Graph> && pm) const Parmetis<Graph> & operator=(Parmetis<Graph> && pm)
......
...@@ -144,7 +144,7 @@ private: ...@@ -144,7 +144,7 @@ private:
template<unsigned int p_sub> void fill_domain(Graph & graph,const Box<dim,size_t> & box, long int ids) template<unsigned int p_sub> void fill_domain(Graph & graph,const Box<dim,size_t> & box, long int ids)
{ {
// Create a subgrid iterator // Create a subgrid iterator
grid_key_dx_iterator_sub<dim,do_not_print_warning_on_adjustment<dim>> g_sub(gh,box.getKP1(),box.getKP2()); grid_key_dx_iterator_sub<dim,no_stencil,do_not_print_warning_on_adjustment<dim>> g_sub(gh,box.getKP1(),box.getKP2());
// iterate through all grid points // iterate through all grid points
...@@ -207,7 +207,7 @@ private: ...@@ -207,7 +207,7 @@ private:
for (size_t d = 0 ; d < v_w.size() ; d++) for (size_t d = 0 ; d < v_w.size() ; d++)
{ {
// Create a sub-grid iterator // Create a sub-grid iterator
grid_key_dx_iterator_sub_bc<dim,do_not_print_warning_on_adjustment<dim>> g_sub(gh,v_w.template get<wavefront<dim>::start>(d),v_w.template get<wavefront<dim>::stop>(d),bc); grid_key_dx_iterator_sub_bc<dim,no_stencil,do_not_print_warning_on_adjustment<dim>> g_sub(gh,v_w.template get<wavefront<dim>::start>(d),v_w.template get<wavefront<dim>::stop>(d),bc);
// iterate through all grid points // iterate through all grid points
...@@ -296,7 +296,7 @@ private: ...@@ -296,7 +296,7 @@ private:
// Create an iterator of the expanded wavefront // Create an iterator of the expanded wavefront
grid_key_dx<dim> start = grid_key_dx<dim>(v_w.template get<wavefront<dim>::start>(d)) + w_comb[d]; grid_key_dx<dim> start = grid_key_dx<dim>(v_w.template get<wavefront<dim>::start>(d)) + w_comb[d];
grid_key_dx<dim> stop = grid_key_dx<dim>(v_w.template get<wavefront<dim>::stop>(d)) + w_comb[d]; grid_key_dx<dim> stop = grid_key_dx<dim>(v_w.template get<wavefront<dim>::stop>(d)) + w_comb[d];
grid_key_dx_iterator_sub<dim,do_not_print_warning_on_adjustment<dim>> it(gh,start,stop); grid_key_dx_iterator_sub<dim,no_stencil,do_not_print_warning_on_adjustment<dim>> it(gh,start,stop);
// for each sub-domain in the expanded wavefront // for each sub-domain in the expanded wavefront
while (it.isNext()) while (it.isNext())
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* \tparam impl implementation * \tparam impl implementation
* *
*/ */
template<unsigned int dim, typename device_grid, int impl > template<unsigned int dim, typename device_grid, int impl,typename stencil = no_stencil >
class grid_dist_iterator class grid_dist_iterator
{ {
...@@ -41,8 +41,8 @@ class grid_dist_iterator ...@@ -41,8 +41,8 @@ class grid_dist_iterator
* \tparam impl implementation * \tparam impl implementation
* *
*/ */
template<unsigned int dim, typename device_grid> template<unsigned int dim, typename device_grid, typename stencil>
class grid_dist_iterator<dim,device_grid,FREE> class grid_dist_iterator<dim,device_grid,FREE,stencil>
{ {
//! grid list counter //! grid list counter
size_t g_c; size_t g_c;
...@@ -54,7 +54,7 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -54,7 +54,7 @@ class grid_dist_iterator<dim,device_grid,FREE>
const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext; const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
//! Actual iterator //! Actual iterator
grid_key_dx_iterator_sub<dim> a_it; grid_key_dx_iterator_sub<dim,stencil> a_it;
//! stop point (is the grid size) //! stop point (is the grid size)
grid_key_dx<dim> stop; grid_key_dx<dim> stop;
...@@ -91,6 +91,26 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -91,6 +91,26 @@ class grid_dist_iterator<dim,device_grid,FREE>
selectValidGrid(); selectValidGrid();
} }
/*! \brief Constructor of the distributed grid iterator with
* stencil support
*
* \param gk std::vector of the local grid
* \param gdb_ext set of local subdomains
* \param stop end point
* \param stencil_pnt stencil points
*
*/
grid_dist_iterator(const openfpm::vector<device_grid> & gk,
const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext,
const grid_key_dx<dim> & stop,
const grid_key_dx<dim> (& stencil_pnt)[stencil::nsp])
:g_c(0),gList(gk),gdb_ext(gdb_ext),a_it(stencil_pnt),stop(stop)
{
// Initialize the current iterator
// with the first grid
selectValidGrid();
}
// Destructor // Destructor
~grid_dist_iterator() ~grid_dist_iterator()
{ {
...@@ -102,7 +122,7 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -102,7 +122,7 @@ class grid_dist_iterator<dim,device_grid,FREE>
* *
*/ */
inline grid_dist_iterator<dim,device_grid,FREE> operator++() inline grid_dist_iterator<dim,device_grid,FREE,stencil> & operator++()
{ {
++a_it; ++a_it;
...@@ -191,6 +211,8 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -191,6 +211,8 @@ class grid_dist_iterator<dim,device_grid,FREE>
* \see grid_dist_key_dx * \see grid_dist_key_dx
* \see grid_dist_iterator * \see grid_dist_iterator
* *
* \param k key position in local coordinates
*
* \return the global position in the grid * \return the global position in the grid
* *
*/ */
...@@ -206,6 +228,18 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -206,6 +228,18 @@ class grid_dist_iterator<dim,device_grid,FREE>
return k_glob; return k_glob;
} }
/*! \brief Return the stencil point offset
*
* \tparam id
*
* \return linearized distributed key
*
*/
template<unsigned int id> inline grid_dist_lin_dx getStencil()
{
return grid_dist_lin_dx(g_c,a_it.getStencil<id>());
}
}; };
...@@ -218,8 +252,8 @@ class grid_dist_iterator<dim,device_grid,FREE> ...@@ -218,8 +252,8 @@ class grid_dist_iterator<dim,device_grid,FREE>
* \tparam impl implementation * \tparam impl implementation
* *
*/ */
template<unsigned int dim, typename device_grid> template<unsigned int dim, typename device_grid,typename stencil>
class grid_dist_iterator<dim,device_grid,FIXED> class grid_dist_iterator<dim,device_grid,FIXED,stencil>
{ {
//! grid list counter //! grid list counter
size_t g_c; size_t g_c;
...@@ -231,7 +265,7 @@ class grid_dist_iterator<dim,device_grid,FIXED> ...@@ -231,7 +265,7 @@ class grid_dist_iterator<dim,device_grid,FIXED>
const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext; const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
//! Actual iterator //! Actual iterator
grid_key_dx_iterator<dim> a_it; grid_key_dx_iterator<dim,stencil> a_it;
/*! \brief from g_c increment g_c until you find a valid grid /*! \brief from g_c increment g_c until you find a valid grid
* *
...@@ -289,7 +323,7 @@ class grid_dist_iterator<dim,device_grid,FIXED> ...@@ -289,7 +323,7 @@ class grid_dist_iterator<dim,device_grid,FIXED>
* *
*/ */
grid_dist_iterator<dim,device_grid,FIXED> operator++() grid_dist_iterator<dim,device_grid,FIXED> & operator++()
{ {
++a_it; ++a_it;
...@@ -349,6 +383,8 @@ class grid_dist_iterator<dim,device_grid,FIXED> ...@@ -349,6 +383,8 @@ class grid_dist_iterator<dim,device_grid,FIXED>
* \see grid_dist_key_dx * \see grid_dist_key_dx
* \see grid_dist_iterator * \see grid_dist_iterator
* *
* \param k local coordinates to convert into global
*
* \return the global position in the grid * \return the global position in the grid
* *
*/ */
...@@ -364,6 +400,18 @@ class grid_dist_iterator<dim,device_grid,FIXED> ...@@ -364,6 +400,18 @@ class grid_dist_iterator<dim,device_grid,FIXED>
return k_glob; return k_glob;
} }
/*! \brief Return the stencil point offset
*
* \tparam id
*