VertexCFD  0.0-dev
VertexCFD_Closure_ExternalFields_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_EXTERNALFIELDS_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_EXTERNALFIELDS_IMPL_HPP
3 
4 #include <Panzer_HierarchicParallelism.hpp>
5 
6 namespace VertexCFD
7 {
8 namespace ClosureModel
9 {
10 //---------------------------------------------------------------------------//
11 template<class EvalType, class Traits>
12 ExternalFields<EvalType, Traits>::ExternalFields(
13  const std::string& evaluator_name,
14  const Teuchos::RCP<const ExternalFieldsManager<Traits>>&
15  external_fields_manager,
16  const std::vector<std::string>& external_field_names,
17  const Teuchos::RCP<const panzer::PureBasis>& basis)
18  : _num_field(external_field_names.size())
19  , _external_fields(_num_field)
20  , _global_indexer(external_fields_manager->globalIndexer())
21  , _field_ids(_num_field)
22  , _ghosted_field_data(external_fields_manager->ghostedFieldData())
23 {
24  // Setup evaluator data.
25  for (int f = 0; f < _num_field; ++f)
26  {
27  _external_fields[f]
28  = PHX::MDField<scalar_type, panzer::Cell, panzer::BASIS>(
29  external_field_names[f], basis->functional);
30  this->addEvaluatedField(_external_fields[f]);
31  }
32  this->setName(evaluator_name);
33 
34  // Get the field ids.
35  for (int f = 0; f < _num_field; ++f)
36  {
37  _field_ids[f] = _global_indexer->getFieldNum(external_field_names[f]);
38  }
39 }
40 
41 //---------------------------------------------------------------------------//
42 template<class EvalType, class Traits>
43 void ExternalFields<EvalType, Traits>::postRegistrationSetup(
44  typename Traits::SetupData d, PHX::FieldManager<Traits>&)
45 {
46  // Setup scratch data for reading the vector data.
47  _scratch_offsets.resize(_num_field);
48  const auto& workset_0 = (*d.worksets_)[0];
49  auto block_id = this->wda(workset_0).block_id;
50 
51  for (int f = 0; f < _num_field; ++f)
52  {
53  const auto& offsets
54  = _global_indexer->getGIDFieldOffsets(block_id, _field_ids[f]);
55  _scratch_offsets[f] = Kokkos::View<int*, PHX::Device>(
56  "external_field_offsets", offsets.size());
57  auto offsets_mirror = Kokkos::create_mirror(_scratch_offsets[f]);
58  for (std::size_t i = 0; i < offsets.size(); ++i)
59  {
60  offsets_mirror(i) = offsets[i];
61  }
62  Kokkos::deep_copy(_scratch_offsets[f], offsets_mirror);
63  }
64 
65  _scratch_lids = Kokkos::View<int**, PHX::Device>(
66  "lids",
67  _external_fields[0].extent(0),
68  _global_indexer->getElementBlockGIDCount(block_id));
69 }
70 
71 //---------------------------------------------------------------------------//
72 template<class EvalType, class Traits>
73 void ExternalFields<EvalType, Traits>::evaluateFields(typename Traits::EvalData d)
74 {
75  // Get the local ids.
76  _global_indexer->getElementLIDs(this->wda(d).cell_local_ids_k,
77  _scratch_lids);
78 
79  // Extract the data.
80  auto lids = _scratch_lids;
81  auto field_data = _ghosted_field_data;
82  for (int f = 0; f < _num_field; ++f)
83  {
84  auto offsets = _scratch_offsets[f];
85  auto gather_field = _external_fields[f].get_static_view();
86  Kokkos::parallel_for(
87  Kokkos::RangePolicy<PHX::Device>(0, d.num_cells),
88  KOKKOS_LAMBDA(const int cell) {
89  const int num_basis = offsets.extent(0);
90  for (int basis = 0; basis < num_basis; ++basis)
91  {
92  auto offset = offsets(basis);
93  auto lid = lids(cell, offset);
94  gather_field(cell, basis) = field_data(lid);
95  }
96  });
97  }
98 }
99 
100 //---------------------------------------------------------------------------//
101 
102 } // end namespace ClosureModel
103 } // end namespace VertexCFD
104 
105 #endif // end VERTEXCFD_CLOSURE_EXTERNALFIELDS_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23