Intrepid2
Intrepid2_ProjectionToolsDefHDIV.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_PROJECTIONTOOLSDEFHDIV_HPP__
50 #define __INTREPID2_PROJECTIONTOOLSDEFHDIV_HPP__
51 
53 #include "Intrepid2_ArrayTools.hpp"
55 
56 
57 namespace Intrepid2 {
58 namespace Experimental {
59 
60 
61 template<typename SpT>
62 template<typename BasisType,
63 typename ortValueType, class ...ortProperties>
64 void
65 ProjectionTools<SpT>::getHDivEvaluationPoints(typename BasisType::scalarViewType evaluationPoints,
66  typename BasisType::scalarViewType extDerivEvaluationPoints,
67  const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
68  const BasisType* cellBasis,
69  ProjectionStruct<SpT, typename BasisType::scalarType> * projStruct,
70  const EvalPointsType evalPointType){
71  typedef typename BasisType::scalarType scalarType;
72  typedef Kokkos::DynRankView<scalarType,SpT> scalarViewType;
73  typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
74  ordinal_type dim = cellBasis->getBaseCellTopology().getDimension();
75  ordinal_type sideDim = dim-1;
76 
77  ordinal_type numSides = cellBasis->getBaseCellTopology().getSideCount();
78 
79  ordinal_type numCells = orts.extent(0);
80  Kokkos::DynRankView<ordinal_type> sOrt("sOrt", numSides);
81 
82  for(ordinal_type is=0; is<numSides; ++is) {
83  range_type sidePointsRange;
84  scalarViewType sideCubPoints;
85  if(evalPointType == TARGET) {
86  sidePointsRange = projStruct->getTargetPointsRange(sideDim, is);
87  sideCubPoints = projStruct->getTargetEvalPoints(sideDim, is);
88  }
89  else {
90  sidePointsRange = projStruct->getBasisPointsRange(sideDim, is);
91  sideCubPoints = projStruct->getBasisEvalPoints(sideDim, is);
92  }
93 
94  scalarViewType orientedTargetCubPoints("orientedTargetCubPoints", sideCubPoints.extent(0),sideDim);
95 
96  const auto topoKey = projStruct->getTopologyKey(sideDim,is);
97 
98  for(ordinal_type ic=0; ic<numCells; ++ic) {
99  if(dim == 3)
100  orts(ic).getFaceOrientation(sOrt.data(), numSides);
101  else
102  orts(ic).getEdgeOrientation(sOrt.data(), numSides);
103  ordinal_type ort = sOrt(is);
104  Impl::OrientationTools::mapToModifiedReference(orientedTargetCubPoints,sideCubPoints,topoKey,ort);
105  CellTools<SpT>::mapToReferenceSubcell(Kokkos::subview(evaluationPoints,ic,sidePointsRange,Kokkos::ALL()), orientedTargetCubPoints, sideDim, is, cellBasis->getBaseCellTopology());
106  }
107  }
108 
109  if(cellBasis->getDofCount(dim,0) <= 0)
110  return;
111 
112  range_type cellDivPointsRange;
113  scalarViewType divCubPoints;
114  if(evalPointType == TARGET) {
115  divCubPoints = projStruct->getTargetDerivEvalPoints(dim, 0);
116  cellDivPointsRange = projStruct->getTargetDerivPointsRange(dim, 0);
117  } else {
118  divCubPoints = projStruct->getBasisDerivEvalPoints(dim, 0);
119  cellDivPointsRange = projStruct->getBasisDerivPointsRange(dim, 0);
120  }
121  RealSpaceTools<SpT>::clone(Kokkos::subview(extDerivEvaluationPoints, Kokkos::ALL(), cellDivPointsRange, Kokkos::ALL()), divCubPoints);
122 
123  if(projStruct->getTargetEvalPoints(dim, 0).data() != NULL)
124  {
125  range_type cellPointsRange;
126  scalarViewType cubPoints;
127  if(evalPointType == TARGET) {
128  cubPoints = projStruct->getTargetEvalPoints(dim, 0);
129  cellPointsRange = projStruct->getTargetPointsRange(dim, 0);
130  } else {
131  cubPoints = projStruct->getBasisEvalPoints(dim, 0);
132  cellPointsRange = projStruct->getBasisPointsRange(dim, 0);
133  }
134  RealSpaceTools<SpT>::clone(Kokkos::subview(evaluationPoints, Kokkos::ALL(), cellPointsRange, Kokkos::ALL()), cubPoints);
135  }
136 }
137 
138 
139 template<typename SpT>
140 template<typename basisCoeffsValueType, class ...basisCoeffsProperties,
141 typename funValsValueType, class ...funValsProperties,
142 typename BasisType,
143 typename ortValueType,class ...ortProperties>
144 void
145 ProjectionTools<SpT>::getHDivBasisCoeffs(Kokkos::DynRankView<basisCoeffsValueType,basisCoeffsProperties...> basisCoeffs,
146  const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetAtEvalPoints,
147  const Kokkos::DynRankView<funValsValueType,funValsProperties...> targetDivAtDivEvalPoints,
148  const typename BasisType::scalarViewType evaluationPoints,
149  const typename BasisType::scalarViewType extDerivEvaluationPoints,
150  const Kokkos::DynRankView<ortValueType, ortProperties...> orts,
151  const BasisType* cellBasis,
152  ProjectionStruct<SpT, typename BasisType::scalarType> * projStruct){
153  typedef typename Kokkos::Impl::is_space<SpT>::host_mirror_space::execution_space host_space_type;
154  typedef typename BasisType::scalarType scalarType;
155  typedef Kokkos::DynRankView<scalarType,SpT> scalarViewType;
156  typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
157  const auto cellTopo = cellBasis->getBaseCellTopology();
158  ordinal_type dim = cellTopo.getDimension();
159  ordinal_type numTotalEvaluationPoints(targetAtEvalPoints.extent(1)),
160  numTotalDivEvaluationPoints(targetDivAtDivEvalPoints.extent(1));
161  ordinal_type basisCardinality = cellBasis->getCardinality();
162  ordinal_type numCells = targetAtEvalPoints.extent(0);
163  const ordinal_type sideDim = dim-1;
164 
165  const std::string& name = cellBasis->getName();
166 
167  ordinal_type numSides = cellBasis->getBaseCellTopology().getSideCount();
168  scalarViewType refSideNormal("refSideNormal", dim);
169 
170  ordinal_type numSideDofs(0);
171  for(ordinal_type is=0; is<numSides; ++is)
172  numSideDofs += cellBasis->getDofCount(sideDim,is);
173 
174  Kokkos::View<ordinal_type*> computedDofs("computedDofs",numSideDofs);
175 
176  ordinal_type computedDofsCount = 0;
177 
178  ordinal_type numTotalCubPoints = projStruct->getNumBasisEvalPoints(), numTotalDivCubPoints = projStruct->getNumBasisDerivEvalPoints();
179  scalarViewType cubPoints_("cubPoints",numCells,numTotalCubPoints, dim);
180  scalarViewType divCubPoints("divCubPoints",numCells,numTotalDivCubPoints, dim);
181  getHDivEvaluationPoints(cubPoints_, divCubPoints, orts, cellBasis, projStruct, BASIS);
182 
183  scalarViewType basisAtCubPoints("basisAtCubPoints",numCells,basisCardinality, numTotalCubPoints, dim);
184  scalarViewType basisAtTargetCubPoints("basisAtTargetCubPoints",numCells,basisCardinality, numTotalEvaluationPoints, dim);
185  {
186  scalarViewType nonOrientedBasisAtCubPoints("nonOrientedBasisAtCubPoints",numCells,basisCardinality, numTotalCubPoints, dim);
187  scalarViewType nonOrientedBasisAtTargetCubPoints("nonOrientedBasisAtTargetCubPoints",numCells,basisCardinality, numTotalEvaluationPoints, dim);
188  for(ordinal_type ic=0; ic<numCells; ++ic) {
189  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtTargetCubPoints,ic,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(evaluationPoints, ic, Kokkos::ALL(), Kokkos::ALL()));
190  cellBasis->getValues(Kokkos::subview(nonOrientedBasisAtCubPoints,ic,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(cubPoints_, ic, Kokkos::ALL(), Kokkos::ALL()));
191  }
192 
193  OrientationTools<SpT>::modifyBasisByOrientation(basisAtCubPoints, nonOrientedBasisAtCubPoints, orts, cellBasis);
194  OrientationTools<SpT>::modifyBasisByOrientation(basisAtTargetCubPoints, nonOrientedBasisAtTargetCubPoints, orts, cellBasis);
195  }
196 
197  scalarViewType basisDivAtDivCubPoints;
198  scalarViewType basisDivAtTargetDivCubPoints;
199  if(numTotalDivEvaluationPoints>0) {
200  scalarViewType nonOrientedBasisDivAtTargetDivCubPoints, nonOrientedBasisDivAtDivCubPoints;
201  basisDivAtDivCubPoints = scalarViewType ("basisDivAtDivCubPoints",numCells,basisCardinality, numTotalDivCubPoints);
202  nonOrientedBasisDivAtDivCubPoints = scalarViewType ("nonOrientedBasisDivAtDivCubPoints",numCells,basisCardinality, numTotalDivCubPoints);
203  basisDivAtTargetDivCubPoints = scalarViewType("basisDivAtTargetDivCubPoints",numCells,basisCardinality, numTotalDivEvaluationPoints);
204  nonOrientedBasisDivAtTargetDivCubPoints = scalarViewType("nonOrientedBasisDivAtTargetDivCubPoints",numCells,basisCardinality, numTotalDivEvaluationPoints);
205 
206  for(ordinal_type ic=0; ic<numCells; ++ic) {
207  cellBasis->getValues(Kokkos::subview(nonOrientedBasisDivAtDivCubPoints,ic,Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(divCubPoints, ic, Kokkos::ALL(), Kokkos::ALL()),OPERATOR_DIV);
208  cellBasis->getValues(Kokkos::subview(nonOrientedBasisDivAtTargetDivCubPoints,ic,Kokkos::ALL(),Kokkos::ALL()), Kokkos::subview(extDerivEvaluationPoints, ic, Kokkos::ALL(), Kokkos::ALL()),OPERATOR_DIV);
209  }
210  OrientationTools<SpT>::modifyBasisByOrientation(basisDivAtDivCubPoints, nonOrientedBasisDivAtDivCubPoints, orts, cellBasis);
211  OrientationTools<SpT>::modifyBasisByOrientation(basisDivAtTargetDivCubPoints, nonOrientedBasisDivAtTargetDivCubPoints, orts, cellBasis);
212  }
213 
214 
215  for(ordinal_type is=0; is<numSides; ++is) {
216 
217  ordinal_type sideCardinality = cellBasis->getDofCount(sideDim,is);
218  ordinal_type numCubPoints = projStruct->getNumBasisEvalPoints(sideDim,is);
219  ordinal_type numTargetCubPoints = projStruct->getNumTargetEvalPoints(sideDim,is);
220 
221  for(ordinal_type i=0; i<sideCardinality; ++i)
222  computedDofs(computedDofsCount++) = cellBasis->getDofOrdinal(sideDim, is, i);
223 
224  CellTools<SpT>::getReferenceSideNormal(refSideNormal, is, cellBasis->getBaseCellTopology());
225 
226  scalarViewType normalBasisAtElemcubPoints("normalBasisAtElemcubPoints",numCells,sideCardinality, numCubPoints);
227  scalarViewType normalBasisAtTargetcubPoints("normalBasisAtTargetcubPoints",numCells,sideCardinality, numTargetCubPoints);
228  scalarViewType weightedNormalBasisAtElemcubPoints("weightedNormalBasisAtElemcubPoints",numCells,sideCardinality, numCubPoints);
229  scalarViewType weightedNormalBasisAtTargetcubPoints("weightedNormalBasisAtTargetcubPoints",numCells,sideCardinality, numTargetCubPoints);
230  scalarViewType normalTargetAtTargetcubPoints("normalTargetAtTargetcubPoints",numCells, numTargetCubPoints);
231 
232  scalarViewType targetEvalWeights = projStruct->getTargetEvalWeights(sideDim, is);
233  scalarViewType basisEvalWeights = projStruct->getBasisEvalWeights(sideDim, is);
234 
235  //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
236  ordinal_type offsetBasis = projStruct->getBasisPointsRange(sideDim, is).first;
237  ordinal_type offsetTarget = projStruct->getTargetPointsRange(sideDim, is).first;
238  for(ordinal_type ic=0; ic<numCells; ++ic) {
239  for(ordinal_type j=0; j <sideCardinality; ++j) {
240  ordinal_type side_dof = cellBasis->getDofOrdinal(sideDim, is, j);
241  for(ordinal_type iq=0; iq <numCubPoints; ++iq) {
242  for(ordinal_type d=0; d <dim; ++d)
243  normalBasisAtElemcubPoints(ic,j,iq) += refSideNormal(d)*basisAtCubPoints(ic,side_dof,offsetBasis+iq,d);
244  weightedNormalBasisAtElemcubPoints(ic,j,iq) = normalBasisAtElemcubPoints(ic,j,iq)*basisEvalWeights(iq);
245  }
246  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq) {
247  for(ordinal_type d=0; d <dim; ++d)
248  normalBasisAtTargetcubPoints(ic,j,iq) += refSideNormal(d)*basisAtTargetCubPoints(ic,side_dof,offsetTarget+iq,d);
249  weightedNormalBasisAtTargetcubPoints(ic,j,iq) = normalBasisAtTargetcubPoints(ic,j,iq)*targetEvalWeights(iq);
250  }
251  }
252  for(ordinal_type iq=0; iq <numTargetCubPoints; ++iq)
253  for(ordinal_type d=0; d <dim; ++d)
254  normalTargetAtTargetcubPoints(ic,iq) += refSideNormal(d)*targetAtEvalPoints(ic,offsetTarget+iq,d);
255  }
256 
257 
258  scalarViewType sideMassMat_("sideMassMat_", numCells, sideCardinality+1, sideCardinality+1),
259  sideRhsMat_("rhsMat_", numCells, sideCardinality+1);
260 
261  scalarViewType targetEvalWeights_("targetEvalWeights", numCells, 1, targetEvalWeights.extent(0));
262  RealSpaceTools<SpT>::clone(targetEvalWeights_, targetEvalWeights);
263 
264  range_type range_H(0, sideCardinality);
265  range_type range_B(sideCardinality, sideCardinality+1);
266  scalarViewType ones("ones",numCells,1,numCubPoints);
267  Kokkos::deep_copy(ones,1);
268 
269  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(sideMassMat_, Kokkos::ALL(), range_H, range_H), normalBasisAtElemcubPoints, weightedNormalBasisAtElemcubPoints);
270  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(sideMassMat_, Kokkos::ALL(), range_H, range_B), weightedNormalBasisAtElemcubPoints, ones);
271 
272  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(sideRhsMat_, Kokkos::ALL(), range_H), normalTargetAtTargetcubPoints, weightedNormalBasisAtTargetcubPoints);
273  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(sideRhsMat_, Kokkos::ALL(), range_B), normalTargetAtTargetcubPoints, targetEvalWeights_);
274 
275  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> sideMassMat("sideMassMat", sideCardinality+1,sideCardinality+1);
276  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> sideRhsMat("sideRhsMat",sideCardinality+1, 1);
277 
278  Teuchos::LAPACK<ordinal_type,funValsValueType> lapack;
279  ordinal_type info = 0;
280  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> pivVec("pivVec", sideCardinality+1, 1);
281 
282  for(ordinal_type ic=0; ic<numCells; ++ic) {
283  Kokkos::deep_copy(sideMassMat,funValsValueType(0)); //LAPACK might overwrite the matrix
284  for(ordinal_type i=0; i<sideCardinality; ++i) {
285  sideRhsMat(i,0) = sideRhsMat_(ic,i);
286  for(ordinal_type j=0; j<sideCardinality+1; ++j){
287  sideMassMat(i,j) = sideMassMat_(ic,i,j);
288  }
289  sideMassMat(sideCardinality,i) = sideMassMat_(ic,i,sideCardinality);
290  }
291  sideRhsMat(sideCardinality,0) = sideRhsMat_(ic,sideCardinality);
292 
293 
294  lapack.GESV(sideCardinality+1, 1,
295  sideMassMat.data(),
296  sideMassMat.stride_1(),
297  (ordinal_type*)pivVec.data(),
298  sideRhsMat.data(),
299  sideRhsMat.stride_1(),
300  &info);
301 
302  for(ordinal_type i=0; i<sideCardinality; ++i){
303  ordinal_type facet_dof = cellBasis->getDofOrdinal(dim-1, is, i);
304  basisCoeffs(ic,facet_dof) = sideRhsMat(i,0);
305  }
306 
307 
308  if (info) {
309  std::stringstream ss;
310  ss << ">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
311  << "LAPACK return with error code: "
312  << info;
313  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
314  }
315  }
316  }
317 
318 
319  //elem
320  ordinal_type numElemDofs = cellBasis->getDofCount(dim,0);
321  if(numElemDofs==0)
322  return;
323 
324  Basis<host_space_type,scalarType,scalarType> *hcurlBasis = NULL;
325  if(name.find("HEX")!=std::string::npos)
326  hcurlBasis = new Basis_HCURL_HEX_In_FEM<host_space_type,scalarType,scalarType>(cellBasis->getDegree());
327  else if(name.find("TET")!=std::string::npos)
328  hcurlBasis = new Basis_HCURL_TET_In_FEM<host_space_type,scalarType,scalarType>(cellBasis->getDegree());
329  else if(name.find("QUAD")!=std::string::npos)
330  hcurlBasis = new Basis_HGRAD_QUAD_Cn_FEM<host_space_type,scalarType,scalarType>(cellBasis->getDegree());
331  else if(name.find("TRI")!=std::string::npos)
332  hcurlBasis = new Basis_HGRAD_TRI_Cn_FEM<host_space_type,scalarType,scalarType>(cellBasis->getDegree());
333  else {
334  std::stringstream ss;
335  ss << ">>> ERROR (Intrepid2::ProjectionTools::getHDivEvaluationPoints): "
336  << "Method not implemented for basis " << name;
337  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
338  }
339  if(hcurlBasis == NULL) return;
340 
341 
342  ordinal_type numTargetDivCubPoints = projStruct->getNumTargetDerivEvalPoints(dim,0);
343  ordinal_type numDivCubPoints = projStruct->getNumBasisDerivEvalPoints(dim,0);
344 
345  scalarViewType weightedBasisDivAtcubPoints("weightedBasisDivAtcubPoints",numCells,numElemDofs, numDivCubPoints);
346  scalarViewType weightedBasisDivAtcubTargetPoints("weightedBasisDivAtcubTargetPoints",numCells, numElemDofs, numTargetDivCubPoints);
347 
348  scalarViewType internalBasisDivAtcubPoints("basisDivAtcubPoints",numCells,numElemDofs, numDivCubPoints);
349 
350  scalarViewType targetDivEvalWeights = projStruct->getTargetDerivEvalWeights(dim, 0);
351  scalarViewType divEvalWeights = projStruct->getBasisDerivEvalWeights(dim, 0);
352  ordinal_type offsetBasisDiv = projStruct->getBasisDerivPointsRange(dim, 0).first;
353  ordinal_type offsetTargetDiv = projStruct->getTargetDerivPointsRange(dim, 0).first;
354 
355  for(ordinal_type ic=0; ic<numCells; ++ic) {
356  for(ordinal_type i=0; i<numElemDofs; ++i) {
357  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, i);
358  for(ordinal_type iq=0; iq<numDivCubPoints; ++iq) {
359  internalBasisDivAtcubPoints(ic,i,iq) = basisDivAtDivCubPoints(ic,idof,offsetBasisDiv+iq);
360  weightedBasisDivAtcubPoints(ic,i,iq) = internalBasisDivAtcubPoints(ic,i,iq) * divEvalWeights(iq);
361  }
362  }
363  for(ordinal_type i=0; i<numElemDofs; ++i) {
364  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, i);
365  for(ordinal_type iq=0; iq<numTargetDivCubPoints; ++iq)
366  weightedBasisDivAtcubTargetPoints(ic,i,iq) = targetDivEvalWeights(iq)*basisDivAtTargetDivCubPoints(ic,idof,offsetTargetDiv+iq);
367  }
368  }
369 
370  ordinal_type hcurlBasisCardinality = hcurlBasis->getCardinality();
371  ordinal_type numCurlInteriorDOFs = hcurlBasis->getDofCount(dim,0);
372 
373  range_type range_H(0, numElemDofs);
374  range_type range_B(numElemDofs, numElemDofs+numCurlInteriorDOFs);
375 
376  Kokkos::DynRankView<funValsValueType,Kokkos::LayoutLeft,host_space_type> massMat_("massMat_",numCells,numElemDofs+numCurlInteriorDOFs,numElemDofs+numCurlInteriorDOFs);
377  Kokkos::DynRankView<funValsValueType,Kokkos::LayoutLeft,host_space_type> rhsMatTrans("rhsMatTrans",numCells,numElemDofs+numCurlInteriorDOFs);
378 
379  scalarViewType targetSideDivAtcubPoints("targetSideDivAtcubPoints",numCells, numDivCubPoints);
380  for(ordinal_type i=0; i<numSideDofs; ++i) {
381  ordinal_type idof = computedDofs(i);
382  for(ordinal_type ic=0; ic<numCells; ++ic)
383  for(ordinal_type iq=0; iq<numDivCubPoints; ++iq){
384  targetSideDivAtcubPoints(ic,iq) -= basisCoeffs(ic,idof)*basisDivAtDivCubPoints(ic,idof,offsetBasisDiv+iq);
385  }
386  }
387 
388  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(massMat_, Kokkos::ALL(), range_H,range_H), internalBasisDivAtcubPoints, weightedBasisDivAtcubPoints);
389  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(rhsMatTrans, Kokkos::ALL(), range_H), targetDivAtDivEvalPoints, weightedBasisDivAtcubTargetPoints);
390  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(rhsMatTrans, Kokkos::ALL(), range_H), targetSideDivAtcubPoints, weightedBasisDivAtcubPoints,true);
391 
392  if(numCurlInteriorDOFs>0){
393  scalarViewType cubPoints = projStruct->getBasisEvalPoints(dim,0);
394  ordinal_type numCubPoints = projStruct->getNumBasisEvalPoints(dim,0);
395  ordinal_type numTargetCubPoints = projStruct->getNumTargetEvalPoints(dim,0);
396 
397  scalarViewType targetSideApproxAtcubPoints("targetSideAtcubPoints",numCells, numCubPoints, dim);
398  scalarViewType internalBasisAtcubPoints("basisAtcubPoints",numCells,numElemDofs, numCubPoints, dim);
399  scalarViewType hcurlBasisCurlAtcubPoints("hcurlBasisCurlAtcubPoints",hcurlBasisCardinality, numCubPoints,dim);
400  scalarViewType internalHcurlBasisCurlAtcubPoints("internalHcurlBasisCurlAtcubPoints",numCells,numCurlInteriorDOFs, numCubPoints,dim);
401  scalarViewType hcurlBasisCurlAtcubTargetPoints("hcurlBasisCurlAtcubTargetPoints", hcurlBasisCardinality,numTargetCubPoints, dim);
402  scalarViewType internalHcurlBasisCurlAtcubTargetPoints("internalHcurlBasisCurlAtcubTargetPoints",numCells, numCurlInteriorDOFs, numTargetCubPoints, dim);
403  scalarViewType weightedHcurlBasisCurlAtcubPoints("weightedHcurlBasisHcurlAtcubPoints", numCells, numCurlInteriorDOFs, numCubPoints,dim);
404  scalarViewType weightedHcurlBasisCurlAtcubTargetPoints("weightedHcurlBasisHcurlAtcubTargetPoints",numCells, numCurlInteriorDOFs, numTargetCubPoints,dim);
405 
406  hcurlBasis->getValues(hcurlBasisCurlAtcubPoints, cubPoints, OPERATOR_CURL);
407 
408  ordinal_type offsetBasis = projStruct->getBasisPointsRange(dim, 0).first;
409  range_type targetPointsRange = projStruct->getTargetPointsRange(dim, 0);
410 
411  scalarViewType targetEvalWeights = projStruct->getTargetEvalWeights(dim, 0);
412  scalarViewType basisEvalWeights = projStruct->getBasisEvalWeights(dim, 0);
413 
414 
415  for(ordinal_type ic=0; ic<numCells; ++ic) {
416 
417  for(ordinal_type i=0; i<numSideDofs; ++i) {
418  ordinal_type idof = computedDofs(i);
419  for(ordinal_type iq=0; iq<numCubPoints; ++iq){
420  for(ordinal_type d=0; d <dim; ++d)
421  targetSideApproxAtcubPoints(ic,iq,d) -= basisCoeffs(ic,idof)*basisAtCubPoints(ic,idof,offsetBasis+iq,d);
422  }
423  }
424 
425  for(ordinal_type i=0; i<numElemDofs; ++i) {
426  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, i);
427  for(ordinal_type iq=0; iq<numCubPoints; ++iq) {
428  for(ordinal_type d=0; d<dim; ++d)
429  internalBasisAtcubPoints(ic,i,iq,d) = basisAtCubPoints(ic,idof,offsetBasis+iq,d);
430  }
431  }
432 
433  for(ordinal_type i=0; i<numCurlInteriorDOFs; ++i) {
434  ordinal_type idof = hcurlBasis->getDofOrdinal(dim, 0, i);
435  for(ordinal_type d=0; d<dim; ++d)
436  for(ordinal_type iq=0; iq<numCubPoints; ++iq) {
437  internalHcurlBasisCurlAtcubPoints(ic,i,iq,d) = hcurlBasisCurlAtcubPoints(idof,iq,d);
438  weightedHcurlBasisCurlAtcubPoints(ic,i,iq,d) = internalHcurlBasisCurlAtcubPoints(ic,i,iq,d)*basisEvalWeights(iq);
439  }
440  }
441 
442  hcurlBasis->getValues(hcurlBasisCurlAtcubTargetPoints, Kokkos::subview(evaluationPoints,ic,targetPointsRange,Kokkos::ALL()), OPERATOR_CURL);
443  for(ordinal_type i=0; i<numCurlInteriorDOFs; ++i) {
444  ordinal_type idof = hcurlBasis->getDofOrdinal(dim, 0, i);
445  for(ordinal_type d=0; d<dim; ++d)
446  for(ordinal_type iq=0; iq<numTargetCubPoints; ++iq) {
447  internalHcurlBasisCurlAtcubTargetPoints(ic,i,iq,d) = hcurlBasisCurlAtcubTargetPoints(idof,iq,d);
448  weightedHcurlBasisCurlAtcubTargetPoints(ic,i,iq,d) = internalHcurlBasisCurlAtcubTargetPoints(ic,i,iq,d)*targetEvalWeights(iq);
449  }
450  }
451  }
452 
453  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(massMat_, Kokkos::ALL(), range_H,range_B), internalBasisAtcubPoints, weightedHcurlBasisCurlAtcubPoints);
454  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(rhsMatTrans, Kokkos::ALL(), range_B), Kokkos::subview(targetAtEvalPoints, Kokkos::ALL(), targetPointsRange, Kokkos::ALL()), weightedHcurlBasisCurlAtcubTargetPoints);
455  FunctionSpaceTools<SpT >::integrate(Kokkos::subview(rhsMatTrans, Kokkos::ALL(), range_B), targetSideApproxAtcubPoints, weightedHcurlBasisCurlAtcubPoints,true);
456 
457 
458  }
459  delete hcurlBasis;
460 
461  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type>
462  massMat("massMat", numElemDofs+numCurlInteriorDOFs, numElemDofs+numCurlInteriorDOFs),
463  rhsMat("rhsMat", numElemDofs+numCurlInteriorDOFs, 1 );
464 
465  Teuchos::LAPACK<ordinal_type,funValsValueType> lapack;
466  ordinal_type info = 0;
467  Kokkos::View<funValsValueType**,Kokkos::LayoutLeft,host_space_type> pivVec("pivVec", 2*(numElemDofs+numCurlInteriorDOFs), 1);
468 
469  for(ordinal_type ic=0; ic<numCells; ++ic) {
470  Kokkos::deep_copy(massMat,funValsValueType(0)); //LAPACK might overwrite the matrix
471 
472  for(ordinal_type i=0; i<numElemDofs+numCurlInteriorDOFs; ++i) {
473  rhsMat(i,0) = rhsMatTrans(ic,i);
474  for(ordinal_type j=0; j<numElemDofs; ++j)
475  massMat(j,i) = massMat_(ic,j,i);
476  }
477 
478  for(ordinal_type i=numElemDofs; i<numElemDofs+numCurlInteriorDOFs; ++i)
479  for(ordinal_type j=0; j<numElemDofs; ++j)
480  massMat(i,j) = massMat(j,i);
481 
482  // lapack.GESV(numElemDofs+numCurlInteriorDOFs, 1,
483  // massMat.data(),
484  // massMat.stride_1(),
485  // (ordinal_type*)pivVec.data(),
486  // rhsMat.data(),
487  // rhsMat.stride_1(),
488  // &info);
489 
490  // Using GELS because the matrix can be close to singular.
491  // TODO check why matrix is close to singular and possibly whether it makes sense to solve the
492  // least square problem with a better method (e.g. GGLSE)
493  lapack.GELS('N', numElemDofs+numCurlInteriorDOFs, numElemDofs+numCurlInteriorDOFs, 1,
494  massMat.data(), massMat.stride_1(),
495  rhsMat.data(), rhsMat.stride_1(),
496  pivVec.data(), pivVec.extent(0),
497  &info);
498 
499  if (info) {
500  std::stringstream ss;
501  ss << ">>> ERROR (Intrepid::ProjectionTools::getBasisCoeffs): "
502  << "LAPACK return with error code: "
503  << info;
504  INTREPID2_TEST_FOR_EXCEPTION( true, std::runtime_error, ss.str().c_str() );
505  }
506 
507  for(ordinal_type i=0; i<numElemDofs; ++i) {
508  ordinal_type idof = cellBasis->getDofOrdinal(dim, 0, i);
509  basisCoeffs(ic,idof) = rhsMat(i,0);
510  }
511  }
512 }
513 
514 
515 
516 }
517 }
518 
519 #endif
520 
Header file for the abstract base class Intrepid2::DefaultCubatureFactory.
static void getHDivBasisCoeffs(Kokkos::DynRankView< basisCoeffsValueType, basisCoeffsProperties...> basisCoeffs, const Kokkos::DynRankView< funValsValueType, funValsProperties...> targetAtEvalPoints, const Kokkos::DynRankView< funValsValueType, funValsProperties...> targetDivAtDivEvalPoints, const typename BasisType::scalarViewType evaluationPoints, const typename BasisType::scalarViewType divEvalPoints, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations, const BasisType *cellBasis, ProjectionStruct< ExecSpaceType, typename BasisType::scalarType > *projStruct)
Computes the basis coefficients of the HDiv projection of the target function.
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 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.
Header file for the Intrepid2::FunctionSpaceTools class.
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 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 getHDivEvaluationPoints(typename BasisType::scalarViewType evaluationPoints, typename BasisType::scalarViewType divEvalPoints, const Kokkos::DynRankView< ortValueType, ortProperties...> cellOrientations, const BasisType *cellBasis, ProjectionStruct< ExecSpaceType, typename BasisType::scalarType > *projStruct, const EvalPointsType evalPointType=TARGET)
Computes evaluation points for HDiv projection.