Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_ProjectField_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef PANZER_STK_PROJECT_FIELD_IMPL_HPP
12 #define PANZER_STK_PROJECT_FIELD_IMPL_HPP
13 
14 #include "Teuchos_Assert.hpp"
15 #include "Phalanx_DataLayout.hpp"
16 
17 #include "Intrepid2_ProjectionTools.hpp"
18 #include "Intrepid2_OrientationTools.hpp"
19 
20 #include "Panzer_PureBasis.hpp"
22 #include "Kokkos_ViewFactory.hpp"
23 
24 #include "Teuchos_FancyOStream.hpp"
25 
26 namespace panzer_stk {
27 
28 template<typename EvalT,typename Traits>
30 ProjectField(const std::string & inName, Teuchos::RCP<panzer::PureBasis> src,
31  Teuchos::RCP<panzer::PureBasis> dst, std::string outName):
32  srcBasis_(src), dstBasis_(dst)
33 {
34  using panzer::Cell;
35  using panzer::BASIS;
36 
37  static_assert(std::is_same<EvalT,panzer::Traits::Residual>::value);
38 
41 
42  if (outName == "") outName = inName;
43  result_ = PHX::MDField<ScalarT,Cell,BASIS>(outName,dstBasis_layout);
44  this->addEvaluatedField(result_);
45 
46  // This shouldn't get modified but needs to be non const
47  // because of downstream templating in intrepid2
48  source_ = PHX::MDField<ScalarT,Cell,BASIS>(inName,srcBasis_layout);
49  this->addNonConstDependentField(source_);
50 
51  this->setName("Project Field");
52 
53  // storage for local (to the workset) orientations
54  auto maxWorksetSize = srcBasis_->functional->extent(0); // max number of cells
55  local_orts_ = Kokkos::DynRankView<Intrepid2::Orientation,PHX::Device>("orts",maxWorksetSize);
56 
57 }
58 
59 // **********************************************************************
60 template<typename EvalT,typename Traits>
62 postRegistrationSetup(typename Traits::SetupData d,
63  PHX::FieldManager<Traits>& /* fm */)
64 {
65  // coming from the orientations interface, this includes all orts for the process
66  orientations_ = d.orientations_;
67 }
68 
69 // **********************************************************************
70 template<typename EvalT,typename Traits>
72 evaluateFields(typename Traits::EvalData workset)
73 {
74 
75  // Is there a chance workset is empty?
76  if (workset.num_cells<=0) return;
77 
78  // Perform local L2 projection
79  using pts = Intrepid2::ProjectionTools<PHX::Device>;
80 
81  size_t numCells = workset.num_cells;
82  const auto cell_range = std::pair<int,int>(0,numCells);
83  // local_orts_ may be too large for final workset so we do the standard subview trick
84  auto sub_local_orts = Kokkos::subview(local_orts_,cell_range);
85  auto orts_host = Kokkos::create_mirror_view(sub_local_orts);
86 
87  // First, need to copy orientations to device
88  if (orientations_ == Teuchos::null) {
89  // If your bases don't require orientations, pass the default (0,0) orientation
90  for (size_t i=0; i < numCells; ++i)
91  orts_host(i) = Intrepid2::Orientation();
92  } else {
93  for (size_t i=0; i < numCells; ++i) // grab orientations for this workset
94  orts_host(i) = orientations_->at(workset.cell_local_ids[i]);
95  }
96  Kokkos::deep_copy(sub_local_orts,orts_host);
97 
98  // TODO BWR Revisit this... maybe we don't need pure basis upstream?
99  Teuchos::RCP<Intrepid2::Basis<PHX::exec_space,double,double> > dstBasis = dstBasis_->getIntrepid2Basis();
100  Teuchos::RCP<Intrepid2::Basis<PHX::exec_space,double,double> > srcBasis = srcBasis_->getIntrepid2Basis();
101 
102  // Same here, need subviews
103  auto sub_result = Kokkos::subview(result_.get_view(),cell_range,Kokkos::ALL());
104  auto sub_source = Kokkos::subview(source_.get_view(),cell_range,Kokkos::ALL());
105 
106  pts::projectField(sub_result,dstBasis.get(),
107  sub_source,srcBasis.get(),sub_local_orts);
108 
109 }
110 
111 }
112 
113 #endif
PHX::MDField< double, panzer::Cell, panzer::BASIS > source_
ProjectField(const std::string &inName, Teuchos::RCP< panzer::PureBasis > src, Teuchos::RCP< panzer::PureBasis > dst, std::string outname="")
T * get() const
Teuchos::RCP< const panzer::PureBasis > srcBasis_
Teuchos::RCP< const panzer::PureBasis > dstBasis_
PHX::MDField< double, panzer::Cell, panzer::BASIS > result_
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
void evaluateFields(typename Traits::EvalData d)
Kokkos::DynRankView< Intrepid2::Orientation, PHX::Device > local_orts_
Teuchos::RCP< PHX::DataLayout > functional
&lt;Cell,Basis&gt; or &lt;Cell,Basis&gt;