14 #include "Shards_CellTopology.hpp"
16 #include "Kokkos_DynRankView.hpp"
17 #include "Intrepid2_FunctionSpaceTools.hpp"
18 #include "Intrepid2_RealSpaceTools.hpp"
19 #include "Intrepid2_CellTools.hpp"
20 #include "Intrepid2_ArrayTools.hpp"
21 #include "Intrepid2_CubatureControlVolume.hpp"
22 #include "Intrepid2_CubatureControlVolumeSide.hpp"
23 #include "Intrepid2_CubatureControlVolumeBoundary.hpp"
31 #include "Phalanx_GetNonConstDynRankViewFromConstMDField.hpp"
43 Intrepid2::DefaultCubatureFactory cubature_factory;
45 if(ir.
getType() == ID::CV_SIDE){
46 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolumeSide<PHX::Device::execution_space,double,double>(*ir.
topology));
47 }
else if(ir.
getType() == ID::CV_VOLUME){
48 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolume<PHX::Device::execution_space,double,double>(*ir.
topology));
49 }
else if(ir.
getType() == ID::CV_BOUNDARY){
51 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolumeBoundary<PHX::Device::execution_space,double,double>(*ir.
topology,ir.
getSide()));
52 }
else if(ir.
getType() == ID::VOLUME){
53 ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(*(ir.
topology),ir.
getOrder());
54 }
else if(ir.
getType() == ID::SIDE){
55 ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(*(ir.
side_topology),ir.
getOrder());
56 }
else if(ir.
getType() == ID::SURFACE){
65 template<
typename Scalar>
68 const int num_real_cells,
69 const int num_virtual_cells,
70 const shards::CellTopology & cell_topology,
71 const SubcellConnectivity & face_connectivity)
73 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::correctVirtualNormals()",corr_virt_norms);
77 const int space_dim = cell_topology.getDimension();
78 const int faces_per_cell = cell_topology.getSubcellCount(space_dim-1);
79 const int points = normals.extent_int(1);
80 const int points_per_face = points / faces_per_cell;
82 Kokkos::parallel_for(num_virtual_cells, KOKKOS_LAMBDA(
const int & virtual_cell_ordinal){
84 const int virtual_cell = virtual_cell_ordinal+num_real_cells;
88 int face, virtual_lidx;
89 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++){
91 face = face_connectivity.subcellForCell(virtual_cell, local_face_id);
93 virtual_lidx = local_face_id;
99 const int real_side = (face_connectivity.cellForSubcell(face, 0) == virtual_cell) ? 1 : 0;
100 const int real_cell = face_connectivity.cellForSubcell(face,real_side);
101 const int real_lidx = face_connectivity.localSubcellForSubcell(face,real_side);
104 KOKKOS_ASSERT(real_cell < num_real_cells);
106 for(
int point_ordinal=0; point_ordinal<points_per_face; point_ordinal++){
109 const int virtual_cell_point = points_per_face * virtual_lidx + point_ordinal;
110 const int real_cell_point = points_per_face * real_lidx + point_ordinal;
112 for (
int d=0; d<space_dim; d++)
113 normals(virtual_cell,virtual_cell_point,d) = -normals(real_cell,real_cell_point,d);
118 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++){
120 if (local_face_id == virtual_lidx)
continue;
122 for (
int point_ordinal=0; point_ordinal<points_per_face; point_ordinal++){
123 const int point = local_face_id * points_per_face + point_ordinal;
124 for (
int dim=0; dim<space_dim; dim++)
125 normals(virtual_cell,point,dim) = 0.0;
129 PHX::Device::execution_space().fence();
133 template<
typename Scalar>
136 const int num_real_cells,
137 const int num_virtual_cells,
138 const shards::CellTopology & cell_topology,
139 const SubcellConnectivity & face_connectivity)
141 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::correctVirtualRotationMatrices()",corr_virt_rotmat);
145 const int space_dim = cell_topology.getDimension();
146 const int faces_per_cell = cell_topology.getSubcellCount(space_dim-1);
147 const int points = rotation_matrices.extent_int(1);
148 const int points_per_face = points / faces_per_cell;
150 Kokkos::parallel_for(num_virtual_cells, KOKKOS_LAMBDA(
const int & virtual_cell_ordinal){
152 const int virtual_cell = virtual_cell_ordinal+num_real_cells;
156 int face, virtual_lidx;
157 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++){
159 face = face_connectivity.subcellForCell(virtual_cell, local_face_id);
161 virtual_lidx = local_face_id;
169 for (
int local_face_id=0; local_face_id<faces_per_cell; local_face_id++){
171 if (local_face_id == virtual_lidx)
continue;
173 for (
int point_ordinal=0; point_ordinal<points_per_face; point_ordinal++){
174 const int point = local_face_id * points_per_face + point_ordinal;
175 for (
int dim=0; dim<3; dim++)
176 for (
int dim2=0; dim2<3; dim2++)
177 rotation_matrices(virtual_cell,point,dim,dim2) = 0.0;
181 PHX::Device::execution_space().fence();
184 template<
typename Scalar>
189 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::applyBasePermutation(rank 1)",app_base_perm_r1);
190 MDFieldArrayFactory af(
"",
true);
192 const int num_ip = field.extent(0);
194 auto scratch = af.template buildStaticArray<Scalar,IP>(
"scratch", num_ip);
195 scratch.deep_copy(field);
196 Kokkos::parallel_for(1, KOKKOS_LAMBDA(
const int & ){
197 for(
int ip=0; ip<num_ip; ++ip)
198 if (ip != permutations(0,ip))
199 field(ip) = scratch(permutations(0,ip));
201 PHX::Device::execution_space().fence();
204 template<
typename Scalar>
209 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::applyBasePermutation(rank 2)",app_base_perm_r2);
210 MDFieldArrayFactory af(
"",
true);
212 const int num_ip = field.extent(0);
213 const int num_dim = field.extent(1);
215 auto scratch = af.template buildStaticArray<Scalar,IP,Dim>(
"scratch", num_ip,num_dim);
216 scratch.deep_copy(field);
217 Kokkos::parallel_for(1, KOKKOS_LAMBDA(
const int & ){
218 for(
int ip=0; ip<num_ip; ++ip)
219 if (ip != permutations(0,ip))
220 for(
int dim=0; dim<num_dim; ++dim)
221 field(ip,dim) = scratch(permutations(0,ip),dim);
223 PHX::Device::execution_space().fence();
226 template<
typename Scalar>
231 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::applyPermutation(rank 2)",app_perm_r2);
232 MDFieldArrayFactory af(
"",
true);
234 const int num_cells = field.extent(0);
235 const int num_ip = field.extent(1);
237 auto scratch = af.template buildStaticArray<Scalar,Cell,IP>(
"scratch", num_cells, num_ip);
238 scratch.deep_copy(field);
239 Kokkos::parallel_for(num_cells, KOKKOS_LAMBDA(
const int & cell){
240 for(
int ip=0; ip<num_ip; ++ip)
241 if (ip != permutations(cell,ip))
242 field(cell,ip) = scratch(cell,permutations(cell,ip));
244 PHX::Device::execution_space().fence();
247 template<
typename Scalar>
252 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::applyPermutation(rank 3)",app_perm_r3);
253 MDFieldArrayFactory af(
"",
true);
255 const int num_cells = field.extent(0);
256 const int num_ip = field.extent(1);
257 const int num_dim = field.extent(2);
259 auto scratch = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"scratch", num_cells, num_ip, num_dim);
260 scratch.deep_copy(field);
261 Kokkos::parallel_for(num_cells, KOKKOS_LAMBDA(
const int & cell){
262 for(
int ip=0; ip<num_ip; ++ip)
263 if (ip != permutations(cell,ip))
264 for(
int dim=0; dim<num_dim; ++dim)
265 field(cell,ip,dim) = scratch(cell,permutations(cell,ip),dim);
267 PHX::Device::execution_space().fence();
270 template<
typename Scalar>
275 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::applyPermutation(rank 4)",app_perm_r4);
276 MDFieldArrayFactory af(
"",
true);
278 const int num_cells = field.extent(0);
279 const int num_ip = field.extent(1);
280 const int num_dim = field.extent(2);
281 const int num_dim2 = field.extent(3);
283 auto scratch = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"scratch", num_cells, num_ip, num_dim, num_dim2);
284 scratch.deep_copy(field);
285 Kokkos::parallel_for(num_cells, KOKKOS_LAMBDA(
const int & cell){
286 for(
int ip=0; ip<num_ip; ++ip)
287 if (ip != permutations(cell,ip))
288 for(
int dim=0; dim<num_dim; ++dim)
289 for(
int dim2=0; dim2<num_dim2; ++dim2)
290 field(cell,ip,dim,dim2) = scratch(cell,permutations(cell,ip),dim,dim2);
292 PHX::Device::execution_space().fence();
299 template <
typename Scalar>
301 generatePermutations(
const int num_cells,
305 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::generatePermutations()",gen_perms);
307 const int num_ip = coords.extent(1);
308 const int num_dim = coords.extent(2);
310 MDFieldArrayFactory af(
"",
true);
313 auto permutation = af.template buildStaticArray<int,Cell,IP>(
"permutation", num_cells, num_ip);
314 permutation.deep_copy(0);
317 auto taken = af.template buildStaticArray<int,Cell,IP>(
"taken", num_cells, num_ip);
320 Kokkos::parallel_for(num_cells, KOKKOS_LAMBDA(
const int & cell){
322 for (
int ip = 0; ip < num_ip; ++ip) {
326 for (
int other_ip = 0; other_ip < num_ip; ++other_ip) {
328 if(taken(cell,other_ip))
continue;
331 for (
int dim = 0; dim < num_dim; ++dim) {
332 const Scalar diff = coords(cell, ip, dim) - other_coords(cell, other_ip, dim);
335 if (d_min < 0 || d < d_min) {
341 permutation(cell,ip) = i_min;
343 taken(cell,i_min) = 1;
346 PHX::Device::execution_space().fence();
352 template <
typename Scalar>
354 generateSurfacePermutations(
const int num_cells,
355 const SubcellConnectivity face_connectivity,
360 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::generateSurfacePermutations()",gen_surf_perms);
367 const int num_points = surface_points.extent_int(1);
368 const int num_faces_per_cell = face_connectivity.numSubcellsOnCellHost(0);
369 const int num_points_per_face = num_points / num_faces_per_cell;
370 const int cell_dim = surface_points.extent(2);
372 MDFieldArrayFactory af(
"",
true);
375 auto permutation = af.template buildStaticArray<int,Cell,IP>(
"permutation", num_cells, num_points);
376 permutation.deep_copy(0);
379 Kokkos::parallel_for(num_cells,KOKKOS_LAMBDA (
const int & cell) {
380 for(
int point=0; point<num_points; ++point)
381 permutation(cell,point) = point;
386 if(num_points_per_face != 1) {
392 #define PANZER_DOT(a,b) (a[0]*b[0] + a[1]*b[1] + a[2]*b[2])
393 #define PANZER_CROSS(a,b,c) {c[0] = a[1]*b[2] - a[2]*b[1]; c[1] = a[2]*b[0] - a[0]*b[2]; c[2] = a[0]*b[1] - a[1]*b[0];}
396 Kokkos::parallel_for(
"face iteration",face_connectivity.numSubcells(),KOKKOS_LAMBDA (
const int face) {
398 const int cell_0 = face_connectivity.cellForSubcell(face,0);
399 const int cell_1 = face_connectivity.cellForSubcell(face,1);
406 const int lidx_0 = face_connectivity.localSubcellForSubcell(face,0);
407 const int lidx_1 = face_connectivity.localSubcellForSubcell(face,1);
410 KOKKOS_ASSERT(lidx_1 >= 0);
415 Scalar xc0[3] = {0}, xc1[3] = {0}, r2 = 0;
416 for(
int face_point=0; face_point<num_points_per_face; ++face_point){
418 for(
int dim=0; dim<cell_dim; ++dim){
419 xc0[dim] += surface_points(cell_0,lidx_0*num_points_per_face + face_point,dim);
420 xc1[dim] += surface_points(cell_1,lidx_1*num_points_per_face + face_point,dim);
421 const Scalar dx = surface_points(cell_0,lidx_0*num_points_per_face + face_point,dim) - surface_points(cell_0,lidx_0*num_points_per_face,dim);
426 r2 = (r2 < dx2) ? dx2 : r2;
428 for(
int dim=0; dim<cell_dim; ++dim){
429 xc0[dim] /= double(num_points_per_face);
430 xc1[dim] /= double(num_points_per_face);
439 const int example_point_0 = lidx_0*num_points_per_face;
440 const int example_point_1 = lidx_1*num_points_per_face;
443 Scalar t[3] = {surface_rotation_matrices(cell_0,example_point_0,1,0), surface_rotation_matrices(cell_0,example_point_0,1,1), surface_rotation_matrices(cell_0,example_point_0,1,2)};
444 Scalar b[3] = {surface_rotation_matrices(cell_0,example_point_0,2,0), surface_rotation_matrices(cell_0,example_point_0,2,1), surface_rotation_matrices(cell_0,example_point_0,2,2)};
450 const Scalar n0[3] = {surface_rotation_matrices(cell_0,example_point_0,0,0), surface_rotation_matrices(cell_0,example_point_0,0,1), surface_rotation_matrices(cell_0,example_point_0,0,2)};
451 const Scalar n1[3] = {surface_rotation_matrices(cell_1,example_point_1,0,0), surface_rotation_matrices(cell_1,example_point_1,0,1), surface_rotation_matrices(cell_1,example_point_1,0,2)};
459 if(Kokkos::fabs(n0_dot_n1 - 1.) < 1.e-8)
463 if(Kokkos::fabs(n0_dot_n1 + 1.) > 1.e-2){
470 const Scalar mag_t = Kokkos::sqrt(
PANZER_DOT(t,t));
476 b[0] = n0[0] + n1[0];
477 b[1] = n0[1] + n1[1];
478 b[2] = n0[2] + n1[2];
481 const Scalar mag_b = Kokkos::sqrt(
PANZER_DOT(b,b));
499 for(
int face_point_1=0; face_point_1<num_points_per_face; ++face_point_1){
502 const int point_1 = lidx_1*num_points_per_face + face_point_1;
505 for(
int dim=0; dim<cell_dim; ++dim)
506 x1[dim] = surface_points(cell_1,point_1,dim) - xc1[dim];
513 for(
int face_point_0=0; face_point_0<num_points_per_face; ++face_point_0){
516 const int point_0 = lidx_0*num_points_per_face + face_point_0;
519 for(
int dim=0; dim<cell_dim; ++dim)
520 x0[dim] = surface_points(cell_0,point_0,dim) - xc0[dim];
527 const Scalar p012 = (p0[0]-p1[0])*(p0[0]-p1[0]) + (p0[1]-p1[1])*(p0[1]-p1[1]);
531 if(p012 / r2 < 1.e-12){
532 permutation(cell_1,lidx_1*num_points_per_face+face_point_0) = point_1;
539 PHX::Device::execution_space().fence();
553 template <
typename Scalar>
556 const bool allocArrays):
558 num_evaluate_cells_(0),
559 num_virtual_cells_(-1),
560 requires_permutation_(false),
561 alloc_arrays_(allocArrays),
568 template <
typename Scalar>
573 cub_points_evaluated_ =
false;
574 side_cub_points_evaluated_ =
false;
575 cub_weights_evaluated_ =
false;
576 node_coordinates_evaluated_ =
false;
577 jac_evaluated_ =
false;
578 jac_inv_evaluated_ =
false;
579 jac_det_evaluated_ =
false;
580 weighted_measure_evaluated_ =
false;
581 weighted_normals_evaluated_ =
false;
582 surface_normals_evaluated_ =
false;
583 surface_rotation_matrices_evaluated_ =
false;
584 covarient_evaluated_ =
false;
585 contravarient_evaluated_ =
false;
586 norm_contravarient_evaluated_ =
false;
587 ip_coordinates_evaluated_ =
false;
588 ref_ip_coordinates_evaluated_ =
false;
593 template <
typename Scalar>
597 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::setupArrays()",setup_arrays);
605 const int num_nodes = ir->
topology->getNodeCount();
607 const int num_space_dim = ir->
topology->getDimension();
610 const bool is_node_rule = (num_space_dim==1) and ir->
isSide();
611 if(not is_node_rule) {
613 intrepid_cubature = getIntrepidCubature(*ir);
616 const int num_ip = is_node_rule ? 1 : ir->
num_points;
618 cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"cub_points",num_ip, num_space_dim);
621 side_cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_ip,ir->
side_topology->getDimension());
623 cub_weights = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
625 node_coordinates = af.template buildStaticArray<Scalar,Cell,BASIS,Dim>(
"node_coordinates",num_cells, num_nodes, num_space_dim);
627 jac = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac",num_cells, num_ip, num_space_dim,num_space_dim);
629 jac_inv = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac_inv",num_cells, num_ip, num_space_dim,num_space_dim);
631 jac_det = af.template buildStaticArray<Scalar,Cell,IP>(
"jac_det",num_cells, num_ip);
633 weighted_measure = af.template buildStaticArray<Scalar,Cell,IP>(
"weighted_measure",num_cells, num_ip);
635 covarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"covarient",num_cells, num_ip, num_space_dim,num_space_dim);
637 contravarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"contravarient",num_cells, num_ip, num_space_dim,num_space_dim);
639 norm_contravarient = af.template buildStaticArray<Scalar,Cell,IP>(
"norm_contravarient",num_cells, num_ip);
641 ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ip_coordiantes",num_cells, num_ip,num_space_dim);
643 ref_ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ref_ip_coordinates",num_cells, num_ip,num_space_dim);
645 weighted_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"weighted_normal",num_cells,num_ip,num_space_dim);
647 surface_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"surface_normals",num_cells, num_ip,num_space_dim);
649 surface_rotation_matrices = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"surface_rotation_matrices",num_cells, num_ip,3,3);
656 template <
typename Scalar>
659 const int in_num_cells,
661 const int num_virtual_cells)
663 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::evaluateValues(with virtual cells)",eval_vals_with_virts);
665 setup(int_rule, in_node_coordinates, in_num_cells);
669 if((int_rule->getType() == ID::SURFACE) and (face_connectivity != Teuchos::null))
670 setupPermutations(face_connectivity, num_virtual_cells);
673 evaluateEverything();
676 template <
typename Scalar>
681 const int in_num_cells)
683 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::evaluateValues(no virtual cells)",eval_vals_no_virts);
685 setup(int_rule, in_node_coordinates, in_num_cells);
688 setupPermutations(other_ip_coordinates);
691 evaluateEverything();
694 template <
typename Scalar>
698 const int num_virtual_cells)
700 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::setupPermutations(connectivity)",setup_perms_conn);
705 "IntegrationValues2::setupPermutations : Face connectivity based permutations are only required for surface integration schemes");
707 "IntegrationValues2::setupPermutations : Number of virtual cells for surface permuations must be >= 0");
709 side_connectivity_ = face_connectivity;
710 num_virtual_cells_ = num_virtual_cells;
711 requires_permutation_ =
false;
712 permutations_ = generateSurfacePermutations<Scalar>(num_evaluate_cells_,*face_connectivity, getCubaturePoints(
false,
true), getSurfaceRotationMatrices(
false,
true));
713 requires_permutation_ =
true;
716 template <
typename Scalar>
721 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::setupPermutations(other_coords)",setup_perms_coords);
723 requires_permutation_ =
false;
724 permutations_ = generatePermutations<Scalar>(num_evaluate_cells_, getCubaturePoints(
false,
true), other_ip_coordinates);
725 requires_permutation_ =
true;
729 template <
typename Scalar>
736 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::setup()",setup);
741 num_cells_ = cell_node_coordinates.extent(0);
742 num_evaluate_cells_ = num_cells < 0 ? cell_node_coordinates.extent(0) : num_cells;
746 intrepid_cubature = getIntrepidCubature(*ir);
752 const int num_space_dim = int_rule->topology->getDimension();
753 const int num_nodes = int_rule->topology->getNodeCount();
754 TEUCHOS_ASSERT(static_cast<int>(cell_node_coordinates.extent(1)) == num_nodes);
756 auto aux = af.template buildStaticArray<Scalar,Cell,NODE,Dim>(
"node_coordinates",num_cells_,num_nodes, num_space_dim);
757 Kokkos::MDRangePolicy<PHX::Device,Kokkos::Rank<3>> policy({0,0,0},{num_evaluate_cells_,num_nodes,num_space_dim});
758 Kokkos::parallel_for(policy,KOKKOS_LAMBDA(
const int & cell,
const int & point,
const int & dim){
759 aux(cell,point,dim) = cell_node_coordinates(cell,point,dim);
761 PHX::Device::execution_space().fence();
762 node_coordinates = aux;
767 template <
typename Scalar>
772 const bool apply_permutation)
const
774 if(cub_points_evaluated_ and (apply_permutation == requires_permutation_) and not force)
778 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getUniformCubaturePointsRef()",get_uniform_cub_pts_ref);
780 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
783 int num_space_dim = int_rule->topology->getDimension();
784 int num_ip = int_rule->num_points;
786 auto aux = af.template buildStaticArray<Scalar,IP,Dim>(
"cub_points",num_ip, num_space_dim);
788 if (int_rule->isSide() && num_space_dim==1) {
789 std::cout <<
"WARNING: 0-D quadrature rule infrastructure does not exist!!! Will not be able to do "
790 <<
"non-natural integration rules.";
795 "IntegrationValues2::getUniformCubaturePointsRef : Cannot build reference cubature points for control volume integration scheme.");
798 "IntegrationValues2::getUniformCubaturePointsRef : Cannot build reference cubature points for surface integration scheme.");
800 auto weights = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
802 if (!int_rule->isSide())
803 intrepid_cubature->getCubature(aux.get_view(), weights.get_view());
805 auto s_cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_ip, num_space_dim-1);
807 intrepid_cubature->getCubature(s_cub_points.get_view(), weights.get_view());
808 cell_tools.mapToReferenceSubcell(aux.get_view(), s_cub_points.get_view(), num_space_dim-1, int_rule->getSide(), *(int_rule->topology));
811 PHX::Device::execution_space().fence();
813 if(apply_permutation and requires_permutation_)
814 applyBasePermutation(aux, permutations_);
816 if(cache and (apply_permutation == requires_permutation_)){
818 cub_points_evaluated_ =
true;
825 template <
typename Scalar>
830 const bool apply_permutation)
const
832 if(side_cub_points_evaluated_ and (apply_permutation == requires_permutation_) and not force)
833 return side_cub_points;
836 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getUniformSideCubaturePointsRef()",get_uniform_side_cub_pts_ref);
840 int num_space_dim = int_rule->topology->getDimension();
841 int num_ip = int_rule->num_points;
843 auto aux = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_ip, num_space_dim-1);
845 if (int_rule->isSide() && num_space_dim==1) {
846 std::cout <<
"WARNING: 0-D quadrature rule infrastructure does not exist!!! Will not be able to do "
847 <<
"non-natural integration rules.";
852 "IntegrationValues2::getUniformSideCubaturePointsRef : Cannot build reference cubature points for control volume integration scheme.");
855 "IntegrationValues2::getUniformSideCubaturePointsRef : Cannot build reference cubature points for surface integration scheme.");
858 "IntegrationValues2::getUniformSideCubaturePointsRef : Requested side points, which is not supported by integration rule.");
860 auto weights = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
862 intrepid_cubature->getCubature(aux.get_view(), weights.get_view());
864 PHX::Device::execution_space().fence();
866 if(apply_permutation and requires_permutation_)
867 applyBasePermutation(aux, permutations_);
869 if(cache and (apply_permutation == requires_permutation_)){
870 side_cub_points = aux;
871 side_cub_points_evaluated_ =
true;
877 template <
typename Scalar>
882 const bool apply_permutation)
const
884 if(cub_weights_evaluated_ and (apply_permutation == requires_permutation_) and not force)
888 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getUniformCubatureWeightRef()",get_uniform_cub_weights_ref);
892 int num_space_dim = int_rule->topology->getDimension();
893 int num_ip = int_rule->num_points;
895 auto aux = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
897 if (int_rule->isSide() && num_space_dim==1) {
898 std::cout <<
"WARNING: 0-D quadrature rule infrastructure does not exist!!! Will not be able to do "
899 <<
"non-natural integration rules.";
904 "IntegrationValues2::getUniformCubatureWeightsRef : Cannot build reference cubature weights for control volume integration scheme.");
907 "IntegrationValues2::getUniformCubatureWeightsRef : Cannot build reference cubature weights for surface integration scheme.");
909 auto points = af.template buildStaticArray<Scalar,IP,Dim>(
"cub_points",num_ip,num_space_dim);
911 intrepid_cubature->getCubature(points.get_view(), aux.get_view());
913 PHX::Device::execution_space().fence();
915 if(apply_permutation and requires_permutation_)
916 applyBasePermutation(aux, permutations_);
918 if(cache and (apply_permutation == requires_permutation_)){
920 cub_weights_evaluated_ =
true;
927 template <
typename Scalar>
932 return node_coordinates;
935 template <
typename Scalar>
939 const bool force)
const
941 if(jac_evaluated_ and not force)
945 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getJacobian()",get_jacobian);
947 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
950 int num_space_dim = int_rule->topology->getDimension();
951 int num_ip = int_rule->num_points;
954 const bool is_cv = (int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_SIDE) or (int_rule->getType() == ID::CV_BOUNDARY);
955 const bool is_surface = int_rule->
getType() == ID::SURFACE;
957 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac",num_cells_, num_ip, num_space_dim,num_space_dim);
959 if(is_cv or is_surface){
962 auto const_ref_coord = getCubaturePointsRef(
false,force);
963 auto ref_coord = PHX::getNonConstDynRankViewFromConstMDField(const_ref_coord);
964 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
966 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
967 auto s_ref_coord = Kokkos::subview(ref_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
968 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
969 auto s_jac = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
971 cell_tools.setJacobian(s_jac, s_ref_coord, s_node_coord,*(int_rule->topology));
976 auto const_ref_coord = getUniformCubaturePointsRef(
false,force,
false);
977 auto ref_coord = PHX::getNonConstDynRankViewFromConstMDField(const_ref_coord);
978 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
980 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
981 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
982 auto s_jac = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
984 cell_tools.setJacobian(s_jac, ref_coord, s_node_coord,*(int_rule->topology));
986 if(requires_permutation_)
987 applyPermutation(aux, permutations_);
991 PHX::Device::execution_space().fence();
995 jac_evaluated_ =
true;
1001 template <
typename Scalar>
1005 const bool force)
const
1007 if(jac_inv_evaluated_ and not force)
1011 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getJacobianInverse()",get_jacobian_inv);
1013 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1016 const int num_space_dim = int_rule->topology->getDimension();
1017 const int num_ip = int_rule->num_points;
1019 auto jacobian = getJacobian(
false,force);
1020 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac_inv",num_cells_, num_ip, num_space_dim,num_space_dim);
1022 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1023 auto s_jac = Kokkos::subview(jacobian.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1024 auto s_jac_inv = Kokkos::subview(aux.get_view(), cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1026 cell_tools.setJacobianInv(s_jac_inv, s_jac);
1028 PHX::Device::execution_space().fence();
1032 jac_inv_evaluated_ =
true;
1038 template <
typename Scalar>
1042 const bool force)
const
1044 if(jac_det_evaluated_ and not force)
1048 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getJacobianDeterminant()",get_jacobian_det);
1050 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1053 const int num_ip = int_rule->num_points;
1055 auto jacobian = getJacobian(
false,force);
1056 auto aux = af.template buildStaticArray<Scalar,Cell,IP>(
"jac_det",num_cells_, num_ip);
1058 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1059 auto s_jac = Kokkos::subview(jacobian.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1060 auto s_jac_det = Kokkos::subview(aux.get_view(), cell_range,Kokkos::ALL());
1062 cell_tools.setJacobianDet(s_jac_det, s_jac);
1064 PHX::Device::execution_space().fence();
1068 jac_det_evaluated_ =
true;
1074 template <
typename Scalar>
1078 const bool force)
const
1080 if(weighted_measure_evaluated_ and not force)
1081 return weighted_measure;
1084 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getWeightedMeasure()",get_wt_meas);
1088 const int num_space_dim = int_rule->topology->getDimension();
1089 const int num_ip = int_rule->num_points;
1091 auto aux = af.template buildStaticArray<Scalar,Cell,IP>(
"weighted_measure",num_cells_, num_ip);
1093 if(int_rule->cv_type !=
"none"){
1096 "IntegrationValues2::getWeightedMeasure : Weighted measure not available for side control volume integrators. Use getWeightedNormals instead.");
1100 auto s_cub_points = af.template buildStaticArray<Scalar, Cell, IP, Dim>(
"cub_points",num_evaluate_cells_,num_ip,num_space_dim);
1102 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
1104 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1105 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1106 auto s_weighted_measure = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL());
1108 intrepid_cubature->getCubature(s_cub_points.get_view(),s_weighted_measure,s_node_coord);
1112 const auto & cell_topology = *int_rule->topology;
1113 const int cell_dim = cell_topology.getDimension();
1114 const int num_sides = (cell_dim==1) ? 2 : cell_topology.getSideCount();
1115 const int cubature_order = int_rule->order();
1116 const int num_points_on_side = num_ip / num_sides;
1118 Intrepid2::DefaultCubatureFactory cubature_factory;
1119 auto jacobian = getJacobian(
false,force);
1121 for(
int side=0; side<num_sides; ++side) {
1123 const int point_offset=side*num_points_on_side;
1126 Kokkos::DynRankView<double,PHX::Device> side_cub_weights;
1128 side_cub_weights = Kokkos::DynRankView<double,PHX::Device>(
"side_cub_weights",num_points_on_side);
1129 auto tmp_side_cub_weights_host = Kokkos::create_mirror_view(side_cub_weights);
1130 tmp_side_cub_weights_host(0)=1.;
1131 Kokkos::deep_copy(side_cub_weights,tmp_side_cub_weights_host);
1135 const shards::CellTopology face_topology(cell_topology.getCellTopologyData(cell_dim-1,side));
1137 auto ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(face_topology,cubature_order);
1139 side_cub_weights = Kokkos::DynRankView<double,PHX::Device>(
"side_cub_weights",num_points_on_side);
1140 auto subcell_cub_points = Kokkos::DynRankView<double,PHX::Device>(
"subcell_cub_points",num_points_on_side,cell_dim-1);
1143 ic->getCubature(subcell_cub_points, side_cub_weights);
1146 PHX::Device::execution_space().fence();
1149 Kokkos::MDRangePolicy<PHX::Device::execution_space,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_points_on_side});
1152 auto side_weighted_measure = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_weighted_measure",num_evaluate_cells_,num_points_on_side);
1154 auto side_cub_weights_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(),side_cub_weights);
1155 Kokkos::deep_copy(side_weighted_measure, side_cub_weights_host(0));
1159 auto side_jacobian = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_jac",num_evaluate_cells_,num_points_on_side,cell_dim,cell_dim);
1161 Kokkos::parallel_for(
"Copy jacobian to side jacobian",policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1162 for(
int dim=0;dim<cell_dim;++dim)
1163 for(
int dim1=0;dim1<cell_dim;++dim1)
1164 side_jacobian(cell,point,dim,dim1) = jacobian(cell,point_offset+point,dim,dim1);
1167 auto scratch = af.template buildStaticArray<Scalar,Point>(
"scratch_for_compute_measure", num_evaluate_cells_*num_points_on_side*num_space_dim*num_space_dim);
1170 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
1171 computeEdgeMeasure(side_weighted_measure, side_jacobian, side_cub_weights,
1173 scratch.get_view());
1174 PHX::Device::execution_space().fence();
1175 }
else if(cell_dim == 3){
1176 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
1177 computeFaceMeasure(side_weighted_measure, side_jacobian, side_cub_weights,
1179 scratch.get_view());
1180 PHX::Device::execution_space().fence();
1186 Kokkos::parallel_for(
"copy surface weighted measure values",policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1187 aux(cell,point_offset + point) = side_weighted_measure(cell,point);
1189 PHX::Device::execution_space().fence();
1194 auto cell_range = std::make_pair(0,num_evaluate_cells_);
1195 auto s_weighted_measure = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL());
1196 auto cubature_weights = getUniformCubatureWeightsRef(
false,force,
false);
1198 if (!int_rule->isSide()) {
1200 auto s_jac_det = Kokkos::subview(getJacobianDeterminant(
false,force).get_view(),cell_range,Kokkos::ALL());
1201 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
1202 computeCellMeasure(s_weighted_measure, s_jac_det, cubature_weights.get_view());
1204 }
else if(int_rule->spatial_dimension==3) {
1206 auto s_jac = Kokkos::subview(getJacobian(
false,force).get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1207 auto scratch = af.template buildStaticArray<Scalar,Point>(
"scratch_for_compute_measure", num_evaluate_cells_*num_ip*num_space_dim*num_space_dim);
1208 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
1209 computeFaceMeasure(s_weighted_measure, s_jac, cubature_weights.get_view(),
1210 int_rule->side, *int_rule->topology,
1211 scratch.get_view());
1213 }
else if(int_rule->spatial_dimension==2) {
1215 auto s_jac = Kokkos::subview(getJacobian(
false,force).get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1216 auto scratch = af.template buildStaticArray<Scalar,Point>(
"scratch_for_compute_measure", num_evaluate_cells_*num_ip*num_space_dim*num_space_dim);
1217 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
1218 computeEdgeMeasure(s_weighted_measure, s_jac, cubature_weights.get_view(),
1219 int_rule->side,*int_rule->topology,
1220 scratch.get_view());
1228 PHX::Device::execution_space().fence();
1231 if(requires_permutation_)
1232 applyPermutation(aux, permutations_);
1235 weighted_measure = aux;
1236 weighted_measure_evaluated_ =
true;
1242 template <
typename Scalar>
1246 const bool force)
const
1248 if(weighted_normals_evaluated_ and not force)
1249 return weighted_normals;
1252 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getWeightedNormals()",get_wt_normals);
1256 const int num_space_dim = int_rule->topology->getDimension();
1257 const int num_ip = int_rule->num_points;
1259 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"weighted_normals",num_cells_,num_ip,num_space_dim);
1262 "IntegrationValues2::getWeightedNormals : Cannot build reference weighted normals for surface integration scheme.");
1264 auto points = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"cub_points",num_cells_,num_ip,num_space_dim);
1266 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
1268 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1269 auto s_cub_points = Kokkos::subview(points.get_view(),cell_range, Kokkos::ALL(), Kokkos::ALL());
1270 auto s_weighted_normals = Kokkos::subview(aux.get_view(), cell_range, Kokkos::ALL(), Kokkos::ALL());
1271 auto s_node_coord = Kokkos::subview(node_coord, cell_range, Kokkos::ALL(), Kokkos::ALL());
1273 intrepid_cubature->getCubature(s_cub_points,s_weighted_normals,s_node_coord);
1275 PHX::Device::execution_space().fence();
1278 if(requires_permutation_)
1279 applyPermutation(aux, permutations_);
1282 weighted_normals = aux;
1283 weighted_normals_evaluated_ =
true;
1289 template <
typename Scalar>
1293 const bool force)
const
1295 if(surface_normals_evaluated_ and not force)
1296 return surface_normals;
1299 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getSurfaceNormals()",get_surf_normals);
1302 "IntegrationValues2::getSurfaceNormals : This call doesn't work with sides (only surfaces).");
1305 "IntegrationValues2::getSurfaceNormals : This call does not support control volume integration schemes.");
1308 "IntegrationValues2::getSurfaceNormals : Can only build for surface integrators.");
1310 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1313 const shards::CellTopology & cell_topology = *(int_rule->topology);
1314 const int cell_dim = cell_topology.getDimension();
1315 const int subcell_dim = cell_topology.getDimension()-1;
1316 const int num_subcells = cell_topology.getSubcellCount(subcell_dim);
1317 const int num_space_dim = int_rule->topology->getDimension();
1318 const int num_ip = int_rule->num_points;
1319 const int num_points_on_face = num_ip / num_subcells;
1321 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"surface_normals",num_cells_,num_ip,num_space_dim);
1326 jacobian = getJacobian(
false,force);
1329 for(
int subcell_index=0; subcell_index<num_subcells; ++subcell_index) {
1331 const int point_offset = subcell_index * num_points_on_face;;
1334 auto side_normals = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_normals",num_evaluate_cells_,num_points_on_face,cell_dim);
1337 const int other_subcell_index = (subcell_index==0) ? 1 : 0;
1338 auto in_node_coordinates_k = getNodeCoordinates().get_view();
1339 const auto min = std::numeric_limits<typename Sacado::ScalarType<Scalar>::type>::min();
1341 Kokkos::parallel_for(
"compute normals 1D",num_evaluate_cells_,KOKKOS_LAMBDA (
const int cell) {
1342 Scalar norm = (in_node_coordinates_k(cell,subcell_index,0) - in_node_coordinates_k(cell,other_subcell_index,0));
1343 side_normals(cell,0,0) = norm / fabs(norm + min);
1349 Kokkos::MDRangePolicy<PHX::Device::execution_space,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_points_on_face});
1351 auto side_jacobian = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_jac",num_evaluate_cells_,num_points_on_face,cell_dim,cell_dim);
1352 Kokkos::parallel_for(
"Copy jacobian to side jacobian",policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1353 for(
int dim=0;dim<cell_dim;++dim)
1354 for(
int dim1=0;dim1<cell_dim;++dim1)
1355 side_jacobian(cell,point,dim,dim1) = jacobian(cell,point_offset+point,dim,dim1);
1359 cell_tools.getPhysicalSideNormals(side_normals,side_jacobian,subcell_index,cell_topology);
1362 Kokkos::parallel_for(
"Normalize the normals",policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1364 for(
int dim=0;dim<cell_dim;++dim){
1365 n += side_normals(cell,point,dim)*side_normals(cell,point,dim);
1369 n = Kokkos::sqrt(n);
1370 for(
int dim=0;dim<cell_dim;++dim)
1371 side_normals(cell,point,dim) /= n;
1376 PHX::Device::execution_space().fence();
1378 Kokkos::MDRangePolicy<PHX::Device::execution_space,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_points_on_face});
1379 Kokkos::parallel_for(
"copy surface normals", policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1380 for(
int dim=0;dim<cell_dim;++dim)
1381 aux(cell,point_offset + point,dim) = side_normals(cell,point,dim);
1383 PHX::Device::execution_space().fence();
1388 TEUCHOS_TEST_FOR_EXCEPT_MSG(side_connectivity_ == Teuchos::null,
1389 "IntegrationValues2::getSurfaceNormals : Surface normals require a SubcellConnectivity object pass in through the setupPermutations call");
1390 TEUCHOS_TEST_FOR_EXCEPT_MSG(num_virtual_cells_ < 0,
1391 "IntegrationValues2::getSurfaceNormals : Number of virtual cells (see setupPermutations or evaluateValues) must be greater or equal to zero");
1394 if(num_virtual_cells_ > 0)
1395 correctVirtualNormals(aux, num_evaluate_cells_ - num_virtual_cells_, num_virtual_cells_, *int_rule->topology, *side_connectivity_);
1399 surface_normals = aux;
1400 surface_normals_evaluated_ =
true;
1407 template <
typename Scalar>
1411 const bool force)
const
1413 if(surface_rotation_matrices_evaluated_ and not force)
1414 return surface_rotation_matrices;
1417 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getSurfaceRotationMatrices()",get_surf_rot_mat);
1421 const int num_ip = int_rule->num_points;
1422 const int cell_dim = int_rule->topology->getDimension();
1426 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"surface_rotation_matrices",num_cells_, num_ip, 3, 3);
1428 Kokkos::MDRangePolicy<PHX::Device::execution_space,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_ip});
1429 Kokkos::parallel_for(
"create surface rotation matrices",policy,KOKKOS_LAMBDA (
const int cell,
const int point) {
1431 for(
int i=0;i<3;i++)
1433 for(
int dim=0; dim<cell_dim; ++dim)
1434 normal[dim] = normals(cell,point,dim);
1436 Scalar transverse[3];
1440 for(
int dim=0; dim<3; ++dim){
1441 aux(cell,point,0,dim) = normal[dim];
1442 aux(cell,point,1,dim) = transverse[dim];
1443 aux(cell,point,2,dim) = binormal[dim];
1446 PHX::Device::execution_space().fence();
1451 "IntegrationValues2::getSurfaceRotationMatrices : Surface normals require a SubcellConnectivity object pass in through the setupPermutations call");
1453 "IntegrationValues2::getSurfaceRotationMatrices : Number of virtual cells (see setupPermutations or evaluateValues) must be greater or equal to zero");
1456 if(num_virtual_cells_ > 0)
1457 correctVirtualRotationMatrices(aux, num_evaluate_cells_ - num_virtual_cells_, num_virtual_cells_, *int_rule->topology, *side_connectivity_);
1461 surface_rotation_matrices = aux;
1462 surface_rotation_matrices_evaluated_ =
true;
1468 template <
typename Scalar>
1472 const bool force)
const
1474 if(covarient_evaluated_ and not force)
1478 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getCovariantMatrix()",get_cov_mat);
1482 const int num_space_dim = int_rule->topology->getDimension();
1483 const int num_ip = int_rule->num_points;
1485 auto jacobian = getJacobian(
false,force).get_static_view();
1486 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"covarient",num_cells_, num_ip, num_space_dim,num_space_dim);
1488 Kokkos::MDRangePolicy<PHX::Device,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_ip});
1489 Kokkos::parallel_for(
"evalaute covarient metric tensor",policy,KOKKOS_LAMBDA (
const int cell,
const int ip) {
1491 for (
int i = 0; i < num_space_dim; ++i) {
1492 for (
int j = 0; j < num_space_dim; ++j) {
1494 for (
int alpha = 0; alpha < num_space_dim; ++alpha)
1495 value += jacobian(cell,ip,i,alpha) * jacobian(cell,ip,j,alpha);
1496 aux(cell,ip,i,j) = value;
1500 PHX::Device::execution_space().fence();
1504 covarient_evaluated_ =
true;
1510 template <
typename Scalar>
1514 const bool force)
const
1516 if(contravarient_evaluated_ and not force)
1517 return contravarient;
1520 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getContravarientMatrix()",get_contra_mat);
1524 const int num_space_dim = int_rule->topology->getDimension();
1525 const int num_ip = int_rule->num_points;
1527 auto cov = getCovarientMatrix(
false,force);
1528 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"contravarient",num_cells_, num_ip, num_space_dim,num_space_dim);
1530 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1531 auto s_contravarient = Kokkos::subview(aux.get_view(), cell_range,Kokkos::ALL,Kokkos::ALL,Kokkos::ALL);
1532 auto s_covarient = Kokkos::subview(cov.get_view(), cell_range,Kokkos::ALL,Kokkos::ALL,Kokkos::ALL);
1534 Intrepid2::RealSpaceTools<PHX::Device::execution_space>::inverse(s_contravarient, s_covarient);
1535 PHX::Device::execution_space().fence();
1538 contravarient = aux;
1539 contravarient_evaluated_ =
true;
1545 template <
typename Scalar>
1549 const bool force)
const
1551 if(norm_contravarient_evaluated_ and not force)
1552 return norm_contravarient;
1555 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getNormContravarientMatrix()",get_norm_contr_mat);
1559 const int num_space_dim = int_rule->topology->getDimension();
1560 const int num_ip = int_rule->num_points;
1562 auto con = getContravarientMatrix(
false,force).get_static_view();
1563 auto aux = af.template buildStaticArray<Scalar,Cell,IP>(
"norm_contravarient",num_cells_, num_ip);
1566 Kokkos::MDRangePolicy<PHX::Device,Kokkos::Rank<2>> policy({0,0},{num_evaluate_cells_,num_ip});
1567 Kokkos::parallel_for(
"evaluate norm_contravarient",policy,KOKKOS_LAMBDA (
const int cell,
const int ip) {
1569 for (
int i = 0; i < num_space_dim; ++i) {
1570 for (
int j = 0; j < num_space_dim; ++j) {
1571 aux(cell,ip) += con(cell,ip,i,j) * con(cell,ip,i,j);
1574 aux(cell,ip) = Kokkos::sqrt(aux(cell,ip));
1576 PHX::Device::execution_space().fence();
1579 norm_contravarient = aux;
1580 norm_contravarient_evaluated_ =
true;
1586 template <
typename Scalar>
1590 const bool force)
const
1592 if(ip_coordinates_evaluated_ and not force)
1593 return ip_coordinates;
1596 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getCubaturePoints()",get_cub_pts);
1600 const int num_space_dim = int_rule->topology->getDimension();
1601 const int num_ip = int_rule->num_points;
1603 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ip_coordinates",num_cells_, num_ip, num_space_dim);
1606 const bool is_cv = (int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_SIDE) or (int_rule->getType() == ID::CV_BOUNDARY);
1607 const bool is_surface = int_rule->
getType() == ID::SURFACE;
1609 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
1614 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1615 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1616 auto s_cub_points = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1619 if(int_rule->cv_type ==
"side"){
1620 auto scratch = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"scratch",num_evaluate_cells_,num_ip,num_space_dim);
1621 intrepid_cubature->getCubature(s_cub_points,scratch.get_view(),s_node_coord);
1624 TEUCHOS_ASSERT((int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_BOUNDARY));
1625 auto scratch = af.template buildStaticArray<Scalar,Cell,IP>(
"scratch",num_evaluate_cells_,num_ip);
1626 intrepid_cubature->getCubature(s_cub_points,scratch.get_view(),s_node_coord);
1629 }
else if(is_surface){
1632 auto const_ref_coord = getCubaturePointsRef(
false,force);
1633 auto ref_coord = PHX::getNonConstDynRankViewFromConstMDField(const_ref_coord);
1635 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1636 auto s_ref_coord = Kokkos::subview(ref_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1637 auto s_coord = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1638 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1640 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1641 cell_tools.mapToPhysicalFrame(s_coord, s_ref_coord, s_node_coord, *(int_rule->topology));
1646 auto const_ref_coord = getUniformCubaturePointsRef(
false,force,
false);
1647 auto ref_coord = PHX::getNonConstDynRankViewFromConstMDField(const_ref_coord);
1649 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1650 auto s_coord = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1651 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1653 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1654 cell_tools.mapToPhysicalFrame(s_coord, ref_coord, s_node_coord, *(int_rule->topology));
1656 if(requires_permutation_)
1657 applyPermutation(aux, permutations_);
1661 PHX::Device::execution_space().fence();
1664 ip_coordinates = aux;
1665 ip_coordinates_evaluated_ =
true;
1672 template <
typename Scalar>
1676 const bool force)
const
1678 if(ref_ip_coordinates_evaluated_ and not force)
1679 return ref_ip_coordinates;
1682 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::getCubaturePointsRef()",get_cub_pts_ref);
1685 const bool is_surface = int_rule->
getType() == ID::SURFACE;
1686 const bool is_cv = (int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_SIDE) or (int_rule->getType() == ID::CV_BOUNDARY);
1688 const int num_space_dim = int_rule->topology->getDimension();
1689 const int num_ip = int_rule->num_points;
1693 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1695 auto aux = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ref_ip_coordinates",num_cells_, num_ip, num_space_dim);
1701 auto node_coord = PHX::getNonConstDynRankViewFromConstMDField(getNodeCoordinates());
1704 auto const_coord = getCubaturePoints(
false,force);
1705 auto coord = PHX::getNonConstDynRankViewFromConstMDField(const_coord);
1707 const auto cell_range = std::make_pair(0,num_evaluate_cells_);
1708 auto s_ref_coord = Kokkos::subview(aux.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL());
1709 auto s_coord = Kokkos::subview(coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1710 auto s_node_coord = Kokkos::subview(node_coord, cell_range,Kokkos::ALL(),Kokkos::ALL());
1712 cell_tools.mapToReferenceFrame(s_ref_coord, s_coord, s_node_coord, *(int_rule->topology));
1714 }
else if(is_surface){
1716 const auto & cell_topology = *int_rule->topology;
1717 const int cell_dim = cell_topology.getDimension();
1718 const int num_sides = (cell_dim==1) ? 2 : cell_topology.getSideCount();
1719 const int subcell_dim = cell_dim-1;
1720 const int num_points_on_face = num_ip / num_sides;
1721 const int order = int_rule->getOrder();
1724 auto side_cub_points2 = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_points_on_face,cell_dim);
1726 Intrepid2::DefaultCubatureFactory cubature_factory;
1729 for(
int side=0; side<num_sides; ++side) {
1731 const int point_offset = side*num_points_on_face;
1736 auto side_cub_points_host = Kokkos::create_mirror_view(side_cub_points2.get_view());
1737 side_cub_points_host(0,0) = (side==0)? -1. : 1.;
1738 Kokkos::deep_copy(side_cub_points2.get_view(),side_cub_points_host);
1742 const shards::CellTopology face_topology(cell_topology.getCellTopologyData(subcell_dim,side));
1745 auto ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(face_topology,order);
1746 auto tmp_side_cub_weights = Kokkos::DynRankView<double,PHX::Device>(
"tmp_side_cub_weights",num_points_on_face);
1747 auto tmp_side_cub_points = Kokkos::DynRankView<double,PHX::Device>(
"tmp_side_cub_points",num_points_on_face,subcell_dim);
1750 ic->getCubature(tmp_side_cub_points, tmp_side_cub_weights);
1753 cell_tools.mapToReferenceSubcell(side_cub_points2.get_view(), tmp_side_cub_points, subcell_dim, side, cell_topology);
1756 PHX::Device::execution_space().fence();
1759 Kokkos::MDRangePolicy<PHX::Device::execution_space,Kokkos::Rank<3>> policy({0,0,0},{num_evaluate_cells_,num_points_on_face, num_space_dim});
1760 Kokkos::parallel_for(
"copy values",policy,KOKKOS_LAMBDA (
const int cell,
const int point,
const int dim) {
1761 aux(cell,point_offset + point,dim) = side_cub_points2(point,dim);
1763 PHX::Device::execution_space().fence();
1770 "ERROR: 0-D quadrature rule infrastructure does not exist!!! Will not be able to do "
1771 <<
"non-natural integration rules.");
1773 auto cub_points2 = getUniformCubaturePointsRef(
false,force,
false);
1775 Kokkos::MDRangePolicy<PHX::Device,Kokkos::Rank<3>> policy({0,0,0},{num_evaluate_cells_,num_ip,num_space_dim});
1776 Kokkos::parallel_for(policy, KOKKOS_LAMBDA(
const int & cell,
const int & ip,
const int & dim){
1777 aux(cell,ip,dim) = cub_points2(ip,dim);
1781 PHX::Device::execution_space().fence();
1783 if(requires_permutation_)
1784 applyPermutation(aux, permutations_);
1787 ref_ip_coordinates = aux;
1788 ref_ip_coordinates_evaluated_ =
true;
1794 template <
typename Scalar>
1799 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::integrationValues2::evaluateEverything()",eval_everything);
1802 const bool is_surface = int_rule->
getType() == ID::SURFACE;
1803 const bool is_cv = (int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_SIDE) or (int_rule->getType() == ID::CV_BOUNDARY);
1804 const bool is_side = int_rule->isSide();
1811 getCubaturePoints(
true);
1812 getCubaturePointsRef(
true);
1815 getUniformCubaturePointsRef(
true,
true,requires_permutation_);
1816 getUniformCubatureWeightsRef(
true,
true,requires_permutation_);
1818 getUniformSideCubaturePointsRef(
true,
true,requires_permutation_);
1820 getCubaturePointsRef(
true);
1821 getCubaturePoints(
true);
1826 getJacobianDeterminant(
true);
1827 getJacobianInverse(
true);
1828 if(int_rule->cv_type ==
"side")
1829 getWeightedNormals(
true);
1831 getWeightedMeasure(
true);
1835 getSurfaceNormals(
true);
1836 getSurfaceRotationMatrices(
true);
1840 if(not (is_surface or is_cv)){
1841 getContravarientMatrix(
true);
1842 getCovarientMatrix(
true);
1843 getNormContravarientMatrix(
true);
1847 #define INTEGRATION_VALUES2_INSTANTIATION(SCALAR) \
1848 template class IntegrationValues2<SCALAR>;
ConstArray_IPDim getUniformSideCubaturePointsRef(const bool cache=true, const bool force=false, const bool apply_permutation=true) const
Get the uniform cubature points for a side.
void setupPermutations(const Teuchos::RCP< const SubcellConnectivity > &face_connectivity, const int num_virtual_cells)
Initialize the permutation arrays given a face connectivity.
ConstArray_CellIPDimDim getContravarientMatrix(const bool cache=true, const bool force=false) const
Get the contravarient matrix.
void setup(const Teuchos::RCP< const panzer::IntegrationRule > &ir, const PHX::MDField< Scalar, Cell, NODE, Dim > &cell_node_coordinates, const int num_cells=-1)
Main setup call for the lazy evaluation interface.
ConstArray_CellIP getWeightedMeasure(const bool cache=true, const bool force=false) const
Get the weighted measure (integration weights)
const int & getType() const
Get type of integrator.
void evaluateEverything()
ConstArray_CellIPDimDim getJacobianInverse(const bool cache=true, const bool force=false) const
Get the inverse of the Jacobian matrix evaluated at the cubature points.
#define INTEGRATION_VALUES2_INSTANTIATION(SCALAR)
ConstArray_CellIPDimDim getCovarientMatrix(const bool cache=true, const bool force=false) const
Get the covarient matrix.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
ConstArray_CellIPDim getWeightedNormals(const bool cache=true, const bool force=false) const
Get the weighted normals.
ConstArray_CellIP getNormContravarientMatrix(const bool cache=true, const bool force=false) const
Get the contravarient matrix.
ConstArray_CellIPDimDim getSurfaceRotationMatrices(const bool cache=true, const bool force=false) const
Get the surface rotation matrices.
#define PANZER_CROSS(a, b, c)
KOKKOS_FORCEINLINE_FUNCTION array_type get_static_view()
Teuchos::RCP< const shards::CellTopology > topology
KOKKOS_INLINE_FUNCTION void convertNormalToRotationMatrix(const Scalar normal[3], Scalar transverse[3], Scalar binormal[3])
ConstArray_CellIPDim getCubaturePoints(const bool cache=true, const bool force=false) const
Get the cubature points in physical space.
void setupArrays(const Teuchos::RCP< const panzer::IntegrationRule > &ir)
Sizes/allocates memory for arrays.
ConstArray_CellIPDim getCubaturePointsRef(const bool cache=true, const bool force=false) const
Get the cubature points in the reference space.
const int & getSide() const
Get side associated with integration - this is for backward compatibility.
ConstArray_IPDim getUniformCubaturePointsRef(const bool cache=true, const bool force=false, const bool apply_permutation=true) const
Get the uniform cubature points.
ConstArray_CellIPDimDim getJacobian(const bool cache=true, const bool force=false) const
Get the Jacobian matrix evaluated at the cubature points.
ConstArray_CellIP getJacobianDeterminant(const bool cache=true, const bool force=false) const
Get the determinant of the Jacobian matrix evaluated at the cubature points.
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral...
IntegrationValues2(const std::string &pre="", const bool allocArrays=false)
Base constructor.
Teuchos::RCP< shards::CellTopology > side_topology
#define TEUCHOS_ASSERT(assertion_test)
ConstArray_CellBASISDim getNodeCoordinates() const
Get the node coordinates describing the geometry of the mesh.
void evaluateValues(const PHX::MDField< Scalar, Cell, NODE, Dim > &cell_node_coordinates, const int num_cells=-1, const Teuchos::RCP< const SubcellConnectivity > &face_connectivity=Teuchos::null, const int num_virtual_cells=-1)
Evaluate basis values.
ConstArray_IP getUniformCubatureWeightsRef(const bool cache=true, const bool force=false, const bool apply_permutation=true) const
Get the uniform cubature weights.
ConstArray_CellIPDim getSurfaceNormals(const bool cache=true, const bool force=false) const
Get the surface normals.
const int & getOrder() const
Get order of integrator.