9#include "util/common.hpp"
10#include "FD_expressions.hpp"
14 constexpr int CENTRAL = 0;
15 constexpr int CENTRAL_ONE_SIDE_FORWARD = 1;
16 constexpr int CENTRAL_ONE_SIDE_BACKWARD = 2;
17 constexpr int CENTRAL_STAG = 3;
18 constexpr int CENTRAL_STAG_ONE_SIDE_FORWARD = 4;
19 constexpr int CENTRAL_STAG_ONE_SIDE_BACKWARD = 5;
23 template<
unsigned int dir,
unsigned int ord_d,
unsigned int ord,
unsigned int impl>
26 template<
typename rtype,
typename expr_type>
29 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error the give derivative scheme with convergence order " << ord <<
" has not been implemented yet" << std::endl;
34 template<
unsigned int dir>
37 template<
typename rtype,
typename expr_type>
41 auto dx = o1.getGrid().spacing(dir);
45 rtype ret = o1.value(key,c_where)*1.0/2.0;
48 ret += o1.value(key,c_where)*(-1.0/2.0);
54 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
55 inline static void calculate_nz(o1_type o1,
56 const gmap_type & g_map,
59 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
60 unordered_map_type & cols,
61 typename Sys_eqs::stype coeff,
65 long int old_val = kmap.
getKeyRef().get(dir);
67 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,coeff/spacing[dir]/2.0,comp,c_where);
72 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-coeff/spacing[dir]/2.0,comp,c_where);
77 template<
unsigned int dir>
80 template<
typename rtype,
typename expr_type>
85 auto dx = o1.getGrid().spacing(dir);
88 if (c_where[dir] == -1)
90 char old_c = c_where[dir];
93 ret = o1.value(key,c_where)*(-1.0);
96 ret += o1.value(key,c_where)*(1.0);
102 char old_c = c_where[dir];
105 ret = o1.value(key,c_where)*(-1.0);
108 ret += o1.value(key,c_where)*(1.0);
110 c_where[dir] = old_c;
116 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
117 inline static void calculate_nz(o1_type o1,
118 const gmap_type & g_map,
121 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
122 unordered_map_type & cols,
123 typename Sys_eqs::stype coeff,
128 long int old_val = kmap.
getKeyRef().get(dir);
130 if (c_where[dir] == -1)
132 char old_c = c_where.
c[dir];
134 kmap.
getKeyRef().set_d(dir, old_val - 1);
135 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-coeff/spacing[dir],comp,c_where);
138 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,coeff/spacing[dir],comp,c_where);
140 c_where.
c[dir] = old_c;
144 char old_c = c_where.
c[dir];
147 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-coeff/spacing[dir],comp,c_where);
149 kmap.
getKeyRef().set_d(dir, old_val + 1);
150 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,coeff/spacing[dir],comp,c_where);
152 c_where.
c[dir] = old_c;
159 template<
unsigned int dir>
162 template<
typename rtype,
typename expr_type>
166 auto dx = o1.getGrid().spacing(dir);
169 rtype ret = o1.value(key,c_where)*(-2.0);
172 ret += o1.value(key,c_where)*(1.0);
175 ret += o1.value(key,c_where)*(1.0);
181 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
182 inline static void calculate_nz(o1_type o1,
183 const gmap_type & g_map,
186 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
187 unordered_map_type & cols,
188 typename Sys_eqs::stype coeff,
192 long int old_val = kmap.
getKeyRef().get(dir);
193 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-2.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
196 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,coeff/(spacing[dir]*spacing[dir]),comp,c_where);
201 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,coeff/(spacing[dir]*spacing[dir]),comp,c_where);
206 enum one_side_direction
213 template<
typename gtype,
typename key_type>
214 one_side_direction use_one_side(gtype & g,
unsigned int dir, key_type & key)
216 if (g.getDecomposition().periodicity()[dir] ==
true)
218 return one_side_direction::OS_CENTRAL;
221 auto keyg = g.getGKey(key);
222 if (keyg.get(dir) == 0)
224 return one_side_direction::OS_FORWARD;
226 else if (keyg.get(dir) == g.getGridInfoVoid().size(dir) - 1)
228 return one_side_direction::OS_BACKWARD;
231 return one_side_direction::OS_CENTRAL;
234 template<
unsigned int dir>
237 template<
typename rtype,
typename expr_type>
241 auto dx = o1.getGrid().spacing(dir);
244 rtype ret = o1.value(key,c_where)*(-3.0/2.0);
247 ret += o1.value(key,c_where)*2.0;
250 ret += o1.value(key,c_where)*(-0.5);
256 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
257 inline static void calculate_nz(o1_type o1,
258 const gmap_type & g_map,
261 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
262 unordered_map_type & cols,
263 typename Sys_eqs::stype coeff,
266 {
long int old_val = kmap.
getKeyRef().get(dir);
268 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-3.0*coeff/spacing[dir]/2.0,comp,c_where);
271 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,2.0*coeff/spacing[dir],comp,c_where);
274 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-0.5*coeff/spacing[dir],comp,c_where);
279 template<
unsigned int dir>
282 template<
typename rtype,
typename expr_type>
286 std::cout << __FILE__ <<
":" << __LINE__ <<
" error we do not have implemented yet one sided staggered grid" << std::endl;
291 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
292 inline static void calculate_nz(o1_type o1,
293 const gmap_type & g_map,
296 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
297 unordered_map_type & cols,
298 typename Sys_eqs::stype coeff,
302 std::cout << __FILE__ <<
":" << __LINE__ <<
" error we do not have implemented yet one sided staggered grid" << std::endl;
306 template<
unsigned int dir>
309 template<
typename rtype,
typename expr_type>
313 auto dx = o1.getGrid().spacing(dir);
316 rtype ret = o1.value(key,c_where)*(2.0);
319 ret += o1.value(key,c_where)*(-5.0);
322 ret += o1.value(key,c_where)*(4.0);
325 ret += o1.value(key,c_where)*(-1.0);
331 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
332 inline static void calculate_nz(o1_type o1,
333 const gmap_type & g_map,
336 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
337 unordered_map_type & cols,
338 typename Sys_eqs::stype coeff,
342 long int old_val = kmap.
getKeyRef().get(dir);
344 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,2.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
347 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-5.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
350 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,4.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
353 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-1.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
360 template<
unsigned int dir>
363 template<
typename rtype,
typename expr_type>
367 auto dx = o1.getGrid().spacing(dir);
370 rtype ret = o1.value(key,c_where)*(3.0/2.0);
373 ret += o1.value(key,c_where)*(-2.0);
376 ret += o1.value(key,c_where)*0.5;
382 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
383 inline static void calculate_nz(o1_type o1,
384 const gmap_type & g_map,
387 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
388 unordered_map_type & cols,
389 typename Sys_eqs::stype coeff,
392 {
long int old_val = kmap.
getKeyRef().get(dir);
394 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,3.0*coeff/spacing[dir]/2.0,comp,c_where);
397 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-2.0*coeff/spacing[dir],comp,c_where);
400 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,0.5*coeff/spacing[dir],comp,c_where);
405 template<
unsigned int dir>
408 template<
typename rtype,
typename expr_type>
412 std::cout << __FILE__ <<
":" << __LINE__ <<
" error we do not have implemented yet one sided staggered grid" << std::endl;
417 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
418 inline static void calculate_nz(o1_type o1,
419 const gmap_type & g_map,
422 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
423 unordered_map_type & cols,
424 typename Sys_eqs::stype coeff,
428 std::cout << __FILE__ <<
":" << __LINE__ <<
" error we do not have implemented yet one sided staggered grid" << std::endl;
432 template<
unsigned int dir>
435 template<
typename rtype,
typename expr_type>
439 auto dx = o1.getGrid().spacing(dir);
442 rtype ret = o1.value(key,c_where)*(2.0);
445 ret += o1.value(key,c_where)*(-5.0);
448 ret += o1.value(key,c_where)*(4.0);
451 ret += o1.value(key,c_where)*(-1.0);
457 template<
typename Sys_eqs,
typename o1_type,
typename gmap_type,
typename unordered_map_type>
458 inline static void calculate_nz(o1_type o1,
459 const gmap_type & g_map,
462 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
463 unordered_map_type & cols,
464 typename Sys_eqs::stype coeff,
467 {
long int old_val = kmap.
getKeyRef().get(dir);
469 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,2.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
472 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-5.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
475 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,4.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
478 o1.template value_nz<Sys_eqs>(g_map,kmap,gs,spacing,cols,-1.0*coeff/(spacing[dir]*spacing[dir]),comp,c_where);
483 template<
unsigned dir_,
unsigned int ord_d_,
unsigned int ord_,
unsigned int impl_>
486 typedef boost::mpl::int_<dir_> dir;
487 typedef boost::mpl::int_<ord_> ord;
488 typedef boost::mpl::int_<ord_d_> ord_d;
489 typedef boost::mpl::int_<impl_> impl;
492 template <
typename exp1,
unsigned int dir,
unsigned int ord_d,
unsigned int ord,
unsigned int impl>
500 typedef typename exp1::gtype gtype;
526 typedef typename std::remove_reference<
decltype(o1.value(key,c_where))>::type r_type;
530 one_side_direction os = use_one_side(getGrid(),dir,key);
532 if (os == one_side_direction::OS_CENTRAL || getGrid().is_staggered() ==
true)
536 else if (os == one_side_direction::OS_FORWARD)
549 template<
typename Sys_eqs,
typename gmap_type,
typename unordered_map_type>
550 inline void value_nz(
const gmap_type & g_map,
553 typename Sys_eqs::stype (& spacing )[Sys_eqs::dims],
554 unordered_map_type & cols,
555 typename Sys_eqs::stype coeff,
560 long int old_val = kmap.
getKeyRef().get(dir);
561 one_side_direction os = use_one_side(getGrid(),dir,kmap);
562 if (os == one_side_direction::OS_CENTRAL || getGrid().is_staggered() ==
true)
564 Derivative_impl<dir,ord_d,ord,impl>::template calculate_nz<Sys_eqs>(o1,g_map,kmap,gs,spacing,cols,coeff,comp,c_where);
566 else if (os == one_side_direction::OS_FORWARD)
568 Derivative_impl<dir,ord_d,ord,impl+1>::template calculate_nz<Sys_eqs>(o1,g_map,kmap,gs,spacing,cols,coeff,comp,c_where);
572 Derivative_impl<dir,ord_d,ord,impl+2>::template calculate_nz<Sys_eqs>(o1,g_map,kmap,gs,spacing,cols,coeff,comp,c_where);
607 template<
unsigned int dir,
unsigned int ord_d ,
unsigned int ord,
unsigned int impl>
617 template<
typename operand_type>
624 template<
unsigned int dim,
unsigned int impl>
634 template<
typename operand_type>
639 operator()(operand_type arg)
652 template<
unsigned int p1,
unsigned int p2,
typename g1,
typename g2,
unsigned int impl_p1,
unsigned int impl_p2>
654 typename std::remove_reference<
decltype(ga.getGrid().template getProp<p1>(ga.getGrid().getDomainIterator().get()))>::type
656 typename std::remove_reference<
decltype(ga.getGrid().template getProp<p1>(ga.getGrid().getDomainIterator().get()))>::type result = 0.0;
658 auto diff_expr = ga + -1*gb;
660 auto & v_cl = create_vcluster();
662 auto it = ga.getGrid().getDomainIterator();
666 auto diff = diff_expr.value(key,s_pos);
684 template<
unsigned int p1,
unsigned int p2,
typename g1,
typename g2,
unsigned int impl_p1,
unsigned int impl_p2>
686 typename std::remove_reference<
decltype(ga.getGrid().template getProp<p1>(ga.getGrid().getDomainIterator().get()))>::type
688 typename std::remove_reference<
decltype(ga.getGrid().template getProp<p1>(ga.getGrid().getDomainIterator().get()))>::type result = 0.0;
690 auto diff_expr = ga + -1*gb;
692 auto & v_cl = create_vcluster();
694 auto it = ga.getGrid().getDomainIterator();
698 auto diff = fabs(diff_expr.value(key,s_pos));
700 if (diff > result) result = diff;
gtype & getGrid()
Return the vector on which is acting.
void init() const
This function must be called before value.
grid_dist_expression_op(const exp1 &o1)
Costruct a FD expression out of two expressions.
const gtype & getGrid() const
Return the vector on which is acting.
const exp1 o1
expression 1
auto value(grid_dist_key_dx< gtype::dims > &key, comb< gtype::dims > &c_where) const -> typename std::remove_reference< decltype(o1.value(key, c_where))>::type
Evaluate the expression.
Grid key for a distributed grid.
base_key & getKeyRef()
Get the reference key.
Position of the element of dimension d in the hyper-cube of dimension dim.
signed char c[dim]
Array that store the combination.