VertexCFD  0.0-dev
VertexCFD_Closure_WallDistance_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_WALLDISTANCE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_WALLDISTANCE_IMPL_HPP
3 
4 #include "mesh/VertexCFD_Mesh_GeometryPrimitives.hpp"
5 
6 #include <Panzer_Workset_Utilities.hpp>
7 
8 #include <cmath>
9 
10 namespace VertexCFD
11 {
12 namespace ClosureModel
13 {
14 
15 //---------------------------------------------------------------------------//
16 template<class EvalType, class Traits, int NumSpaceDim>
17 WallDistance<EvalType, Traits, NumSpaceDim>::WallDistance(
18  const panzer::IntegrationRule& ir,
19  Teuchos::RCP<Mesh::Topology::SidesetGeometry> sideset_geometry)
20  : _distance("distance", ir.dl_scalar)
21  , _ir_degree(ir.cubature_degree)
22 {
23  this->addEvaluatedField(_distance);
24  this->setName("distance");
25 
26  _key = sideset_geometry->topology()->getKey();
27  _sides = sideset_geometry->sides();
28 
29  _normals = Kokkos::View<double**, PHX::mem_space>(
30  "normals", _sides.extent(0), num_space_dim);
31 }
32 
33 //---------------------------------------------------------------------------//
34 template<class EvalType, class Traits, int NumSpaceDim>
35 void WallDistance<EvalType, Traits, NumSpaceDim>::postRegistrationSetup(
36  typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
37 {
38  _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
39  _number_worksets = (*sd.worksets_).size();
40 
41  // Initialize the size of the _distance_vector view
42  _distance_vector
43  = Kokkos::View<double***, PHX::mem_space>("distance_vector",
44  _number_worksets,
45  _distance.extent(0),
46  _distance.extent(1));
47 
48  // size the iterator vectors for storing intial workset cell data
49  _workset_id.resize(_number_worksets);
50 
51  // Loop over worksets to calculate wall distance and fill iterator data
52  for (std::size_t wks = 0; wks < (*sd.worksets_).size(); ++wks)
53  {
54  _current_workset = wks;
55  panzer::Workset workset = (*sd.worksets_)[wks];
56  // If the workset is empty, skip the iterator setup
57  if (workset.num_cells > 0)
58  {
59  _workset_id[wks] = workset.getIdentifier();
60  }
61  _ip_coords = workset.int_rules[_ir_index]->ip_coordinates;
62  auto policy = Kokkos::RangePolicy<PHX::exec_space, RegistrationTag>(
63  0, workset.num_cells);
64  // Call operator for wall distance over cells in workset "wks"
65  Kokkos::parallel_for(this->getName(), policy, *this);
66  }
67 }
68 
69 //---------------------------------------------------------------------------//
70 
71 //---------------------------------------------------------------------------//
72 template<class EvalType, class Traits, int NumSpaceDim>
73 void WallDistance<EvalType, Traits, NumSpaceDim>::evaluateFields(
74  typename Traits::EvalData workset)
75 {
76  // Only fill distance info if the workset is not null
77  if (workset.num_cells > 0)
78  {
79  for (int i = 0; i < _number_worksets; ++i)
80  {
81  // Check which workset is the current one
82  if (_workset_id[i] == workset.getIdentifier())
83  {
84  _current_workset = i;
85  break;
86  }
87  }
88 
89  // Loop over cells in the workset and points in the cell and set the
90  // distance based off pre-calculated value
91  auto policy = Kokkos::RangePolicy<PHX::exec_space, EvaluateTag>(
92  0, workset.num_cells);
93  Kokkos::parallel_for("SetDistanceField", policy, *this);
94  }
95 }
96 //---------------------------------------------------------------------------//
97 
98 //---------------------------------------------------------------------------//
99 template<class EvalType, class Traits, int NumSpaceDim>
100 KOKKOS_INLINE_FUNCTION void
101 WallDistance<EvalType, Traits, NumSpaceDim>::operator()(RegistrationTag,
102  const int cell) const
103 {
104  const int num_point = _distance.extent(1);
105  for (int point = 0; point < num_point; ++point)
106  {
107  double distance = 1e8;
108  double temp = 1e8;
109 
110  // loop over sides and calculate the minimum distance to the current ip
111  for (long unsigned int n = 0; n < _sides.extent(0); ++n)
112  {
113  // call the triangle distance function and store the distance if
114  // it is a minimum
115  if constexpr (num_space_dim == 3)
116  {
117  if (_key == shards::Tetrahedron<4>::key)
118  {
119  int index[3] = {0, 1, 2};
120  temp = GeometryPrimitives::distanceToTriangleFace(
121  _sides, _normals, n, _ip_coords, cell, point, index);
122  }
123  if (_key == shards::Hexahedron<8>::key)
124  {
125  int index[3] = {0, 1, 2};
126  const double t2 = GeometryPrimitives::distanceToTriangleFace(
127  _sides, _normals, n, _ip_coords, cell, point, index);
128  index[1] = 2;
129  index[2] = 3;
130  const double t1 = GeometryPrimitives::distanceToTriangleFace(
131  _sides, _normals, n, _ip_coords, cell, point, index);
132  temp = std::fmin(t1, t2);
133  }
134  }
135  if constexpr (num_space_dim == 2)
136  {
137  int index[2] = {0, 1};
138  temp = GeometryPrimitives::distanceToLinearEdge(
139  _sides, n, _ip_coords, cell, point, 2, index);
140  }
141  if (temp < distance)
142  {
143  distance = temp;
144  }
145  }
146 
147  _distance_vector(_current_workset, cell, point) = distance;
148  }
149 }
150 //---------------------------------------------------------------------------//
151 
152 //---------------------------------------------------------------------------//
153 template<class EvalType, class Traits, int NumSpaceDim>
154 KOKKOS_INLINE_FUNCTION void
155 WallDistance<EvalType, Traits, NumSpaceDim>::operator()(EvaluateTag,
156  const int cell) const
157 {
158  const int num_point = _distance.extent(1);
159  for (int point = 0; point < num_point; ++point)
160  {
161  _distance(cell, point)
162  = _distance_vector(_current_workset, cell, point);
163  }
164 }
165 //---------------------------------------------------------------------------//
166 
167 } // end namespace ClosureModel
168 } // end namespace VertexCFD
169 
170 #endif // end VERTEXCFD_CLOSURE_WALLDISTANCE_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23