Reference documentation for deal.II version 8.4.2
boundary_lib.cc
1 #include <deal.II/opencascade/boundary_lib.h>
2 
3 #ifdef DEAL_II_WITH_OPENCASCADE
4 
5 #include <GCPnts_AbscissaPoint.hxx>
6 #include <BRepAdaptor_Curve.hxx>
7 #include <BRepAdaptor_CompCurve.hxx>
8 #include <BRepAdaptor_HCurve.hxx>
9 #include <BRepAdaptor_HCompCurve.hxx>
10 #include <GCPnts_AbscissaPoint.hxx>
11 #include <ShapeAnalysis_Curve.hxx>
12 #include <BRep_Tool.hxx>
13 #include <TopoDS.hxx>
14 #include <Adaptor3d_HCurve.hxx>
15 #include <Handle_Adaptor3d_HCurve.hxx>
16 
17 DEAL_II_NAMESPACE_OPEN
18 
19 
20 namespace OpenCASCADE
21 {
22 
23 
24  namespace
25  {
31  Handle_Adaptor3d_HCurve curve_adaptor(const TopoDS_Shape &shape)
32  {
33  Assert( (shape.ShapeType() == TopAbs_WIRE) ||
34  (shape.ShapeType() == TopAbs_EDGE),
35  ExcUnsupportedShape());
36  if (shape.ShapeType() == TopAbs_WIRE)
37  return (Handle(BRepAdaptor_HCompCurve(new BRepAdaptor_HCompCurve(TopoDS::Wire(shape)))));
38  else if (shape.ShapeType() == TopAbs_EDGE)
39  return (Handle(BRepAdaptor_HCurve(new BRepAdaptor_HCurve(TopoDS::Edge(shape)))));
40 
41  Assert(false, ExcInternalError());
42  return Handle(BRepAdaptor_HCurve(new BRepAdaptor_HCurve()));
43  }
44 
45 
46 
47 // Helper internal functions.
48  double shape_length(const TopoDS_Shape &sh)
49  {
50  Handle_Adaptor3d_HCurve adapt = curve_adaptor(sh);
51  return GCPnts_AbscissaPoint::Length(adapt->GetCurve());
52  }
53  }
54 
55  /*============================== NormalProjectionBoundary ==============================*/
56  template <int dim, int spacedim>
58  const double tolerance) :
59  sh(sh),
60  tolerance(tolerance)
61  {
62  Assert(spacedim == 3, ExcNotImplemented());
63  }
64 
65 
66  template <int dim, int spacedim>
68  project_to_manifold (const std::vector<Point<spacedim> > &surrounding_points,
69  const Point<spacedim> &candidate) const
70  {
71  (void)surrounding_points;
72 #ifdef DEBUG
73  for (unsigned int i=0; i<surrounding_points.size(); ++i)
74  Assert(closest_point(sh, surrounding_points[i], tolerance)
75  .distance(surrounding_points[i]) <
76  std::max(tolerance*surrounding_points[i].norm(), tolerance),
77  ExcPointNotOnManifold(surrounding_points[i]));
78 #endif
79  return closest_point(sh, candidate,tolerance);
80  }
81 
82 
83  /*============================== DirectionalProjectionBoundary ==============================*/
84  template <int dim, int spacedim>
86  const Tensor<1,spacedim> &direction,
87  const double tolerance) :
88  sh(sh),
89  direction(direction),
90  tolerance(tolerance)
91  {
92  Assert(spacedim == 3, ExcNotImplemented());
93  }
94 
95 
96  template <int dim, int spacedim>
98  project_to_manifold (const std::vector<Point<spacedim> > &surrounding_points,
99  const Point<spacedim> &candidate) const
100  {
101  (void)surrounding_points;
102 #ifdef DEBUG
103  for (unsigned int i=0; i<surrounding_points.size(); ++i)
104  Assert(closest_point(sh, surrounding_points[i],tolerance)
105  .distance(surrounding_points[i]) <
106  std::max(tolerance*surrounding_points[i].norm(), tolerance),
107  ExcPointNotOnManifold(surrounding_points[i]));
108 #endif
109  return line_intersection(sh, candidate, direction, tolerance);
110  }
111 
112 
113 
114  /*============================== NormalToMeshProjectionBoundary ==============================*/
115  template <int dim, int spacedim>
117  const double tolerance) :
118  sh(sh),
119  tolerance(tolerance)
120  {
121  Assert(spacedim == 3, ExcNotImplemented());
122  Assert(std_cxx11::get<0>(count_elements(sh)) > 0,
123  ExcMessage("NormalToMeshProjectionBoundary needs a shape containing faces to operate."));
124  }
125 
126 
127  template <int dim, int spacedim>
129  project_to_manifold (const std::vector<Point<spacedim> > &surrounding_points,
130  const Point<spacedim> &candidate) const
131  {
132  TopoDS_Shape out_shape;
133  Tensor<1,3> average_normal;
134 #ifdef DEBUG
135  for (unsigned int i=0; i<surrounding_points.size(); ++i)
136  {
137  Assert(closest_point(sh, surrounding_points[i], tolerance)
138  .distance(surrounding_points[i]) <
139  std::max(tolerance*surrounding_points[i].norm(), tolerance),
140  ExcPointNotOnManifold(surrounding_points[i]));
141  }
142 #endif
143 
144  switch (surrounding_points.size())
145  {
146  case 2:
147  {
148  for (unsigned int i=0; i<surrounding_points.size(); ++i)
149  {
150  std_cxx11::tuple<Point<3>, Point<3>, double>
151  p_and_diff_forms =
153  surrounding_points[i],
154  tolerance);
155  average_normal += std_cxx11::get<1>(p_and_diff_forms);
156  }
157 
158  average_normal/=2.0;
159 
160  Assert(average_normal.norm() > 1e-4,
161  ExcMessage("Failed to refine cell: the average of the surface normals at the surrounding edge turns out to be a null vector, making the projection direction undetermined."));
162 
163  Tensor<1,3> T = surrounding_points[0]-surrounding_points[1];
164  T /= T.norm();
165  average_normal = average_normal-(average_normal*T)*T;
166  average_normal /= average_normal.norm();
167  break;
168  }
169  case 8:
170  {
171  Tensor<1,3> u = surrounding_points[1]-surrounding_points[0];
172  Tensor<1,3> v = surrounding_points[2]-surrounding_points[0];
173  const double n1_coords[3] = {u[1] *v[2]-u[2] *v[1],u[2] *v[0]-u[0] *v[2],u[0] *v[1]-u[1] *v[0]};
174  Tensor<1,3> n1(n1_coords);
175  n1 = n1/n1.norm();
176  u = surrounding_points[2]-surrounding_points[3];
177  v = surrounding_points[1]-surrounding_points[3];
178  const double n2_coords[3] = {u[1] *v[2]-u[2] *v[1],u[2] *v[0]-u[0] *v[2],u[0] *v[1]-u[1] *v[0]};
179  Tensor<1,3> n2(n2_coords);
180  n2 = n2/n2.norm();
181  u = surrounding_points[4]-surrounding_points[7];
182  v = surrounding_points[6]-surrounding_points[7];
183  const double n3_coords[3] = {u[1] *v[2]-u[2] *v[1],u[2] *v[0]-u[0] *v[2],u[0] *v[1]-u[1] *v[0]};
184  Tensor<1,3> n3(n3_coords);
185  n3 = n3/n3.norm();
186  u = surrounding_points[6]-surrounding_points[7];
187  v = surrounding_points[5]-surrounding_points[7];
188  const double n4_coords[3] = {u[1] *v[2]-u[2] *v[1],u[2] *v[0]-u[0] *v[2],u[0] *v[1]-u[1] *v[0]};
189  Tensor<1,3> n4(n4_coords);
190  n4 = n4/n4.norm();
191  //for (unsigned int i=0; i<surrounding_points.size(); ++i)
192  // cout<<surrounding_points[i]<<endl;
193  //cout<<"-"<<endl;
194  //cout<<n1<<endl;cout<<n2<<endl;cout<<n3<<endl;cout<<n4<<endl;
195 
196  average_normal = (n1+n2+n3+n4)/4.0;
197 
198  Assert(average_normal.norm() > tolerance,
199  ExcMessage("Failed to refine cell: the normal estimated via the surrounding points turns out to be a null vector, making the projection direction undetermined."));
200 
201  average_normal /= average_normal.norm();
202  break;
203  }
204  default:
205  {
206  AssertThrow(false, ExcNotImplemented());
207  break;
208  }
209  }
210 
211  return line_intersection(sh, candidate, average_normal, tolerance);
212  }
213 
214 
215  /*============================== ArclengthProjectionLineManifold ==============================*/
216  template <int dim, int spacedim>
218  const double tolerance):
219 
220  ChartManifold<dim,spacedim,1>(sh.Closed() ?
221  Point<1>(shape_length(sh)) :
222  Point<1>()),
223  curve(curve_adaptor(sh)),
224  tolerance(tolerance),
225  length(shape_length(sh))
226  {
227  Assert(spacedim == 3, ExcNotImplemented());
228  }
229 
230 
231  template <int dim, int spacedim>
232  Point<1>
234  {
235  double t (0.0);
236  ShapeAnalysis_Curve curve_analysis;
237  gp_Pnt proj;
238  const double dist = curve_analysis.Project(curve->GetCurve(), point(space_point), tolerance, proj, t, true);
239  Assert(dist < tolerance*length, ExcPointNotOnManifold(space_point));
240  (void)dist; // Silence compiler warning in Release mode.
241  return Point<1>(GCPnts_AbscissaPoint::Length(curve->GetCurve(),curve->GetCurve().FirstParameter(),t));
242  }
243 
244 
245 
246  template <int dim, int spacedim>
249  {
250  GCPnts_AbscissaPoint AP(curve->GetCurve(), chart_point[0], curve->GetCurve().FirstParameter());
251  gp_Pnt P = curve->GetCurve().Value(AP.Parameter());
252  return point(P);
253  }
254 
255 
256 // Explicit instantiations
257 #include "boundary_lib.inst"
258 
259 } // end namespace OpenCASCADE
260 
261 DEAL_II_NAMESPACE_CLOSE
262 
263 #endif
std_cxx11::tuple< Point< 3 >, Point< 3 >, double > closest_point_and_differential_forms(const TopoDS_Shape &in_shape, const Point< 3 > &origin, const double tolerance=1e-7)
Definition: utilities.cc:535
Point< 3 > line_intersection(const TopoDS_Shape &in_shape, const Point< 3 > &origin, const Tensor< 1, 3 > &direction, const double tolerance=1e-7)
Definition: utilities.cc:372
::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:1047
std_cxx11::tuple< unsigned int, unsigned int, unsigned int > count_elements(const TopoDS_Shape &shape)
Definition: utilities.cc:73
NormalToMeshProjectionBoundary(const TopoDS_Shape &sh, const double tolerance=1e-7)
virtual Point< spacedim > project_to_manifold(const std::vector< Point< spacedim > > &surrounding_points, const Point< spacedim > &candidate) const
#define Assert(cond, exc)
Definition: exceptions.h:294
virtual Point< spacedim > project_to_manifold(const std::vector< Point< spacedim > > &surrounding_points, const Point< spacedim > &candidate) const
Definition: boundary_lib.cc:98
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
Point< 3 > closest_point(const TopoDS_Shape &in_shape, const Point< 3 > &origin, const double tolerance=1e-7)
Definition: utilities.cc:525
virtual Point< spacedim > push_forward(const Point< 1 > &chart_point) const
ArclengthProjectionLineManifold(const TopoDS_Shape &sh, const double tolerance=1e-7)
virtual Point< spacedim > project_to_manifold(const std::vector< Point< spacedim > > &surrounding_points, const Point< spacedim > &candidate) const
Definition: boundary_lib.cc:68
NormalProjectionBoundary(const TopoDS_Shape &sh, const double tolerance=1e-7)
Definition: boundary_lib.cc:57
Point< 3 > point(const gp_Pnt &p)
Definition: utilities.cc:156
virtual Point< 1 > pull_back(const Point< spacedim > &space_point) const
DirectionalProjectionBoundary(const TopoDS_Shape &sh, const Tensor< 1, spacedim > &direction, const double tolerance=1e-7)
Definition: boundary_lib.cc:85