Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_GatherNormals_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_GATHER_NORMALS_IMPL_HPP
44#define PANZER_GATHER_NORMALS_IMPL_HPP
45
46#include "Teuchos_Assert.hpp"
47#include "Phalanx_DataLayout.hpp"
48
49#include "Panzer_PureBasis.hpp"
50#include "Kokkos_ViewFactory.hpp"
51
52#include "Intrepid2_Kernels.hpp"
53#include "Intrepid2_OrientationTools.hpp"
54
55#include "Teuchos_FancyOStream.hpp"
56
57template<typename EvalT,typename Traits>
60 const Teuchos::ParameterList& p)
61{
62 dof_name_ = (p.get< std::string >("DOF Name"));
63
64 if(p.isType< Teuchos::RCP<PureBasis> >("Basis"))
65 basis_ = p.get< Teuchos::RCP<PureBasis> >("Basis");
66 else
67 basis_ = p.get< Teuchos::RCP<const PureBasis> >("Basis");
68
69 pointRule_ = p.get<Teuchos::RCP<const PointRule> >("Point Rule");
70
71 Teuchos::RCP<PHX::DataLayout> basis_layout = basis_->functional;
72 Teuchos::RCP<PHX::DataLayout> vector_layout_vector = basis_->functional_grad;
73
74 // some sanity checks
75 TEUCHOS_ASSERT(basis_->isVectorBasis());
76
77 // setup the orientation field
78 std::string orientationFieldName = basis_->name() + " Orientation";
79 // setup all fields to be evaluated and constructed
81 pointValues_.setupArrays(pointRule_);
82
83 // the field manager will allocate all of these field
85 this->addDependentField(constJac_);
86
87 gatherFieldNormals_ = PHX::MDField<ScalarT,Cell,NODE,Dim>(dof_name_+"_Normals",vector_layout_vector);
88 this->addEvaluatedField(gatherFieldNormals_);
89
90 this->setName("Gather Normals");
91}
92
93// **********************************************************************
94template<typename EvalT,typename Traits>
98{
99 auto orientations = d.orientations_;
100 orientations_ = Kokkos::View<Intrepid2::Orientation*>("orientations_",orientations->size());
101 auto orientations_host = Kokkos::create_mirror_view(orientations_);
102 for (size_t i=0; i < orientations->size(); ++i)
103 orientations_host(i) = (*orientations)[i];
104 Kokkos::deep_copy(orientations_,orientations_host);
105
106 this->utils.setFieldData(pointValues_.jac,fm);
107
108 const shards::CellTopology & parentCell = *basis_->getCellTopology();
109 int sideDim = parentCell.getDimension()-1;
110 sideParam_ = Intrepid2::RefSubcellParametrization<PHX::Device>::get(sideDim, parentCell.getKey());
111
112 int numFaces = gatherFieldNormals_.extent(1);
113 keys_ = Kokkos::View<unsigned int*>("parentCell.keys",numFaces);
114 auto keys_host = Kokkos::create_mirror_view(keys_);
115 for (int i=0; i < numFaces; ++i)
116 keys_host(i) = parentCell.getKey(sideDim,i);
117 Kokkos::deep_copy(keys_,keys_host);
118
119 // allocate space that is sized correctly for AD
120 int cellDim = parentCell.getDimension();
121 refEdges_ = Kokkos::createDynRankViewWithType<Kokkos::DynRankView<ScalarT,PHX::Device>>(gatherFieldNormals_.get_static_view(),"ref_edges", (*d.worksets_)[0].num_cells, sideDim, cellDim);
122 phyEdges_ = Kokkos::createDynRankViewWithType<Kokkos::DynRankView<ScalarT,PHX::Device>>(gatherFieldNormals_.get_static_view(),"phy_edges", (*d.worksets_)[0].num_cells, sideDim, cellDim);
123}
124
125// **********************************************************************
126template<typename EvalT,typename Traits>
128evaluateFields(typename Traits::EvalData workset)
129{
130
131 if(workset.num_cells<=0)
132 return;
133
134 int numFaces = gatherFieldNormals_.extent(1);
135 const auto worksetJacobians = pointValues_.jac.get_view();
136 const auto cell_local_ids = workset.getLocalCellIDs();
137 auto gatherFieldNormals = gatherFieldNormals_;
138 auto sideParam = sideParam_;
139 auto keys = keys_;
140 auto orientations = orientations_;
141 auto refEdges = refEdges_;
142 auto phyEdges = phyEdges_;
143
144 // Loop over workset faces and edge points
145 Kokkos::parallel_for("panzer::GatherNormals",workset.num_cells,KOKKOS_LAMBDA(const int c){
146 int faceOrts[6] = {};
147 orientations(cell_local_ids(c)).getFaceOrientation(faceOrts, numFaces);
148
149 for(int pt = 0; pt < numFaces; pt++) {
150 auto ortEdgeTan_U = Kokkos::subview(refEdges, c, 0, Kokkos::ALL());
151 auto ortEdgeTan_V = Kokkos::subview(refEdges, c, 1, Kokkos::ALL());
152
153 auto tmpRefEdges = Kokkos::subview(refEdges, c, Kokkos::ALL(), Kokkos::ALL());
154 Intrepid2::Impl::OrientationTools::getRefSubcellTangents(tmpRefEdges,
155 sideParam,
156 keys(pt),
157 pt,
158 faceOrts[pt]);
159
160 auto phyEdgeTan_U = Kokkos::subview(phyEdges, c, 0, Kokkos::ALL());
161 auto phyEdgeTan_V = Kokkos::subview(phyEdges, c, 1, Kokkos::ALL());
162 auto J = Kokkos::subview(worksetJacobians, c, pt, Kokkos::ALL(), Kokkos::ALL());
163
164 Intrepid2::Kernels::Serial::matvec_product(phyEdgeTan_U, J, ortEdgeTan_U);
165 Intrepid2::Kernels::Serial::matvec_product(phyEdgeTan_V, J, ortEdgeTan_V);
166
167 // take the cross product of the two vectors
168 gatherFieldNormals(c,pt,0) = (phyEdgeTan_U(1)*phyEdgeTan_V(2) - phyEdgeTan_U(2)*phyEdgeTan_V(1));
169 gatherFieldNormals(c,pt,1) = (phyEdgeTan_U(2)*phyEdgeTan_V(0) - phyEdgeTan_U(0)*phyEdgeTan_V(2));
170 gatherFieldNormals(c,pt,2) = (phyEdgeTan_U(0)*phyEdgeTan_V(1) - phyEdgeTan_U(1)*phyEdgeTan_V(0));
171 }
172 });
173
174}
175
176#endif
void evaluateFields(typename Traits::EvalData d)
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &vm)
PHX::MDField< ScalarT, Cell, NODE, Dim > gatherFieldNormals_
Kokkos::View< unsigned int * > keys_
PointValues2< double > pointValues_
Kokkos::View< Intrepid2::Orientation * > orientations_
PHX::MDField< const double, Cell, IP, Dim, Dim > constJac_
Teuchos::RCP< const PointRule > pointRule_
Kokkos::DynRankView< ScalarT, PHX::Device > refEdges_
Intrepid2::RefSubcellParametrization< PHX::Device >::ConstViewType sideParam_
Teuchos::RCP< const PureBasis > basis_
Kokkos::DynRankView< ScalarT, PHX::Device > phyEdges_
Kokkos::View< const int *, PHX::Device > getLocalCellIDs() const
Get the local cell IDs for the workset.
int num_cells
DEPRECATED - use: numCells().
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
Teuchos::RCP< const std::vector< Intrepid2::Orientation > > orientations_
const panzer::Workset & EvalData
const SD & SetupData