Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_BasisValues2_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Panzer: A partial differential equation assembly
4// engine for strongly coupled complex multiphysics systems
5//
6// Copyright 2011 NTESS and the Panzer contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#include "PanzerDiscFE_config.hpp"
12#include "Panzer_Traits.hpp"
13
15#include "Kokkos_ViewFactory.hpp"
17
18#include "Intrepid2_Utils.hpp"
19#include "Intrepid2_FunctionSpaceTools.hpp"
20#include "Intrepid2_Orientation.hpp"
21#include "Intrepid2_OrientationTools.hpp"
22
23// FIXME: There are some calls in Intrepid2 that require non-const arrays when they should be const - search for PHX::getNonConstDynRankViewFromConstMDField
24#include "Phalanx_GetNonConstDynRankViewFromConstMDField.hpp"
25
26namespace panzer {
27namespace {
28
29template<typename Scalar>
30void
31applyOrientationsImpl(const int num_cells,
32 Kokkos::DynRankView<Scalar, PHX::Device> view,
33 Kokkos::DynRankView<Intrepid2::Orientation, PHX::Device> orientations,
34 const typename BasisValues2<Scalar>::IntrepidBasis & basis)
35{
36 using ots=Intrepid2::OrientationTools<PHX::Device>;
37
38 auto sub_orientations = Kokkos::subview(orientations, std::make_pair(0,num_cells));
39
40 // There are two options based on rank
41 if(view.rank() == 3){
42 // Grab subview of object to re-orient and create a copy of it
43 auto sub_view = Kokkos::subview(view, std::make_pair(0,num_cells), Kokkos::ALL(), Kokkos::ALL());
44 auto sub_view_clone = Kokkos::createDynRankView(view, "sub_view_clone", sub_view.extent(0), sub_view.extent(1), sub_view.extent(2));
45 Kokkos::deep_copy(sub_view_clone, sub_view);
46
47 // Apply the orientations to the subview
48 ots::modifyBasisByOrientation(sub_view, sub_view_clone, sub_orientations, &basis);
49 } else if (view.rank() == 4){
50 // Grab subview of object to re-orient and create a copy of it
51 auto sub_view = Kokkos::subview(view, std::make_pair(0,num_cells), Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
52 auto sub_view_clone = Kokkos::createDynRankView(view, "sub_view_clone", sub_view.extent(0), sub_view.extent(1), sub_view.extent(2), sub_view.extent(3));
53 Kokkos::deep_copy(sub_view_clone, sub_view);
54
55 // Apply the orientations to the subview
56 ots::modifyBasisByOrientation(sub_view, sub_view_clone, sub_orientations, &basis);
57 } else
58 throw std::logic_error("applyOrientationsImpl : Unknown view of rank " + std::to_string(view.rank()));
59}
60
61template<typename Scalar>
62void
63applyOrientationsImpl(const int num_cells,
64 Kokkos::DynRankView<Scalar, PHX::Device> view,
65 const std::vector<Intrepid2::Orientation> & orientations,
66 const typename BasisValues2<Scalar>::IntrepidBasis & basis)
67{
68
69 // Move orientations vector to device
70 Kokkos::DynRankView<Intrepid2::Orientation,PHX::Device> device_orientations("drv_orts", num_cells);
71 auto host_orientations = Kokkos::create_mirror_view(device_orientations);
72 for(int i=0; i < num_cells; ++i)
73 host_orientations(i) = orientations[i];
74 Kokkos::deep_copy(device_orientations,host_orientations);
75
76 // Call the device orientations applicator
77 applyOrientationsImpl(num_cells, view, device_orientations, basis);
78}
79
80}
81
82
83template <typename Scalar>
85BasisValues2(const std::string & pre,
86 const bool allocArrays,
87 const bool buildWeighted)
88 : compute_derivatives(true)
89 , build_weighted(buildWeighted)
90 , alloc_arrays(allocArrays)
91 , prefix(pre)
92 , ddims_(1,0)
93 , references_evaluated(false)
94 , orientations_applied_(false)
95 , num_cells_(0)
96 , num_evaluate_cells_(0)
97 , is_uniform_(false)
98 , num_orientations_cells_(0)
99
100{
101 // Default all lazy evaluated components to not-evaluated
107 grad_basis_evaluated_ = false;
113 div_basis_evaluated_ = false;
122}
123
124template <typename Scalar>
126evaluateValues(const PHX::MDField<Scalar,IP,Dim> & cub_points,
127 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac,
128 const PHX::MDField<Scalar,Cell,IP> & jac_det,
129 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac_inv,
130 const int in_num_cells)
131{
132 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::evaluateValues(5 arg)",bv_ev_5);
133
134 build_weighted = false;
135
136 setupUniform(basis_layout, cub_points, jac, jac_det, jac_inv, in_num_cells);
137
138 const auto elmtspace = getElementSpace();
139 const int num_dims = jac.extent(2);
140
141 // Evaluate Reference values
142 if(elmtspace == PureBasis::HGRAD or elmtspace == PureBasis::CONST or elmtspace == PureBasis::HVOL)
143 getBasisValuesRef(true,true);
144
145 if(elmtspace == PureBasis::HDIV or elmtspace == PureBasis::HCURL)
146 getVectorBasisValuesRef(true,true);
147
148 if(elmtspace == PureBasis::HGRAD and compute_derivatives)
149 getGradBasisValuesRef(true,true);
150
151 if(elmtspace == PureBasis::HCURL and compute_derivatives){
152 if(num_dims == 2)
153 getCurl2DVectorBasisRef(true,true);
154 else if(num_dims == 3)
155 getCurlVectorBasisRef(true,true);
156 }
157
158 if(elmtspace == PureBasis::HDIV and compute_derivatives)
159 getDivVectorBasisRef(true, true);
160
161 references_evaluated = true;
162
163 // Evaluate real space values
164 if(elmtspace == PureBasis::HGRAD or elmtspace == PureBasis::CONST or elmtspace == PureBasis::HVOL)
165 getBasisValues(false,true,true);
166
167 if(elmtspace == PureBasis::HDIV or elmtspace == PureBasis::HCURL)
168 getVectorBasisValues(false,true,true);
169
170 if(elmtspace == PureBasis::HGRAD and compute_derivatives)
171 getGradBasisValues(false,true,true);
172
173 if(elmtspace == PureBasis::HCURL and compute_derivatives){
174 if(num_dims == 2)
175 getCurl2DVectorBasis(false,true,true);
176 else if(num_dims == 3)
177 getCurlVectorBasis(false,true,true);
178 }
179
180 if(elmtspace == PureBasis::HDIV and compute_derivatives)
181 getDivVectorBasis(false,true,true);
182
183 // Orientations have been applied if the number of them is greater than zero
184 orientations_applied_ = (orientations_.size()>0);
185}
186
187template <typename Scalar>
189evaluateValues(const PHX::MDField<Scalar,IP,Dim> & cub_points,
190 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac,
191 const PHX::MDField<Scalar,Cell,IP> & jac_det,
192 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac_inv,
193 const PHX::MDField<Scalar,Cell,IP> & weighted_measure,
194 const PHX::MDField<Scalar,Cell,NODE,Dim> & node_coordinates,
195 bool use_node_coordinates,
196 const int in_num_cells)
197{
198 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::evaluateValues(8 arg, uniform cub pts)",bv_ev_8u);
199
200 // This is the base call that will add all the non-weighted versions
201 evaluateValues(cub_points, jac, jac_det, jac_inv, in_num_cells);
202 if(weighted_measure.size() > 0)
203 setWeightedMeasure(weighted_measure);
204
205 cell_node_coordinates_ = node_coordinates;
206
207 // Add the weighted versions of all basis components - this will add to the non-weighted versions generated by evaluateValues above
208
209 const auto elmtspace = getElementSpace();
210 const int num_dims = jac.extent(2);
211
212 if(elmtspace == PureBasis::HGRAD or elmtspace == PureBasis::CONST or elmtspace == PureBasis::HVOL)
213 getBasisValues(true,true,true);
214
215 if(elmtspace == PureBasis::HDIV or elmtspace == PureBasis::HCURL)
216 getVectorBasisValues(true,true,true);
217
218 if(elmtspace == PureBasis::HGRAD and compute_derivatives)
219 getGradBasisValues(true,true,true);
220
221 if(elmtspace == PureBasis::HCURL and compute_derivatives){
222 if(num_dims == 2)
223 getCurl2DVectorBasis(true,true,true);
224 else if(num_dims == 3)
225 getCurlVectorBasis(true,true,true);
226 }
227
228 if(elmtspace == PureBasis::HDIV and compute_derivatives)
229 getDivVectorBasis(true,true,true);
230
231 // Add the node components
232 if(use_node_coordinates){
233 getBasisCoordinatesRef(true,true);
234 getBasisCoordinates(true,true);
235 }
236
237 // Orientations have been applied if the number of them is greater than zero
238 orientations_applied_ = (orientations_.size()>0);
239}
240
241template <typename Scalar>
243evaluateValues(const PHX::MDField<Scalar,Cell,IP,Dim> & cub_points,
244 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac,
245 const PHX::MDField<Scalar,Cell,IP> & jac_det,
246 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac_inv,
247 const PHX::MDField<Scalar,Cell,IP> & weighted_measure,
248 const PHX::MDField<Scalar,Cell,NODE,Dim> & node_coordinates,
249 bool use_node_coordinates,
250 const int in_num_cells)
251{
252 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::evaluateValues(8 arg,nonuniform cub pts)",bv_ev_8nu);
253
254 cell_node_coordinates_ = node_coordinates;
255
256 setup(basis_layout, cub_points, jac, jac_det, jac_inv, in_num_cells);
257 if(weighted_measure.size() > 0)
258 setWeightedMeasure(weighted_measure);
259
260 const auto elmtspace = getElementSpace();
261 const int num_dims = jac.extent(2);
262
263 if(elmtspace == PureBasis::HGRAD or elmtspace == PureBasis::CONST or elmtspace == PureBasis::HVOL){
264 getBasisValues(false,true,true);
265 if(build_weighted) getBasisValues(true,true,true);
266 }
267
268 if(elmtspace == PureBasis::HDIV or elmtspace == PureBasis::HCURL){
269 getVectorBasisValues(false,true,true);
270 if(build_weighted) getVectorBasisValues(true,true,true);
271 }
272
273 if(elmtspace == PureBasis::HGRAD and compute_derivatives){
274 getGradBasisValues(false,true,true);
275 if(build_weighted) getGradBasisValues(true,true,true);
276 }
277
278 if(elmtspace == PureBasis::HCURL and compute_derivatives){
279 if(num_dims == 2){
280 getCurl2DVectorBasis(false,true,true);
281 if(build_weighted) getCurl2DVectorBasis(true,true,true);
282 } else if(num_dims == 3) {
283 getCurlVectorBasis(false,true,true);
284 if(build_weighted) getCurlVectorBasis(true,true,true);
285 }
286 }
287
288 if(elmtspace == PureBasis::HDIV and compute_derivatives){
289 getDivVectorBasis(false,true,true);
290 if(build_weighted) getDivVectorBasis(true,true,true);
291 }
292
293 // Add the node components
294 if(use_node_coordinates){
295 getBasisCoordinatesRef(true,true);
296 getBasisCoordinates(true,true);
297 }
298
299 // Orientations have been applied if the number of them is greater than zero
300 orientations_applied_ = (orientations_.size()>0);
301}
302
303template <typename Scalar>
305evaluateValuesCV(const PHX::MDField<Scalar,Cell,IP,Dim> & cub_points,
306 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac,
307 const PHX::MDField<Scalar,Cell,IP> & jac_det,
308 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac_inv)
309{
310 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::evaluateValuesCV(5 arg)",bv_ev_cv_5);
311
312 PHX::MDField<Scalar,Cell,IP> weighted_measure;
313 PHX::MDField<Scalar,Cell,NODE,Dim> node_coordinates;
314 evaluateValues(cub_points,jac,jac_det,jac_inv,weighted_measure,node_coordinates,false,jac.extent(0));
315}
316
317template <typename Scalar>
319evaluateValuesCV(const PHX::MDField<Scalar,Cell,IP,Dim> & cell_cub_points,
320 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac,
321 const PHX::MDField<Scalar,Cell,IP> & jac_det,
322 const PHX::MDField<Scalar,Cell,IP,Dim,Dim> & jac_inv,
323 const PHX::MDField<Scalar,Cell,NODE,Dim> & node_coordinates,
324 bool use_node_coordinates,
325 const int in_num_cells)
326{
327 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::evaluateValuesCV(7 arg)",bv_ev_cv_7);
328 PHX::MDField<Scalar,Cell,IP> weighted_measure;
329 evaluateValues(cell_cub_points,jac,jac_det,jac_inv,weighted_measure,node_coordinates,use_node_coordinates,in_num_cells);
330}
331
332template <typename Scalar>
334evaluateBasisCoordinates(const PHX::MDField<Scalar,Cell,NODE,Dim> & node_coordinates,
335 const int in_num_cells)
336{
337 num_evaluate_cells_ = in_num_cells < 0 ? node_coordinates.extent(0) : in_num_cells;
338 cell_node_coordinates_ = node_coordinates;
339
340 getBasisCoordinates(true,true);
341}
342
343// method for applying orientations
344template <typename Scalar>
346applyOrientations(const std::vector<Intrepid2::Orientation> & orientations,
347 const int in_num_cells)
348{
349 if (!intrepid_basis->requireOrientation())
350 return;
351
352 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::applyOrientations()",bv_ev_app_orts);
353
354 // We only allow the orientations to be applied once
355 TEUCHOS_ASSERT(not orientations_applied_);
356
357 const PureBasis::EElementSpace elmtspace = getElementSpace();
358
359 const int num_cell_basis_layout = in_num_cells < 0 ? basis_layout->numCells() : in_num_cells;
360 const int num_cell_orientation = orientations.size();
361 const int num_cells = num_cell_basis_layout < num_cell_orientation ? num_cell_basis_layout : num_cell_orientation;
362 const int num_dim = basis_layout->dimension();
363
364 // Copy orientations to device
365 Kokkos::DynRankView<Intrepid2::Orientation,PHX::Device> device_orientations("device_orientations", num_cells);
366 auto host_orientations = Kokkos::create_mirror_view(device_orientations);
367 for(int i=0; i < num_cells; ++i)
368 host_orientations(i) = orientations[i];
369 Kokkos::deep_copy(device_orientations,host_orientations);
370
371 if (elmtspace == PureBasis::HGRAD){
372 applyOrientationsImpl<Scalar>(num_cells, basis_scalar.get_view(), device_orientations, *intrepid_basis);
373 if(build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_basis_scalar.get_view(), device_orientations, *intrepid_basis);
374 if(compute_derivatives) applyOrientationsImpl<Scalar>(num_cells, grad_basis.get_view(), device_orientations, *intrepid_basis);
375 if(compute_derivatives and build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_grad_basis.get_view(), device_orientations, *intrepid_basis);
376 }
377
378 if(elmtspace == PureBasis::HCURL){
379 applyOrientationsImpl<Scalar>(num_cells, basis_vector.get_view(), device_orientations, *intrepid_basis);
380 if(build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_basis_vector.get_view(), device_orientations, *intrepid_basis);
381 if(num_dim == 2){
382 if(compute_derivatives) applyOrientationsImpl<Scalar>(num_cells, curl_basis_scalar.get_view(), device_orientations, *intrepid_basis);
383 if(compute_derivatives and build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_curl_basis_scalar.get_view(), device_orientations, *intrepid_basis);
384 }
385 if(num_dim == 3){
386 if(compute_derivatives) applyOrientationsImpl<Scalar>(num_cells, curl_basis_vector.get_view(), device_orientations, *intrepid_basis);
387 if(compute_derivatives and build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_curl_basis_vector.get_view(), device_orientations, *intrepid_basis);
388 }
389 }
390
391 if(elmtspace == PureBasis::HDIV){
392 applyOrientationsImpl<Scalar>(num_cells, basis_vector.get_view(), device_orientations, *intrepid_basis);
393 if(build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_basis_vector.get_view(), device_orientations, *intrepid_basis);
394 if(compute_derivatives) applyOrientationsImpl<Scalar>(num_cells, div_basis.get_view(), device_orientations, *intrepid_basis);
395 if(compute_derivatives and build_weighted) applyOrientationsImpl<Scalar>(num_cells, weighted_div_basis.get_view(), device_orientations, *intrepid_basis);
396 }
397
398 orientations_applied_ = true;
399}
400
401// method for applying orientations
402template <typename Scalar>
404applyOrientations(const PHX::MDField<const Scalar,Cell,BASIS> & orientations)
405{
406 TEUCHOS_TEST_FOR_EXCEPT_MSG(true,"panzer::BasisValues2::applyOrientations : this should not be called.");
407}
408
409template <typename Scalar>
411{ return basis_layout->getBasis()->getElementSpace(); }
412
413template <typename Scalar>
415setupArrays(const Teuchos::RCP<const panzer::BasisIRLayout>& layout,
416 bool computeDerivatives)
417{
418 MDFieldArrayFactory af(prefix,alloc_arrays);
419
420 compute_derivatives = computeDerivatives;
421 basis_layout = layout;
422 num_cells_ = basis_layout->numCells();
423 Teuchos::RCP<const panzer::PureBasis> basisDesc = layout->getBasis();
424
425 // for convience pull out basis and quadrature information
426 int num_quad = layout->numPoints();
427 int dim = basisDesc->dimension();
428 int card = basisDesc->cardinality();
429 int numcells = basisDesc->numCells();
430 panzer::PureBasis::EElementSpace elmtspace = basisDesc->getElementSpace();
431 cell_topology_ = basisDesc->getCellTopology();
432
433 intrepid_basis = basisDesc->getIntrepid2Basis<PHX::Device::execution_space,Scalar,Scalar>();
434
435 // allocate field containers
436 // field sizes defined by http://trilinos.sandia.gov/packages/docs/dev/packages/intrepid/doc/html/basis_page.html#basis_md_array_sec
437
438 // compute basis fields
439 if(elmtspace==panzer::PureBasis::HGRAD) {
440 // HGRAD is a nodal field
441
442 // build values
444 basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("basis_ref",card,num_quad); // F, P
445 basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("basis",numcells,card,num_quad);
446
447 if(build_weighted)
448 weighted_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("weighted_basis",numcells,card,num_quad);
449
450 // build gradients
452
453 if(compute_derivatives) {
454 grad_basis_ref = af.buildStaticArray<Scalar,BASIS,IP,Dim>("grad_basis_ref",card,num_quad,dim); // F, P, D
455 grad_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("grad_basis",numcells,card,num_quad,dim);
456
457 if(build_weighted)
458 weighted_grad_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("weighted_grad_basis",numcells,card,num_quad,dim);
459 }
460
461 // build curl
463
464 // nothing - HGRAD does not support CURL operation
465 }
466 else if(elmtspace==panzer::PureBasis::HCURL) {
467 // HCURL is a vector field
468
469 // build values
471
472 basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("basis_ref",card,num_quad,dim); // F, P, D
473 basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("basis",numcells,card,num_quad,dim);
474
475 if(build_weighted)
476 weighted_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("weighted_basis",numcells,card,num_quad,dim);
477
478 // build gradients
480
481 // nothing - HCURL does not support GRAD operation
482
483 // build curl
485
486 if(compute_derivatives) {
487 if(dim==2) {
488 // curl of HCURL basis is not dimension dependent
489 curl_basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("curl_basis_ref",card,num_quad); // F, P
490 curl_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("curl_basis",numcells,card,num_quad);
491
492 if(build_weighted)
493 weighted_curl_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("weighted_curl_basis",numcells,card,num_quad);
494 }
495 else if(dim==3){
496 curl_basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("curl_basis_ref",card,num_quad,dim); // F, P, D
497 curl_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("curl_basis",numcells,card,num_quad,dim);
498
499 if(build_weighted)
500 weighted_curl_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("weighted_curl_basis",numcells,card,num_quad,dim);
501 }
502 else { TEUCHOS_ASSERT(false); } // what do I do with 1D?
503 }
504 }
505 else if(elmtspace==panzer::PureBasis::HDIV) {
506 // HDIV is a vector field
507
508 // build values
510
511 basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("basis_ref",card,num_quad,dim); // F, P, D
512 basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("basis",numcells,card,num_quad,dim);
513
514 if(build_weighted)
515 weighted_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("weighted_basis",numcells,card,num_quad,dim);
516
517 // build gradients
519
520 // nothing - HCURL does not support GRAD operation
521
522 // build curl
524
525 // nothing - HDIV does not support CURL operation
526
527 // build div
529
530 if(compute_derivatives) {
531 div_basis_ref = af.buildStaticArray<Scalar,BASIS,IP>("div_basis_ref",card,num_quad); // F, P
532 div_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP>("div_basis",numcells,card,num_quad);
533
534 if(build_weighted)
535 weighted_div_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP>("weighted_div_basis",numcells,card,num_quad);
536 }
537 }
538 else if(elmtspace==panzer::PureBasis::CONST || elmtspace==panzer::PureBasis::HVOL) {
539 // CONST is a nodal field
540
541 // build values
543 basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("basis_ref",card,num_quad); // F, P
544 basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("basis",numcells,card,num_quad);
545
546 if(build_weighted)
547 weighted_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("weighted_basis",numcells,card,num_quad);
548
549 // build gradients
551
552 // nothing - CONST does not support GRAD operation
553
554 // build curl
556
557 // nothing - CONST does not support CURL operation
558
559 // build div
561
562 // nothing - CONST does not support DIV operation
563 }
564 else { TEUCHOS_ASSERT(false); }
565
566 basis_coordinates_ref = af.buildStaticArray<Scalar,BASIS,Dim>("basis_coordinates_ref",card,dim);
567 basis_coordinates = af.buildStaticArray<Scalar,Cell,BASIS,Dim>("basis_coordinates",numcells,card,dim);
568}
569
570
571//=======================================================================================================
572// New Interface
573
574
575template <typename Scalar>
576void
578setup(const Teuchos::RCP<const panzer::BasisIRLayout> & basis,
579 PHX::MDField<const Scalar, Cell, IP, Dim> reference_points,
580 PHX::MDField<const Scalar, Cell, IP, Dim, Dim> point_jacobian,
581 PHX::MDField<const Scalar, Cell, IP> point_jacobian_determinant,
582 PHX::MDField<const Scalar, Cell, IP, Dim, Dim> point_jacobian_inverse,
583 const int num_evaluated_cells)
584{
585 basis_layout = basis;
586 intrepid_basis = basis->getBasis()->getIntrepid2Basis<PHX::Device::execution_space,Scalar,Scalar>();
587 cell_topology_ = basis->getCellTopologyInfo()->getCellTopology();
588 num_cells_ = basis_layout->numCells();
589 num_evaluate_cells_ = num_evaluated_cells >= 0 ? num_evaluated_cells : num_cells_;
590 build_weighted = false;
591 is_uniform_ = false;
592
593 cubature_points_ref_ = reference_points;
594 cubature_jacobian_ = point_jacobian;
595 cubature_jacobian_determinant_ = point_jacobian_determinant;
596 cubature_jacobian_inverse_ = point_jacobian_inverse;
597
598 // Reset internal data
599 resetArrays();
600}
601
602template <typename Scalar>
603void
605setupUniform(const Teuchos::RCP<const panzer::BasisIRLayout> & basis,
606 PHX::MDField<const Scalar, IP, Dim> reference_points,
607 PHX::MDField<const Scalar, Cell, IP, Dim, Dim> point_jacobian,
608 PHX::MDField<const Scalar, Cell, IP> point_jacobian_determinant,
609 PHX::MDField<const Scalar, Cell, IP, Dim, Dim> point_jacobian_inverse,
610 const int num_evaluated_cells)
611{
612 basis_layout = basis;
613 intrepid_basis = basis->getBasis()->getIntrepid2Basis<PHX::Device::execution_space,Scalar,Scalar>();
614 cell_topology_ = basis->getCellTopologyInfo()->getCellTopology();
615 num_cells_ = basis_layout->numCells();
616 num_evaluate_cells_ = num_evaluated_cells >= 0 ? num_evaluated_cells : num_cells_;
617 cubature_points_uniform_ref_ = reference_points;
618 build_weighted = false;
619 is_uniform_ = true;
620
621 cubature_jacobian_ = point_jacobian;
622 cubature_jacobian_determinant_ = point_jacobian_determinant;
623 cubature_jacobian_inverse_ = point_jacobian_inverse;
624
625 // Reset internal data
626 resetArrays();
627}
628
629template <typename Scalar>
630void
632setOrientations(const std::vector<Intrepid2::Orientation> & orientations,
633 const int num_orientations_cells)
634{
635 if(num_orientations_cells < 0)
636 num_orientations_cells_ = num_evaluate_cells_;
637 else
638 num_orientations_cells_ = num_orientations_cells;
639 if(orientations.size() == 0){
640 orientations_applied_ = false;
641 // Normally we would reset arrays here, but it seems to causes a lot of problems
642 } else {
643 orientations_ = orientations;
644 orientations_applied_ = true;
645 // Setting orientations means that we need to reset our arrays
646 resetArrays();
647 }
648}
649
650template <typename Scalar>
651void
653setCellNodeCoordinates(PHX::MDField<Scalar,Cell,NODE,Dim> node_coordinates)
654{
655 cell_node_coordinates_ = node_coordinates;
656}
657
658template <typename Scalar>
660{
661 auto pure_basis = basis_layout->getBasis();
662 return {pure_basis->order(),pure_basis->type()};
663}
664
665template <typename Scalar>
666void
669{
670 // Turn off all evaluated fields (forces re-evaluation)
671 basis_ref_scalar_evaluated_ = false;
672 basis_scalar_evaluated_ = false;
673 basis_ref_vector_evaluated_ = false;
674 basis_vector_evaluated_ = false;
675 grad_basis_ref_evaluated_ = false;
676 grad_basis_evaluated_ = false;
677 curl_basis_ref_scalar_evaluated_ = false;
678 curl_basis_scalar_evaluated_ = false;
679 curl_basis_ref_vector_evaluated_ = false;
680 curl_basis_vector_evaluated_ = false;
681 div_basis_ref_evaluated_ = false;
682 div_basis_evaluated_ = false;
683 weighted_basis_scalar_evaluated_ = false;
684 weighted_basis_vector_evaluated_ = false;
685 weighted_grad_basis_evaluated_ = false;
686 weighted_curl_basis_scalar_evaluated_ = false;
687 weighted_curl_basis_vector_evaluated_ = false;
688 weighted_div_basis_evaluated_ = false;
689 basis_coordinates_ref_evaluated_ = false;
690 basis_coordinates_evaluated_ = false;
691
692 // TODO: Enable this feature - requires the old interface to go away
693 // De-allocate arrays if necessary
694// if(not alloc_arrays){
695// basis_ref_scalar = Array_BasisIP();
696// basis_scalar = Array_CellBasisIP();
697// basis_ref_vector = Array_BasisIPDim();
698// basis_vector = Array_CellBasisIPDim();
699// grad_basis_ref = Array_BasisIPDim();
700// grad_basis = Array_CellBasisIPDim();
701// curl_basis_ref_scalar = Array_BasisIP();
702// curl_basis_scalar = Array_CellBasisIP();
703// curl_basis_ref_vector = Array_BasisIPDim();
704// curl_basis_vector = Array_CellBasisIPDim();
705// div_basis_ref = Array_BasisIP();
706// div_basis = Array_CellBasisIP();
707// weighted_basis_scalar = Array_CellBasisIP();
708// weighted_basis_vector = Array_CellBasisIPDim();
709// weighted_grad_basis = Array_CellBasisIPDim();
710// weighted_curl_basis_scalar = Array_CellBasisIP();
711// weighted_curl_basis_vector = Array_CellBasisIPDim();
712// weighted_div_basis = Array_CellBasisIP();
713// basis_coordinates_ref = Array_BasisDim();
714// basis_coordinates = Array_CellBasisDim();
715// }
716}
717
718template <typename Scalar>
719void
721setWeightedMeasure(PHX::MDField<const Scalar, Cell, IP> weighted_measure)
722{
723 TEUCHOS_TEST_FOR_EXCEPT_MSG(build_weighted,
724 "BasisValues2::setWeightedMeasure : Weighted measure already set. Can only set weighted measure once after setup or setupUniform have beens called.");
725 cubature_weights_ = weighted_measure;
726 build_weighted = true;
727}
728
729// If the array is allocated we can not reassign it - this means we
730// have to deep copy into it. The use of deep_copy is need when an
731// applicaiton or the library has cached a BasisValues2 member view
732// outside of the BasisValues object. This could happen when the basis
733// values object is embedded in an evalautor for mesh motion.
734#define PANZER_CACHE_DATA(name) \
735 if(cache) { \
736 if(name.size()==tmp_##name.size()){ \
737 Kokkos::deep_copy(name.get_view(), tmp_##name.get_view()); \
738 } else { \
739 name = tmp_##name; \
740 } \
741 name##_evaluated_ = true; \
742 }
743
744template <typename Scalar>
747getBasisCoordinatesRef(const bool cache,
748 const bool force) const
749{
750 // Check if array already exists
751 if(basis_coordinates_ref_evaluated_ and not force)
752 return basis_coordinates_ref;
753
754 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getBasisCoordinatesRef()",bv_get_bc_ref);
755
756 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
757
758 const int num_card = basis_layout->cardinality();
759 const int num_dim = basis_layout->dimension();
760
761 using coordsScalarType = typename Intrepid2::Basis<PHX::Device::execution_space,Scalar,Scalar>::scalarType;
762 auto tmp_basis_coordinates_ref = af.buildStaticArray<coordsScalarType,BASIS,Dim>("basis_coordinates_ref", num_card, num_dim);
763 intrepid_basis->getDofCoords(tmp_basis_coordinates_ref.get_view());
764 PHX::Device().fence();
765
766 // Store for later if cache is enabled
767 PANZER_CACHE_DATA(basis_coordinates_ref)
768
769 return tmp_basis_coordinates_ref;
770}
771
772template <typename Scalar>
775getBasisValuesRef(const bool cache,
776 const bool force) const
777{
778 // Check if array already exists
779 if(basis_ref_scalar_evaluated_ and not force)
780 return basis_ref_scalar;
781
782 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getBasisValuesRef()",bv_get_bV_ref);
783
784 // Reference quantities only exist for a uniform reference space
785 TEUCHOS_ASSERT(hasUniformReferenceSpace());
786
787 // Make sure basis is valid
788 PureBasis::EElementSpace elmtspace = getElementSpace();
789 TEUCHOS_ASSERT(elmtspace==PureBasis::HGRAD || elmtspace==PureBasis::CONST || elmtspace==PureBasis::HVOL);
790
791 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
792
793 const int num_quad = basis_layout->numPoints();
794 const int num_card = basis_layout->cardinality();
795
796 auto tmp_basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("dyn_basis_ref_scalar",num_card,num_quad);
797 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
798
799 intrepid_basis->getValues(tmp_basis_ref_scalar.get_view(), cubature_points_uniform_ref, Intrepid2::OPERATOR_VALUE);
800 PHX::Device().fence();
801
802 // Store for later if cache is enabled
803 PANZER_CACHE_DATA(basis_ref_scalar);
804
805 return tmp_basis_ref_scalar;
806}
807
808template <typename Scalar>
811getVectorBasisValuesRef(const bool cache,
812 const bool force) const
813{
814 // Check if array already exists
815 if(basis_ref_vector_evaluated_ and not force)
816 return basis_ref_vector;
817
818 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getVectorBasisValuesRef()",bv_get_vec_bv_ref);
819
820 // Reference quantities only exist for a uniform reference space
821 TEUCHOS_ASSERT(hasUniformReferenceSpace());
822
823 // Make sure basis is valid
824 PureBasis::EElementSpace elmtspace = getElementSpace();
825 TEUCHOS_ASSERT(elmtspace==PureBasis::HDIV || elmtspace==PureBasis::HCURL);
826
827 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
828
829 const int num_quad = basis_layout->numPoints();
830 const int num_card = basis_layout->cardinality();
831 const int num_dim = basis_layout->dimension();
832
833 auto tmp_basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("dyn_basis_ref_vector",num_card,num_quad,num_dim);
834 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
835
836 intrepid_basis->getValues(tmp_basis_ref_vector.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_VALUE);
837 PHX::Device().fence();
838
839 // Store for later if cache is enabled
840 PANZER_CACHE_DATA(basis_ref_vector);
841
842 return tmp_basis_ref_vector;
843}
844
845template <typename Scalar>
848getGradBasisValuesRef(const bool cache,
849 const bool force) const
850{
851 // Check if array already exists
852 if(grad_basis_ref_evaluated_ and not force)
853 return grad_basis_ref;
854
855 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getGradBasisValuesRef()",bv_get_grad_bv_ref);
856
857 // Reference quantities only exist for a uniform reference space
858 TEUCHOS_ASSERT(hasUniformReferenceSpace());
859
860 // Make sure basis is valid
861 PureBasis::EElementSpace elmtspace = getElementSpace();
862 TEUCHOS_ASSERT(elmtspace==PureBasis::HGRAD);
863
864 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
865
866 const int num_quad = basis_layout->numPoints();
867 const int num_card = basis_layout->cardinality();
868 const int num_dim = basis_layout->dimension();
869
870 auto tmp_grad_basis_ref = af.buildStaticArray<Scalar,BASIS,IP,Dim>("dyn_basis_ref_vector",num_card,num_quad,num_dim);
871 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
872
873 intrepid_basis->getValues(tmp_grad_basis_ref.get_view(), cubature_points_uniform_ref, Intrepid2::OPERATOR_GRAD);
874 PHX::Device().fence();
875
876 // Store for later if cache is enabled
877 PANZER_CACHE_DATA(grad_basis_ref);
878
879 return tmp_grad_basis_ref;
880}
881
882template <typename Scalar>
885getCurl2DVectorBasisRef(const bool cache,
886 const bool force) const
887{
888 // Check if array already exists
889 if(curl_basis_ref_scalar_evaluated_ and not force)
890 return curl_basis_ref_scalar;
891
892 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getCurl2DVectorBasisRef()",bv_get_curl2_bv_ref);
893
894 // Reference quantities only exist for a uniform reference space
895 TEUCHOS_ASSERT(hasUniformReferenceSpace());
896 TEUCHOS_ASSERT(basis_layout->dimension() == 2);
897
898 // Make sure basis is valid
899 PureBasis::EElementSpace elmtspace = getElementSpace();
900 TEUCHOS_ASSERT(elmtspace==PureBasis::HCURL);
901
902 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
903
904 const int num_quad = basis_layout->numPoints();
905 const int num_card = basis_layout->cardinality();
906
907 auto tmp_curl_basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("dyn_curl_basis_ref_scalar",num_card,num_quad);
908 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
909
910 intrepid_basis->getValues(tmp_curl_basis_ref_scalar.get_view(), cubature_points_uniform_ref, Intrepid2::OPERATOR_CURL);
911 PHX::Device().fence();
912
913 // Store for later if cache is enabled
914 PANZER_CACHE_DATA(curl_basis_ref_scalar);
915
916 return tmp_curl_basis_ref_scalar;
917}
918
919template <typename Scalar>
922getCurlVectorBasisRef(const bool cache,
923 const bool force) const
924{
925 // Check if array already exists
926 if(curl_basis_ref_vector_evaluated_ and not force)
927 return curl_basis_ref_vector;
928
929 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getCurlVectorBasisRef()",bv_get_curl_vec_bv_ref);
930
931 // Reference quantities only exist for a uniform reference space
932 TEUCHOS_ASSERT(hasUniformReferenceSpace());
933 TEUCHOS_ASSERT(basis_layout->dimension() == 3);
934
935 // Make sure basis is valid
936 PureBasis::EElementSpace elmtspace = getElementSpace();
937 TEUCHOS_ASSERT(elmtspace==PureBasis::HCURL);
938
939 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
940
941 const int num_quad = basis_layout->numPoints();
942 const int num_card = basis_layout->cardinality();
943 const int num_dim = basis_layout->dimension();
944
945 auto tmp_curl_basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("dyn_curl_basis_ref_vector",num_card,num_quad,num_dim);
946 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
947
948 intrepid_basis->getValues(tmp_curl_basis_ref_vector.get_view(), cubature_points_uniform_ref, Intrepid2::OPERATOR_CURL);
949 PHX::Device().fence();
950
951 // Store for later if cache is enabled
952 PANZER_CACHE_DATA(curl_basis_ref_vector);
953
954 return tmp_curl_basis_ref_vector;
955}
956
957template <typename Scalar>
960getDivVectorBasisRef(const bool cache,
961 const bool force) const
962{
963 // Check if array already exists
964 if(div_basis_ref_evaluated_ and not force)
965 return div_basis_ref;
966
967 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getDivVectorBasisRef()",bv_get_div_vec_bv_ref);
968
969 // Reference quantities only exist for a uniform reference space
970 TEUCHOS_ASSERT(hasUniformReferenceSpace());
971
972 // Make sure basis is valid
973 PureBasis::EElementSpace elmtspace = getElementSpace();
974 TEUCHOS_ASSERT(elmtspace==PureBasis::HDIV);
975
976 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
977
978 const int num_quad = basis_layout->numPoints();
979 const int num_card = basis_layout->cardinality();
980
981 auto tmp_div_basis_ref = af.buildStaticArray<Scalar,BASIS,IP>("dyn_div_basis_ref_scalar",num_card,num_quad);
982 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
983
984 intrepid_basis->getValues(tmp_div_basis_ref.get_view(), cubature_points_uniform_ref, Intrepid2::OPERATOR_DIV);
985 PHX::Device().fence();
986
987 // Store for later if cache is enabled
988 PANZER_CACHE_DATA(div_basis_ref);
989
990 return tmp_div_basis_ref;
991}
992
993template <typename Scalar>
996getBasisCoordinates(const bool cache,
997 const bool force) const
998{
999 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getBasisCoordinates()",bv_get_bc);
1000
1001 // Check if array already exists
1002 if(basis_coordinates_evaluated_ and not force)
1003 return basis_coordinates;
1004
1005 TEUCHOS_ASSERT(cell_node_coordinates_.size() > 0);
1006
1007 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1008 const auto s_node_coordinates = Kokkos::subview(cell_node_coordinates_.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1009
1010 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1011
1012 const int num_card = basis_layout->cardinality();
1013 const int num_dim = basis_layout->dimension();
1014
1015 auto tmp_basis_coordinates = af.buildStaticArray<Scalar, Cell, BASIS, IP>("basis_coordinates", num_cells_, num_card, num_dim);
1016 auto s_aux = Kokkos::subview(tmp_basis_coordinates.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1017
1018 // Don't forget that since we are not caching this, we have to make sure the managed view remains alive while we use the non-const wrapper
1019 auto const_bcr = getBasisCoordinatesRef(false);
1020 auto bcr = PHX::getNonConstDynRankViewFromConstMDField(const_bcr);
1021
1022 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1023 cell_tools.mapToPhysicalFrame(s_aux, bcr, s_node_coordinates, *cell_topology_);
1024 PHX::Device().fence();
1025
1026 // Store for later if cache is enabled
1027 PANZER_CACHE_DATA(basis_coordinates);
1028
1029 return tmp_basis_coordinates;
1030}
1031
1032template <typename Scalar>
1035getBasisValues(const bool weighted,
1036 const bool cache,
1037 const bool force) const
1038{
1039 if(weighted){
1040 if(weighted_basis_scalar_evaluated_ and not force)
1041 return weighted_basis_scalar;
1042 } else
1043 if(basis_scalar_evaluated_ and not force)
1044 return basis_scalar;
1045
1046 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getBasisValues()",bv_get_bv);
1047
1048 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1049
1050 const int num_cells = num_cells_;
1051 const int num_points = basis_layout->numPoints();
1052 const int num_card = basis_layout->cardinality();
1053
1054 if(weighted){
1055 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1056
1057 // Get the basis_scalar values - do not cache
1058 const auto bv = getBasisValues(false, force);
1059
1060 // Apply the weighted measure (cubature weights)
1061 auto tmp_weighted_basis_scalar = af.buildStaticArray<Scalar, Cell, BASIS, IP>("weighted_basis_scalar", num_cells, num_card, num_points);
1062
1063 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1064 auto s_aux = Kokkos::subview(tmp_weighted_basis_scalar.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1065 auto s_cw = Kokkos::subview(cubature_weights_.get_view(),cell_range,Kokkos::ALL());
1066 auto s_bv = Kokkos::subview(bv.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1067
1068 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1069 fst::multiplyMeasure(s_aux,s_cw,s_bv);
1070
1071 // NOTE: Weighted path has orientations already applied so doesn't
1072 // need the applyOrientations call at the bottom of this function.
1073
1074 // Store for later if cache is enabled
1075 PANZER_CACHE_DATA(weighted_basis_scalar);
1076
1077 return tmp_weighted_basis_scalar;
1078
1079 } else {
1080
1081 const auto element_space = getElementSpace();
1082 TEUCHOS_ASSERT(element_space == PureBasis::HVOL || element_space == PureBasis::HGRAD || element_space == PureBasis::CONST);
1083
1084 // HVol requires the jacobian determinant
1085 if(element_space == PureBasis::HVOL){
1086 TEUCHOS_ASSERT(cubature_jacobian_determinant_.size() > 0);
1087 }
1088
1089 auto tmp_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("basis_scalar",num_cells,num_card,num_points);
1090
1091 if(hasUniformReferenceSpace()){
1092
1093 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1094
1095 // Apply a single reference representation to all cells
1096 auto cell_basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("cell_basis_ref_scalar",num_card,num_points);
1097 intrepid_basis->getValues(cell_basis_ref_scalar.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_VALUE);
1098
1099 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1100 auto s_aux = Kokkos::subview(tmp_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1101
1102 // Apply transformation (HGRAD version is just a copy operation)
1103 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1104 if (element_space == PureBasis::HVOL){
1105 auto s_cjd = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1106 fst::HVOLtransformVALUE(s_aux,s_cjd,cell_basis_ref_scalar.get_view());
1107 } else if (element_space == PureBasis::HGRAD || element_space == PureBasis::CONST) {
1108 fst::HGRADtransformVALUE(s_aux,cell_basis_ref_scalar.get_view());
1109 }
1110 PHX::Device().fence();
1111
1112 } else {
1113 // getValues currently assumes a single reference cell. Calling
1114 // it serially on host until the function supports multiple
1115 // reference cells to avoid a kernel launch per cell.
1116
1117 // Mirror views on host can't be used with intrepid basis
1118 // getValues() call when UVM or UNIFIED_MEMORY is
1119 // enabled. getHostBasis() returns a "HostSpace" basis object
1120 // while create_mirror_view creates views in UVMSpace or
1121 // HIPSpace. These are not "assignable" in kokkos. We do an
1122 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1123#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1124#ifdef KOKKOS_ENABLE_CUDA
1125 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_basis_scalar.get_view())::memory_space>::value) {
1126#else
1127 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_basis_scalar.get_view())::memory_space>::value) {
1128#endif
1129 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1130 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1131 auto tmp_basis_scalar_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_basis_scalar.get_view());
1132 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1133
1134 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1135 auto my_cell_basis_host = Kokkos::subview(tmp_basis_scalar_host,cell,Kokkos::ALL(),Kokkos::ALL());
1136 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1137 intrepid_basis_host->getValues(my_cell_basis_host,my_cell_cub_points_ref_host);
1138 }
1139 auto tmp_basis_scalar_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_basis_scalar_ref",num_cells,num_card,num_points);
1140 Kokkos::deep_copy(tmp_basis_scalar_ref.get_view(),tmp_basis_scalar_host);
1141 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1142 auto s_aux = Kokkos::subview(tmp_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1143 auto s_ref = Kokkos::subview(tmp_basis_scalar_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1144
1145 using fst=Intrepid2::FunctionSpaceTools<PHX::Device>;
1146 if(element_space == PureBasis::HVOL){
1147 auto s_cjd = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1148 fst::HVOLtransformVALUE(s_aux,s_cjd,s_ref);
1149 } else if(element_space == PureBasis::HGRAD || element_space == PureBasis::CONST) {
1150 fst::HGRADtransformVALUE(s_aux,s_ref);
1151 }
1152 } else {
1153#endif
1154 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1155 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1156 auto tmp_basis_scalar_host = Kokkos::create_mirror_view(tmp_basis_scalar.get_view());
1157 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1158
1159 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1160 auto my_cell_basis_host = Kokkos::subview(tmp_basis_scalar_host,cell,Kokkos::ALL(),Kokkos::ALL());
1161 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1162 intrepid_basis_host->getValues(my_cell_basis_host,my_cell_cub_points_ref_host);
1163 }
1164 auto tmp_basis_scalar_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_basis_scalar_ref",num_cells,num_card,num_points);
1165 Kokkos::deep_copy(tmp_basis_scalar_ref.get_view(),tmp_basis_scalar_host);
1166 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1167 auto s_aux = Kokkos::subview(tmp_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1168 auto s_ref = Kokkos::subview(tmp_basis_scalar_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1169
1170 using fst=Intrepid2::FunctionSpaceTools<PHX::Device>;
1171 if(element_space == PureBasis::HVOL){
1172 auto s_cjd = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1173 fst::HVOLtransformVALUE(s_aux,s_cjd,s_ref);
1174 } else if(element_space == PureBasis::HGRAD || element_space == PureBasis::CONST) {
1175 fst::HGRADtransformVALUE(s_aux,s_ref);
1176 }
1177#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1178 }
1179#endif
1180 PHX::Device().fence();
1181 }
1182
1183 // NOTE: weighted already has orientations applied, so this code
1184 // should only be reached if non-weighted. This is a by-product of
1185 // the two construction paths in panzer. Unification should help
1186 // fix the logic.
1187 if(orientations_.size() > 0)
1188 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_basis_scalar.get_view(), orientations_, *intrepid_basis);
1189
1190 // Store for later if cache is enabled
1191 PANZER_CACHE_DATA(basis_scalar);
1192
1193 return tmp_basis_scalar;
1194
1195 }
1196
1197}
1198
1199template <typename Scalar>
1202getVectorBasisValues(const bool weighted,
1203 const bool cache,
1204 const bool force) const
1205{
1206 if(weighted){
1207 if(weighted_basis_vector_evaluated_ and not force)
1208 return weighted_basis_vector;
1209 } else
1210 if(basis_vector_evaluated_ and not force)
1211 return basis_vector;
1212
1213 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getVectorBasisValues()",bv_get_vec_bv);
1214
1215 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1216
1217 const int num_cells = num_cells_;
1218 const int num_points = basis_layout->numPoints();
1219 const int num_card = basis_layout->cardinality();
1220 const int num_dim = basis_layout->dimension();
1221
1222 if(weighted){
1223
1224 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1225
1226 // Get the basis_scalar values - do not cache
1227 const auto bv = getVectorBasisValues(false, force);
1228
1229 // Apply the weighted measure (cubature weights)
1230 auto tmp_weighted_basis_vector = af.buildStaticArray<Scalar, Cell, BASIS, IP, Dim>("weighted_basis_vector", num_cells, num_card, num_points, num_dim);
1231
1232 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1233 auto s_aux = Kokkos::subview(tmp_weighted_basis_vector.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1234 auto s_cw = Kokkos::subview(cubature_weights_.get_view(),cell_range,Kokkos::ALL());
1235 auto s_bv = Kokkos::subview(bv.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1236
1237 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1238 fst::multiplyMeasure(s_aux, s_cw, s_bv);
1239
1240 // Store for later if cache is enabled
1241 PANZER_CACHE_DATA(weighted_basis_vector);
1242
1243 return tmp_weighted_basis_vector;
1244
1245 } else { // non-weighted
1246
1247 const auto element_space = getElementSpace();
1248 TEUCHOS_ASSERT(element_space == PureBasis::HCURL || element_space == PureBasis::HDIV);
1249 TEUCHOS_ASSERT(num_dim != 1);
1250
1251 // HDIV and HCURL have unique jacobian requirements
1252 if(element_space == PureBasis::HCURL){
1253 TEUCHOS_ASSERT(cubature_jacobian_inverse_.size() > 0);
1254 } else if(element_space == PureBasis::HDIV){
1255 TEUCHOS_ASSERT(cubature_jacobian_.size() > 0 && cubature_jacobian_determinant_.size() > 0);
1256 }
1257
1258 auto tmp_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("basis_vector",num_cells,num_card,num_points,num_dim);
1259
1260 if(hasUniformReferenceSpace()){
1261
1262 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1263
1264 // Apply a single reference representation to all cells
1265 auto cell_basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("cell_basis_ref_scalar",num_card,num_points,num_dim);
1266 intrepid_basis->getValues(cell_basis_ref_vector.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_VALUE);
1267
1268 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1269 auto s_aux = Kokkos::subview(tmp_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1270
1271 // Apply transformation (HGRAD version is just a copy operation)
1272 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1273 if(element_space == PureBasis::HCURL){
1274 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1275 fst::HCURLtransformVALUE(s_aux,s_jac_inv,cell_basis_ref_vector.get_view());
1276 } else if(element_space == PureBasis::HDIV){
1277 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1278 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1279 fst::HDIVtransformVALUE(s_aux,s_jac, s_jac_det, cell_basis_ref_vector.get_view());
1280 }
1281 PHX::Device().fence();
1282
1283 } else {
1284
1285 // getValues currently assumes a single reference cell. Calling
1286 // it serially on host until the function supports multiple
1287 // reference cells to avoid a kernel launch per cell.
1288
1289 // Mirror views on host can't be used with intrepid basis
1290 // getValues() call when UVM or UNIFIED_MEMORY is
1291 // enabled. getHostBasis() returns a "HostSpace" basis object
1292 // while create_mirror_view creates views in UVMSpace or
1293 // HIPSpace. These are not "assignable" in kokkos. We do an
1294 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1295#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1296#ifdef KOKKOS_ENABLE_CUDA
1297 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_basis_vector.get_view())::memory_space>::value) {
1298#else
1299 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_basis_vector.get_view())::memory_space>::value) {
1300#endif
1301 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1302 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1303 auto tmp_basis_vector_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_basis_vector.get_view());
1304
1305 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1306 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1307 auto my_cell_basis_host = Kokkos::subview(tmp_basis_vector_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1308 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1309 intrepid_basis_host->getValues(my_cell_basis_host,my_cell_cub_points_ref_host);
1310 }
1311 auto tmp_basis_vector_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_basis_vector_ref",num_cells,num_card,num_points,num_dim);
1312 Kokkos::deep_copy(tmp_basis_vector_ref.get_view(),tmp_basis_vector_host);
1313
1314 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1315 auto s_aux = Kokkos::subview(tmp_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1316 auto s_ref = Kokkos::subview(tmp_basis_vector_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1317
1318 using fst=Intrepid2::FunctionSpaceTools<PHX::Device>;
1319 if(element_space == PureBasis::HCURL){
1320 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1321 fst::HCURLtransformVALUE(s_aux,s_jac_inv,s_ref);
1322 } else if(element_space == PureBasis::HDIV){
1323 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1324 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1325 fst::HDIVtransformVALUE(s_aux,s_jac, s_jac_det, s_ref);
1326 }
1327 } else {
1328#endif
1329 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1330 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1331 auto tmp_basis_vector_host = Kokkos::create_mirror_view(tmp_basis_vector.get_view());
1332
1333 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1334 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1335 auto my_cell_basis_host = Kokkos::subview(tmp_basis_vector_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1336 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1337 intrepid_basis_host->getValues(my_cell_basis_host,my_cell_cub_points_ref_host);
1338 }
1339 auto tmp_basis_vector_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_basis_vector_ref",num_cells,num_card,num_points,num_dim);
1340 Kokkos::deep_copy(tmp_basis_vector_ref.get_view(),tmp_basis_vector_host);
1341
1342 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1343 auto s_aux = Kokkos::subview(tmp_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1344 auto s_ref = Kokkos::subview(tmp_basis_vector_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1345
1346 using fst=Intrepid2::FunctionSpaceTools<PHX::Device>;
1347 if(element_space == PureBasis::HCURL){
1348 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1349 fst::HCURLtransformVALUE(s_aux,s_jac_inv,s_ref);
1350 } else if(element_space == PureBasis::HDIV){
1351 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1352 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1353 fst::HDIVtransformVALUE(s_aux,s_jac, s_jac_det, s_ref);
1354 }
1355#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1356 }
1357#endif
1358 PHX::Device().fence();
1359
1360 }
1361
1362 if(orientations_.size() > 0)
1363 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_basis_vector.get_view(), orientations_, *intrepid_basis);
1364
1365 // Store for later if cache is enabled
1366 PANZER_CACHE_DATA(basis_vector);
1367
1368 return tmp_basis_vector;
1369
1370 }
1371
1372}
1373
1374template <typename Scalar>
1377getGradBasisValues(const bool weighted,
1378 const bool cache,
1379 const bool force) const
1380{
1381 if(weighted){
1382 if(weighted_grad_basis_evaluated_ and not force)
1383 return weighted_grad_basis;
1384 } else
1385 if(grad_basis_evaluated_ and not force)
1386 return grad_basis;
1387
1388 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getGradBasisValues()",bv_get_grad_bv);
1389
1390 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1391
1392 const int num_cells = num_cells_;
1393 const int num_points = basis_layout->numPoints();
1394 const int num_card = basis_layout->cardinality();
1395 const int num_dim = basis_layout->dimension();
1396
1397 if(weighted){
1398
1399 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1400
1401 // Get the basis_scalar values - do not cache
1402 const auto bv = getGradBasisValues(false, force);
1403
1404 // Apply the weighted measure (cubature weights)
1405 auto tmp_weighted_grad_basis = af.buildStaticArray<Scalar, Cell, BASIS, IP, Dim>("weighted_grad_basis", num_cells, num_card, num_points, num_dim);
1406
1407 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1408 auto s_aux = Kokkos::subview(tmp_weighted_grad_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1409 auto s_cw = Kokkos::subview(cubature_weights_.get_view(), cell_range, Kokkos::ALL());
1410 auto s_bv = Kokkos::subview(bv.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1411
1412 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1413 fst::multiplyMeasure(s_aux,s_cw,s_bv);
1414
1415 // Store for later if cache is enabled
1416 PANZER_CACHE_DATA(weighted_grad_basis);
1417
1418 return tmp_weighted_grad_basis;
1419
1420 } else {
1421
1422 TEUCHOS_ASSERT(cubature_jacobian_inverse_.size() > 0);
1423
1424 const auto element_space = getElementSpace();
1425 TEUCHOS_ASSERT(element_space == PureBasis::CONST || element_space == PureBasis::HGRAD);
1426
1427 auto cell_grad_basis_ref = af.buildStaticArray<Scalar,BASIS,IP,Dim>("cell_grad_basis_ref",num_card,num_points,num_dim);
1428 auto tmp_grad_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("basis_scalar",num_cells,num_card,num_points,num_dim);
1429
1430 if(hasUniformReferenceSpace()){
1431
1432 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1433
1434 // Apply a single reference representation to all cells
1435 intrepid_basis->getValues(cell_grad_basis_ref.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_GRAD);
1436
1437 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1438 auto s_aux = Kokkos::subview(tmp_grad_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1439 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1440
1441 // Apply transformation
1442 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1443 fst::HGRADtransformGRAD(s_aux, s_jac_inv,cell_grad_basis_ref.get_view());
1444
1445 PHX::Device().fence();
1446
1447 } else {
1448
1449 // getValues currently assumes a single reference cell. Calling
1450 // it serially on host until the function supports multiple
1451 // reference cells to avoid a kernel launch per cell.
1452
1453 // Mirror views on host can't be used with intrepid basis
1454 // getValues() call when UVM or UNIFIED_MEMORY is
1455 // enabled. getHostBasis() returns a "HostSpace" basis object
1456 // while create_mirror_view creates views in UVMSpace or
1457 // HIPSpace. These are not "assignable" in kokkos. We do an
1458 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1459#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1460#ifdef KOKKOS_ENABLE_CUDA
1461 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_grad_basis.get_view())::memory_space>::value) {
1462#else
1463 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_grad_basis.get_view())::memory_space>::value) {
1464#endif
1465 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1466 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1467 auto tmp_grad_basis_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_grad_basis.get_view());
1468
1469 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1470 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1471 auto my_cell_grad_basis_host = Kokkos::subview(tmp_grad_basis_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1472 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1473 intrepid_basis_host->getValues(my_cell_grad_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_GRAD);
1474 }
1475 auto tmp_grad_basis_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_grad_basis_ref",num_cells,num_card,num_points,num_dim);
1476 Kokkos::deep_copy(tmp_grad_basis_ref.get_view(),tmp_grad_basis_host);
1477
1478 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1479 auto s_aux = Kokkos::subview(tmp_grad_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1480 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1481 auto s_ref = Kokkos::subview(tmp_grad_basis_ref.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1482
1483 // Apply transformation
1484 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1485 fst::HGRADtransformGRAD(s_aux, s_jac_inv, s_ref);
1486 } else {
1487#endif
1488 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1489 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1490 auto tmp_grad_basis_host = Kokkos::create_mirror_view(tmp_grad_basis.get_view());
1491
1492 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1493 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1494 auto my_cell_grad_basis_host = Kokkos::subview(tmp_grad_basis_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1495 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1496 intrepid_basis_host->getValues(my_cell_grad_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_GRAD);
1497 }
1498 auto tmp_grad_basis_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_grad_basis_ref",num_cells,num_card,num_points,num_dim);
1499 Kokkos::deep_copy(tmp_grad_basis_ref.get_view(),tmp_grad_basis_host);
1500
1501 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1502 auto s_aux = Kokkos::subview(tmp_grad_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1503 auto s_jac_inv = Kokkos::subview(cubature_jacobian_inverse_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1504 auto s_ref = Kokkos::subview(tmp_grad_basis_ref.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1505
1506 // Apply transformation
1507 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1508 fst::HGRADtransformGRAD(s_aux, s_jac_inv, s_ref);
1509#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1510 }
1511#endif
1512 PHX::Device().fence();
1513
1514 }
1515
1516 if(orientations_.size() > 0)
1517 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_grad_basis.get_view(), orientations_, *intrepid_basis);
1518
1519 // Store for later if cache is enabled
1520 PANZER_CACHE_DATA(grad_basis);
1521
1522 return tmp_grad_basis;
1523
1524 }
1525
1526}
1527
1528template <typename Scalar>
1531getCurl2DVectorBasis(const bool weighted,
1532 const bool cache,
1533 const bool force) const
1534{
1535 if(weighted){
1536 if(weighted_curl_basis_scalar_evaluated_ and not force)
1537 return weighted_curl_basis_scalar;
1538 } else
1539 if(curl_basis_scalar_evaluated_ and not force)
1540 return curl_basis_scalar;
1541
1542 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getCurl2DVectorBasis()",bv_get_curl2d_vec_bv);
1543
1544 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1545
1546 const int num_cells = num_cells_;
1547 const int num_points = basis_layout->numPoints();
1548 const int num_card = basis_layout->cardinality();
1549 const int num_dim = basis_layout->dimension();
1550
1551 if(weighted){
1552
1553 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1554
1555 // Get the basis_scalar values - do not cache
1556 const auto bv = getCurl2DVectorBasis(false, force);
1557
1558 // Apply the weighted measure (cubature weights)
1559 auto tmp_weighted_curl_basis_scalar = af.buildStaticArray<Scalar, Cell, BASIS, IP>("weighted_curl_basis_scalar", num_cells, num_card, num_points);
1560
1561 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1562 auto s_aux = Kokkos::subview(tmp_weighted_curl_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1563 auto s_cw = Kokkos::subview(cubature_weights_.get_view(), cell_range, Kokkos::ALL());
1564 auto s_bv = Kokkos::subview(bv.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1565
1566 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1567 fst::multiplyMeasure(s_aux,s_cw,s_bv);
1568
1569 // Store for later if cache is enabled
1570 PANZER_CACHE_DATA(weighted_curl_basis_scalar);
1571
1572 return tmp_weighted_curl_basis_scalar;
1573
1574 } else {
1575
1576 TEUCHOS_ASSERT(cubature_jacobian_determinant_.size() > 0);
1577 TEUCHOS_ASSERT(num_dim == 2);
1578
1579 const auto element_space = getElementSpace();
1580 TEUCHOS_ASSERT(element_space == PureBasis::HCURL);
1581
1582 auto tmp_curl_basis_scalar = af.buildStaticArray<Scalar,Cell,BASIS,IP>("curl_basis_scalar",num_cells,num_card,num_points);
1583
1584 if(hasUniformReferenceSpace()){
1585
1586 auto cell_curl_basis_ref_scalar = af.buildStaticArray<Scalar,BASIS,IP>("cell_curl_basis_ref_scalar",num_card,num_points);
1587 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1588
1589 intrepid_basis->getValues(cell_curl_basis_ref_scalar.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_CURL);
1590
1591 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1592 auto s_aux = Kokkos::subview(tmp_curl_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1593 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1594
1595 // note only volume deformation is needed!
1596 // this relates directly to this being in
1597 // the divergence space in 2D!
1598 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1599 fst::HDIVtransformDIV(s_aux,s_jac_det,cell_curl_basis_ref_scalar.get_view());
1600 PHX::Device().fence();
1601
1602 } else {
1603
1604 // getValues currently assumes a single reference cell. Calling
1605 // it serially on host until the function supports multiple
1606 // reference cells to avoid a kernel launch per cell.
1607
1608 // Mirror views on host can't be used with intrepid basis
1609 // getValues() call when UVM or UNIFIED_MEMORY is
1610 // enabled. getHostBasis() returns a "HostSpace" basis object
1611 // while create_mirror_view creates views in UVMSpace or
1612 // HIPSpace. These are not "assignable" in kokkos. We do an
1613 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1614#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1615#ifdef KOKKOS_ENABLE_CUDA
1616 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_curl_basis_scalar.get_view())::memory_space>::value) {
1617#else
1618 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_curl_basis_scalar.get_view())::memory_space>::value) {
1619#endif
1620 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1621 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1622 auto tmp_curl_basis_scalar_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_curl_basis_scalar.get_view());
1623
1624 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1625 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1626 auto my_cell_curl_basis_host = Kokkos::subview(tmp_curl_basis_scalar_host,cell,Kokkos::ALL(),Kokkos::ALL());
1627 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1628 intrepid_basis_host->getValues(my_cell_curl_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_CURL);
1629 }
1630 auto tmp_curl_basis_scalar_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_curl_basis_scalar_ref",num_cells,num_card,num_points);
1631 Kokkos::deep_copy(tmp_curl_basis_scalar_ref.get_view(),tmp_curl_basis_scalar_host);
1632
1633 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1634 auto s_aux = Kokkos::subview(tmp_curl_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1635 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1636 auto s_ref = Kokkos::subview(tmp_curl_basis_scalar_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1637
1638 // note only volume deformation is needed!
1639 // this relates directly to this being in
1640 // the divergence space in 2D!
1641 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1642 fst::HDIVtransformDIV(s_aux,s_jac_det,s_ref);
1643 } else {
1644#endif
1645 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1646 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1647 auto tmp_curl_basis_scalar_host = Kokkos::create_mirror_view(tmp_curl_basis_scalar.get_view());
1648
1649 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1650 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1651 auto my_cell_curl_basis_host = Kokkos::subview(tmp_curl_basis_scalar_host,cell,Kokkos::ALL(),Kokkos::ALL());
1652 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1653 intrepid_basis_host->getValues(my_cell_curl_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_CURL);
1654 }
1655 auto tmp_curl_basis_scalar_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_curl_basis_scalar_ref",num_cells,num_card,num_points);
1656 Kokkos::deep_copy(tmp_curl_basis_scalar_ref.get_view(),tmp_curl_basis_scalar_host);
1657
1658 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1659 auto s_aux = Kokkos::subview(tmp_curl_basis_scalar.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1660 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1661 auto s_ref = Kokkos::subview(tmp_curl_basis_scalar_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1662
1663 // note only volume deformation is needed!
1664 // this relates directly to this being in
1665 // the divergence space in 2D!
1666 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1667 fst::HDIVtransformDIV(s_aux,s_jac_det,s_ref);
1668#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1669 }
1670#endif
1671 PHX::Device().fence();
1672 }
1673
1674 if(orientations_.size() > 0)
1675 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_curl_basis_scalar.get_view(), orientations_, *intrepid_basis);
1676
1677 // Store for later if cache is enabled
1678 PANZER_CACHE_DATA(curl_basis_scalar);
1679
1680 return tmp_curl_basis_scalar;
1681
1682 }
1683
1684}
1685
1686template <typename Scalar>
1689getCurlVectorBasis(const bool weighted,
1690 const bool cache,
1691 const bool force) const
1692{
1693 if(weighted){
1694 if(weighted_curl_basis_vector_evaluated_ and not force)
1695 return weighted_curl_basis_vector;
1696 } else
1697 if(curl_basis_vector_evaluated_ and not force)
1698 return curl_basis_vector;
1699
1700 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getCurlVectorBasis()",bv_get_curl_vec_bv);
1701
1702 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1703
1704 const int num_cells = num_cells_;
1705 const int num_points = basis_layout->numPoints();
1706 const int num_card = basis_layout->cardinality();
1707 const int num_dim = basis_layout->dimension();
1708
1709 if(weighted){
1710
1711 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1712
1713 // Get the basis_scalar values - do not cache
1714 const auto bv = getCurlVectorBasis(false, force);
1715
1716 // Apply the weighted measure (cubature weights)
1717 auto tmp_weighted_curl_basis_vector = af.buildStaticArray<Scalar, Cell, BASIS, IP, Dim>("weighted_curl_basis_vector", num_cells, num_card, num_points, num_dim);
1718
1719 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1720 auto s_aux = Kokkos::subview(tmp_weighted_curl_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1721 auto s_cw = Kokkos::subview(cubature_weights_.get_view(), cell_range, Kokkos::ALL());
1722 auto s_bv = Kokkos::subview(bv.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1723
1724 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1725 fst::multiplyMeasure(s_aux, s_cw, s_bv);
1726
1727 // Store for later if cache is enabled
1728 PANZER_CACHE_DATA(weighted_curl_basis_vector);
1729
1730 return tmp_weighted_curl_basis_vector;
1731
1732 } else {
1733
1734 TEUCHOS_ASSERT(cubature_jacobian_determinant_.size() > 0);
1735 TEUCHOS_ASSERT(num_dim == 3);
1736
1737 const auto element_space = getElementSpace();
1738 TEUCHOS_ASSERT(element_space == PureBasis::HCURL);
1739
1740 auto tmp_curl_basis_vector = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("curl_basis_vector",num_cells,num_card,num_points,num_dim);
1741
1742 if(hasUniformReferenceSpace()){
1743
1744 auto cell_curl_basis_ref_vector = af.buildStaticArray<Scalar,BASIS,IP,Dim>("cell_curl_basis_ref_vector",num_card,num_points,num_dim);
1745 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1746
1747 intrepid_basis->getValues(cell_curl_basis_ref_vector.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_CURL);
1748
1749 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1750 auto s_aux = Kokkos::subview(tmp_curl_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1751 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1752 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1753
1754 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1755 fst::HCURLtransformCURL(s_aux, s_jac, s_jac_det,cell_curl_basis_ref_vector.get_view());
1756 PHX::Device().fence();
1757
1758 } else {
1759
1760 // getValues currently assumes a single reference cell. Calling
1761 // it serially on host until the function supports multiple
1762 // reference cells to avoid a kernel launch per cell.
1763
1764 // Mirror views on host can't be used with intrepid basis
1765 // getValues() call when UVM or UNIFIED_MEMORY is
1766 // enabled. getHostBasis() returns a "HostSpace" basis object
1767 // while create_mirror_view creates views in UVMSpace or
1768 // HIPSpace. These are not "assignable" in kokkos. We do an
1769 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1770#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1771#ifdef KOKKOS_ENABLE_CUDA
1772 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_curl_basis_vector.get_view())::memory_space>::value) {
1773#else
1774 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_curl_basis_vector.get_view())::memory_space>::value) {
1775#endif
1776 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1777 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1778 auto tmp_curl_basis_vector_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_curl_basis_vector.get_view());
1779
1780 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1781 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1782 auto my_cell_curl_basis_host = Kokkos::subview(tmp_curl_basis_vector_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1783 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1784 intrepid_basis_host->getValues(my_cell_curl_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_CURL);
1785 }
1786 auto tmp_curl_basis_vector_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_curl_basis_scalar_ref",num_cells,num_card,num_points,num_dim);
1787 Kokkos::deep_copy(tmp_curl_basis_vector_ref.get_view(),tmp_curl_basis_vector_host);
1788
1789 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1790 auto s_aux = Kokkos::subview(tmp_curl_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1791 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1792 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1793 auto s_ref = Kokkos::subview(tmp_curl_basis_vector_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1794
1795 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1796 fst::HCURLtransformCURL(s_aux, s_jac, s_jac_det, s_ref);
1797 } else {
1798#endif
1799 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1800 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1801 auto tmp_curl_basis_vector_host = Kokkos::create_mirror_view(tmp_curl_basis_vector.get_view());
1802
1803 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1804 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1805 auto my_cell_curl_basis_host = Kokkos::subview(tmp_curl_basis_vector_host,cell,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1806 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1807 intrepid_basis_host->getValues(my_cell_curl_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_CURL);
1808 }
1809 auto tmp_curl_basis_vector_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP,Dim>("tmp_curl_basis_scalar_ref",num_cells,num_card,num_points,num_dim);
1810 Kokkos::deep_copy(tmp_curl_basis_vector_ref.get_view(),tmp_curl_basis_vector_host);
1811
1812 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1813 auto s_aux = Kokkos::subview(tmp_curl_basis_vector.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1814 auto s_jac = Kokkos::subview(cubature_jacobian_.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1815 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1816 auto s_ref = Kokkos::subview(tmp_curl_basis_vector_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL());
1817
1818 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1819 fst::HCURLtransformCURL(s_aux, s_jac, s_jac_det, s_ref);
1820#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1821 }
1822#endif
1823 PHX::Device().fence();
1824
1825 }
1826
1827 if(orientations_.size() > 0)
1828 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_curl_basis_vector.get_view(), orientations_, *intrepid_basis);
1829
1830 // Store for later if cache is enabled
1831 PANZER_CACHE_DATA(curl_basis_vector);
1832
1833 return tmp_curl_basis_vector;
1834
1835 }
1836
1837}
1838
1839template <typename Scalar>
1842getDivVectorBasis(const bool weighted,
1843 const bool cache,
1844 const bool force) const
1845{
1846 if(weighted){
1847 if(weighted_div_basis_evaluated_ and not force)
1848 return weighted_div_basis;
1849 } else
1850 if(div_basis_evaluated_ and not force)
1851 return div_basis;
1852
1853 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::basisValues2::getDevVectorBasis()",bv_get_div_vec_bv);
1854
1855 MDFieldArrayFactory af(prefix,getExtendedDimensions(),true);
1856
1857 const int num_cells = num_cells_;
1858 const int num_points = basis_layout->numPoints();
1859 const int num_card = basis_layout->cardinality();
1860
1861 if(weighted){
1862
1863 TEUCHOS_ASSERT(cubature_weights_.size() > 0);
1864
1865 // Get the basis_scalar values - do not cache
1866 const auto bv = getDivVectorBasis(false, force);
1867
1868 // Apply the weighted measure (cubature weights)
1869 auto tmp_weighted_div_basis = af.buildStaticArray<Scalar, Cell, BASIS, IP>("weighted_div_basis", num_cells, num_card, num_points);
1870
1871 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1872 auto s_aux = Kokkos::subview(tmp_weighted_div_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1873 auto s_cw = Kokkos::subview(cubature_weights_.get_view(), cell_range, Kokkos::ALL());
1874 auto s_bv = Kokkos::subview(bv.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1875
1876 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1877 fst::multiplyMeasure(s_aux, s_cw, s_bv);
1878
1879 // Store for later if cache is enabled
1880 PANZER_CACHE_DATA(weighted_div_basis);
1881
1882 return tmp_weighted_div_basis;
1883
1884 } else {
1885
1886 TEUCHOS_ASSERT(cubature_jacobian_determinant_.size() > 0);
1887
1888 const auto element_space = getElementSpace();
1889 TEUCHOS_ASSERT(element_space == PureBasis::HDIV);
1890
1891 auto tmp_div_basis = af.buildStaticArray<Scalar,Cell,BASIS,IP>("div_basis",num_cells,num_card,num_points);
1892
1893 if(hasUniformReferenceSpace()){
1894
1895 auto cell_div_basis_ref = af.buildStaticArray<Scalar,BASIS,IP>("cell_div_basis_ref",num_card,num_points);
1896 auto cubature_points_uniform_ref = PHX::getNonConstDynRankViewFromConstMDField(cubature_points_uniform_ref_);
1897
1898 intrepid_basis->getValues(cell_div_basis_ref.get_view(),cubature_points_uniform_ref,Intrepid2::OPERATOR_DIV);
1899
1900 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1901 auto s_aux = Kokkos::subview(tmp_div_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1902 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1903
1904 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1905 fst::HDIVtransformDIV(s_aux,s_jac_det,cell_div_basis_ref.get_view());
1906 PHX::Device().fence();
1907
1908 } else {
1909
1910 // getValues currently assumes a single reference cell. Calling
1911 // it serially on host until the function supports multiple
1912 // reference cells to avoid a kernel launch per cell.
1913
1914 // Mirror views on host can't be used with intrepid basis
1915 // getValues() call when UVM or UNIFIED_MEMORY is
1916 // enabled. getHostBasis() returns a "HostSpace" basis object
1917 // while create_mirror_view creates views in UVMSpace or
1918 // HIPSpace. These are not "assignable" in kokkos. We do an
1919 // inefficient copy if UVM or UNIFIED_MEMORY is enabled.
1920#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1921#ifdef KOKKOS_ENABLE_CUDA
1922 if constexpr (std::is_same<Kokkos::CudaUVMSpace,typename decltype(tmp_div_basis.get_view())::memory_space>::value) {
1923#else
1924 if constexpr (std::is_same<Kokkos::HIPSpace,typename decltype(tmp_div_basis.get_view())::memory_space>::value) {
1925#endif
1926 auto cubature_points_ref_host = Kokkos::create_mirror(Kokkos::HostSpace{},cubature_points_ref_.get_view());
1927 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1928 auto tmp_div_basis_host = Kokkos::create_mirror(Kokkos::HostSpace{},tmp_div_basis.get_view());
1929
1930 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1931 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1932 auto my_cell_div_basis_host = Kokkos::subview(tmp_div_basis_host,cell,Kokkos::ALL(),Kokkos::ALL());
1933 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1934 intrepid_basis_host->getValues(my_cell_div_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_DIV);
1935 }
1936 auto tmp_div_basis_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_div_basis_ref",num_cells,num_card,num_points);
1937 Kokkos::deep_copy(tmp_div_basis_ref.get_view(),tmp_div_basis_host);
1938
1939 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1940 auto s_aux = Kokkos::subview(tmp_div_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1941 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1942 auto s_ref = Kokkos::subview(tmp_div_basis_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1943
1944 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1945 fst::HDIVtransformDIV(s_aux,s_jac_det,s_ref);
1946 } else {
1947#endif
1948 auto cubature_points_ref_host = Kokkos::create_mirror_view(cubature_points_ref_.get_view());
1949 Kokkos::deep_copy(cubature_points_ref_host,cubature_points_ref_.get_view());
1950 auto tmp_div_basis_host = Kokkos::create_mirror_view(tmp_div_basis.get_view());
1951
1952 auto intrepid_basis_host = intrepid_basis->getHostBasis();
1953 for(int cell=0; cell<num_evaluate_cells_; ++cell) {
1954 auto my_cell_div_basis_host = Kokkos::subview(tmp_div_basis_host,cell,Kokkos::ALL(),Kokkos::ALL());
1955 auto my_cell_cub_points_ref_host = Kokkos::subview(cubature_points_ref_host,cell,Kokkos::ALL(),Kokkos::ALL());
1956 intrepid_basis_host->getValues(my_cell_div_basis_host,my_cell_cub_points_ref_host,Intrepid2::OPERATOR_DIV);
1957 }
1958 auto tmp_div_basis_ref = af.buildStaticArray<Scalar,Cell,BASIS,IP>("tmp_div_basis_ref",num_cells,num_card,num_points);
1959 Kokkos::deep_copy(tmp_div_basis_ref.get_view(),tmp_div_basis_host);
1960
1961 const std::pair<int,int> cell_range(0,num_evaluate_cells_);
1962 auto s_aux = Kokkos::subview(tmp_div_basis.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1963 auto s_jac_det = Kokkos::subview(cubature_jacobian_determinant_.get_view(), cell_range, Kokkos::ALL());
1964 auto s_ref = Kokkos::subview(tmp_div_basis_ref.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1965
1966 using fst=Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>;
1967 fst::HDIVtransformDIV(s_aux,s_jac_det,s_ref);
1968#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_IMPL_HIP_UNIFIED_MEMORY)
1969 }
1970#endif
1971 PHX::Device().fence();
1972
1973 }
1974
1975 if(orientations_.size() > 0)
1976 applyOrientationsImpl<Scalar>(num_orientations_cells_, tmp_div_basis.get_view(), orientations_, *intrepid_basis);
1977
1978 // Store for later if cache is enabled
1979 PANZER_CACHE_DATA(div_basis);
1980
1981 return tmp_div_basis;
1982
1983 }
1984
1985}
1986
1987//=======================================================================================================
1988
1989} // namespace panzer
#define PANZER_CACHE_DATA(name)
PHX::MDField< const Scalar, Cell, BASIS, IP > ConstArray_CellBasisIP
ConstArray_BasisIP getCurl2DVectorBasisRef(const bool cache=true, const bool force=false) const
Get the curl of a vector basis evaluated at reference points.
BasisValues2(const std::string &prefix="", const bool allocArrays=false, const bool buildWeighted=false)
Main constructor.
Intrepid2::Basis< PHX::Device::execution_space, Scalar, Scalar > IntrepidBasis
ConstArray_CellBasisIP getDivVectorBasis(const bool weighted, const bool cache=true, const bool force=false) const
Get the divergence of a vector basis evaluated at mesh points.
void evaluateValuesCV(const PHX::MDField< Scalar, Cell, IP, Dim > &cell_cub_points, const PHX::MDField< Scalar, Cell, IP, Dim, Dim > &jac, const PHX::MDField< Scalar, Cell, IP > &jac_det, const PHX::MDField< Scalar, Cell, IP, Dim, Dim > &jac_inv)
ConstArray_BasisIPDim getGradBasisValuesRef(const bool cache=true, const bool force=false) const
Get the gradient of the basis evaluated at reference points.
ConstArray_BasisIPDim getVectorBasisValuesRef(const bool cache=true, const bool force=false) const
Get the vector basis values evaluated at reference points.
void setCellNodeCoordinates(PHX::MDField< Scalar, Cell, NODE, Dim > node_coordinates)
Set the cell node coordinates (required for getBasisCoordinates())
PureBasis::EElementSpace getElementSpace() const
ConstArray_CellBasisIPDim getCurlVectorBasis(const bool weighted, const bool cache=true, const bool force=false) const
Get the curl of a 3D vector basis evaluated at mesh points.
void evaluateBasisCoordinates(const PHX::MDField< Scalar, Cell, NODE, Dim > &node_coordinates, const int in_num_cells=-1)
void setup(const Teuchos::RCP< const panzer::BasisIRLayout > &basis, PHX::MDField< const Scalar, Cell, IP, Dim > reference_points, PHX::MDField< const Scalar, Cell, IP, Dim, Dim > point_jacobian, PHX::MDField< const Scalar, Cell, IP > point_jacobian_determinant, PHX::MDField< const Scalar, Cell, IP, Dim, Dim > point_jacobian_inverse, const int num_evaluated_cells=-1)
Setup for lazy evaluation for non-uniform point layout.
ConstArray_CellBasisIP getBasisValues(const bool weighted, const bool cache=true, const bool force=false) const
Get the basis values evaluated at mesh points.
ConstArray_BasisIP getBasisValuesRef(const bool cache=true, const bool force=false) const
Get the basis values evaluated at reference points.
PHX::MDField< const Scalar, BASIS, IP, Dim > ConstArray_BasisIPDim
void setOrientations(const std::vector< Intrepid2::Orientation > &orientations, const int num_orientations_cells=-1)
Set the orientations object for applying orientations using the lazy evaluation path - required for c...
void evaluateValues(const PHX::MDField< Scalar, IP, Dim > &cub_points, const PHX::MDField< Scalar, Cell, IP, Dim, Dim > &jac, const PHX::MDField< Scalar, Cell, IP > &jac_det, const PHX::MDField< Scalar, Cell, IP, Dim, Dim > &jac_inv, const int in_num_cells=-1)
ConstArray_CellBasisIPDim getGradBasisValues(const bool weighted, const bool cache=true, const bool force=false) const
Get the gradient of the basis evaluated at mesh points.
PHX::MDField< const Scalar, Cell, BASIS, IP, Dim > ConstArray_CellBasisIPDim
void setWeightedMeasure(PHX::MDField< const Scalar, Cell, IP > weighted_measure)
Set the cubature weights (weighted measure) for the basis values object - required to get weighted ba...
ConstArray_BasisDim getBasisCoordinatesRef(const bool cache=true, const bool force=false) const
Get the reference coordinates for basis.
ConstArray_CellBasisIP getCurl2DVectorBasis(const bool weighted, const bool cache=true, const bool force=false) const
Get the curl of a 2D vector basis evaluated at mesh points.
PHX::MDField< const Scalar, BASIS, IP > ConstArray_BasisIP
panzer::BasisDescriptor getBasisDescriptor() const
Return the basis descriptor.
ConstArray_BasisIPDim getCurlVectorBasisRef(const bool cache=true, const bool force=false) const
Get the curl of a vector basis evaluated at reference points.
bool basis_ref_scalar_evaluated_
Used to check if arrays have been cached.
ConstArray_CellBasisDim getBasisCoordinates(const bool cache=true, const bool force=false) const
Carterisan coordinates for basis coefficients in mesh space.
void setupArrays(const Teuchos::RCP< const panzer::BasisIRLayout > &basis, bool computeDerivatives=true)
Sizes/allocates memory for arrays.
void setupUniform(const Teuchos::RCP< const panzer::BasisIRLayout > &basis, PHX::MDField< const Scalar, IP, Dim > reference_points, PHX::MDField< const Scalar, Cell, IP, Dim, Dim > point_jacobian, PHX::MDField< const Scalar, Cell, IP > point_jacobian_determinant, PHX::MDField< const Scalar, Cell, IP, Dim, Dim > point_jacobian_inverse, const int num_evaluated_cells=-1)
Setup for lazy evaluation for uniform point layout.
PHX::MDField< const Scalar, Cell, BASIS, Dim > ConstArray_CellBasisDim
ConstArray_CellBasisIPDim getVectorBasisValues(const bool weighted, const bool cache=true, const bool force=false) const
Get the vector basis values evaluated at mesh points.
ConstArray_BasisIP getDivVectorBasisRef(const bool cache=true, const bool force=false) const
Get the divergence of a vector basis evaluated at reference points.
void applyOrientations(const PHX::MDField< const Scalar, Cell, BASIS > &orientations)
Method to apply orientations to a basis values container.
PHX::MDField< const Scalar, BASIS, Dim > ConstArray_BasisDim
PHX::MDField< Scalar, T0 > buildStaticArray(const std::string &str, int d0) const