Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_ExprEval_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Panzer: A partial differential equation assembly
5// engine for strongly coupled complex multiphysics systems
6// Copyright (2011) Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39// Eric C. Cyr (eccyr@sandia.gov)
40// ***********************************************************************
41// @HEADER
42
43#ifndef PANZER_EXPR_EVAL_IMPL_HPP
44#define PANZER_EXPR_EVAL_IMPL_HPP
45
46#include <Panzer_ExprEval.hpp>
47
48#include <algorithm>
49#include <cmath>
50
51namespace panzer
52{
53namespace Expr
54{
55
57 template <typename T>
58 static KOKKOS_FORCEINLINE_FUNCTION
59 T apply(bool cond, T const& left, T const& right) {
60 return cond ? left : right;
61 }
62};
63
64struct ScalarOr {
65 static KOKKOS_FORCEINLINE_FUNCTION
66 bool apply(bool left, bool right) {
67 return left || right;
68 }
69};
70
71struct ScalarAnd {
72 static KOKKOS_FORCEINLINE_FUNCTION
73 bool apply(bool left, bool right) {
74 return left && right;
75 }
76};
77
78struct ScalarGT {
79 template <typename T>
80 static KOKKOS_FORCEINLINE_FUNCTION
81 bool apply(T const& left, T const& right) {
82 return left > right;
83 }
84};
85
86struct ScalarLT {
87 template <typename T>
88 static KOKKOS_FORCEINLINE_FUNCTION
89 bool apply(T const& left, T const& right) {
90 return left < right;
91 }
92};
93
94struct ScalarGEQ {
95 template <typename T>
96 static KOKKOS_FORCEINLINE_FUNCTION
97 bool apply(T const& left, T const& right) {
98 return left >= right;
99 }
100};
101
102struct ScalarLEQ {
103 template <typename T>
104 static KOKKOS_FORCEINLINE_FUNCTION
105 bool apply(T const& left, T const& right) {
106 return left <= right;
107 }
108};
109
110struct ScalarEQ {
111 template <typename T>
112 static KOKKOS_FORCEINLINE_FUNCTION
113 bool apply(T const& left, T const& right) {
114 return left == right;
115 }
116};
117
118struct ScalarAdd {
119 template <typename T>
120 static KOKKOS_FORCEINLINE_FUNCTION
121 T apply(T const& left, T const& right) {
122 return left + right;
123 }
124};
125
126struct ScalarSub {
127 template <typename T>
128 static KOKKOS_FORCEINLINE_FUNCTION
129 T apply(T const& left, T const& right) {
130 return left - right;
131 }
132};
133
134struct ScalarMul {
135 template <typename T>
136 static KOKKOS_FORCEINLINE_FUNCTION
137 T apply(T const& left, T const& right) {
138 return left * right;
139 }
140};
141
142struct ScalarDiv {
143 template <typename T>
144 static KOKKOS_FORCEINLINE_FUNCTION
145 T apply(T const& left, T const& right) {
146 return left / right;
147 }
148};
149
150struct ScalarPow {
151 template <typename T>
152 static KOKKOS_FORCEINLINE_FUNCTION
153 T apply(T const& left, T const& right) {
154 using std::pow;
155 return pow(left, right);
156 }
157};
158
159struct ScalarNeg {
160 template <typename T>
161 static KOKKOS_FORCEINLINE_FUNCTION
162 T apply(T const& right) {
163 return -right;
164 }
165};
166
167// TODO: replace this with .access() after next Kokkos release
168template <typename Indexed, size_t IterationRank, size_t IndexedRank = Indexed::rank>
169struct Indexer;
170
171template <typename ViewType>
172struct Indexer<ViewType, 1, 0> {
173 template <typename Integral>
174 static KOKKOS_FORCEINLINE_FUNCTION
175 typename ViewType::reference_type index(ViewType const& x, Integral) { return x(); }
176};
177
178template <typename ViewType>
179struct Indexer<ViewType, 1, 1> {
180 template <typename Integral>
181 static KOKKOS_FORCEINLINE_FUNCTION
182 typename ViewType::reference_type index(ViewType const& x, Integral i) { return x(i); }
183};
184
185template <typename ViewType>
186struct Indexer<ViewType, 2, 0> {
187 template <typename Integral>
188 static KOKKOS_FORCEINLINE_FUNCTION
189 typename ViewType::reference_type index(ViewType const& x, Integral, Integral) { return x(); }
190};
191
192template <typename ViewType>
193struct Indexer<ViewType, 2, 1> {
194 template <typename Integral>
195 static KOKKOS_FORCEINLINE_FUNCTION
196 typename ViewType::reference_type index(ViewType const& x, Integral i, Integral) { return x(i); }
197};
198
199template <typename ViewType>
200struct Indexer<ViewType, 2, 2> {
201 template <typename Integral>
202 static KOKKOS_FORCEINLINE_FUNCTION
203 typename ViewType::reference_type index(ViewType const& x, Integral i, Integral j) { return x(i, j); }
204};
205
206//TODO: just use std::max once C++14 is the Trilinos standard (which makes std::max constexpr)
207template <typename T, typename ... TS>
208struct MaxRank;
209
210template <typename T>
211struct MaxRank<T> {
212 static constexpr size_t value = T::rank;
213};
214
215template <typename T, typename ... TS>
216struct MaxRank {
217 static constexpr size_t left_value = T::rank;
218 static constexpr size_t right_value = MaxRank<TS ...>::value;
219 static constexpr size_t value = left_value > right_value ? left_value : right_value;
220};
221
222template <typename A, typename B>
224 static constexpr size_t a_rank = A::rank;
225 static constexpr size_t b_rank = B::rank;
226 using biggest_type = typename std::conditional<(b_rank > a_rank), B, A>::type;
229};
230
231template <typename C, typename A, typename B>
233 static constexpr size_t a_rank = A::rank;
234 static constexpr size_t b_rank = B::rank;
235 static constexpr size_t c_rank = C::rank;
236 using biggest_ab_type = typename std::conditional<(b_rank > a_rank), B, A>::type;
237 using biggest_type = typename std::conditional<(c_rank > biggest_ab_type::rank), C, biggest_ab_type>::type;
240};
241
242template <typename Op, typename Result, typename Left, typename Right, size_t Rank = Result::rank>
244
245template <typename Op, typename Result, typename Left, typename Right>
246struct BinaryFunctor<Op, Result, Left, Right, 0> {
248 using execution_space = typename Result::execution_space;
250 Left left_;
251 Right right_;
252 KOKKOS_INLINE_FUNCTION
253 void operator()(typename execution_space::size_type) const {
254 result_() = Op::apply(left_(), right_());
255 }
256 BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
257 left_ = Teuchos::any_cast<Left>(left);
258 right_ = Teuchos::any_cast<Right>(right);
259 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name));
260 Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, 1), *this);
261 result = Result(result_);
262 }
263};
264
265template <typename Op, typename Result, typename Left, typename Right>
266struct BinaryFunctor<Op, Result, Left, Right, 1> {
268 using execution_space = typename Result::execution_space;
270 Left left_;
271 Right right_;
272 KOKKOS_INLINE_FUNCTION
273 void operator()(typename execution_space::size_type i) const {
274 result_(i) =
275 Op::apply(
276 Indexer<Left, 1>::index(left_, i),
277 Indexer<Right, 1>::index(right_, i));
278 }
279 BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
280 left_ = Teuchos::any_cast<Left>(left);
281 right_ = Teuchos::any_cast<Right>(right);
282 auto extent_0 = std::max(left_.extent(0), right_.extent(0));
283 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
284 Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
285 result = Result{result_};
286 }
287};
288
289template <typename Op, typename Result, typename Left, typename Right>
290struct BinaryFunctor<Op, Result, Left, Right, 2> {
292 using execution_space = typename Result::execution_space;
294 Left left_;
295 Right right_;
296 KOKKOS_INLINE_FUNCTION
297 void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
298 result_(i, j) =
299 Op::apply(
300 Indexer<Left, 2>::index(left_, i, j),
301 Indexer<Right, 2>::index(right_, i, j));
302 }
303 BinaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
304 left_ = Teuchos::any_cast<Left>(left);
305 right_ = Teuchos::any_cast<Right>(right);
306 auto extent_0 = std::max(left_.extent(0), right_.extent(0));
307 auto extent_1 = std::max(left_.extent(1), right_.extent(1));
308 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
309 using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
310 Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
311 result = Result{result_};
312 }
313};
314
315template <typename Cond, typename Left, typename Right, size_t Rank = MaxRank<Cond, Left, Right>::value>
317
318template <typename Cond, typename Left, typename Right>
319struct TernaryFunctor<Cond, Left, Right, 1> {
322 using execution_space = typename Result::execution_space;
324 Cond cond_;
325 Left left_;
326 Right right_;
327 KOKKOS_INLINE_FUNCTION
328 void operator()(typename execution_space::size_type i) const {
329 result_(i) =
330 Indexer<Cond, 1>::index(cond_, i) ?
331 Indexer<Left, 1>::index(left_, i) :
332 Indexer<Right, 1>::index(right_, i);
333 }
334 TernaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
335 cond_ = Teuchos::any_cast<Cond>(cond);
336 left_ = Teuchos::any_cast<Left>(left);
337 right_ = Teuchos::any_cast<Right>(right);
338 auto extent_0 =
339 std::max(cond_.extent(0),
340 std::max(left_.extent(0), right_.extent(0)));
341 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
342 Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
343 result = Result{result_};
344 }
345};
346
347template <typename Cond, typename Left, typename Right>
348struct TernaryFunctor<Cond, Left, Right, 2> {
351 using execution_space = typename Result::execution_space;
353 Cond cond_;
354 Left left_;
355 Right right_;
356 KOKKOS_INLINE_FUNCTION
357 void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
358 result_(i, j) =
359 Indexer<Cond, 2>::index(cond_, i, j) ?
360 Indexer<Left, 2>::index(left_, i, j) :
361 Indexer<Right, 2>::index(right_, i, j);
362 }
363 TernaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
364 cond_ = Teuchos::any_cast<Cond>(cond);
365 left_ = Teuchos::any_cast<Left>(left);
366 right_ = Teuchos::any_cast<Right>(right);
367 auto extent_0 =
368 std::max(cond_.extent(0),
369 std::max(left_.extent(0), right_.extent(0)));
370 auto extent_1 =
371 std::max(cond_.extent(1),
372 std::max(left_.extent(1), right_.extent(1)));
373 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
374 using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
375 Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
376 result = Result{result_};
377 }
378};
379
380template <typename DT, typename ... VP>
382 : EvalBase()
383{
384}
385
386template <typename DT, typename ... VP>
387void Eval<DT, VP ...>::set(std::string const& name, bool value) {
388 single_bool_view_type view{Kokkos::ViewAllocateWithoutInitializing{name}};
389 auto host_view = Kokkos::create_mirror_view(view);
390 host_view() = value;
391 Kokkos::deep_copy(view, host_view);
392 symbol_map[name] = const_single_bool_view_type{view};
393}
394
395template <typename DT, typename ... VP>
396void Eval<DT, VP ...>::set(std::string const& name, scalar_type const& value) {
397 single_view_type view{Kokkos::ViewAllocateWithoutInitializing{name}};
398 auto host_view = Kokkos::create_mirror_view(view);
399 host_view() = value;
400 Kokkos::deep_copy(view, host_view);
401 symbol_map[name] = const_single_view_type{view};
402 bool a, b;
403 this->inspect_arg(symbol_map[name], a, b);
404}
405
406template <typename DT, typename ... VP>
407void Eval<DT, VP ...>::set(std::string const& name, const_view_type const& value) {
408 symbol_map[name] = value;
409}
410
411template <typename DT, typename ... VP>
412void Eval<DT, VP ...>::make_constant(Teuchos::any& result, double const& value) {
413 single_view_type view{Kokkos::ViewAllocateWithoutInitializing{"constant"}};
414 auto host_view = Kokkos::create_mirror_view(view);
415 host_view() = value;
416 Kokkos::deep_copy(view, host_view);
418 bool a, b;
419 this->inspect_arg(result, a, b);
420}
421
422template <typename DT, typename ... VP>
423void Eval<DT, VP ...>::inspect_arg(Teuchos::any const& arg, bool& is_many, bool& is_bool) {
424 if (arg.type() == typeid(const_single_bool_view_type)) {
425 is_many = false;
426 is_bool = true;
427 } else if (arg.type() == typeid(const_single_view_type)) {
428 is_many = false;
429 is_bool = false;
430 } else if (arg.type() == typeid(const_view_type)) {
431 is_many = true;
432 is_bool = false;
433 } else if (arg.type() == typeid(const_bool_view_type)) {
434 is_many = true;
435 is_bool = true;
436 } else {
437 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::ParserFail,
438 "value is of illegal type " << arg.typeName() << ", view type is "
439 << typeid(const_view_type).name());
440 }
441}
442
443template <typename DT, typename ... VP>
444void Eval<DT, VP ...>::single_single_ternary_op(Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
445 using ManyBool = const_bool_view_type;
446 using Single = const_single_view_type;
447 TernaryFunctor<ManyBool, Single, Single>("many ? single : single", result, cond, left, right);
448}
449
450template <typename DT, typename ... VP>
451void Eval<DT, VP ...>::single_many_ternary_op(Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
452 using ManyBool = const_bool_view_type;
453 using Single = const_single_view_type;
454 using Many = const_view_type;
455 TernaryFunctor<ManyBool, Single, Many>("many ? single : many", result, cond, left, right);
456}
457
458template <typename DT, typename ... VP>
459void Eval<DT, VP ...>::many_single_ternary_op(Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
460 using ManyBool = const_bool_view_type;
461 using Single = const_single_view_type;
462 using Many = const_view_type;
463 TernaryFunctor<ManyBool, Many, Single>("many ? many : single", result, cond, left, right);
464}
465
466template <typename DT, typename ... VP>
467void Eval<DT, VP ...>::many_many_ternary_op(Teuchos::any& result, Teuchos::any& cond, Teuchos::any& left, Teuchos::any& right) {
468 using ManyBool = const_bool_view_type;
469 using Many = const_view_type;
470 TernaryFunctor<ManyBool, Many, Many>("many ? many : many", result, cond, left, right);
471}
472
473template <typename DT, typename ... VP>
474void Eval<DT, VP ...>::single_single_binary_op(BinaryOpCode code, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
475 using SingleBool = const_single_bool_view_type;
476 using Single = const_single_view_type;
477 switch (code) {
480 case BinaryOpCode::LT: BinaryFunctor<ScalarLT , SingleBool, Single, Single>("single< single", result, left, right); break;
481 case BinaryOpCode::GT: BinaryFunctor<ScalarGT , SingleBool, Single, Single>("single> single", result, left, right); break;
482 case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, SingleBool, Single, Single>("single>=single", result, left, right); break;
483 case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, SingleBool, Single, Single>("single<=single", result, left, right); break;
484 case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , SingleBool, Single, Single>("single==single", result, left, right); break;
485 case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Single, Single, Single>("single* single", result, left, right); break;
486 case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Single, Single, Single>("single/ single", result, left, right); break;
487 case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Single, Single, Single>("single+ single", result, left, right); break;
488 case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Single, Single, Single>("single- single", result, left, right); break;
489 case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Single, Single, Single>("single^ single", result, left, right); break;
490 }
491}
492
493template <typename DT, typename ... VP>
494void Eval<DT, VP ...>::single_many_binary_op(BinaryOpCode code, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
495 using Single = const_single_view_type;
496 using SingleBool = const_single_bool_view_type;
497 using Many = const_view_type;
498 using ManyBool = const_bool_view_type;
499 switch (code) {
502 case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Single, Many>("single< many", result, left, right); break;
503 case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Single, Many>("single> many", result, left, right); break;
504 case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Single, Many>("single>=many", result, left, right); break;
505 case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Single, Many>("single<=many", result, left, right); break;
506 case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Single, Many>("single==many", result, left, right); break;
507 case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Single, Many>("single* many", result, left, right); break;
508 case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Single, Many>("single/ many", result, left, right); break;
509 case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Single, Many>("single+ many", result, left, right); break;
510 case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Single, Many>("single- many", result, left, right); break;
511 case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Single, Many>("single^ many", result, left, right); break;
512 }
513}
514
515template <typename DT, typename ... VP>
516void Eval<DT, VP ...>::many_single_binary_op(BinaryOpCode code, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
517 using Single = const_single_view_type;
518 using SingleBool = const_single_bool_view_type;
519 using Many = const_view_type;
520 using ManyBool = const_bool_view_type;
521 switch (code) {
524 case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Many, Single>("many< single", result, left, right); break;
525 case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Many, Single>("many> single", result, left, right); break;
526 case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Many, Single>("many>=single", result, left, right); break;
527 case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Many, Single>("many<=single", result, left, right); break;
528 case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Many, Single>("many==single", result, left, right); break;
529 case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Many, Single>("many* single", result, left, right); break;
530 case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Many, Single>("many/ single", result, left, right); break;
531 case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Many, Single>("many+ single", result, left, right); break;
532 case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Many, Single>("many- single", result, left, right); break;
533 case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Many, Single>("many^ single", result, left, right); break;
534 }
535}
536
537template <typename DT, typename ... VP>
538void Eval<DT, VP ...>::many_many_binary_op(BinaryOpCode code, Teuchos::any& result, Teuchos::any& left, Teuchos::any& right) {
539 using Many = const_view_type;
540 using ManyBool = const_bool_view_type;
541 switch (code) {
544 case BinaryOpCode::LT: BinaryFunctor<ScalarLT , ManyBool, Many, Many>("many< many", result, left, right); break;
545 case BinaryOpCode::GT: BinaryFunctor<ScalarGT , ManyBool, Many, Many>("many> many", result, left, right); break;
546 case BinaryOpCode::GEQ: BinaryFunctor<ScalarGEQ, ManyBool, Many, Many>("many>=many", result, left, right); break;
547 case BinaryOpCode::LEQ: BinaryFunctor<ScalarLEQ, ManyBool, Many, Many>("many<=many", result, left, right); break;
548 case BinaryOpCode::EQ: BinaryFunctor<ScalarEQ , ManyBool, Many, Many>("many==many", result, left, right); break;
549 case BinaryOpCode::MUL: BinaryFunctor<ScalarMul, Many, Many, Many>("many* many", result, left, right); break;
550 case BinaryOpCode::DIV: BinaryFunctor<ScalarDiv, Many, Many, Many>("many/ many", result, left, right); break;
551 case BinaryOpCode::ADD: BinaryFunctor<ScalarAdd, Many, Many, Many>("many+ many", result, left, right); break;
552 case BinaryOpCode::SUB: BinaryFunctor<ScalarSub, Many, Many, Many>("many- many", result, left, right); break;
553 case BinaryOpCode::POW: BinaryFunctor<ScalarPow, Many, Many, Many>("many^ many", result, left, right); break;
554 }
555}
556
557template <typename Op, typename Result, size_t Rank = Result::rank>
559
560template <typename Op, typename Result>
561struct UnaryFunctor<Op, Result, 0> {
563 using execution_space = typename Result::execution_space;
565 Result right_;
566 KOKKOS_INLINE_FUNCTION
567 void operator()(typename execution_space::size_type i) const {
568 result_() = Op::apply(right_());
569 }
570 UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
571 right_ = Teuchos::any_cast<Result>(right);
572 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name));
573 Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, 1), *this);
574 result = Result(result_);
575 }
576};
577
578template <typename Op, typename Result>
579struct UnaryFunctor<Op, Result, 1> {
581 using execution_space = typename Result::execution_space;
583 Result right_;
584 KOKKOS_INLINE_FUNCTION
585 void operator()(typename execution_space::size_type i) const {
586 result_(i) = Op::apply(right_(i));
587 }
588 UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
589 right_ = Teuchos::any_cast<Result>(right);
590 auto extent_0 = right_.extent(0);
591 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0);
592 Kokkos::parallel_for(name, Kokkos::RangePolicy<execution_space>(0, extent_0), *this);
593 result = Result(result_);
594 }
595};
596
597template <typename Op, typename Result>
598struct UnaryFunctor<Op, Result, 2> {
600 using execution_space = typename Result::execution_space;
602 Result right_;
603 KOKKOS_INLINE_FUNCTION
604 void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const {
605 result_(i, j) = Op::apply(right_(i, j));
606 }
607 UnaryFunctor(std::string const& name, Teuchos::any& result, Teuchos::any& right) {
608 right_ = Teuchos::any_cast<Result>(right);
609 auto extent_0 = right_.extent(0);
610 auto extent_1 = right_.extent(1);
611 result_ = NonConstResult(Kokkos::ViewAllocateWithoutInitializing(name), extent_0, extent_1);
612 using policy_type = Kokkos::MDRangePolicy<execution_space, Kokkos::Rank<2>>;
613 Kokkos::parallel_for(name, policy_type({0, 0}, {extent_0, extent_1}), *this);
614 result = Result(result_);
615 }
616};
617
618template <typename DT, typename ... VP>
619void Eval<DT, VP ...>::many_neg_op(Teuchos::any& result, Teuchos::any& right) {
621}
622
623template <typename DT, typename ... VP>
624void Eval<DT, VP ...>::single_neg_op(Teuchos::any& result, Teuchos::any& right) {
626}
627
628struct ScalarAbs {
629 template <typename T>
630 static KOKKOS_FORCEINLINE_FUNCTION
631 T apply(T const& right) {
632 using std::abs;
633 return abs(right);
634 }
635};
636
637struct ScalarExp {
638 template <typename T>
639 static KOKKOS_FORCEINLINE_FUNCTION
640 T apply(T const& right) {
641 using std::exp;
642 return exp(right);
643 }
644};
645
646struct ScalarLog {
647 template <typename T>
648 static KOKKOS_FORCEINLINE_FUNCTION
649 T apply(T const& right) {
650 using std::log;
651 return log(right);
652 }
653};
654
656 template <typename T>
657 static KOKKOS_FORCEINLINE_FUNCTION
658 T apply(T const& right) {
659 using std::sqrt;
660 return sqrt(right);
661 }
662};
663
664struct ScalarSin {
665 template <typename T>
666 static KOKKOS_FORCEINLINE_FUNCTION
667 T apply(T const& right) {
668 using std::sin;
669 return sin(right);
670 }
671};
672
673struct ScalarCos {
674 template <typename T>
675 static KOKKOS_FORCEINLINE_FUNCTION
676 T apply(T const& right) {
677 using std::cos;
678 return cos(right);
679 }
680};
681
682struct ScalarTan {
683 template <typename T>
684 static KOKKOS_FORCEINLINE_FUNCTION
685 T apply(T const& right) {
686 using std::tan;
687 return tan(right);
688 }
689};
690
691template <typename Op, typename EvalType>
693 void operator()(std::string const& name, Teuchos::any& result, std::vector<Teuchos::any>& rhs) const {
694 auto& right = rhs.at(0);
695 using single_type = typename EvalType::const_single_view_type;
696 using many_type = typename EvalType::const_view_type;
697 if (right.type() == typeid(single_type)) {
699 } else if (right.type() == typeid(many_type)) {
701 } else {
702 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::ParserFail,
703 "Unexpected type " << right.typeName() << " passed to UnaryFunction \"" << name << "\"\n");
704 }
705 }
706};
707
708template <typename DT, typename ... VP>
710 using eval_type = Eval<DT, VP ...>;
711 EvalBase& eval_base = eval;
719}
720
721}} // end namespace panzer::Expr
722
723#endif // PANZER_EXPR_EVAL_IMPL_HPP
Declares the panzer::Expr::Eval templated class.
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
Base class for panzer::Expr::Eval, does everything that is independent of the Kokkos::View template p...
std::function< void(std::string const &name, Teuchos::any &, std::vector< Teuchos::any > &rhs)> Function
The type of user-defined functions which are callable in the math language.
void set(std::string const &name, Function const &value)
Registers an EvalBase::Function, binding it to a name and making it callable.
Interprets mathematical expressions in a string and evaluates them using Kokkos::View objects as valu...
Kokkos::View< scalar_type, VP ... > single_view_type
One scalar (same for all evaluation points)
Kokkos::View< typename RebindDataType< view_data_type, bool const >::type, VP ... > const_bool_view_type
One boolean for each evaluation point, read-only.
typename original_view_type::non_const_value_type scalar_type
The scalar type.
Kokkos::View< bool const, VP ... > const_single_bool_view_type
One boolean (same for all evaluation points), read-only.
void many_many_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void single_single_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
void many_neg_op(Teuchos::any &result, Teuchos::any &right) override
void make_constant(Teuchos::any &result, double const &value) override
void single_single_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void single_many_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void many_many_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
void set(std::string const &name, bool value)
Assign a boolean value to a variable symbol.
void inspect_arg(Teuchos::any const &arg, bool &is_many, bool &is_bool) override
void many_single_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
Kokkos::View< typename RebindDataType< view_data_type, scalar_type const >::type, VP ... > const_view_type
One scalar for each evaluation point, read-only.
void single_neg_op(Teuchos::any &result, Teuchos::any &right) override
Kokkos::View< scalar_type const, VP ... > const_single_view_type
One scalar (same for all evaluation points), read-only.
void single_many_ternary_op(Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right) override
Kokkos::View< bool, VP ... > single_bool_view_type
One boolean (same for all evaluation points)
void many_single_binary_op(BinaryOpCode code, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right) override
void set_cmath_functions(Eval< DT, VP ... > &eval)
Add support for functions such as sqrt(), sin(), and cos()
BinaryOpCode
Denotes the native binary operators in the Teuchos::MathExpr language.
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type) const
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
BinaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &left, Teuchos::any &right)
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral, Integral)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i, Integral)
static KOKKOS_FORCEINLINE_FUNCTION ViewType::reference_type index(ViewType const &x, Integral i, Integral j)
static constexpr size_t right_value
static constexpr size_t value
static constexpr size_t left_value
Builds on RebindDataType, but acts directly on a Kokkos::View type.
typename RebindViewType< biggest_type, typename biggest_type::non_const_value_type >::type type
static constexpr size_t a_rank
typename std::conditional<(b_rank > a_rank), B, A >::type biggest_type
static constexpr size_t b_rank
typename RebindViewType< biggest_type, typename biggest_type::const_value_type >::type const_type
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(bool left, bool right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION bool apply(bool left, bool right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &left, T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(T const &right)
static KOKKOS_FORCEINLINE_FUNCTION T apply(bool cond, T const &left, T const &right)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
typename TernaryResultType< Cond, Left, Right >::type Result
TernaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right)
typename TernaryResultType< Cond, Left, Right >::non_const_type NonConstResult
TernaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &cond, Teuchos::any &left, Teuchos::any &right)
typename TernaryResultType< Cond, Left, Right >::type Result
typename TernaryResultType< Cond, Left, Right >::non_const_type NonConstResult
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
typename std::conditional<(b_rank > a_rank), B, A >::type biggest_ab_type
typename RebindViewType< biggest_type, typename A::const_value_type >::type type
typename std::conditional<(c_rank > biggest_ab_type::rank), C, biggest_ab_type >::type biggest_type
typename RebindViewType< biggest_type, typename A::non_const_value_type >::type non_const_type
void operator()(std::string const &name, Teuchos::any &result, std::vector< Teuchos::any > &rhs) const
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)
typename Result::execution_space execution_space
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
typename Result::execution_space execution_space
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i) const
KOKKOS_INLINE_FUNCTION void operator()(typename execution_space::size_type i, typename execution_space::size_type j) const
typename RebindViewType< Result, typename Result::non_const_value_type >::type NonConstResult
typename Result::execution_space execution_space
UnaryFunctor(std::string const &name, Teuchos::any &result, Teuchos::any &right)