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 //
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_STK_PROJECT_FIELD_IMPL_HPP
44 #define PANZER_STK_PROJECT_FIELD_IMPL_HPP
45 
46 #include "Teuchos_Assert.hpp"
47 #include "Phalanx_DataLayout.hpp"
48 
49 #include "Intrepid2_ProjectionTools.hpp"
50 #include "Intrepid2_OrientationTools.hpp"
51 
52 #include "Panzer_PureBasis.hpp"
54 #include "Kokkos_ViewFactory.hpp"
55 
56 #include "Teuchos_FancyOStream.hpp"
57 
58 namespace panzer_stk {
59 
60 template<typename EvalT,typename Traits>
62 ProjectField(const std::string & inName, Teuchos::RCP<panzer::PureBasis> src,
63  Teuchos::RCP<panzer::PureBasis> dst, std::string outName):
64  srcBasis_(src), dstBasis_(dst)
65 {
66  using panzer::Cell;
67  using panzer::BASIS;
68 
69  static_assert(std::is_same<EvalT,panzer::Traits::Residual>::value);
70 
73 
74  if (outName == "") outName = inName;
75  result_ = PHX::MDField<ScalarT,Cell,BASIS>(outName,dstBasis_layout);
76  this->addEvaluatedField(result_);
77 
78  // This shouldn't get modified but needs to be non const
79  // because of downstream templating in intrepid2
80  source_ = PHX::MDField<ScalarT,Cell,BASIS>(inName,srcBasis_layout);
81  this->addNonConstDependentField(source_);
82 
83  this->setName("Project Field");
84 
85  // storage for local (to the workset) orientations
86  auto maxWorksetSize = srcBasis_->functional->extent(0); // max number of cells
87  local_orts_ = Kokkos::DynRankView<Intrepid2::Orientation,PHX::Device>("orts",maxWorksetSize);
88 
89 }
90 
91 // **********************************************************************
92 template<typename EvalT,typename Traits>
94 postRegistrationSetup(typename Traits::SetupData d,
95  PHX::FieldManager<Traits>& /* fm */)
96 {
97  // coming from the orientations interface, this includes all orts for the process
98  orientations_ = d.orientations_;
99 }
100 
101 // **********************************************************************
102 template<typename EvalT,typename Traits>
104 evaluateFields(typename Traits::EvalData workset)
105 {
106 
107  // Is there a chance workset is empty?
108  if (workset.num_cells<=0) return;
109 
110  // Perform local L2 projection
111  using pts = Intrepid2::ProjectionTools<PHX::Device>;
112 
113  size_t numCells = workset.num_cells;
114  const auto cell_range = std::pair<int,int>(0,numCells);
115  // local_orts_ may be too large for final workset so we do the standard subview trick
116  auto sub_local_orts = Kokkos::subview(local_orts_,cell_range);
117  auto orts_host = Kokkos::create_mirror_view(sub_local_orts);
118 
119  // First, need to copy orientations to device
120  if (orientations_ == Teuchos::null) {
121  // If your bases don't require orientations, pass the default (0,0) orientation
122  for (size_t i=0; i < numCells; ++i)
123  orts_host(i) = Intrepid2::Orientation();
124  } else {
125  for (size_t i=0; i < numCells; ++i) // grab orientations for this workset
126  orts_host(i) = orientations_->at(workset.cell_local_ids[i]);
127  }
128  Kokkos::deep_copy(sub_local_orts,orts_host);
129 
130  // TODO BWR Revisit this... maybe we don't need pure basis upstream?
131  Teuchos::RCP<Intrepid2::Basis<PHX::exec_space,double,double> > dstBasis = dstBasis_->getIntrepid2Basis();
132  Teuchos::RCP<Intrepid2::Basis<PHX::exec_space,double,double> > srcBasis = srcBasis_->getIntrepid2Basis();
133 
134  // Same here, need subviews
135  auto sub_result = Kokkos::subview(result_.get_view(),cell_range,Kokkos::ALL());
136  auto sub_source = Kokkos::subview(source_.get_view(),cell_range,Kokkos::ALL());
137 
138  pts::projectField(sub_result,dstBasis.get(),
139  sub_source,srcBasis.get(),sub_local_orts);
140 
141 }
142 
143 }
144 
145 #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;