46 #include "Shards_CellTopology.hpp"
48 #include "Kokkos_DynRankView.hpp"
49 #include "Intrepid2_FunctionSpaceTools.hpp"
50 #include "Intrepid2_RealSpaceTools.hpp"
51 #include "Intrepid2_CellTools.hpp"
52 #include "Intrepid2_ArrayTools.hpp"
53 #include "Intrepid2_CubatureControlVolume.hpp"
54 #include "Intrepid2_CubatureControlVolumeSide.hpp"
55 #include "Intrepid2_CubatureControlVolumeBoundary.hpp"
67 template <
typename Scalar>
73 int num_nodes = ir->
topology->getNodeCount();
75 int num_space_dim = ir->
topology->getDimension();
79 dyn_cub_points = af.template buildArray<double,IP,Dim>(
"cub_points",num_ip, num_space_dim);
80 dyn_cub_weights = af.template buildArray<double,IP>(
"cub_weights",num_ip);
82 cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"cub_points",num_ip, num_space_dim);
85 dyn_side_cub_points = af.template buildArray<double,IP,Dim>(
"side_cub_points",num_ip, ir->
side_topology->getDimension());
86 side_cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_ip,ir->
side_topology->getDimension());
90 dyn_phys_cub_points = af.template buildArray<double,Cell,IP,Dim>(
"phys_cub_points",num_cells, num_ip, num_space_dim);
91 dyn_phys_cub_weights = af.template buildArray<double,Cell,IP>(
"phys_cub_weights",num_cells, num_ip);
93 dyn_phys_cub_norms = af.template buildArray<double,Cell,IP,Dim>(
"phys_cub_norms",num_cells, num_ip, num_space_dim);
97 dyn_node_coordinates = af.template buildArray<double,Cell,BASIS,Dim>(
"node_coordinates",num_cells, num_nodes, num_space_dim);
99 cub_weights = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
101 node_coordinates = af.template buildStaticArray<Scalar,Cell,BASIS,Dim>(
"node_coordinates",num_cells, num_nodes, num_space_dim);
103 jac = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac",num_cells, num_ip, num_space_dim,num_space_dim);
105 jac_inv = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac_inv",num_cells, num_ip, num_space_dim,num_space_dim);
107 jac_det = af.template buildStaticArray<Scalar,Cell,IP>(
"jac_det",num_cells, num_ip);
109 weighted_measure = af.template buildStaticArray<Scalar,Cell,IP>(
"weighted_measure",num_cells, num_ip);
111 covarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"covarient",num_cells, num_ip, num_space_dim,num_space_dim);
113 contravarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"contravarient",num_cells, num_ip, num_space_dim,num_space_dim);
115 norm_contravarient = af.template buildStaticArray<Scalar,Cell,IP>(
"norm_contravarient",num_cells, num_ip);
117 ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ip_coordiantes",num_cells, num_ip,num_space_dim);
119 ref_ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ref_ip_coordinates",num_cells, num_ip,num_space_dim);
121 weighted_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"weighted normal",num_cells, num_ip,num_space_dim);
123 surface_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"surface_normals",num_cells, num_ip,num_space_dim);
125 surface_rotation_matrices = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"surface_rotation_matrices",num_cells, num_ip,3,3);
129 template <
typename Scalar>
139 int num_nodes = ir->
topology->getNodeCount();
141 int num_space_dim = ir->
topology->getDimension();
144 if(num_space_dim==1 && ir->
isSide()) {
145 setupArraysForNodeRule(ir);
150 intrepid_cubature = getIntrepidCubature(*ir);
173 dyn_cub_points = af.template buildArray<double,IP,Dim>(
"cub_points",num_ip, num_space_dim);
174 dyn_cub_weights = af.template buildArray<double,IP>(
"cub_weights",num_ip);
176 cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"cub_points",num_ip, num_space_dim);
179 dyn_side_cub_points = af.template buildArray<double,IP,Dim>(
"side_cub_points",num_ip, ir->
side_topology->getDimension());
180 side_cub_points = af.template buildStaticArray<Scalar,IP,Dim>(
"side_cub_points",num_ip,ir->
side_topology->getDimension());
184 dyn_phys_cub_points = af.template buildArray<double,Cell,IP,Dim>(
"phys_cub_points",num_cells, num_ip, num_space_dim);
185 dyn_phys_cub_weights = af.template buildArray<double,Cell,IP>(
"phys_cub_weights",num_cells, num_ip);
187 dyn_phys_cub_norms = af.template buildArray<double,Cell,IP,Dim>(
"phys_cub_norms",num_cells, num_ip, num_space_dim);
191 dyn_node_coordinates = af.template buildArray<double,Cell,BASIS,Dim>(
"node_coordinates",num_cells, num_nodes, num_space_dim);
193 cub_weights = af.template buildStaticArray<Scalar,IP>(
"cub_weights",num_ip);
195 node_coordinates = af.template buildStaticArray<Scalar,Cell,BASIS,Dim>(
"node_coordinates",num_cells, num_nodes, num_space_dim);
197 jac = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac",num_cells, num_ip, num_space_dim,num_space_dim);
199 jac_inv = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"jac_inv",num_cells, num_ip, num_space_dim,num_space_dim);
201 jac_det = af.template buildStaticArray<Scalar,Cell,IP>(
"jac_det",num_cells, num_ip);
203 weighted_measure = af.template buildStaticArray<Scalar,Cell,IP>(
"weighted_measure",num_cells, num_ip);
205 covarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"covarient",num_cells, num_ip, num_space_dim,num_space_dim);
207 contravarient = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"contravarient",num_cells, num_ip, num_space_dim,num_space_dim);
209 norm_contravarient = af.template buildStaticArray<Scalar,Cell,IP>(
"norm_contravarient",num_cells, num_ip);
211 ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ip_coordiantes",num_cells, num_ip,num_space_dim);
213 ref_ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"ref_ip_coordinates",num_cells, num_ip,num_space_dim);
215 weighted_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"weighted_normal",num_cells,num_ip,num_space_dim);
217 surface_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
"surface_normals",num_cells, num_ip,num_space_dim);
219 surface_rotation_matrices = af.template buildStaticArray<Scalar,Cell,IP,Dim,Dim>(
"surface_rotation_matrices",num_cells, num_ip,3,3);
221 scratch_for_compute_side_measure =
222 af.template buildStaticArray<Scalar,Point>(
"scratch_for_compute_side_measure", jac.get_view().span());
226 template <
typename Scalar>
234 Intrepid2::DefaultCubatureFactory cubature_factory;
236 if(ir.
getType() == ID::CV_SIDE){
237 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolumeSide<PHX::Device::execution_space,double,double>(*ir.
topology));
238 }
else if(ir.
getType() == ID::CV_VOLUME){
239 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolume<PHX::Device::execution_space,double,double>(*ir.
topology));
240 }
else if(ir.
getType() == ID::CV_BOUNDARY){
241 ic =
Teuchos::rcp(
new Intrepid2::CubatureControlVolumeBoundary<PHX::Device::execution_space,double,double>(*ir.
topology,ir.
getSide()));
243 if(ir.
getType() == ID::VOLUME){
244 ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(*(ir.
topology),ir.
getOrder());
245 }
else if(ir.
getType() == ID::SIDE){
246 ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(*(ir.
side_topology),ir.
getOrder());
247 }
else if(ir.
getType() == ID::SURFACE){
261 template <
typename Scalar>
264 const int in_num_cells)
267 const bool is_surface = int_rule->
getType() == ID::SURFACE;
268 const bool is_cv = (int_rule->getType() == ID::CV_VOLUME) or (int_rule->getType() == ID::CV_SIDE) or (int_rule->getType() == ID::CV_BOUNDARY);
273 generateSurfaceCubatureValues(in_node_coordinates,in_num_cells);
275 getCubatureCV(in_node_coordinates, in_num_cells);
276 evaluateValuesCV(in_node_coordinates, in_num_cells);
278 getCubature(in_node_coordinates, in_num_cells);
279 evaluateRemainingValues(in_node_coordinates, in_num_cells);
283 template <
typename Scalar>
285 getCubature(
const PHX::MDField<Scalar,Cell,NODE,Dim>& in_node_coordinates,
286 const int in_num_cells)
289 int num_space_dim = int_rule->topology->getDimension();
290 if (int_rule->isSide() && num_space_dim==1) {
291 std::cout <<
"WARNING: 0-D quadrature rule ifrastructure does not exist!!! Will not be able to do "
292 <<
"non-natural integration rules.";
296 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
298 if (!int_rule->isSide())
299 intrepid_cubature->getCubature(dyn_cub_points.get_view(), dyn_cub_weights.get_view());
301 intrepid_cubature->getCubature(dyn_side_cub_points.get_view(), dyn_cub_weights.get_view());
303 cell_tools.mapToReferenceSubcell(dyn_cub_points.get_view(),
304 dyn_side_cub_points.get_view(),
305 int_rule->spatial_dimension-1,
307 *(int_rule->topology));
311 const int num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : in_num_cells;
312 auto s_ip_coordinates = Kokkos::subview(ip_coordinates.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL());
313 auto s_in_node_coordinates = Kokkos::subview(in_node_coordinates.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL());
314 cell_tools.mapToPhysicalFrame(s_ip_coordinates,
315 dyn_cub_points.get_view(),
316 s_in_node_coordinates,
317 *(int_rule->topology));
327 template <
typename array_t,
typename scalar_t>
332 point_sorter_t() =
delete;
333 point_sorter_t(
const array_t & array,
const int cell,
const int offset):
344 bool operator()(
const int & point_a,
const int & point_b)
const
352 const scalar_t rel = std::max(std::fabs(x_a),std::fabs(x_b));
354 return test_less(x_a,x_b,rel);
364 const scalar_t rel_x = std::max(std::fabs(x_a),std::fabs(x_b));
365 const scalar_t rel_y = std::max(std::fabs(y_a),std::fabs(y_b));
366 const scalar_t rel = std::max(rel_x,rel_y);
368 if(test_eq(y_a,y_b,rel)){
369 if(test_less(x_a,x_b,rel)){
373 }
else if(test_less(y_a,y_b,rel)){
392 const scalar_t rel_x = std::max(std::fabs(x_a),std::fabs(x_b));
393 const scalar_t rel_y = std::max(std::fabs(y_a),std::fabs(y_b));
394 const scalar_t rel_z = std::max(std::fabs(z_a),std::fabs(z_b));
395 const scalar_t rel = std::max(rel_x,std::max(rel_y,rel_z));
397 if(test_less(z_a,z_b,rel)){
400 }
else if(test_eq(z_a,z_b,rel)){
401 if(test_eq(y_a,y_b,rel)){
402 if(test_less(x_a,x_b,rel)){
406 }
else if(test_less(y_a,y_b,rel)){
422 test_eq(
const scalar_t & a,
const scalar_t & b,
const scalar_t & rel)
const
427 return std::fabs(a-b) <
_rel_tol * rel;
431 test_less(
const scalar_t & a,
const scalar_t & b,
const scalar_t & rel)
const
449 template <
typename Scalar>
455 const T n = sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]);
460 transverse[0]=0.;transverse[1]=1.;transverse[2]=0.;
461 if(std::fabs(normal[0]*transverse[0]+normal[1]*transverse[1])>0.9){
462 transverse[0]=1.;transverse[1]=0.;
465 const T nt = normal[0]*transverse[0]+normal[1]*transverse[1]+normal[2]*transverse[2];
468 const T mult = nt/(n*n);
471 for(
int dim=0;dim<3;++dim){
472 transverse[dim] = transverse[dim] - mult * normal[dim];
475 const T t = sqrt(transverse[0]*transverse[0]+transverse[1]*transverse[1]+transverse[2]*transverse[2]);
477 for(
int dim=0;dim<3;++dim){
478 transverse[dim] /= t;
482 binormal[0] = (normal[1] * transverse[2] - normal[2] * transverse[1]);
483 binormal[1] = (normal[2] * transverse[0] - normal[0] * transverse[2]);
484 binormal[2] = (normal[0] * transverse[1] - normal[1] * transverse[0]);
487 const T b = sqrt(binormal[0]*binormal[0]+binormal[1]*binormal[1]+binormal[2]*binormal[2]);
488 for(
int dim=0;dim<3;++dim){
501 template <
typename Scalar>
507 const int new_cell_point = a;
508 const int old_cell_point = b;
510 const int cell_dim = ref_ip_coordinates.extent(2);
514 hold = weighted_measure(cell,new_cell_point);
515 weighted_measure(cell,new_cell_point) = weighted_measure(cell,old_cell_point);
516 weighted_measure(cell,old_cell_point) = hold;
518 hold = jac_det(cell,new_cell_point);
519 jac_det(cell,new_cell_point) = jac_det(cell,old_cell_point);
520 jac_det(cell,old_cell_point) = hold;
522 for(
int dim=0;dim<cell_dim;++dim){
524 hold = ref_ip_coordinates(cell,new_cell_point,dim);
525 ref_ip_coordinates(cell,new_cell_point,dim) = ref_ip_coordinates(cell,old_cell_point,dim);
526 ref_ip_coordinates(cell,old_cell_point,dim) = hold;
528 hold = ip_coordinates(cell,new_cell_point,dim);
529 ip_coordinates(cell,new_cell_point,dim) = ip_coordinates(cell,old_cell_point,dim);
530 ip_coordinates(cell,old_cell_point,dim) = hold;
532 hold = surface_normals(cell,new_cell_point,dim);
533 surface_normals(cell,new_cell_point,dim) = surface_normals(cell,old_cell_point,dim);
534 surface_normals(cell,old_cell_point,dim) = hold;
536 for(
int dim2=0;dim2<cell_dim;++dim2){
538 hold =
jac(cell,new_cell_point,dim,dim2);
539 jac(cell,new_cell_point,dim,dim2) =
jac(cell,old_cell_point,dim,dim2);
540 jac(cell,old_cell_point,dim,dim2) = hold;
542 hold = jac_inv(cell,new_cell_point,dim,dim2);
543 jac_inv(cell,new_cell_point,dim,dim2) = jac_inv(cell,old_cell_point,dim,dim2);
544 jac_inv(cell,old_cell_point,dim,dim2) = hold;
549 template <
typename Scalar>
554 std::vector<int> & order)
556 for(
size_t point_index=0;point_index<order.size();++point_index){
557 order[point_index] = point_index;
563 point_sorter_t<Array_CellIPDim,Scalar> sorter(coords,cell,offset);
564 std::sort(order.begin(),order.end(),sorter);
567 template <
typename Scalar>
570 const int in_num_cells)
575 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
577 const shards::CellTopology & cell_topology = *(int_rule->topology);
580 const int num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : in_num_cells;
584 const int num_nodes = in_node_coordinates.extent(1);
585 const int num_dims = in_node_coordinates.extent(2);
587 for(
int cell=0; cell<num_cells; ++cell){
588 for(
int node=0; node<num_nodes; ++node){
589 for(
int dim=0; dim<num_dims; ++dim){
590 node_coordinates(cell,node,dim) = in_node_coordinates(cell,node,dim);
599 const int cell_dim = cell_topology.getDimension();
600 const int subcell_dim = cell_topology.getDimension()-1;
601 const int num_subcells = cell_topology.getSubcellCount(subcell_dim);
603 Intrepid2::DefaultCubatureFactory cubature_factory;
608 for(
int subcell_index=0; subcell_index<num_subcells; ++subcell_index) {
611 int num_points_on_face = 1;
614 Kokkos::DynRankView<double,PHX::Device> tmp_side_cub_weights;
615 Kokkos::DynRankView<double,PHX::Device> tmp_side_cub_points;
617 tmp_side_cub_weights = Kokkos::DynRankView<double,PHX::Device>(
"tmp_side_cub_weights",num_points_on_face);
618 tmp_side_cub_points = Kokkos::DynRankView<double,PHX::Device>(
"cell_tmp_side_cub_points",num_points_on_face,cell_dim);
619 tmp_side_cub_weights(0)=1.;
620 tmp_side_cub_points(0,0) = (subcell_index==0)? -1. : 1.;
624 const shards::CellTopology face_topology(cell_topology.getCellTopologyData(subcell_dim,subcell_index));
626 auto ic = cubature_factory.create<PHX::Device::execution_space,double,
double>(face_topology,ir.
getOrder());
627 num_points_on_face = ic->getNumPoints();
629 tmp_side_cub_weights = Kokkos::DynRankView<double,PHX::Device>(
"tmp_side_cub_weights",num_points_on_face);
630 tmp_side_cub_points = Kokkos::DynRankView<double,PHX::Device>(
"cell_tmp_side_cub_points",num_points_on_face,cell_dim);
632 auto subcell_cub_points = Kokkos::DynRankView<double,PHX::Device>(
"subcell_cub_points",num_points_on_face,subcell_dim);
635 ic->getCubature(subcell_cub_points, tmp_side_cub_weights);
638 cell_tools.mapToReferenceSubcell(tmp_side_cub_points,
646 for(
int local_point=0;local_point<num_points_on_face;++local_point){
647 const int point = point_offset + local_point;
648 for(
int dim=0;dim<cell_dim;++dim){
649 cub_points(point,dim) = tmp_side_cub_points(local_point,dim);
655 auto side_ip_coordinates = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_ip_coordinates",num_cells,num_points_on_face,cell_dim);
656 auto s_node_coordinates = Kokkos::subview(node_coordinates.get_view(),std::make_pair(0,num_cells),Kokkos::ALL,Kokkos::ALL);
657 cell_tools.mapToPhysicalFrame(side_ip_coordinates,
663 auto side_jacobian = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_jac",num_cells,num_points_on_face,cell_dim,cell_dim);
664 cell_tools.setJacobian(side_jacobian,
669 auto side_inverse_jacobian = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_inv_jac",num_cells,num_points_on_face,cell_dim,cell_dim);
670 cell_tools.setJacobianInv(side_inverse_jacobian, side_jacobian);
672 auto side_det_jacobian = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_det_jac",num_cells,num_points_on_face);
673 cell_tools.setJacobianDet(side_det_jacobian, side_jacobian);
676 auto side_weighted_measure = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_weighted_measure",num_cells,num_points_on_face);
678 Kokkos::deep_copy(side_weighted_measure, tmp_side_cub_weights(0));
679 }
else if(cell_dim == 2){
680 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
681 computeEdgeMeasure(side_weighted_measure, side_jacobian, tmp_side_cub_weights,
682 subcell_index,cell_topology,
683 scratch_for_compute_side_measure.get_view());
684 }
else if(cell_dim == 3){
685 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
686 computeFaceMeasure(side_weighted_measure, side_jacobian, tmp_side_cub_weights,
687 subcell_index,cell_topology,
688 scratch_for_compute_side_measure.get_view());
692 auto side_normals = Kokkos::DynRankView<Scalar,PHX::Device>(
"side_normals",num_cells,num_points_on_face,cell_dim);
695 int other_subcell_index = (subcell_index==0) ? 1 : 0;
697 for(
int cell=0;cell<num_cells;++cell){
698 Scalar norm = (in_node_coordinates(cell,subcell_index,0) - in_node_coordinates(cell,other_subcell_index,0));
699 side_normals(cell,0,0) = norm / fabs(norm+std::numeric_limits<
typename Sacado::ScalarType<Scalar>::type>::min());
704 cell_tools.getPhysicalSideNormals(side_normals,side_jacobian,subcell_index,cell_topology);
707 for(
int cell=0;cell<num_cells;++cell){
708 for(
int point=0;point<num_points_on_face;++point){
710 for(
int dim=0;dim<cell_dim;++dim){
711 n += side_normals(cell,point,dim)*side_normals(cell,point,dim);
716 for(
int dim=0;dim<cell_dim;++dim){
717 side_normals(cell,point,dim) /= n;
727 for(
int cell=0;cell<num_cells;++cell){
728 for(
int side_point=0; side_point<num_points_on_face;++side_point){
729 const int cell_point = point_offset + side_point;
731 weighted_measure(cell,cell_point) = side_weighted_measure(cell,side_point);
732 jac_det(cell,cell_point) = side_det_jacobian(cell,side_point);
733 for(
int dim=0;dim<cell_dim;++dim){
734 ref_ip_coordinates(cell,cell_point,dim) = cub_points(cell_point,dim);
735 ip_coordinates(cell,cell_point,dim) = side_ip_coordinates(cell,side_point,dim);
736 surface_normals(cell,cell_point,dim) = side_normals(cell,side_point,dim);
738 for(
int dim2=0;dim2<cell_dim;++dim2){
739 jac(cell,cell_point,dim,dim2) = side_jacobian(cell,side_point,dim,dim2);
740 jac_inv(cell,cell_point,dim,dim2) = side_inverse_jacobian(cell,side_point,dim,dim2);
745 point_offset += num_points_on_face;
751 for(
int subcell_index=0; subcell_index<num_subcells;++subcell_index){
754 const int num_points_on_face = ir.
getPointOffset(subcell_index+1) - point_offset;
755 std::vector<int> point_indexes(num_points_on_face,-1);
757 for(
int cell=0; cell<num_cells; ++cell){
760 uniqueCoordOrdering(ip_coordinates,cell,point_offset,point_indexes);
763 reorder(point_indexes,[=](
int a,
int b) { swapQuadraturePoints(cell,point_offset+a,point_offset+b); });
771 Scalar transverse[3];
773 for(
int i=0;i<3;i++){normal[i]=0.;}
774 for(
int i=0;i<3;i++){transverse[i]=0.;}
775 for(
int i=0;i<3;i++){binormal[i]=0.;}
776 for(
int cell=0; cell<num_cells; ++cell){
777 for(
int subcell_index=0; subcell_index<num_subcells; ++subcell_index){
778 for(
int point=0; point<num_points; ++point){
780 for(
int dim=0; dim<3; ++dim)
783 for(
int dim=0; dim<cell_dim; ++dim){
784 normal[dim] = surface_normals(cell,point,dim);
787 convertNormalToRotationMatrix(normal,transverse,binormal);
789 for(
int dim=0; dim<3; ++dim){
790 surface_rotation_matrices(cell,point,0,dim) = normal[dim];
791 surface_rotation_matrices(cell,point,1,dim) = transverse[dim];
792 surface_rotation_matrices(cell,point,2,dim) = binormal[dim];
802 for (
int cell = 0; cell < num_cells; ++cell) {
803 for (
size_type ip = 0; ip < contravarient.extent(1); ++ip) {
806 for (
size_type i = 0; i < contravarient.extent(2); ++i)
807 for (
size_type j = 0; j < contravarient.extent(3); ++j)
808 covarient(cell,ip,i,j) = 0.0;
811 for (
size_type i = 0; i < contravarient.extent(2); ++i) {
812 for (
size_type j = 0; j < contravarient.extent(3); ++j) {
813 for (
size_type alpha = 0; alpha < contravarient.extent(2); ++alpha) {
814 covarient(cell,ip,i,j) +=
jac(cell,ip,i,alpha) *
jac(cell,ip,j,alpha);
822 auto s_contravarient = Kokkos::subview(contravarient.get_view(), std::make_pair(0,num_cells),Kokkos::ALL,Kokkos::ALL,Kokkos::ALL);
823 auto s_covarient = Kokkos::subview(covarient.get_view(), std::make_pair(0,num_cells),Kokkos::ALL,Kokkos::ALL,Kokkos::ALL);
824 Intrepid2::RealSpaceTools<PHX::Device::execution_space>::inverse(s_contravarient, s_covarient);
827 for (
int cell = 0; cell < num_cells; ++cell) {
828 for (
size_type ip = 0; ip < contravarient.extent(1); ++ip) {
829 norm_contravarient(cell,ip) = 0.0;
830 for (
size_type i = 0; i < contravarient.extent(2); ++i) {
831 for (
size_type j = 0; j < contravarient.extent(3); ++j) {
832 norm_contravarient(cell,ip) += contravarient(cell,ip,i,j) * contravarient(cell,ip,i,j);
835 norm_contravarient(cell,ip) = std::sqrt(norm_contravarient(cell,ip));
842 template <
typename Scalar>
845 const int in_num_cells)
847 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
851 size_type num_ip = dyn_cub_points.extent(0);
852 size_type num_dims = dyn_cub_points.extent(1);
854 for (
size_type ip = 0; ip < num_ip; ++ip) {
855 cub_weights(ip) = dyn_cub_weights(ip);
856 for (
size_type dim = 0; dim < num_dims; ++dim)
857 cub_points(ip,dim) = dyn_cub_points(ip,dim);
861 if (int_rule->isSide()) {
862 const size_type num_ip = dyn_cub_points.extent(0), num_side_dims = dyn_side_cub_points.extent(1);
863 for (
size_type ip = 0; ip < num_ip; ++ip)
864 for (
size_type dim = 0; dim < num_side_dims; ++dim)
865 side_cub_points(ip,dim) = dyn_side_cub_points(ip,dim);
868 const int num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : in_num_cells;
871 size_type num_nodes = in_node_coordinates.extent(1);
872 size_type num_dims = in_node_coordinates.extent(2);
874 for (
int cell = 0; cell < num_cells; ++cell) {
875 for (
size_type node = 0; node < num_nodes; ++node) {
876 for (
size_type dim = 0; dim < num_dims; ++dim) {
877 node_coordinates(cell,node,dim) =
878 in_node_coordinates(cell,node,dim);
884 auto s_in_node_coordinates = Kokkos::subview(in_node_coordinates.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL());
885 auto s_jac = Kokkos::subview(
jac.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
886 cell_tools.setJacobian(
jac.get_view(),
887 cub_points.get_view(),
888 node_coordinates.get_view(),
889 *(int_rule->topology));
891 auto s_jac_inv = Kokkos::subview(jac_inv.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
892 cell_tools.setJacobianInv(s_jac_inv, s_jac);
894 auto s_jac_det = Kokkos::subview(jac_det.get_view(),std::make_pair(0,num_cells),Kokkos::ALL());
895 cell_tools.setJacobianDet(s_jac_det, s_jac);
897 auto s_weighted_measure = Kokkos::subview(weighted_measure.get_view(),std::make_pair(0,num_cells),Kokkos::ALL());
898 if (!int_rule->isSide()) {
899 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
900 computeCellMeasure(s_weighted_measure, s_jac_det, cub_weights.get_view());
902 else if(int_rule->spatial_dimension==3) {
903 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
904 computeFaceMeasure(s_weighted_measure, s_jac, cub_weights.get_view(),
905 int_rule->side, *int_rule->topology,
906 scratch_for_compute_side_measure.get_view());
908 else if(int_rule->spatial_dimension==2) {
909 Intrepid2::FunctionSpaceTools<PHX::Device::execution_space>::
910 computeEdgeMeasure(s_weighted_measure, s_jac, cub_weights.get_view(),
911 int_rule->side,*int_rule->topology,
912 scratch_for_compute_side_measure.get_view());
917 for (
int cell = 0; cell < num_cells; ++cell) {
918 for (
size_type ip = 0; ip < contravarient.extent(1); ++ip) {
921 for (
size_type i = 0; i < contravarient.extent(2); ++i)
922 for (
size_type j = 0; j < contravarient.extent(3); ++j)
923 covarient(cell,ip,i,j) = 0.0;
926 for (
size_type i = 0; i < contravarient.extent(2); ++i) {
927 for (
size_type j = 0; j < contravarient.extent(3); ++j) {
928 for (
size_type alpha = 0; alpha < contravarient.extent(2); ++alpha) {
929 covarient(cell,ip,i,j) +=
jac(cell,ip,i,alpha) *
jac(cell,ip,j,alpha);
937 auto s_covarient = Kokkos::subview(covarient.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
938 auto s_contravarient = Kokkos::subview(contravarient.get_view(),std::make_pair(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
939 Intrepid2::RealSpaceTools<PHX::Device::execution_space>::inverse(s_contravarient, s_covarient);
942 for (
int cell = 0; cell < num_cells; ++cell) {
943 for (
size_type ip = 0; ip < contravarient.extent(1); ++ip) {
944 norm_contravarient(cell,ip) = 0.0;
945 for (
size_type i = 0; i < contravarient.extent(2); ++i) {
946 for (
size_type j = 0; j < contravarient.extent(3); ++j) {
947 norm_contravarient(cell,ip) += contravarient(cell,ip,i,j) * contravarient(cell,ip,i,j);
950 norm_contravarient(cell,ip) = std::sqrt(norm_contravarient(cell,ip));
958 template <
typename Scalar>
961 const PHX::MDField<Scalar,Cell,IP,Dim>& other_coords,
962 std::vector<
typename ArrayTraits<Scalar,PHX::MDField<Scalar> >::size_type>& permutation)
968 const size_type cell = 0;
969 const size_type num_ip = coords.extent(1), num_dim = coords.extent(2);
970 permutation.resize(num_ip);
971 std::vector<char> taken(num_ip, 0);
972 for (size_type ip = 0; ip < num_ip; ++ip) {
976 for (size_type other_ip = 0; other_ip < num_ip; ++other_ip) {
978 if (taken[other_ip])
continue;
981 for (size_type dim = 0; dim < num_dim; ++dim) {
982 const Scalar diff = coords(cell, ip, dim) - other_coords(cell, other_ip, dim);
985 if (d_min < 0 || d < d_min) {
991 permutation[ip] = i_min;
997 template <
typename Scalar>
1000 const PHX::MDField<Scalar,Cell,IP,Dim>& other_ip_coordinates,
1001 const int in_num_cells)
1003 const int num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : in_num_cells;
1005 if (int_rule->cv_type ==
"none") {
1007 getCubature(in_node_coordinates, in_num_cells);
1011 std::vector<size_type> permutation(other_ip_coordinates.extent(1));
1012 permuteToOther(ip_coordinates, other_ip_coordinates, permutation);
1016 const size_type num_ip = dyn_cub_points.extent(0);
1018 const size_type num_dim = dyn_side_cub_points.extent(1);
1019 DblArrayDynamic old_dyn_side_cub_points = af.template buildArray<double,IP,Dim>(
1020 "old_dyn_side_cub_points", num_ip, num_dim);
1021 old_dyn_side_cub_points.deep_copy(dyn_side_cub_points);
1022 for (
size_type ip = 0; ip < num_ip; ++ip)
1023 if (ip != permutation[ip])
1024 for (
size_type dim = 0; dim < num_dim; ++dim)
1025 dyn_side_cub_points(ip, dim) = old_dyn_side_cub_points(permutation[ip], dim);
1028 const size_type num_dim = dyn_cub_points.extent(1);
1029 DblArrayDynamic old_dyn_cub_points = af.template buildArray<double,IP,Dim>(
1030 "old_dyn_cub_points", num_ip, num_dim);
1031 old_dyn_cub_points.deep_copy(dyn_cub_points);
1032 for (
size_type ip = 0; ip < num_ip; ++ip)
1033 if (ip != permutation[ip])
1034 for (
size_type dim = 0; dim < num_dim; ++dim)
1035 dyn_cub_points(ip, dim) = old_dyn_cub_points(permutation[ip], dim);
1038 DblArrayDynamic old_dyn_cub_weights = af.template buildArray<double,IP>(
1039 "old_dyn_cub_weights", num_ip);
1040 old_dyn_cub_weights.deep_copy(dyn_cub_weights);
1041 for (
size_type ip = 0; ip < dyn_cub_weights.extent(0); ++ip)
1042 if (ip != permutation[ip])
1043 dyn_cub_weights(ip) = old_dyn_cub_weights(permutation[ip]);
1047 const size_type num_ip = ip_coordinates.extent(1);
1048 const size_type num_dim = ip_coordinates.extent(2);
1049 Array_CellIPDim old_ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
1050 "old_ip_coordinates", ip_coordinates.extent(0), num_ip, num_dim);
1051 Kokkos::deep_copy(old_ip_coordinates.get_static_view(), ip_coordinates.get_static_view());
1052 for (
int cell = 0; cell < num_cells; ++cell)
1053 for (
size_type ip = 0; ip < num_ip; ++ip)
1054 if (ip != permutation[ip])
1055 for (
size_type dim = 0; dim < num_dim; ++dim)
1056 ip_coordinates(cell, ip, dim) = old_ip_coordinates(cell, permutation[ip], dim);
1061 evaluateRemainingValues(in_node_coordinates, in_num_cells);
1066 getCubatureCV(in_node_coordinates, in_num_cells);
1069 std::vector<size_type> permutation(other_ip_coordinates.extent(1));
1070 permuteToOther(ip_coordinates, other_ip_coordinates, permutation);
1075 const size_type workset_size = ip_coordinates.extent(0), num_ip = ip_coordinates.extent(1),
1076 num_dim = ip_coordinates.extent(2);
1077 Array_CellIPDim old_ip_coordinates = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
1078 "old_ip_coordinates", workset_size, num_ip, num_dim);
1079 Kokkos::deep_copy(old_ip_coordinates.get_static_view(), ip_coordinates.get_static_view());
1080 Array_CellIPDim old_weighted_normals = af.template buildStaticArray<Scalar,Cell,IP,Dim>(
1081 "old_weighted_normals", workset_size, num_ip, num_dim);
1082 Array_CellIP old_weighted_measure = af.template buildStaticArray<Scalar,Cell,IP>(
1083 "old_weighted_measure", workset_size, num_ip);
1084 if (int_rule->cv_type ==
"side")
1085 Kokkos::deep_copy(old_weighted_normals.get_static_view(), weighted_normals.get_static_view());
1087 Kokkos::deep_copy(old_weighted_measure.get_static_view(), weighted_measure.get_static_view());
1088 for (
int cell = 0; cell < num_cells; ++cell)
1090 for (
size_type ip = 0; ip < num_ip; ++ip)
1092 if (ip != permutation[ip]) {
1093 if (int_rule->cv_type ==
"boundary" || int_rule->cv_type ==
"volume")
1094 weighted_measure(cell, ip) = old_weighted_measure(cell, permutation[ip]);
1095 for (
size_type dim = 0; dim < num_dim; ++dim)
1097 ip_coordinates(cell, ip, dim) = old_ip_coordinates(cell, permutation[ip], dim);
1098 if (int_rule->cv_type ==
"side")
1099 weighted_normals(cell, ip, dim) = old_weighted_normals(cell, permutation[ip], dim);
1107 evaluateValuesCV(in_node_coordinates, in_num_cells);
1111 template <
typename Scalar>
1114 const int in_num_cells)
1116 int num_space_dim = int_rule->topology->getDimension();
1117 if (int_rule->isSide() && num_space_dim==1) {
1118 std::cout <<
"WARNING: 0-D quadrature rule infrastructure does not exist!!! Will not be able to do "
1119 <<
"non-natural integration rules.";
1123 size_type num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : (
size_type) in_num_cells;
1124 std::pair<int,int> cell_range(0,num_cells);
1126 size_type num_nodes = in_node_coordinates.extent(1);
1127 size_type num_dims = in_node_coordinates.extent(2);
1129 for (
size_type cell = 0; cell < num_cells; ++cell) {
1130 for (
size_type node = 0; node < num_nodes; ++node) {
1131 for (
size_type dim = 0; dim < num_dims; ++dim) {
1132 node_coordinates(cell,node,dim) =
1133 in_node_coordinates(cell,node,dim);
1134 dyn_node_coordinates(cell,node,dim) =
1135 Sacado::ScalarValue<Scalar>::eval(in_node_coordinates(cell,node,dim));
1141 auto s_dyn_phys_cub_points = Kokkos::subdynrankview(dyn_phys_cub_points.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1142 auto s_dyn_node_coordinates = Kokkos::subdynrankview(dyn_node_coordinates.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1143 if (int_rule->cv_type ==
"side") {
1144 auto s_dyn_phys_cub_norms = Kokkos::subdynrankview(dyn_phys_cub_norms.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1145 intrepid_cubature->getCubature(s_dyn_phys_cub_points,s_dyn_phys_cub_norms,s_dyn_node_coordinates);
1148 auto s_dyn_phys_cub_weights = Kokkos::subdynrankview(dyn_phys_cub_weights.get_view(),cell_range,Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1149 intrepid_cubature->getCubature(s_dyn_phys_cub_points,s_dyn_phys_cub_weights,s_dyn_node_coordinates);
1153 size_type num_ip =dyn_phys_cub_points.extent(1);
1154 size_type num_dims = dyn_phys_cub_points.extent(2);
1156 for (
size_type cell = 0; cell < num_cells; ++cell) {
1157 for (
size_type ip = 0; ip < num_ip; ++ip) {
1158 if (int_rule->cv_type !=
"side")
1159 weighted_measure(cell,ip) = dyn_phys_cub_weights(cell,ip);
1160 for (
size_type dim = 0; dim < num_dims; ++dim) {
1161 ip_coordinates(cell,ip,dim) = dyn_phys_cub_points(cell,ip,dim);
1162 if (int_rule->cv_type ==
"side")
1163 weighted_normals(cell,ip,dim) = dyn_phys_cub_norms(cell,ip,dim);
1170 template <
typename Scalar>
1173 const int in_num_cells)
1176 Intrepid2::CellTools<PHX::Device::execution_space> cell_tools;
1178 size_type num_cells = in_num_cells < 0 ? in_node_coordinates.extent(0) : (
size_type) in_num_cells;
1180 auto s_ref_ip_coordinates = Kokkos::subview(ref_ip_coordinates.get_view(),std::make_pair(0,(
int)num_cells),Kokkos::ALL(),Kokkos::ALL());
1181 auto s_ip_coordinates = Kokkos::subview(ip_coordinates.get_view(),std::make_pair<int,int>(0,num_cells),Kokkos::ALL(),Kokkos::ALL());
1182 auto s_node_coordinates = Kokkos::subview(node_coordinates.get_view(),std::make_pair<int,int>(0,num_cells),Kokkos::ALL(),Kokkos::ALL());
1184 cell_tools.mapToReferenceFrame(s_ref_ip_coordinates,
1187 *(int_rule->topology));
1189 auto s_jac = Kokkos::subview(
jac.get_view(),std::make_pair<int,int>(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1191 cell_tools.setJacobian(s_jac,
1192 s_ref_ip_coordinates,
1194 *(int_rule->topology));
1196 auto s_jac_inv = Kokkos::subview(jac_inv.get_view(),std::make_pair<int,int>(0,num_cells),Kokkos::ALL(),Kokkos::ALL(),Kokkos::ALL());
1198 cell_tools.setJacobianInv(s_jac_inv, s_jac);
1200 auto s_jac_det = Kokkos::subview(jac_det.get_view(),std::make_pair<int,int>(0,num_cells),Kokkos::ALL());
1202 cell_tools.setJacobianDet(s_jac_det, s_jac);
1205 #define INTEGRATION_VALUES2_INSTANTIATION(SCALAR) \
1206 template class IntegrationValues2<SCALAR>;
static void convertNormalToRotationMatrix(const Scalar normal[3], Scalar transverse[3], Scalar binormal[3])
static void uniqueCoordOrdering(Array_CellIPDim &coords, int cell, int offset, std::vector< int > &order)
Using coordinate build an arrray that specifies a unique ordering.
PHX::MDField< Scalar, Cell, IP > Array_CellIP
void evaluateValuesCV(const PHX::MDField< Scalar, Cell, NODE, Dim > &vertex_coordinates, const int in_num_cells)
const int & getType() const
Get type of integrator.
void generateSurfaceCubatureValues(const PHX::MDField< Scalar, Cell, NODE, Dim > &in_node_coordinates, const int in_num_cells)
void swapQuadraturePoints(int cell, int a, int b)
Swap the ordering of quadrature points in a specified cell.
void getCubatureCV(const PHX::MDField< Scalar, Cell, NODE, Dim > &in_node_coordinates, const int in_num_cells)
#define INTEGRATION_VALUES2_INSTANTIATION(SCALAR)
int getPointOffset(const int subcell_index) const
Returns the integration point offset for a given subcell_index (i.e. local face index) ...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void evaluateValues(const PHX::MDField< Scalar, Cell, NODE, Dim > &vertex_coordinates, const int num_cells=-1)
Evaluate basis values.
Teuchos::RCP< const shards::CellTopology > topology
void evaluateRemainingValues(const PHX::MDField< Scalar, Cell, NODE, Dim > &in_node_coordinates, const int in_num_cells)
ArrayTraits< Scalar, PHX::MDField< Scalar > >::size_type size_type
void setupArrays(const Teuchos::RCP< const panzer::IntegrationRule > &ir)
Sizes/allocates memory for arrays.
const int & getSide() const
Get side associated with integration - this is for backward compatibility.
void getCubature(const PHX::MDField< Scalar, Cell, NODE, Dim > &in_node_coordinates, const int in_num_cells)
PHX::MDField< Scalar, Cell, IP, Dim > Array_CellIPDim
void reorder(std::vector< int > &order, std::function< void(int, int)> swapper)
Using a functor, reorder an array using a order vector.
Teuchos::RCP< Intrepid2::Cubature< PHX::Device::execution_space, double, double > > getIntrepidCubature(const panzer::IntegrationRule &ir) const
PHX::MDField< double > DblArrayDynamic
Teuchos::RCP< shards::CellTopology > side_topology
#define TEUCHOS_ASSERT(assertion_test)
static void permuteToOther(const PHX::MDField< Scalar, Cell, IP, Dim > &coords, const PHX::MDField< Scalar, Cell, IP, Dim > &other_coords, std::vector< typename ArrayTraits< Scalar, PHX::MDField< Scalar > >::size_type > &permutation)
void setupArraysForNodeRule(const Teuchos::RCP< const panzer::IntegrationRule > &ir)
const int & getOrder() const
Get order of integrator.