Intrepid2
Intrepid2_ProjectionToolsDefL2.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kyungjoo Kim (kyukim@sandia.gov), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
49 #ifndef __INTREPID2_PROJECTIONTOOLSDEFL2_HPP__
50 #define __INTREPID2_PROJECTIONTOOLSDEFL2_HPP__
51 
53 #include "Intrepid2_ArrayTools.hpp"
55 
56 
57 namespace Intrepid2 {
58 namespace Experimental {
59 
60 template<typename SpT>
61 template<typename BasisType,
62 typename ortValueType, class ...ortProperties>
63 void
64 ProjectionTools<SpT>::getL2EvaluationPoints(typename BasisType::scalarViewType evaluationPoints,
65  const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
66  const BasisType* cellBasis,
67  ProjectionStruct<SpT, typename BasisType::scalarType> * projStruct,
68  const EvalPointsType evalPointType) {
69  typedef typename BasisType::scalarType scalarType;
70  typedef Kokkos::DynRankView<scalarType,SpT> scalarViewType;
71  typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
72  const auto cellTopo = cellBasis->getBaseCellTopology();
73  ordinal_type dim = cellTopo.getDimension();
74  ordinal_type numCells = evaluationPoints.extent(0);
75  const ordinal_type edgeDim = 1;
76  const ordinal_type faceDim = 2;
77 
78  ordinal_type numVertices = (cellBasis->getDofCount(0, 0) > 0) ? cellTopo.getVertexCount() : 0;
79  ordinal_type numEdges = (cellBasis->getDofCount(1, 0) > 0) ? cellTopo.getEdgeCount() : 0;
80  ordinal_type numFaces = (cellBasis->getDofCount(2, 0) > 0) ? cellTopo.getFaceCount() : 0;
81 
82  Kokkos::View<ordinal_type*> eOrt("eOrt", numEdges), fOrt("fOrt", numFaces);
83 
84  if(numVertices>0) {
85  //TODO: use lattice to retrieve vertex coordinates.
86  scalarViewType dofCoords("dofCoords", cellBasis->getCardinality(), dim);
87  cellBasis->getDofCoords(dofCoords);
88  for(ordinal_type iv=0; iv<numVertices; ++iv) {
89  ordinal_type idof = cellBasis->getDofOrdinal(0, iv, 0);
90  for(ordinal_type d=0; d<dim; d++)
91  for(ordinal_type ic=0; ic<numCells; ++ic)
92  evaluationPoints(ic,iv,d) = dofCoords(idof,d);
93  }
94  }
95 
96  for(ordinal_type ie=0; ie<numEdges; ++ie) {
97  range_type edgePointsRange;
98  scalarViewType cubPoints;
99  if(evalPointType == TARGET) {
100  edgePointsRange = projStruct->getTargetPointsRange(edgeDim, ie);
101  cubPoints = projStruct->getTargetEvalPoints(edgeDim, ie);
102  }
103  else {
104  edgePointsRange = projStruct->getBasisPointsRange(edgeDim, ie);
105  cubPoints = projStruct->getBasisEvalPoints(edgeDim, ie);
106  }
107 
108  scalarViewType orientedTargetCubPoints("orientedTargetCubPoints", cubPoints.extent(0),edgeDim);
109 
110  const auto topoKey = projStruct->getTopologyKey(edgeDim,ie);
111 
112  for(ordinal_type ic=0; ic<numCells; ++ic) {
113  orts(ic).getEdgeOrientation(eOrt.data(), numEdges);
114  ordinal_type ort = eOrt(ie);
115  Impl::OrientationTools::mapToModifiedReference(orientedTargetCubPoints,cubPoints,topoKey,ort);
116  CellTools<SpT>::mapToReferenceSubcell(Kokkos::subview(evaluationPoints,ic,edgePointsRange,Kokkos::ALL()), orientedTargetCubPoints, edgeDim, ie, cellBasis->getBaseCellTopology());
117  }
118  }
119 
120 
121  for(ordinal_type iface=0; iface<numFaces; ++iface) {
122 
123  scalarViewType cubPoints;
124  range_type facePointsRange;
125  if(evalPointType == TARGET) {
126  cubPoints = projStruct->getTargetEvalPoints(faceDim, iface);
127  facePointsRange = projStruct->getTargetPointsRange(faceDim, iface);
128  } else {
129  cubPoints = projStruct->getBasisEvalPoints(faceDim, iface);
130  facePointsRange = projStruct->getBasisPointsRange(faceDim, iface);
131  }
132 
133  scalarViewType faceCubPoints("faceCubPoints", cubPoints.extent(0), faceDim);
134 
135  const auto topoKey = projStruct->getTopologyKey(faceDim,iface);
136  for(ordinal_type ic=0; ic<numCells; ++ic) {
137 
138  orts(ic).getFaceOrientation(fOrt.data(), numFaces);
139 
140  ordinal_type ort = fOrt(iface);
141  Impl::OrientationTools::mapToModifiedReference(faceCubPoints,cubPoints,topoKey,ort);
142  CellTools<SpT>::mapToReferenceSubcell(Kokkos::subview(evaluationPoints, ic, facePointsRange, Kokkos::ALL()), faceCubPoints, faceDim, iface, cellBasis->getBaseCellTopology());
143  }
144  }
145 
146  if(cellBasis->getDofCount(dim,0)>0) {
147  range_type cellPointsRange;
148  scalarViewType cubPoints;
149  if(evalPointType == TARGET) {
150  cubPoints = projStruct->getTargetEvalPoints(dim, 0);
151  cellPointsRange = projStruct->getTargetPointsRange(dim, 0);
152  } else {
153  cubPoints = projStruct->getBasisEvalPoints(dim, 0);
154  cellPointsRange = projStruct->getBasisPointsRange(dim, 0);
155  }
156  RealSpaceTools<SpT>::clone(Kokkos::subview(evaluationPoints, Kokkos::ALL(), cellPointsRange, Kokkos::ALL()), cubPoints);
157  }
158 }
159 
160 
161 template<typename SpT>
162 template<typename basisCoeffsValueType, class ...basisCoeffsProperties,
163 typename funValsValueType, class ...funValsProperties,
164 typename BasisType,
165 typename ortValueType,class ...ortProperties>
166 void
167 ProjectionTools<SpT>::getL2BasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
168  const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
169  const typename BasisType::scalarViewType evaluationPoints,
170  const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
171  const BasisType* cellBasis,
172  ProjectionStruct<SpT, typename BasisType::scalarType> * projStruct){
173 
174  typedef typename Kokkos::Impl::is_space<SpT>::host_mirror_space::execution_space host_space_type;
175  typedef typename BasisType::scalarType scalarType;
176  typedef Kokkos::DynRankView<scalarType,SpT> scalarViewType;
177  typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
178  const auto cellTopo = cellBasis->getBaseCellTopology();
179  ordinal_type dim = cellTopo.getDimension();
180  ordinal_type numTotalEvaluationPoints(targetAtEvalPoints.extent(1));
181  ordinal_type basisCardinality = cellBasis->getCardinality();
182  ordinal_type numCells = targetAtEvalPoints.extent(0);
183  const ordinal_type edgeDim = 1;
184  const ordinal_type faceDim = 2;
185  const ordinal_type fieldDim = (targetAtEvalPoints.rank()==2) ? 1 : targetAtEvalPoints.extent(2);
186 
187  const std::string& name = cellBasis->getName();
188 
189  ordinal_type numVertices = (cellBasis->getDofCount(0, 0) > 0) ? cellTopo.getVertexCount() : 0;
190  ordinal_type numEdges = (cellBasis->getDofCount(1, 0) > 0) ? cellTopo.getEdgeCount() : 0;
191  ordinal_type numFaces = (cellBasis->getDofCount(2, 0) > 0) ? cellTopo.getFaceCount() : 0;
192 
193  Kokkos::View<ordinal_type*> eOrt("eOrt", numEdges);
194  Kokkos::View<ordinal_type*> fOrt("fOrt", numFaces);
195  scalarViewType refEdgeTan("refEdgeTan", dim);
196  scalarViewType refEdgeNormal("refEdgeNormal", dim);
197  scalarViewType refFaceTangents("refFaceTangents", dim, 2);
198  scalarViewType refFaceNormal("refFaceNormal", dim);
199  auto refFaceTanU = Kokkos::subview(refFaceTangents, Kokkos::ALL, 0);
200  auto refFaceTanV = Kokkos::subview(refFaceTangents, Kokkos::ALL, 1);
201 
202  ordinal_type numVertexDofs = numVertices;
203 
204  ordinal_type numEdgeDofs(0);
205  for(ordinal_type ie=0; ie<numEdges; ++ie)
206  numEdgeDofs += cellBasis->getDofCount(edgeDim,ie);
207 
208  ordinal_type numFaceDofs(0);
209  for(ordinal_type iface=0; iface<numFaces; ++iface)
210  numFaceDofs += cellBasis->getDofCount(faceDim,iface);
211 
212  Kokkos::View<ordinal_type*> computedDofs("computedDofs",numVertexDofs+numEdgeDofs+numFaceDofs);
213 
214  ordinal_type computedDofsCount = 0;
215 
216  ordinal_type numTotalCubPoints = projStruct->getNumBasisEvalPoints();
217  scalarViewType cubPoints("cubPoints",numCells,numTotalCubPoints, dim);
218  getL2EvaluationPoints(cubPoints, orts, cellBasis, projStruct, BASIS);
219 
220  scalarViewType basisAtCubPoints("basisAtCubPoints",numCells,basisCardinality, numTotalCubPoints, fieldDim);
221  scalarViewType basisAtTargetCubPoints("basisAtTargetCubPoints",numCells,basisCardinality, numTotalEvaluationPoints, fieldDim);
222  {
223  if(fieldDim == 1) {
224  scalarViewType nonOrientedBasisAtCubPoints("nonOrientedBasisAtCubPoints",numCells,basisCardinality, numTotalCubPoints);
225  scalarViewType nonOrientedBasisAtTargetCubPoints("nonOrientedBasisAtTargetCubPoints",numCells,basisCardinality, numTotalEvaluationPoints);
226  for(ordinal_type ic=0; ic<numCells; ++ic) {
227  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtTargetCubPoints,ic,Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(evaluationPoints, ic, Kokkos::ALL(), Kokkos::ALL()));
228  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtCubPoints,ic,Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(cubPoints, ic, Kokkos::ALL(), Kokkos::ALL()));
229  }
230  OrientationTools<SpT>::modifyBasisByOrientation(Kokkos::subview(basisAtCubPoints, Kokkos::ALL(), Kokkos::ALL(),
231  Kokkos::ALL(),0), nonOrientedBasisAtCubPoints, orts, cellBasis);
232  OrientationTools<SpT>::modifyBasisByOrientation(Kokkos::subview(basisAtTargetCubPoints, Kokkos::ALL(),
233  Kokkos::ALL(), Kokkos::ALL(),0), nonOrientedBasisAtTargetCubPoints, orts, cellBasis);
234 
235  }
236  else {
237  scalarViewType nonOrientedBasisAtCubPoints("nonOrientedBasisAtCubPoints",numCells,basisCardinality, numTotalCubPoints,fieldDim);
238  scalarViewType nonOrientedBasisAtTargetCubPoints("nonOrientedBasisAtTargetCubPoints",numCells,basisCardinality, numTotalEvaluationPoints,fieldDim);
239  for(ordinal_type ic=0; ic<numCells; ++ic) {
240  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtTargetCubPoints,ic,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(evaluationPoints, ic, Kokkos::ALL(), Kokkos::ALL()));
241  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtCubPoints,ic,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(cubPoints, ic, Kokkos::ALL(), Kokkos::ALL()));
242  }
243  OrientationTools<SpT>::modifyBasisByOrientation(basisAtCubPoints, nonOrientedBasisAtCubPoints, orts, cellBasis);
244  OrientationTools<SpT>::modifyBasisByOrientation(basisAtTargetCubPoints, nonOrientedBasisAtTargetCubPoints, orts, cellBasis);
245  }
246  }
247 
248  for(ordinal_type iv=0; iv<numVertices; ++iv) {
249  ordinal_type idof = cellBasis->getDofOrdinal(0, iv, 0);
250  computedDofs(computedDofsCount++) = idof;
251  for(ordinal_type ic=0; ic<numCells; ++ic)
252  basisCoeffs(ic,idof) = targetAtEvalPoints(ic,iv);
253  }
254 
255  bool isHCurlBAsis = name.find("HCURL") != std::string::npos;
256 
257  ordinal_type faceDofDim = isHCurlBAsis ? 2 : 1;
258 
259  scalarViewType edgeCoeff("edgeCoeff", fieldDim);
260  for(ordinal_type ie=0; ie<numEdges; ++ie) {
261 
262  if(fieldDim == 1)
263  edgeCoeff(0) = 1;
264  else if(isHCurlBAsis) {
265  CellTools<SpT>::getReferenceEdgeTangent(refEdgeTan,ie, cellTopo);
266  Kokkos::deep_copy(edgeCoeff,refEdgeTan);
267  } else {
268  CellTools<SpT>::getReferenceSideNormal(refEdgeNormal, ie, cellTopo);
269  Kokkos::deep_copy(edgeCoeff,refEdgeNormal);
270  }
271 
272  ordinal_type edgeCardinality = cellBasis->getDofCount(edgeDim,ie);
273  ordinal_type numCubPoints = projStruct->getNumBasisEvalPoints(edgeDim, ie);
274  ordinal_type numTargetCubPoints = projStruct->getNumTargetEvalPoints(edgeDim, ie);
275 
276  scalarViewType edgeBasisAtCubPoints("tanBasisAtElemCubPoints",numCells,edgeCardinality, numCubPoints);
277  scalarViewType edgeTargetAtTargetCubPoints("tanBasisAtTargetCubPoints",numCells, numTargetCubPoints);
278  scalarViewType weightedBasisAtElemCubPoints("weightedTanBasisAtElemCubPoints",numCells,edgeCardinality, numCubPoints);
279  scalarViewType weightedBasisAtTargetCubPoints("weightedTanBasisAtTargetCubPoints",numCells,edgeCardinality, numTargetCubPoints);
280  scalarViewType mComputedProjection("mComputedProjection", numCells, numCubPoints);
281 
282  scalarViewType targetEvalWeights = projStruct->getTargetEvalWeights(edgeDim, ie);
283  scalarViewType basisEvalWeights = projStruct->getBasisEvalWeights(edgeDim, ie);
284 
285  //Note: we are not considering the jacobian of the orientation map since it is simply a scalar term for the integrals and it does not affect the projection
286  ordinal_type offsetBasis = projStruct->getBasisPointsRange(edgeDim, ie).first;
287  ordinal_type offsetTarget = projStruct->getTargetPointsRange(edgeDim, ie).first;
288  for(ordinal_type j=0; j <edgeCardinality; ++j) {
289  ordinal_type jdof = cellBasis->getDofOrdinal(edgeDim, ie, j);
290  for(ordinal_type ic=0; ic<numCells; ++ic) {
291  for(ordinal_type iq=0; iq <numCubPoints; ++iq) {
292  for(ordinal_type d=0; d <fieldDim; ++d)
293  edgeBasisAtCubPoints(ic,j,iq) += basisAtCubPoints(ic,jdof,offsetBasis+iq,d)*edgeCoeff(d);
294  weightedBasisAtElemCubPoints(ic,j,iq) = edgeBasisAtCubPoints(ic,j,iq)*basisEvalWeights(iq);
295  }
296  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq) {
297  for(ordinal_type d=0; d <fieldDim; ++d)
298  weightedBasisAtTargetCubPoints(ic,j,iq) += basisAtTargetCubPoints(ic,jdof,offsetTarget+iq,d)*edgeCoeff(d)*targetEvalWeights(iq);
299  }
300  }
301  }
302 
303  for(ordinal_type ic=0; ic<numCells; ++ic)
304  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq)
305  for(ordinal_type d=0; d <fieldDim; ++d)
306  edgeTargetAtTargetCubPoints(ic,iq) += targetAtEvalPoints(ic,offsetTarget+iq,d)*edgeCoeff(d);
307 
308  for(ordinal_type j=0; j <numVertexDofs; ++j) {
309  ordinal_type jdof = computedDofs(j);
310  for(ordinal_type ic=0; ic<numCells; ++ic)
311  for(ordinal_type iq=0; iq <numCubPoints; ++iq)
312  for(ordinal_type d=0; d <fieldDim; ++d)
313  mComputedProjection(ic,iq) -= basisCoeffs(ic,jdof)*basisAtCubPoints(ic,jdof,offsetBasis+iq,d)*edgeCoeff(d);
314  }
315 
316 
317  scalarViewType edgeMassMat_("edgeMassMat_", numCells, edgeCardinality, edgeCardinality),
318  edgeRhsMat_("rhsMat_", numCells, edgeCardinality);
319 
320  scalarViewType cubWeights_("cubWeights_", numCells, 1, basisEvalWeights.extent(0)), targetEvalWeights_("targetEvalWeights", numCells, 1, targetEvalWeights.extent(0));
321  RealSpaceTools<SpT>::clone(cubWeights_, basisEvalWeights);
322  RealSpaceTools<SpT>::clone(targetEvalWeights_, targetEvalWeights);
323 
324  FunctionSpaceTools<SpT >::integrate(edgeMassMat_, edgeBasisAtCubPoints, weightedBasisAtElemCubPoints);
325  FunctionSpaceTools<SpT >::integrate(edgeRhsMat_, edgeTargetAtTargetCubPoints, weightedBasisAtTargetCubPoints);
326  FunctionSpaceTools<SpT >::integrate(edgeRhsMat_, mComputedProjection, weightedBasisAtElemCubPoints,true);
327 
328 
329  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> edgeMassMat("edgeMassMat", edgeCardinality,edgeCardinality);
330  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> edgeRhsMat("edgeRhsMat",edgeCardinality, 1);
331 
332  Teuchos::LAPACK<ordinal_type,funValsValueType> lapack;
333  ordinal_type info = 0;
334  for(ordinal_type ic=0; ic<numCells; ++ic) {
335  for(ordinal_type i=0; i<edgeCardinality; ++i) {
336  edgeRhsMat(i,0) = edgeRhsMat_(ic,i);
337  for(ordinal_type j=0; j<edgeCardinality; ++j)
338  edgeMassMat(i,j) = edgeMassMat_(ic,i,j);
339  }
340 
341  lapack.POSV('U', edgeCardinality, 1,
342  edgeMassMat.data(),
343  edgeMassMat.stride_1(),
344  edgeRhsMat.data(),
345  edgeRhsMat.stride_1(),
346  &info);
347 
348  if (info) {
349  std::stringstream ss;
350  ss << ">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
351  << "LAPACK return with error code: "
352  << info;
353  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
354  }
355 
356  for(ordinal_type i=0; i<edgeCardinality; ++i){
357  ordinal_type edge_dof = cellBasis->getDofOrdinal(edgeDim, ie, i);
358  basisCoeffs(ic,edge_dof) = edgeRhsMat(i,0);
359  }
360  }
361  for(ordinal_type i=0; i<edgeCardinality; ++i)
362  computedDofs(computedDofsCount++) = cellBasis->getDofOrdinal(edgeDim, ie, i);
363  }
364 
365  scalarViewType ortJacobian("ortJacobian", faceDim, faceDim);
366 
367  scalarViewType faceCoeff("faceCoeff", fieldDim, faceDofDim);
368  for(ordinal_type iface=0; iface<numFaces; ++iface) {
369 
370 
371  const auto topoKey = projStruct->getTopologyKey(faceDim,iface);
372 
373 
374  ordinal_type faceCardinality = cellBasis->getDofCount(faceDim,iface);
375 
376  ordinal_type numTargetCubPoints = projStruct->getNumTargetEvalPoints(faceDim, iface);
377  ordinal_type numCubPoints = projStruct->getNumBasisEvalPoints(faceDim, iface);
378 
379  if(fieldDim == 1)
380  faceCoeff(0,0) = 1;
381  else if(isHCurlBAsis) {
382  CellTools<SpT>::getReferenceFaceTangents(refFaceTanU, refFaceTanV,iface, cellTopo);
383  } else {
384  CellTools<SpT>::getReferenceFaceNormal(refFaceNormal, iface, cellTopo);
385  for(ordinal_type d=0; d <dim; ++d)
386  faceCoeff(d,0) = refFaceNormal(d);
387  }
388 
389  scalarViewType faceBasisDofAtCubPoints("normaBasisAtCubPoints",numCells,faceCardinality, numCubPoints,faceDofDim);
390  scalarViewType wBasisDofAtCubPoints("weightedNormalBasisAtCubPoints",numCells,faceCardinality, numCubPoints,faceDofDim);
391 
392  scalarViewType faceBasisAtTargetCubPoints("normalBasisAtTargetCubPoints",numCells,faceCardinality, numTargetCubPoints,faceDofDim);
393  scalarViewType wBasisBasisAtTargetCubPoints("weightedNormalBasisAtTargetCubPoints",numCells,faceCardinality, numTargetCubPoints,faceDofDim);
394 
395  scalarViewType targetAtTargetCubPoints("targetAtTargetCubPoints",numCells, numTargetCubPoints,faceDofDim);
396  scalarViewType mComputedProjection("mNormalComputedProjection", numCells,numCubPoints,faceDofDim);
397 
398  ordinal_type offsetBasis = projStruct->getBasisPointsRange(faceDim, iface).first;
399  ordinal_type offsetTarget = projStruct->getTargetPointsRange(faceDim, iface).first;
400  scalarViewType targetCubWeights = projStruct->getTargetEvalWeights(faceDim, iface);
401  scalarViewType CubWeights = projStruct->getBasisEvalWeights(faceDim, iface);
402 
403  //Note: we are not considering the jacobian of the orientation map since it is simply a scalar term for the integrals and it does not affect the projection
404  for(ordinal_type ic=0; ic<numCells; ++ic) {
405 
406  orts(ic).getFaceOrientation(fOrt.data(), numFaces);
407 
408  ordinal_type ort = fOrt(iface);
409  if(isHCurlBAsis) {
410  Kokkos::deep_copy(faceCoeff,0);
411  Impl::OrientationTools::getJacobianOfOrientationMap(ortJacobian, topoKey, ort);
412  for(ordinal_type d=0; d <dim; ++d)
413  for(ordinal_type itan=0; itan <faceDim; ++itan)
414  for(ordinal_type jtan=0; jtan <faceDim; ++jtan)
415  faceCoeff(d,itan) += refFaceTangents(d, jtan)*ortJacobian(jtan,itan);
416  }
417  for(ordinal_type j=0; j <faceCardinality; ++j) {
418  ordinal_type jdof = cellBasis->getDofOrdinal(faceDim, iface, j);
419  for(ordinal_type itan=0; itan <faceDofDim; ++itan) {
420  for(ordinal_type iq=0; iq <numCubPoints; ++iq) {
421  for(ordinal_type d=0; d <fieldDim; ++d)
422  faceBasisDofAtCubPoints(ic,j,iq,itan) += faceCoeff(d, itan)*basisAtCubPoints(ic,jdof,offsetBasis+iq,d);
423  wBasisDofAtCubPoints(ic,j,iq,itan) = faceBasisDofAtCubPoints(ic,j,iq,itan) * CubWeights(iq);
424  }
425  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq) {
426  for(ordinal_type d=0; d <fieldDim; ++d)
427  faceBasisAtTargetCubPoints(ic,j,iq,itan) += faceCoeff(d, itan)*basisAtTargetCubPoints(ic,jdof,offsetTarget+iq,d);
428  wBasisBasisAtTargetCubPoints(ic,j,iq,itan) = faceBasisAtTargetCubPoints(ic,j,iq,itan) * targetCubWeights(iq);
429  }
430  }
431  }
432 
433  for(ordinal_type d=0; d <fieldDim; ++d)
434  for(ordinal_type itan=0; itan <faceDofDim; ++itan)
435  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq)
436  targetAtTargetCubPoints(ic,iq,itan) += faceCoeff(d, itan)*targetAtEvalPoints(ic,offsetTarget+iq,d);
437 
438  for(ordinal_type j=0; j <numVertexDofs+numEdgeDofs; ++j) {
439  ordinal_type jdof = computedDofs(j);
440  for(ordinal_type iq=0; iq <numCubPoints; ++iq)
441  for(ordinal_type d=0; d <fieldDim; ++d)
442  for(ordinal_type itan=0; itan <faceDofDim; ++itan)
443  mComputedProjection(ic,iq,itan) -= basisCoeffs(ic,jdof)*faceCoeff(d, itan)*basisAtCubPoints(ic,jdof,offsetBasis+iq,d);
444  }
445  }
446 
447  scalarViewType faceMassMat_("faceMassMat_", numCells, faceCardinality, faceCardinality),
448  faceRhsMat_("rhsMat_", numCells, faceCardinality);
449 
450  FunctionSpaceTools<SpT >::integrate(faceMassMat_, faceBasisDofAtCubPoints, wBasisDofAtCubPoints);
451  FunctionSpaceTools<SpT >::integrate(faceRhsMat_, targetAtTargetCubPoints, wBasisBasisAtTargetCubPoints);
452  FunctionSpaceTools<SpT >::integrate(faceRhsMat_, mComputedProjection, wBasisDofAtCubPoints,true);
453 
454  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> faceMassMat("faceMassMat", faceCardinality,faceCardinality);
455  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> faceRhsMat("faceRhsMat",faceCardinality, 1);
456 
457  Teuchos::LAPACK<ordinal_type,funValsValueType> lapack;
458  ordinal_type info = 0;
459  for(ordinal_type ic=0; ic<numCells; ++ic) {
460 
461  for(ordinal_type i=0; i<faceCardinality; ++i) {
462  faceRhsMat(i,0) = faceRhsMat_(ic,i);
463  for(ordinal_type j=0; j<faceCardinality; ++j){
464  faceMassMat(i,j) = faceMassMat_(ic,i,j);
465  }
466  }
467 
468  lapack.POSV('U', faceCardinality, 1,
469  faceMassMat.data(),
470  faceMassMat.stride_1(),
471  faceRhsMat.data(),
472  faceRhsMat.stride_1(),
473  &info);
474 
475  if (info) {
476  std::stringstream ss;
477  ss << ">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
478  << "LAPACK return with error code: "
479  << info;
480  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
481  }
482 
483  for(ordinal_type i=0; i<faceCardinality; ++i){
484  ordinal_type face_dof = cellBasis->getDofOrdinal(faceDim, iface, i);
485  basisCoeffs(ic,face_dof) = faceRhsMat(i,0);
486  }
487  }
488 
489  for(ordinal_type i=0; i<faceCardinality; ++i)
490  computedDofs(computedDofsCount++) = cellBasis->getDofOrdinal(faceDim, iface, i);
491  }
492 
493  ordinal_type numElemDofs = cellBasis->getDofCount(dim,0);
494 
495  if(numElemDofs>0) {
496 
497  range_type cellPointsRange = projStruct->getTargetPointsRange(dim, 0);
498 
499  ordinal_type numTargetCubPoints = projStruct->getNumTargetEvalPoints(dim,0);
500  ordinal_type numCubPoints = projStruct->getNumBasisEvalPoints(dim,0);
501 
502  scalarViewType internalBasisAtCubPoints("internalBasisAtCubPoints",numCells,numElemDofs, numCubPoints, fieldDim);
503  scalarViewType mComputedProjection("mComputedProjection", numCells, numCubPoints, fieldDim);
504 
505  scalarViewType targetCubWeights = projStruct->getTargetEvalWeights(dim, 0);
506  scalarViewType cubWeights = projStruct->getBasisEvalWeights(dim, 0);
507  ordinal_type offsetBasis = projStruct->getBasisPointsRange(dim, 0).first;
508  ordinal_type offsetTarget = projStruct->getTargetPointsRange(dim, 0).first;
509 
510 
511  scalarViewType wBasisAtCubPoints("weightedBasisAtCubPoints",numCells,numElemDofs, numCubPoints,fieldDim);
512  scalarViewType wBasisBasisAtTargetCubPoints("weightedBasisAtTargetCubPoints",numCells,numElemDofs, numTargetCubPoints,fieldDim);
513  for(ordinal_type j=0; j <numElemDofs; ++j) {
514  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, j);
515  for(ordinal_type ic=0; ic<numCells; ++ic) {
516  for(ordinal_type d=0; d <fieldDim; ++d) {
517  for(ordinal_type iq=0; iq <numCubPoints; ++iq) {
518  internalBasisAtCubPoints(ic,j,iq,d) = basisAtCubPoints(ic,idof,offsetBasis+iq,d);
519  wBasisAtCubPoints(ic,j,iq,d) = internalBasisAtCubPoints(ic,j,iq,d) * cubWeights(iq);
520  }
521  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq) {
522  wBasisBasisAtTargetCubPoints(ic,j,iq,d) = basisAtTargetCubPoints(ic,idof,offsetTarget+iq,d)* targetCubWeights(iq);
523  }
524  }
525  }
526  }
527 
528  for(ordinal_type j=0; j <numVertexDofs+numEdgeDofs+numFaceDofs; ++j) {
529  ordinal_type jdof = computedDofs(j);
530  for(ordinal_type iq=0; iq <numCubPoints; ++iq)
531  for(ordinal_type ic=0; ic<numCells; ++ic) {
532  for(ordinal_type d=0; d <fieldDim; ++d) {
533  mComputedProjection(ic,iq,d) -= basisCoeffs(ic,jdof)*basisAtCubPoints(ic,jdof,offsetBasis+iq,d);
534  }
535  }
536  }
537 
538 
539  scalarViewType cellMassMat_("cellMassMat_", numCells, numElemDofs, numElemDofs),
540  cellRhsMat_("rhsMat_", numCells, numElemDofs);
541 
542  FunctionSpaceTools<SpT >::integrate(cellMassMat_, internalBasisAtCubPoints, wBasisAtCubPoints);
543  if(fieldDim==1)
544  FunctionSpaceTools<SpT >::integrate(cellRhsMat_, Kokkos::subview(targetAtEvalPoints,Kokkos::ALL(),cellPointsRange,Kokkos::ALL()),
545  Kokkos::subview(wBasisBasisAtTargetCubPoints,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),0));
546  else
547  FunctionSpaceTools<SpT >::integrate(cellRhsMat_, Kokkos::subview(targetAtEvalPoints,Kokkos::ALL(),cellPointsRange,Kokkos::ALL()), wBasisBasisAtTargetCubPoints);
548  FunctionSpaceTools<SpT >::integrate(cellRhsMat_, mComputedProjection, wBasisAtCubPoints, true);
549 
550  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> cellMassMat("cellMassMat", numElemDofs,numElemDofs);
551  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> cellRhsMat("cellRhsMat",numElemDofs, 1);
552 
553  Teuchos::LAPACK<ordinal_type,funValsValueType> lapack;
554  ordinal_type info = 0;
555  for(ordinal_type ic=0; ic<numCells; ++ic) {
556  for(ordinal_type i=0; i<numElemDofs; ++i) {
557  cellRhsMat(i,0) = cellRhsMat_(ic,i);
558  for(ordinal_type j=0; j<numElemDofs; ++j)
559  cellMassMat(i,j) = cellMassMat_(ic,i,j);
560  }
561 
562  lapack.POSV('U', numElemDofs, 1,
563  cellMassMat.data(),
564  cellMassMat.stride_1(),
565  cellRhsMat.data(),
566  cellRhsMat.stride_1(),
567  &info);
568 
569  for(ordinal_type i=0; i<numElemDofs; ++i){
570  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, i);
571  basisCoeffs(ic,idof) = cellRhsMat(i,0);
572  }
573 
574  if (info) {
575  std::stringstream ss;
576  ss << ">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
577  << "LAPACK return with error code: "
578  << info;
579  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
580  }
581  }
582  }
583 }
584 }
585 }
586 
587 #endif
588 
static void getReferenceEdgeTangent(Kokkos::DynRankView< refEdgeTangentValueType, refEdgeTangentProperties...> refEdgeTangent, const ordinal_type edgeOrd, const shards::CellTopology parentCell)
Computes constant tangent vectors to edges of 2D or 3D reference cells.
Header file for the abstract base class Intrepid2::DefaultCubatureFactory.
static void getReferenceSideNormal(Kokkos::DynRankView< refSideNormalValueType, refSideNormalProperties...> refSideNormal, const ordinal_type sideOrd, const shards::CellTopology parentCell)
Computes constant normal vectors to sides of 2D or 3D reference cells.
static void getJacobianOfOrientationMap(JacobianViewType jacobian, const shards::CellTopology cellTopo, const ordinal_type cellOrt)
Computes jacobian of the parameterization maps of 1- and 2-subcells with orientation.
static void modifyBasisByOrientation(Kokkos::DynRankView< outputValueType, outputProperties...> output, const Kokkos::DynRankView< inputValueType, inputProperties...> input, const Kokkos::DynRankView< ortValueType, ortProperties...> orts, const BasisPtrType basis)
Modify basis due to orientation.
static void integrate(Kokkos::DynRankView< outputValueValueType, outputValueProperties...> outputValues, const Kokkos::DynRankView< leftValueValueType, leftValueProperties...> leftValues, const Kokkos::DynRankView< rightValueValueType, rightValueProperties...> rightValues, const bool sumInto=false)
Contracts leftValues and rightValues arrays on the point and possibly space dimensions and stores the...
static void mapToReferenceSubcell(Kokkos::DynRankView< refSubcellPointValueType, refSubcellPointProperties...> refSubcellPoints, const Kokkos::DynRankView< paramPointValueType, paramPointProperties...> paramPoints, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell)
Computes parameterization maps of 1- and 2-subcells of reference cells.
static void getL2EvaluationPoints(typename BasisType::scalarViewType evaluationPoints, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations, const BasisType *cellBasis, ProjectionStruct< ExecSpaceType, typename BasisType::scalarType > *projStruct, const EvalPointsType evalPointType=TARGET)
Computes evaluation points for L2 projection.
Header file for the Intrepid2::FunctionSpaceTools class.
static void getL2BasisCoeffs(Kokkos::DynRankView< basisCoeffsValueType, basisCoeffsProperties...> basisCoeffs, const Kokkos::DynRankView< funValsValueType, funValsProperties...> targetAtEvalPoints, const typename BasisType::scalarViewType evaluationPoints, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations, const BasisType *cellBasis, ProjectionStruct< ExecSpaceType, typename BasisType::scalarType > *projStruct)
Computes the basis coefficients of the L2 projection of the target function.
static void clone(Kokkos::DynRankView< outputValueType, outputProperties...> output, const Kokkos::DynRankView< inputValueType, inputProperties...> input)
Clone input array.
Header file for Intrepid2::ArrayTools class providing utilities for array operations.
static void getReferenceFaceTangents(Kokkos::DynRankView< refFaceTanUValueType, refFaceTanUProperties...> refFaceTanU, Kokkos::DynRankView< refFaceTanVValueType, refFaceTanVProperties...> refFaceTanV, const ordinal_type faceOrd, const shards::CellTopology parentCell)
Computes pairs of constant tangent vectors to faces of a 3D reference cells.
static void mapToModifiedReference(outPointViewType outPoints, const refPointViewType refPoints, const shards::CellTopology cellTopo, const ordinal_type cellOrt=0)
Computes modified parameterization maps of 1- and 2-subcells with orientation.
static void getReferenceFaceNormal(Kokkos::DynRankView< refFaceNormalValueType, refFaceNormalProperties...> refFaceNormal, const ordinal_type faceOrd, const shards::CellTopology parentCell)
Computes constant normal vectors to faces of 3D reference cell.