1 #ifndef VERTEXCFD_CLOSURE_SINGULARVALUEELEMENTLENGTH_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_SINGULARVALUEELEMENTLENGTH_IMPL_HPP
4 #include <Panzer_HierarchicParallelism.hpp>
5 #include <Panzer_Workset_Utilities.hpp>
19 namespace ClosureModel
22 template<
class EvalType,
class Traits>
23 SingularValueElementLength<EvalType, Traits>::SingularValueElementLength(
24 const panzer::IntegrationRule& ir,
25 const std::string& method,
26 const std::string& prefix)
27 : _element_length(prefix +
"element_length", ir.dl_vector)
28 , _ir_degree(ir.cubature_degree)
30 if (method ==
"singular_value_min")
32 _method = Method::Min;
34 else if (method ==
"singular_value_max")
36 _method = Method::Max;
40 const std::string msg =
41 "Element Length Method '" + method +
42 "' is not a correct input.\n"
43 "Choose between 'singular_value_min' or 'singular_value_max'";
44 throw std::runtime_error(msg);
47 this->addEvaluatedField(_element_length);
48 this->setName(
"Singular Value Element Length");
52 template<
class EvalType,
class Traits>
53 void SingularValueElementLength<EvalType, Traits>::postRegistrationSetup(
54 typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
56 _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
60 template<
class EvalType,
class Traits>
61 void SingularValueElementLength<EvalType, Traits>::evaluateFields(
62 typename Traits::EvalData workset)
64 _cell_jac = workset.int_rules[_ir_index]->jac;
65 auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
67 Kokkos::parallel_for(this->getName(), policy, *
this);
71 template<
class EvalType,
class Traits>
72 KOKKOS_INLINE_FUNCTION
void
73 SingularValueElementLength<EvalType, Traits>::operator()(
74 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
76 const int cell = team.league_rank();
77 const int num_point = _element_length.extent(1);
78 const int num_space_dim = _element_length.extent(2);
81 Kokkos::TeamThreadRange(team, 0, num_point), [&](
const int point) {
91 const auto a11 = _cell_jac(cell, point, 0, 0);
92 const auto a12 = _cell_jac(cell, point, 0, 1);
93 const auto a21 = _cell_jac(cell, point, 1, 0);
94 const auto a22 = _cell_jac(cell, point, 1, 1);
98 const double b = -(a11 * a11 + a12 * a12 + a21 * a21 + a22 * a22);
99 const double c = -(a11 * a21 + a12 * a22) * (a11 * a21 + a12 * a22)
100 + (a11 * a11 + a12 * a12)
101 * (a21 * a21 + a22 * a22);
104 const double delta = fmax(b * b - 4 * a * c, 0.0);
107 const double lambda1 = 0.5 * (-b - sqrt(delta)) / a;
108 const double lambda2 = 0.5 * (-b + sqrt(delta)) / a;
111 const double h2 = _method == Method::Min ? fmin(lambda1, lambda2)
112 : fmax(lambda1, lambda2);
113 const double h = sqrt(h2);
117 for (
int i = 0; i < num_space_dim; i++)
119 _element_length(cell, point, i) = h;
129 #endif // end VERTEXCFD_CLOSURE_SINGULARVALUEELEMENTLENGTH_IMPL_HPP