Intrepid2
Intrepid2_CellToolsDefPhysToRef.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Intrepid2 Package
4//
5// Copyright 2007 NTESS and the Intrepid2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10
16#ifndef __INTREPID2_CELLTOOLS_DEF_PHYS_TO_REF_HPP__
17#define __INTREPID2_CELLTOOLS_DEF_PHYS_TO_REF_HPP__
18
19// disable clang warnings
20#if defined (__clang__) && !defined (__INTEL_COMPILER)
21#pragma clang system_header
22#endif
23
24namespace Intrepid2 {
25
26
27 //============================================================================================//
28 // //
29 // Reference-to-physical frame mapping and its inverse //
30 // //
31 //============================================================================================//
32
33 template<typename DeviceType>
34 template<typename refPointValueType, class ...refPointProperties,
35 typename physPointValueType, class ...physPointProperties,
36 typename worksetCellValueType, class ...worksetCellProperties>
37 void
39 mapToReferenceFrame( Kokkos::DynRankView<refPointValueType,refPointProperties...> refPoints,
40 const Kokkos::DynRankView<physPointValueType,physPointProperties...> physPoints,
41 const Kokkos::DynRankView<worksetCellValueType,worksetCellProperties...> worksetCell,
42 const shards::CellTopology cellTopo ) {
43 constexpr bool are_accessible =
44 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
45 typename decltype(refPoints)::memory_space>::accessible &&
46 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
47 typename decltype(physPoints)::memory_space>::accessible &&
48 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
49 typename decltype(worksetCell)::memory_space>::accessible;
50
51 static_assert(are_accessible, "CellTools<DeviceType>::mapToReferenceFrame(..): input/output views' memory spaces are not compatible with DeviceType");
52
53#ifdef HAVE_INTREPID2_DEBUG
54 CellTools_mapToReferenceFrameArgs(refPoints, physPoints, worksetCell, cellTopo);
55#endif
56 using deviceType = typename decltype(refPoints)::device_type;
57
59 typedef Kokkos::DynRankView<typename ScalarTraits<refPointValueType>::scalar_type,deviceType> refPointViewSpType;
60
61 const auto spaceDim = cellTopo.getDimension();
62 refPointViewSpType
63 cellCenter("CellTools::mapToReferenceFrame::cellCenter", spaceDim);
64 getReferenceCellCenter(cellCenter, cellTopo);
65
66 // Default: map (C,P,D) array of physical pt. sets to (C,P,D) array. Requires (C,P,D) initial guess.
67 const auto numCells = worksetCell.extent(0);
68 const auto numPoints = physPoints.extent(1);
69
70 // init guess is created locally and non fad whatever refpoints type is
71 using result_layout = typename DeduceLayout< decltype(refPoints) >::result_layout;
72 auto vcprop = Kokkos::common_view_alloc_prop(refPoints);
73 using common_value_type = refPointValueType;
74 Kokkos::DynRankView< common_value_type, result_layout, deviceType > initGuess ( Kokkos::view_alloc("CellTools::mapToReferenceFrame::initGuess", vcprop), numCells, numPoints, spaceDim );
75 //refPointViewSpType initGuess("CellTools::mapToReferenceFrame::initGuess", numCells, numPoints, spaceDim);
76 rst::clone(initGuess, cellCenter);
77
78 mapToReferenceFrameInitGuess(refPoints, initGuess, physPoints, worksetCell, cellTopo);
79 }
80
81
82 template<typename DeviceType>
83 template<typename refPointValueType, class ...refPointProperties,
84 typename initGuessValueType, class ...initGuessProperties,
85 typename physPointValueType, class ...physPointProperties,
86 typename worksetCellValueType, class ...worksetCellProperties,
87 typename HGradBasisPtrType>
88 void
90 mapToReferenceFrameInitGuess( Kokkos::DynRankView<refPointValueType,refPointProperties...> refPoints,
91 const Kokkos::DynRankView<initGuessValueType,initGuessProperties...> initGuess,
92 const Kokkos::DynRankView<physPointValueType,physPointProperties...> physPoints,
93 const Kokkos::DynRankView<worksetCellValueType,worksetCellProperties...> worksetCell,
94 const HGradBasisPtrType basis ) {
95#ifdef HAVE_INTREPID2_DEBUG
96 CellTools_mapToReferenceFrameInitGuessArgs(refPoints, initGuess, physPoints, worksetCell,
97 basis->getBaseCellTopology());
98
99#endif
100
101 constexpr bool are_accessible =
102 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
103 typename decltype(refPoints)::memory_space>::accessible &&
104 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
105 typename decltype(initGuess)::memory_space>::accessible &&
106 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
107 typename decltype(physPoints)::memory_space>::accessible &&
108 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
109 typename decltype(worksetCell)::memory_space>::accessible;
110
111 static_assert(are_accessible, "CellTools<DeviceType>::mapToReferenceFrameInitGuess(..): input/output views' memory spaces are not compatible with DeviceType");
112
113
114 const auto cellTopo = basis->getBaseCellTopology();
115 const auto spaceDim = cellTopo.getDimension();
116
117 // Default: map (C,P,D) array of physical pt. sets to (C,P,D) array.
118 // Requires (C,P,D) temp arrays and (C,P,D,D) Jacobians.
119 const auto numCells = worksetCell.extent(0);
120 const auto numPoints = physPoints.extent(1);
121
122 using rst = RealSpaceTools<DeviceType>;
123 const auto tol = tolerence();
124
125 using result_layout = typename DeduceLayout< decltype(refPoints) >::result_layout;
126 auto vcprop = Kokkos::common_view_alloc_prop(refPoints);
127 using viewType = Kokkos::DynRankView<typename decltype(refPoints)::value_type, result_layout, DeviceType >;
128
129 // Temp arrays for Newton iterates and Jacobians. Resize according to rank of ref. point array
130 viewType xOld(Kokkos::view_alloc("CellTools::mapToReferenceFrameInitGuess::xOld", vcprop), numCells, numPoints, spaceDim);
131 viewType xTmp(Kokkos::view_alloc("CellTools::mapToReferenceFrameInitGuess::xTmp", vcprop), numCells, numPoints, spaceDim);
132
133 // deep copy may not work with FAD but this is right thing to do as it can move data between devices
134 Kokkos::deep_copy(xOld, initGuess);
135
136 // jacobian should select fad dimension between xOld and worksetCell as they are input; no front interface yet
137 auto vcpropJ = Kokkos::common_view_alloc_prop(refPoints, worksetCell);
138 // using valueTypeJ = typename Sacado::Promote<typename decltype(refPoints)::value_type,
139 // typename decltype(worksetCell)::value_type>::type;
140 using valueTypeJ = std::common_type_t<typename decltype(refPoints)::value_type,
141 typename decltype(worksetCell)::value_type>;
142 using viewTypeJ = Kokkos::DynRankView<valueTypeJ, result_layout, DeviceType >;
143 viewTypeJ jacobian(Kokkos::view_alloc("CellTools::mapToReferenceFrameInitGuess::jacobian", vcpropJ), numCells, numPoints, spaceDim, spaceDim);
144 viewTypeJ jacobianInv(Kokkos::view_alloc("CellTools::mapToReferenceFrameInitGuess::jacobianInv", vcpropJ), numCells, numPoints, spaceDim, spaceDim);
145
146 using errorViewType = Kokkos::DynRankView<typename ScalarTraits<refPointValueType>::scalar_type, DeviceType>;
147 errorViewType
148 xScalarTmp ("CellTools::mapToReferenceFrameInitGuess::xScalarTmp", numCells, numPoints, spaceDim),
149 errorPointwise("CellTools::mapToReferenceFrameInitGuess::errorPointwise", numCells, numPoints),
150 errorCellwise ("CellTools::mapToReferenceFrameInitGuess::errorCellwise", numCells);
151
152 // Newton method to solve the equation F(refPoints) - physPoints = 0:
153 // refPoints = xOld - DF^{-1}(xOld)*(F(xOld) - physPoints) = xOld + DF^{-1}(xOld)*(physPoints - F(xOld))
154 for (ordinal_type iter=0;iter<Parameters::MaxNewton;++iter) {
155
156 // Jacobians at the old iterates and their inverses.
157 setJacobian(jacobian, xOld, worksetCell, basis);
158 setJacobianInv(jacobianInv, jacobian);
159
160 // The Newton step.
161 mapToPhysicalFrame(xTmp, xOld, worksetCell, basis); // xTmp <- F(xOld)
162 rst::subtract(xTmp, physPoints, xTmp); // xTmp <- physPoints - F(xOld)
163 rst::matvec(refPoints, jacobianInv, xTmp); // refPoints <- DF^{-1}( physPoints - F(xOld) )
164 rst::add(refPoints, xOld); // refPoints <- DF^{-1}( physPoints - F(xOld) ) + xOld
165
166 // l2 error (Euclidean distance) between old and new iterates: |xOld - xNew|
167 rst::subtract(xTmp, xOld, refPoints);
168
169 // extract values
170 rst::extractScalarValues(xScalarTmp, xTmp);
171 rst::vectorNorm(errorPointwise, xScalarTmp, NORM_TWO);
172
173 // Average L2 error for a multiple sets of physical points: error is rank-2 (C,P) array
174 rst::vectorNorm(errorCellwise, errorPointwise, NORM_ONE);
175
176 auto errorCellwise_h = Kokkos::create_mirror_view(errorCellwise);
177 Kokkos::deep_copy(errorCellwise_h, errorCellwise);
178 const auto errorTotal = rst::Serial::vectorNorm(errorCellwise_h, NORM_ONE);
179
180 // Stopping criterion:
181 if (errorTotal < tol)
182 break;
183
184 // initialize next Newton step ( this is not device friendly )
185 Kokkos::deep_copy(xOld, refPoints);
186 }
187 }
188
189}
190
191#endif
void CellTools_mapToReferenceFrameArgs(const refPointViewType refPoints, const physPointViewType physPoints, const worksetCellViewType worksetCell, const shards::CellTopology cellTopo)
Validates arguments to Intrepid2::CellTools::mapToReferenceFrame with default initial guess.
static void mapToReferenceFrame(Kokkos::DynRankView< refPointValueType, refPointProperties... > refPoints, const Kokkos::DynRankView< physPointValueType, physPointProperties... > physPoints, const Kokkos::DynRankView< worksetCellValueType, worksetCellProperties... > worksetCell, const shards::CellTopology cellTopo)
Computes , the inverse of the reference-to-physical frame map using a default initial guess.
static void mapToReferenceFrameInitGuess(Kokkos::DynRankView< refPointValueType, refPointProperties... > refPoints, const Kokkos::DynRankView< initGuessValueType, initGuessProperties... > initGuess, const Kokkos::DynRankView< physPointValueType, physPointProperties... > physPoints, const Kokkos::DynRankView< worksetCellValueType, worksetCellProperties... > worksetCell, const HGradBasisPtrType basis)
Computation of , the inverse of the reference-to-physical frame map using user-supplied initial guess...
static constexpr ordinal_type MaxNewton
Maximum number of Newton iterations used internally in methods such as computing the action of the in...
Implementation of basic linear algebra functionality in Euclidean space.
layout deduction (temporary meta-function)