51 #include <Teuchos_RCP.hpp> 52 #include <Teuchos_ScalarTraits.hpp> 53 #include <Teuchos_as.hpp> 55 #include <Shards_BasicTopologies.hpp> 57 #include <Intrepid_RealSpaceTools.hpp> 69 const shards::CellTopology &cell_topo,
70 Intrepid::FieldContainer<double> &cell_center )
72 DTK_REQUIRE( 2 == cell_center.rank() );
73 DTK_REQUIRE( Teuchos::as<unsigned>( cell_center.dimension( 1 ) ) ==
74 cell_topo.getDimension() );
76 int num_cells = cell_center.dimension( 0 );
78 switch ( cell_topo.getKey() )
80 case shards::Line<2>::key:
81 case shards::Line<3>::key:
82 for (
int n = 0; n < num_cells; ++n )
84 cell_center( n, 0 ) = Teuchos::ScalarTraits<double>::zero();
88 case shards::Triangle<3>::key:
89 case shards::Triangle<4>::key:
90 case shards::Triangle<6>::key:
91 for (
int n = 0; n < num_cells; ++n )
94 cell_center( n, 0 ) = 1.0 / 3.0;
95 cell_center( n, 1 ) = 1.0 / 3.0;
99 case shards::Quadrilateral<4>::key:
100 case shards::Quadrilateral<8>::key:
101 case shards::Quadrilateral<9>::key:
102 for (
int n = 0; n < num_cells; ++n )
104 cell_center( n, 0 ) = Teuchos::ScalarTraits<double>::zero();
105 cell_center( n, 1 ) = Teuchos::ScalarTraits<double>::zero();
109 case shards::Tetrahedron<4>::key:
110 case shards::Tetrahedron<10>::key:
111 case shards::Tetrahedron<11>::key:
112 for (
int n = 0; n < num_cells; ++n )
114 cell_center( n, 0 ) = 1.0 / 6.0;
115 cell_center( n, 1 ) = 1.0 / 6.0;
116 cell_center( n, 2 ) = 1.0 / 6.0;
120 case shards::Hexahedron<8>::key:
121 case shards::Hexahedron<20>::key:
122 case shards::Hexahedron<27>::key:
123 for (
int n = 0; n < num_cells; ++n )
125 cell_center( n, 0 ) = Teuchos::ScalarTraits<double>::zero();
126 cell_center( n, 1 ) = Teuchos::ScalarTraits<double>::zero();
127 cell_center( n, 2 ) = Teuchos::ScalarTraits<double>::zero();
131 case shards::Wedge<6>::key:
132 case shards::Wedge<15>::key:
133 case shards::Wedge<18>::key:
134 for (
int n = 0; n < num_cells; ++n )
136 cell_center( n, 0 ) = 1.0 / 3.0;
137 cell_center( n, 1 ) = 1.0 / 3.0;
138 cell_center( n, 2 ) = Teuchos::ScalarTraits<double>::zero();
142 case shards::Pyramid<5>::key:
143 case shards::Pyramid<13>::key:
144 case shards::Pyramid<14>::key:
145 for (
int n = 0; n < num_cells; ++n )
147 cell_center( n, 0 ) = Teuchos::ScalarTraits<double>::zero();
148 cell_center( n, 1 ) = Teuchos::ScalarTraits<double>::zero();
149 cell_center( n, 2 ) = 1.0 / 4.0;
154 bool cell_topo_supported =
false;
155 DTK_INSIST( cell_topo_supported );
177 const Teuchos::ParameterList ¶meters,
178 const Intrepid::FieldContainer<double> &point,
179 const Intrepid::FieldContainer<double> &face_nodes,
180 const Intrepid::FieldContainer<double> &face_node_normals,
181 const shards::CellTopology &face_topology )
183 DTK_REQUIRE( 1 == point.rank() );
184 DTK_REQUIRE( 2 == face_nodes.rank() );
185 DTK_REQUIRE( 2 == face_node_normals.rank() );
186 DTK_REQUIRE( point.dimension( 0 ) == face_nodes.dimension( 1 ) );
187 DTK_REQUIRE( point.dimension( 0 ) == face_node_normals.dimension( 1 ) );
188 DTK_REQUIRE( face_nodes.dimension( 0 ) ==
189 face_node_normals.dimension( 0 ) );
190 DTK_REQUIRE( Teuchos::as<unsigned>( face_nodes.dimension( 0 ) ) ==
191 face_topology.getNodeCount() );
194 int space_dim = point.dimension( 0 );
195 DTK_CHECK( 3 == space_dim );
198 double geometric_tolerance =
199 parameters.get<
double>(
"Geometric Tolerance" );
206 Intrepid::FieldContainer<double> face_edge_nodes( 2, space_dim );
207 Intrepid::FieldContainer<double> face_edge_node_normals( 2, space_dim );
208 double distance_to_surface = 0.0;
209 int face_num_edges = face_nodes.dimension( 0 );
212 for (
int e = 0; e < face_num_edges - 1; ++e )
214 for (
int i = 0; i < space_dim; ++i )
216 face_edge_nodes( 0, i ) = face_nodes( e, i );
217 face_edge_nodes( 1, i ) = face_nodes( e + 1, i );
218 face_edge_node_normals( 0, i ) = face_node_normals( e, i );
219 face_edge_node_normals( 1, i ) = face_node_normals( e + 1, i );
221 distance_to_surface = distanceToFaceBilinearSurface(
222 parameters, point, face_edge_nodes, face_edge_node_normals );
223 if ( distance_to_surface > geometric_tolerance )
230 for (
int i = 0; i < space_dim; ++i )
232 face_edge_nodes( 0, i ) = face_nodes( face_num_edges - 1, i );
233 face_edge_nodes( 1, i ) = face_nodes( 0, i );
234 face_edge_node_normals( 0, i ) =
235 face_node_normals( face_num_edges - 1, i );
236 face_edge_node_normals( 1, i ) = face_node_normals( 0, i );
238 distance_to_surface = distanceToFaceBilinearSurface(
239 parameters, point, face_edge_nodes, face_edge_node_normals );
240 if ( distance_to_surface > geometric_tolerance )
280 const Teuchos::ParameterList ¶meters,
281 const Intrepid::FieldContainer<double> &point,
282 const Intrepid::FieldContainer<double> &face_nodes,
283 const Intrepid::FieldContainer<double> &face_node_normals,
284 const shards::CellTopology &face_topology,
285 Intrepid::FieldContainer<double> ¶metric_point,
286 Intrepid::FieldContainer<double> &physical_point,
int &face_edge_id,
289 DTK_REQUIRE( 1 == point.rank() );
290 DTK_REQUIRE( 2 == face_nodes.rank() );
291 DTK_REQUIRE( 2 == face_node_normals.rank() );
292 DTK_REQUIRE( 1 == physical_point.rank() );
293 DTK_REQUIRE( point.dimension( 0 ) == face_nodes.dimension( 1 ) );
294 DTK_REQUIRE( point.dimension( 0 ) == face_node_normals.dimension( 1 ) );
295 DTK_REQUIRE( point.dimension( 0 ) == physical_point.dimension( 0 ) );
296 DTK_REQUIRE( face_nodes.dimension( 0 ) ==
297 face_node_normals.dimension( 0 ) );
298 DTK_REQUIRE( Teuchos::as<unsigned>( face_nodes.dimension( 0 ) ) ==
299 face_topology.getNodeCount() );
300 DTK_REQUIRE( 2 == parametric_point.rank() );
301 DTK_REQUIRE( 1 == parametric_point.dimension( 0 ) );
302 DTK_REQUIRE( point.dimension( 0 ) == parametric_point.dimension( 1 ) );
305 int space_dim = point.dimension( 0 );
306 int topo_dim = face_topology.getDimension();
309 double geometric_tolerance =
310 parameters.get<
double>(
"Geometric Tolerance" );
313 double newton_tolerance = parameters.get<
double>(
"Newton Tolerance" );
316 double max_newton_iters = parameters.get<
int>(
"Max Newton Iterations" );
319 Teuchos::RCP<Intrepid::Basis<double, Intrepid::FieldContainer<double>>>
320 face_basis = IntrepidBasisFactory::create( face_topology );
323 parametric_point.initialize( 0.0 );
328 Intrepid::FieldContainer<double> face_center( num_points, topo_dim );
330 for (
int n = 0; n < topo_dim; ++n )
332 parametric_point( 0, n ) = face_center( 0, n );
334 parametric_point( 0, topo_dim ) = Teuchos::ScalarTraits<double>::zero();
338 face_basis, point, face_nodes, face_node_normals );
342 parametric_point, nonlinear_problem, newton_tolerance,
347 if ( std::abs( parametric_point( 0, 0 ) ) < geometric_tolerance )
349 parametric_point( 0, 0 ) = 0.0;
351 else if ( std::abs( 1.0 - parametric_point( 0, 0 ) ) < geometric_tolerance )
353 parametric_point( 0, 0 ) = 1.0;
355 else if ( std::abs( 1.0 + parametric_point( 0, 0 ) ) < geometric_tolerance )
357 parametric_point( 0, 0 ) = -1.0;
359 if ( std::abs( parametric_point( 0, 1 ) ) < geometric_tolerance )
361 parametric_point( 0, 1 ) = 0.0;
363 else if ( std::abs( 1.0 - parametric_point( 0, 1 ) ) < geometric_tolerance )
365 parametric_point( 0, 1 ) = 1.0;
367 else if ( std::abs( 1.0 + parametric_point( 0, 1 ) ) < geometric_tolerance )
369 parametric_point( 0, 1 ) = -1.0;
372 if ( std::abs( 1.0 - parametric_point( 0, 0 ) - parametric_point( 0, 1 ) ) <
373 geometric_tolerance )
375 parametric_point( 0, 0 ) = 1.0 - parametric_point( 0, 1 );
381 for (
int d = 0; d < space_dim; ++d )
383 physical_point( d ) = 0.0;
384 for (
int n = 0; n < nonlinear_problem.d_cardinality; ++n )
386 physical_point( d ) +=
387 nonlinear_problem.d_basis_evals( n, 0 ) * face_nodes( n, d );
396 if ( ( shards::Triangle<3>::key == face_topology.getKey() ) ||
397 ( shards::Triangle<4>::key == face_topology.getKey() ) ||
398 ( shards::Triangle<6>::key == face_topology.getKey() ) )
400 if ( ( 0.0 == parametric_point( 0, 0 ) ) &&
401 ( 0.0 == parametric_point( 0, 1 ) ) )
405 else if ( ( 1.0 == parametric_point( 0, 0 ) ) &&
406 ( 0.0 == parametric_point( 0, 1 ) ) )
410 else if ( ( 0.0 == parametric_point( 0, 0 ) ) &&
411 ( 1.0 == parametric_point( 0, 1 ) ) )
415 else if ( 0.0 == parametric_point( 0, 1 ) )
419 else if ( 1.0 == parametric_point( 0, 0 ) + parametric_point( 0, 1 ) )
423 else if ( 0.0 == parametric_point( 0, 0 ) )
429 else if ( ( shards::Quadrilateral<4>::key == face_topology.getKey() ) ||
430 ( shards::Quadrilateral<8>::key == face_topology.getKey() ) ||
431 ( shards::Quadrilateral<9>::key == face_topology.getKey() ) )
433 if ( ( -1.0 == parametric_point( 0, 0 ) ) &&
434 ( -1.0 == parametric_point( 0, 1 ) ) )
438 else if ( ( 1.0 == parametric_point( 0, 0 ) ) &&
439 ( -1.0 == parametric_point( 0, 1 ) ) )
443 else if ( ( 1.0 == parametric_point( 0, 0 ) ) &&
444 ( 1.0 == parametric_point( 0, 1 ) ) )
448 else if ( ( -1.0 == parametric_point( 0, 0 ) ) &&
449 ( 1.0 == parametric_point( 0, 1 ) ) )
453 else if ( -1.0 == parametric_point( 0, 1 ) )
457 else if ( 1.0 == parametric_point( 0, 0 ) )
461 else if ( 1.0 == parametric_point( 0, 1 ) )
465 else if ( -1.0 == parametric_point( 0, 0 ) )
474 ( shards::Triangle<3>::key == face_topology.getKey() ) ||
475 ( shards::Triangle<4>::key == face_topology.getKey() ) ||
476 ( shards::Triangle<6>::key == face_topology.getKey() ) ||
477 ( shards::Quadrilateral<4>::key == face_topology.getKey() ) ||
478 ( shards::Quadrilateral<8>::key == face_topology.getKey() ) ||
479 ( shards::Quadrilateral<9>::key == face_topology.getKey() ) );
504 bool ProjectionPrimitives::projectPointFeatureToEdgeFeature(
505 const Teuchos::ParameterList ¶meters,
506 const Intrepid::FieldContainer<double> &point,
507 const Intrepid::FieldContainer<double> &point_normal,
508 const Intrepid::FieldContainer<double> &edge_nodes,
509 const Intrepid::FieldContainer<double> &edge_node_normals,
510 Intrepid::FieldContainer<double> &projected_point,
int &edge_node_id )
512 DTK_REQUIRE( 1 == point.rank() );
513 DTK_REQUIRE( 1 == point_normal.rank() );
514 DTK_REQUIRE( 2 == edge_nodes.rank() );
515 DTK_REQUIRE( 2 == edge_node_normals.rank() );
516 DTK_REQUIRE( 1 == projected_point.rank() );
517 DTK_REQUIRE( point.dimension( 0 ) == edge_nodes.dimension( 1 ) );
518 DTK_REQUIRE( point.dimension( 0 ) == edge_node_normals.dimension( 1 ) );
519 DTK_REQUIRE( point.dimension( 0 ) == projected_point.dimension( 0 ) );
520 DTK_REQUIRE( edge_nodes.dimension( 0 ) ==
521 edge_node_normals.dimension( 0 ) );
522 DTK_REQUIRE( edge_nodes.dimension( 0 ) == 2 );
525 int space_dim = point.dimension( 0 );
528 double geometric_tolerance =
529 parameters.get<
double>(
"Geometric Tolerance" );
532 double normal_tolerance = parameters.get<
double>(
"Normal Tolerance" );
535 double newton_tolerance = parameters.get<
double>(
"Newton Tolerance" );
538 double max_newton_iters = parameters.get<
int>(
"Max Newton Iterations" );
544 for (
int d = 0; d < space_dim; ++d )
546 dot_1 += point_normal( d ) * edge_node_normals( 0, d );
547 dot_2 += point_normal( d ) * edge_node_normals( 1, d );
549 if ( dot_1 > -0.5 * normal_tolerance || dot_2 > -0.5 * normal_tolerance )
555 Intrepid::FieldContainer<double> gvec( space_dim );
556 for (
int d = 0; d < space_dim; ++d )
558 gvec( d ) = edge_nodes( 1, d ) - edge_nodes( 0, d );
560 Intrepid::FieldContainer<double> normal( space_dim );
561 Intrepid::FieldContainer<double> l( space_dim );
562 Intrepid::FieldContainer<double> edge_node_binormals(
563 edge_node_normals.dimension( 0 ), edge_node_normals.dimension( 1 ) );
564 for (
int n = 0; n < 2; ++n )
566 for (
int d = 0; d < space_dim; ++d )
568 normal( d ) = edge_node_normals( n, d );
570 Intrepid::RealSpaceTools<double>::vecprod( l, normal, gvec );
571 for (
int d = 0; d < space_dim; ++d )
573 edge_node_binormals( n, d ) = l( d );
579 Intrepid::FieldContainer<double> u( num_points, space_dim );
582 for (
int n = 0; n < space_dim; ++n )
589 point, edge_nodes, edge_node_normals, edge_node_binormals );
593 u, nonlinear_problem, newton_tolerance, max_newton_iters );
596 if ( std::abs( u( 0, 0 ) ) < geometric_tolerance )
600 else if ( std::abs( 1.0 - u( 0, 0 ) ) < geometric_tolerance )
606 if ( 0.0 > u( 0, 0 ) || 1.0 < u( 0, 0 ) )
613 for (
int d = 0; d < space_dim; ++d )
615 projected_point( d ) = edge_nodes( 0, d ) + u( 0, 0 ) * gvec( d );
621 if ( u( 0, 0 ) == 0.0 )
625 else if ( u( 0, 0 ) == 1.0 )
664 const Teuchos::ParameterList ¶meters,
665 const Intrepid::FieldContainer<double> &edge_1,
666 const Intrepid::FieldContainer<double> &edge_2,
667 const Intrepid::FieldContainer<double> &edge_2_node_normals,
668 Intrepid::FieldContainer<double> &edge_1_intersection,
669 Intrepid::FieldContainer<double> &edge_2_intersection,
int &edge_1_node_id,
670 int &edge_2_node_id )
672 DTK_REQUIRE( 2 == edge_1.rank() );
673 DTK_REQUIRE( 2 == edge_2.rank() );
674 DTK_REQUIRE( 2 == edge_2_node_normals.rank() );
675 DTK_REQUIRE( 1 == edge_1_intersection.rank() );
676 DTK_REQUIRE( 1 == edge_2_intersection.rank() );
677 DTK_REQUIRE( 2 == edge_1.dimension( 0 ) );
678 DTK_REQUIRE( 2 == edge_2.dimension( 0 ) );
679 DTK_REQUIRE( 2 == edge_2_node_normals.dimension( 0 ) );
680 DTK_REQUIRE( edge_1.dimension( 1 ) == edge_2.dimension( 1 ) );
681 DTK_REQUIRE( edge_1.dimension( 1 ) == edge_2_node_normals.dimension( 1 ) );
682 DTK_REQUIRE( edge_1.dimension( 1 ) == edge_1_intersection.dimension( 0 ) );
683 DTK_REQUIRE( edge_1.dimension( 1 ) == edge_2_intersection.dimension( 0 ) );
686 double cond_tol = 1.0 / std::sqrt( std::numeric_limits<double>::epsilon() );
689 int space_dim = edge_1.dimension( 1 );
692 double geometric_tolerance =
693 parameters.get<
double>(
"Geometric Tolerance" );
696 double merge_tolerance = parameters.get<
double>(
"Merge Tolerance" );
699 Intrepid::FieldContainer<double> bvec( space_dim );
700 Intrepid::FieldContainer<double> gvec( space_dim );
701 Intrepid::FieldContainer<double> dvec( space_dim );
702 Intrepid::FieldContainer<double> d0( space_dim );
703 Intrepid::FieldContainer<double> g0minusb0( space_dim );
704 for (
int i = 0; i < space_dim; ++i )
706 bvec( i ) = edge_1( 1, i ) - edge_1( 0, i );
707 gvec( i ) = edge_2( 1, i ) - edge_2( 0, i );
708 dvec( i ) = edge_2_node_normals( 1, i ) - edge_2_node_normals( 0, i );
709 d0( i ) = edge_2_node_normals( 0, i );
710 g0minusb0( i ) = edge_2( 0, i ) - edge_1( 0, i );
719 Intrepid::FieldContainer<double> work_vec( space_dim );
720 Intrepid::RealSpaceTools<double>::vecprod( work_vec, bvec, dvec );
721 double a = Intrepid::RealSpaceTools<double>::dot( work_vec, gvec );
722 double b = Intrepid::RealSpaceTools<double>::dot( work_vec, g0minusb0 );
723 Intrepid::RealSpaceTools<double>::vecprod( work_vec, bvec, d0 );
724 b += Intrepid::RealSpaceTools<double>::dot( work_vec, gvec );
725 double c = Intrepid::RealSpaceTools<double>::dot( work_vec, g0minusb0 );
729 if ( std::abs( a ) > geometric_tolerance )
732 double sqrt_arg = b * b - 4 * a * c;
734 if ( std::abs( sqrt_arg ) < geometric_tolerance )
741 if ( sqrt_arg < 0.0 )
747 double sqrt_val = std::sqrt( sqrt_arg );
748 double beta_1 = ( -b + sqrt_val ) / ( ax2 );
749 double beta_2 = ( -b - sqrt_val ) / ( ax2 );
754 if ( std::abs( beta_1 ) < merge_tolerance )
758 else if ( std::abs( 1.0 - beta_1 ) < merge_tolerance )
762 if ( std::abs( beta_2 ) < merge_tolerance )
766 else if ( std::abs( 1.0 - beta_2 ) < merge_tolerance )
773 if ( ( beta_1 >= 0.0 && beta_1 <= 1.0 ) &&
774 ( beta_2 >= 0.0 && beta_2 <= 1.0 ) )
780 if ( beta_1 >= 0.0 && beta_1 <= 1.0 )
784 else if ( beta_2 >= 0.0 && beta_2 <= 1.0 )
796 else if ( std::abs( b ) > geometric_tolerance )
803 if ( std::abs( beta ) < merge_tolerance )
807 else if ( std::abs( 1.0 - beta ) < merge_tolerance )
819 Intrepid::FieldContainer<double> nvec( space_dim );
820 double n_length = 0.0;
821 double g_length = 0.0;
822 for (
int i = 0; i < space_dim; ++i )
824 nvec( i ) = g0minusb0( i ) + beta * gvec( i );
825 n_length += nvec( i ) * nvec( i );
826 g_length += gvec( i ) * gvec( i );
828 Intrepid::FieldContainer<double> ncrossg( space_dim );
829 Intrepid::RealSpaceTools<double>::vecprod( ncrossg, nvec, gvec );
830 double ncrossg_length = 0.0;
831 for (
int i = 0; i < space_dim; ++i )
833 ncrossg_length += ncrossg( i ) * ncrossg( i );
837 if ( ncrossg_length > geometric_tolerance &&
838 n_length > geometric_tolerance )
840 double beta_cond = std::sqrt( n_length ) * std::sqrt( g_length ) /
841 std::sqrt( ncrossg_length );
842 if ( beta_cond > cond_tol )
850 Intrepid::FieldContainer<double> l( space_dim );
851 Intrepid::RealSpaceTools<double>::scale( dvec, beta );
852 Intrepid::RealSpaceTools<double>::add( work_vec, d0, dvec );
853 Intrepid::RealSpaceTools<double>::vecprod( l, gvec, work_vec );
854 double dot1 = Intrepid::RealSpaceTools<double>::dot( l, g0minusb0 );
855 double dot2 = Intrepid::RealSpaceTools<double>::dot( l, bvec );
857 if ( std::abs( dot2 ) < geometric_tolerance )
865 if ( std::abs( alpha ) < merge_tolerance )
869 else if ( std::abs( 1.0 - alpha ) < merge_tolerance )
875 Intrepid::FieldContainer<double> lvec( space_dim );
876 double l_length = 0.0;
877 double b_length = 0.0;
878 for (
int i = 0; i < space_dim; ++i )
880 lvec( i ) = alpha * bvec( i ) - g0minusb0( i );
881 l_length += lvec( i ) * lvec( i );
882 b_length += bvec( i ) * bvec( i );
884 Intrepid::FieldContainer<double> lcrossb( space_dim );
885 Intrepid::RealSpaceTools<double>::vecprod( lcrossb, lvec, bvec );
886 double lcrossb_length = 0.0;
887 for (
int i = 0; i < space_dim; ++i )
889 lcrossb_length += lcrossb( i ) * lcrossb( i );
893 if ( lcrossb_length > geometric_tolerance &&
894 l_length > geometric_tolerance )
896 double alpha_cond = std::sqrt( l_length ) * std::sqrt( b_length ) /
897 std::sqrt( lcrossb_length );
898 if ( alpha_cond > cond_tol )
905 if ( alpha < 0.0 || alpha > 1.0 )
911 if ( beta < 0.0 || beta > 1.0 )
917 for (
int i = 0; i < space_dim; ++i )
919 edge_2_intersection( i ) = edge_2( 0, i ) + beta * gvec( i );
923 for (
int i = 0; i < space_dim; ++i )
925 edge_1_intersection( i ) = edge_1( 0, i ) + alpha * bvec( i );
929 double d_length = 0.0;
930 Intrepid::FieldContainer<double> v_vec( space_dim );
931 for (
int i = 0; i < space_dim; ++i )
933 d_length += work_vec( i ) * work_vec( i );
934 v_vec( i ) = edge_1_intersection( i ) - edge_2_intersection( i );
936 d_length *= -d_length;
938 for (
int i = 0; i < space_dim; ++i )
940 v_vec( i ) *= d_length;
942 double v_length = 0.0;
943 for (
int i = 0; i < space_dim; ++i )
945 v_length += v_vec( i ) * v_vec( i );
947 double error = std::sqrt( v_length ) /
948 std::min( std::sqrt( b_length ), std::sqrt( g_length ) );
949 if ( error > cond_tol || b_length < geometric_tolerance ||
950 g_length < geometric_tolerance )
960 else if ( 1.0 == alpha )
974 else if ( 1.0 == beta )
1004 typename Intrepid::FieldContainer<double>::scalar_type
1005 ProjectionPrimitives::distanceToFaceBilinearSurface(
1006 const Teuchos::ParameterList ¶meters,
1007 const Intrepid::FieldContainer<double> &point,
1008 const Intrepid::FieldContainer<double> &face_edge_nodes,
1009 const Intrepid::FieldContainer<double> &face_edge_node_normals )
1012 double geometric_tolerance =
1013 parameters.get<
double>(
"Geometric Tolerance" );
1016 double newton_tolerance = parameters.get<
double>(
"Newton Tolerance" );
1019 double max_newton_iters = parameters.get<
int>(
"Max Newton Iterations" );
1023 double xdist = face_edge_nodes( 1, 0 ) - face_edge_nodes( 0, 0 );
1024 double ydist = face_edge_nodes( 1, 1 ) - face_edge_nodes( 0, 1 );
1025 double zdist = face_edge_nodes( 1, 2 ) - face_edge_nodes( 0, 2 );
1026 double c = 0.5 * std::sqrt( xdist * xdist + ydist * ydist + zdist * zdist );
1029 Intrepid::FieldContainer<double> u( 1, point.dimension( 0 ) );
1032 u( 0, 2 ) = Teuchos::ScalarTraits<double>::zero();
1034 point, face_edge_nodes, face_edge_node_normals, c );
1036 u, nonlinear_problem, newton_tolerance, max_newton_iters );
1040 Intrepid::FieldContainer<double> v1( nonlinear_problem.d_space_dim );
1041 Intrepid::FieldContainer<double> v2( nonlinear_problem.d_space_dim );
1042 for (
int i = 0; i < nonlinear_problem.d_space_dim; ++i )
1044 v1( i ) = nonlinear_problem.d_face_edge_nodes( 1, i ) -
1045 nonlinear_problem.d_face_edge_nodes( 0, i );
1047 nonlinear_problem.d_c * u( 0, 1 ) *
1048 ( nonlinear_problem.d_face_edge_node_normals( 1, i ) -
1049 nonlinear_problem.d_face_edge_node_normals( 0, i ) );
1053 if ( Intrepid::RealSpaceTools<double>::dot( v1, v2 ) < geometric_tolerance )
static void solve(MDArray &u, NonlinearProblem &problem, const double tolerance, const int max_iters)
Get the center of the reference cell of the given topology.
Nonlinear problem struct for ProjectBlueFeatureToGreenFeature. This problem projects a feature point ...
A stateless class for Newton's method.
static void referenceCellCenter(const shards::CellTopology &cell_topo, Intrepid::FieldContainer< double > ¢er)
Get the center of the reference cell of the given topology.
Nonlinear problem for projecting a point into the reference frame of a face.
void updateState(const Intrepid::FieldContainer< double > &u)
Update the state of the problem given the new solution vector.
Nonlinear problem struct for pointInFaceVolumeOfInfluence. This problem projects a point onto the sur...
Assertions and Design-by-Contract for error handling.
static void projectPointToFace(const Teuchos::ParameterList ¶meters, const Intrepid::FieldContainer< double > &point, const Intrepid::FieldContainer< double > &face_nodes, const Intrepid::FieldContainer< double > &face_node_normals, const shards::CellTopology &face_topology, Intrepid::FieldContainer< double > ¶metric_point, Intrepid::FieldContainer< double > &physical_point, int &face_edge_id, int &face_node_id)
Project a point onto a face and return the physical coordinates of the projected point on that face...
void updateState(const Intrepid::FieldContainer< double > &u)
Update the state of the problem given the new solution vector.
static bool edgeEdgeIntersection(const Teuchos::ParameterList ¶meters, const Intrepid::FieldContainer< double > &edge_1, const Intrepid::FieldContainer< double > &edge_2, const Intrepid::FieldContainer< double > &edge_2_node_normals, Intrepid::FieldContainer< double > &edge_1_intersection, Intrepid::FieldContainer< double > &edge_2_intersection, int &edge_1_node_id, int &edge_2_node_id)
Intersect two edges in 3 dimensions and return their intersection point realized on both edges...
Factory for Intrepid basis functions.
Nonlinear problem definitions for projection primitives.
static bool pointInFaceVolumeOfInfluence(const Teuchos::ParameterList ¶meters, const Intrepid::FieldContainer< double > &point, const Intrepid::FieldContainer< double > &face_nodes, const Intrepid::FieldContainer< double > &face_node_normals, const shards::CellTopology &face_topology)
Determine if a point is within the volume of influence of a face.
A stateless class of projection primitive operations.