RINGMesh  Version 5.0.0
A programming library for geological model meshes
well.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #include <ringmesh/mesh/well.h>
37 
38 #include <cmath>
39 #include <numeric>
40 #include <stack>
41 
42 #include <geogram/mesh/mesh.h>
43 #include <geogram/mesh/mesh_geometry.h>
44 
46 #include <ringmesh/basic/box.h>
48 
51 
53 
59 namespace
60 {
61  using namespace RINGMesh;
62 
63  template < index_t DIMENSION >
64  bool inexact_equal( const vecn< DIMENSION >& v1,
65  const vecn< DIMENSION >& v2,
66  double epsilon )
67  {
68  return length( v2 - v1 ) < epsilon;
69  }
70 
79  index_t find_region(
80  const GeoModel3D& geomodel, index_t surface_part_id, bool side )
81  {
82  ringmesh_assert( surface_part_id < geomodel.nb_surfaces() );
83  gmme_id cur_surface( Surface3D::type_name_static(), surface_part_id );
84  const Surface3D& surface = geomodel.surface( surface_part_id );
85  for( auto r : range( surface.nb_incident_entities() ) )
86  {
87  const Region3D& cur_region = surface.incident_entity( r );
88  for( auto s : range( cur_region.nb_boundaries() ) )
89  {
90  if( cur_region.side( s ) == side
91  && cur_region.boundary_gmme( s ) == cur_surface )
92  {
93  return r;
94  }
95  }
96  }
97  return NO_ID;
98  }
99 
100  struct LineInstersection
101  {
102  LineInstersection( const vec3& intersection,
103  index_t surface_id = NO_ID,
104  index_t trgl_id = NO_ID )
105  : intersection_( intersection ),
106  surface_id_( surface_id ),
107  trgl_id_( trgl_id )
108  {
109  }
110  LineInstersection()
111  : intersection_( vec3() ), surface_id_( NO_ID ), trgl_id_( NO_ID )
112  {
113  }
114  vec3 intersection_;
115  index_t surface_id_;
116  index_t trgl_id_;
117  };
118 
119  template < index_t DIMENSION >
120  index_t find_or_create_corner( Well< DIMENSION >& well,
121  index_t region,
122  const LineInstersection& corner,
123  double epsilon )
124  {
125  index_t corner_id = well.find_corner( corner.intersection_, epsilon );
126  if( corner_id == NO_ID )
127  {
128  bool is_on_surface = corner.surface_id_ != NO_ID;
129  index_t id = NO_ID;
130  if( is_on_surface )
131  {
132  id = corner.surface_id_;
133  }
134  else
135  {
136  id = region;
137  }
138  corner_id =
139  well.create_corner( corner.intersection_, is_on_surface, id );
140  }
141  return corner_id;
142  }
143 
144  bool get_side( const vec3& vertex,
145  const vec3& on_surface,
146  const Surface3D& surface,
147  index_t triangle )
148  {
149  vec3 direction = vertex - on_surface;
150  return dot( direction, surface.mesh().polygon_normal( triangle ) ) > 0;
151  }
152 
153  index_t find_region_from_corners( const GeoModel3D& geomodel,
154  const std::vector< vec3 > vertices,
155  const LineInstersection& start,
156  const LineInstersection& end )
157  {
158  if( start.surface_id_ != NO_ID )
159  {
160  bool sign = get_side( vertices[1], start.intersection_,
161  geomodel.surface( start.surface_id_ ), start.trgl_id_ );
162  return find_region( geomodel, start.surface_id_, sign );
163  }
164  else if( end.surface_id_ != NO_ID )
165  {
166  bool sign =
167  get_side( vertices[vertices.size() - 2], end.intersection_,
168  geomodel.surface( end.surface_id_ ), end.trgl_id_ );
169  return find_region( geomodel, end.surface_id_, sign );
170  }
171  else
172  {
173  double best_distance = max_float64();
174  index_t best_surface = NO_ID;
175  vec3 best_nearest;
176  index_t best_triangle = NO_ID;
177  for( const auto& surface : geomodel.surfaces() )
178  {
179  index_t triangle = NO_ID;
180  vec3 nearest;
181  double distance = max_float64();
182  std::tie( triangle, nearest, distance ) =
183  surface.polygon_aabb().closest_triangle(
184  start.intersection_ );
185  if( distance < best_distance )
186  {
187  best_distance = distance;
188  best_nearest = nearest;
189  best_surface = surface.index();
190  best_triangle = triangle;
191  }
192  }
193  bool sign = get_side( start.intersection_, best_nearest,
194  geomodel.surface( best_surface ), best_triangle );
195  return find_region( geomodel, best_surface, sign );
196  }
197  }
198 
199  template < index_t DIMENSION >
200  void create_well_part_and_corners( const GeoModel3D& geomodel,
201  Well< DIMENSION >& well,
202  const std::vector< vec3 > vertices,
203  const LineInstersection& start,
204  const LineInstersection& end )
205  {
206  index_t region =
207  find_region_from_corners( geomodel, vertices, start, end );
208  if( region == NO_ID )
209  {
210  return;
211  }
212 
213  index_t new_well_part_id = well.create_part( region );
214  WellPart< DIMENSION >& well_part = well.part( new_well_part_id );
215 
216  index_t corner0 =
217  find_or_create_corner( well, region, start, geomodel.epsilon() );
218  well_part.set_corner( 0, corner0 );
219 
220  index_t corner1 =
221  find_or_create_corner( well, region, end, geomodel.epsilon() );
222  well_part.set_corner( 1, corner1 );
223  well_part.set_points( vertices );
224  }
225 
226  class EdgeConformerAction
227  {
228  public:
229  EdgeConformerAction( const Surface3D& surface,
230  const vec3& v_from,
231  const vec3& v_to,
232  std::vector< LineInstersection >& intersections )
233  : surface_( surface ),
234  segment_( v_from, v_to ),
235  intersections_( intersections )
236  {
237  }
238 
239  void operator()( index_t trgl )
240  {
241  bool does_seg_intersect_triangle = false;
242  vec3 result;
243  std::tie( does_seg_intersect_triangle, result ) =
245  { surface_.mesh_element_vertex( { trgl, 0 } ),
246  surface_.mesh_element_vertex( { trgl, 1 } ),
247  surface_.mesh_element_vertex( { trgl, 2 } ) } );
248  if( does_seg_intersect_triangle )
249  {
250  intersections_.push_back(
251  LineInstersection( result, surface_.index(), trgl ) );
252  }
253  }
254 
255  private:
256  const Surface3D& surface_;
257  Geometry::Segment3D segment_;
258 
259  std::vector< LineInstersection >& intersections_;
260  };
261 
262  struct OrientedEdge
263  {
264  OrientedEdge(
265  const LineMesh3D& mesh, index_t edge, index_t vertex_from )
266  : edge_( edge ), vertex_from_( vertex_from )
267  {
268  if( mesh.edge_vertex( ElementLocalVertex( edge, 0 ) )
269  == vertex_from )
270  {
271  edge_vertex_ = 0;
272  }
273  else
274  {
276  mesh.edge_vertex( ElementLocalVertex( edge, 1 ) )
277  == vertex_from );
278  edge_vertex_ = 1;
279  }
280  }
281  index_t edge_;
282  index_t edge_vertex_;
283  index_t vertex_from_;
284  };
285 }
286 
287 namespace RINGMesh
288 {
289  template < index_t DIMENSION >
291  : well_( well )
292  {
293  }
294 
295  // --------------------------------------------------------------------------
296 
297  template < index_t DIMENSION >
299  const vecn< DIMENSION >& point,
300  bool is_on_surface,
301  index_t id )
302  : WellEntity< DIMENSION >( well ),
303  is_on_surface_( is_on_surface ),
304  id_( id ),
305  mesh_( PointSetMesh< DIMENSION >::create_mesh(
306  GeogramPointSetMesh< DIMENSION >::type_name_static() ) )
307  {
309  ->create_vertex( point );
310  }
311 
312  template < index_t DIMENSION >
314  {
315  return mesh_->vertex( 0 );
316  }
317 
318  template < index_t DIMENSION >
319  GEO::AttributesManager&
321  {
322  return mesh_->vertex_attribute_manager();
323  }
324 
325  // --------------------------------------------------------------------------
326 
327  template < index_t DIMENSION >
329  : WellEntity< DIMENSION >( well ),
330  id_( id ),
331  mesh_( LineMesh< DIMENSION >::create_mesh(
332  GeogramLineMesh< DIMENSION >::type_name_static() ) )
333  {
334  corners_[0] = NO_ID;
335  corners_[1] = NO_ID;
336  }
337 
338  template < index_t DIMENSION >
340  const std::vector< vecn< DIMENSION > >& points )
341  {
342  index_t nb_points = static_cast< index_t >( points.size() );
343  std::unique_ptr< LineMeshBuilder< DIMENSION > > builder =
345  builder->create_vertices( nb_points );
346  for( auto p : range( nb_points ) )
347  {
348  builder->set_vertex( p, points[p] );
349  }
350 
351  index_t nb_edges = nb_points - 1;
352  builder->create_edges( nb_edges );
353  for( auto e : range( nb_edges ) )
354  {
355  builder->set_edge_vertex( EdgeLocalVertex( e, 0 ), e );
356  builder->set_edge_vertex( EdgeLocalVertex( e, 1 ), e + 1 );
357  }
358  }
359 
360  template < index_t DIMENSION >
362  {
363  return mesh_->nb_edges();
364  }
365 
366  template < index_t DIMENSION >
368  {
369  return mesh_->nb_vertices();
370  }
371 
372  template < index_t DIMENSION >
374  {
375  return mesh_->vertex( v );
376  }
377 
378  template < index_t DIMENSION >
380  const ElementLocalVertex& well_edge_local_vertex ) const
381  {
382  return vertex( mesh_->edge_vertex( well_edge_local_vertex ) );
383  }
384 
385  template < index_t DIMENSION >
386  const NNSearch< DIMENSION >&
388  {
389  return mesh_->vertex_nn_search();
390  }
391 
392  template < index_t DIMENSION >
394  {
395  double l = 0.0;
396  for( auto e : range( nb_edges() ) )
397  {
398  l += ( vertex( e + 1 ) - vertex( e ) ).length();
399  }
400  return l;
401  }
402 
403  template < index_t DIMENSION >
404  GEO::AttributesManager&
406  {
407  return mesh_->vertex_attribute_manager();
408  }
409  template < index_t DIMENSION >
410  GEO::AttributesManager&
412  {
413  return mesh_->edge_attribute_manager();
414  }
415 
416  // --------------------------------------------------------------------------
417 
418  template < index_t DIMENSION >
419  Well< DIMENSION >::Well() : nb_edges_( NO_ID )
420  {
421  }
422 
423  template < index_t DIMENSION >
425  const vecn< DIMENSION >& vertex, double epsilon ) const
426  {
427  for( auto c : range( nb_corners() ) )
428  {
429  if( inexact_equal( vertex, corner( c ).point(), epsilon ) )
430  {
431  return c;
432  }
433  }
434  return NO_ID;
435  }
436 
437  template < index_t DIMENSION >
439  Well< DIMENSION >& well ) const
440  {
441  well.name_ = name_;
443 
444  well.corners_.reserve( nb_corners() );
445  for( auto c : range( nb_corners() ) )
446  {
447  well.create_corner( corners_[c]->point(),
448  corners_[c]->is_on_surface(), corners_[c]->id() );
449  }
450 
451  well.parts_.reserve( nb_parts() );
452  for( auto part_id : range( nb_parts() ) )
453  {
454  well.create_part( part_region_id( part_id ) );
455  const WellPart< DIMENSION >& from_part = part( part_id );
456  WellPart< DIMENSION >& cur_part = well.part( part_id );
457  cur_part.set_corner( 0, from_part.corner( 0 ) );
458  cur_part.set_corner( 1, from_part.corner( 1 ) );
459  }
460  }
461 
462  template < index_t DIMENSION >
464  {
465  if( nb_edges_ == NO_ID )
466  {
467  index_t nb_edges = 0;
468  for( auto part_id : range( nb_parts() ) )
469  {
470  nb_edges += part( part_id ).nb_edges();
471  }
472  const_cast< Well< DIMENSION >* >( this )->nb_edges_ = nb_edges;
473  }
474  return nb_edges_;
475  }
476 
477  template < index_t DIMENSION >
479  index_t part_id, std::vector< Edge< DIMENSION > >& edges ) const
480  {
481  const WellPart< DIMENSION >& well_part = part( part_id );
482  for( auto e : range( well_part.nb_edges() ) )
483  {
484  edges.emplace_back(
485  well_part.vertex( e ), well_part.vertex( e + 1 ) );
486  }
487  }
488 
489  template < index_t DIMENSION >
491  index_t region, std::vector< Edge< DIMENSION > >& edges ) const
492  {
493  for( auto part_id : range( nb_parts() ) )
494  {
495  if( part_region_id( part_id ) == region )
496  {
497  get_part_edges( part_id, edges );
498  }
499  }
500  }
501 
502  // --------------------------------------------------------------------------
503 
504  template < index_t DIMENSION >
505  WellGroup< DIMENSION >::WellGroup() : geomodel_( nullptr )
506  {
507  }
508 
509  template < index_t DIMENSION >
511  index_t region, std::vector< Edge< DIMENSION > >& edges ) const
512  {
513  for( auto w : range( nb_wells() ) )
514  {
515  const Well< DIMENSION >& cur_well = well( w );
516  for( auto part_id : range( cur_well.nb_parts() ) )
517  {
518  if( cur_well.part_region_id( part_id ) == region )
519  {
520  cur_well.get_part_edges( part_id, edges );
521  }
522  }
523  }
524  }
525 
526  template < index_t DIMENSION >
528  std::vector< std::vector< Edge< DIMENSION > > >& edges ) const
529  {
530  edges.clear();
531  edges.resize( nb_wells() );
532  for( auto w : range( nb_wells() ) )
533  {
534  const Well< DIMENSION >& cur_well = well( w );
535  cur_well.get_region_edges( region, edges[w] );
536  }
537  }
538 
539  template < index_t DIMENSION >
541  {
542  wells_.resize( nb, nullptr );
543  for( auto w : range( nb_wells() ) )
544  {
545  wells_[w] = new Well< DIMENSION >;
546  }
547  }
548 
549  template <>
551  const LineMesh< 2 >& in, LineMesh< 2 >& out )
552  {
553  ringmesh_unused( in );
554  ringmesh_unused( out );
555  throw RINGMeshException(
556  "Wells", "2D Wells not fully implemented yet" );
557  }
558 
559  template <>
561  const LineMesh3D& in, LineMesh3D& out )
562  {
563  double epsilon = geomodel_->epsilon();
564  std::unique_ptr< LineMeshBuilder3D > builder =
565  LineMeshBuilder3D::create_builder( out );
566  builder->clear( false, false );
567 
568  GEO::Attribute< LineInstersection > vertex_info(
569  out.vertex_attribute_manager(), "info" );
570  builder->create_vertices( in.nb_vertices() );
571  for( auto v : range( in.nb_vertices() ) )
572  {
573  const vec3& vertex = in.vertex( v );
574  builder->set_vertex( v, vertex );
575  vertex_info[v] = LineInstersection( vertex );
576  }
577 
578  for( auto e : range( in.nb_edges() ) )
579  {
580  index_t from_id = in.edge_vertex( ElementLocalVertex( e, 0 ) );
581  const vec3& from_vertex = in.vertex( from_id );
582  index_t to_id = in.edge_vertex( ElementLocalVertex( e, 1 ) );
583  const vec3& to_vertex = in.vertex( to_id );
584 
585  Box3D box;
586  box.add_point( from_vertex );
587  box.add_point( to_vertex );
588  std::vector< LineInstersection > intersections;
589  for( const auto& surface : geomodel_->surfaces() )
590  {
591  EdgeConformerAction action(
592  surface, from_vertex, to_vertex, intersections );
593  surface.polygon_aabb().compute_bbox_element_bbox_intersections(
594  box, action );
595  }
596 
597  std::vector< index_t > indices( intersections.size() );
598  std::iota( indices.begin(), indices.end(), 0 );
599  std::vector< double > distances( intersections.size() );
600  for( auto i : range( intersections.size() ) )
601  {
602  distances[i] =
603  length( from_vertex - intersections[i].intersection_ );
604  }
605  indirect_sort( distances, indices );
606  double edge_length = length( from_vertex - to_vertex );
607  index_t last_vertex = from_id;
608  for( auto i : range( intersections.size() ) )
609  {
610  if( distances[indices[i]] < epsilon )
611  {
612  vertex_info[from_id] = intersections[i];
613  }
614  else if( std::fabs( distances[indices[i]] - edge_length )
615  < epsilon )
616  {
617  vertex_info[to_id] = intersections[i];
618  }
619  else
620  {
621  index_t vertex_id = builder->create_vertex(
622  intersections[i].intersection_ );
623  vertex_info[vertex_id] = intersections[i];
624  builder->create_edge( last_vertex, vertex_id );
625  last_vertex = vertex_id;
626  }
627  }
628  builder->create_edge( last_vertex, to_id );
629  }
630  }
631 
632  template <>
634  const LineMesh< 2 >& mesh, const std::string& name )
635  {
636  ringmesh_unused( mesh );
637  ringmesh_unused( name );
638  throw RINGMeshException(
639  "Wells", "2D Wells not fully implemented yet" );
640  }
641 
642  template <>
644  const LineMesh3D& mesh, const std::string& name )
645  {
647  if( find_well( name ) != NO_ID )
648  return;
649  wells_.push_back( new Well3D );
650  Well3D& new_well = *wells_.back();
651  new_well.set_name( name );
652 
653  GeogramLineMesh3D conformal_mesh;
654  compute_conformal_mesh( mesh, conformal_mesh );
655 
656  std::vector< std::vector< index_t > > edges_around_vertices(
657  conformal_mesh.nb_vertices() );
658  for( auto e : range( conformal_mesh.nb_edges() ) )
659  {
660  for( auto i : range( 2 ) )
661  {
662  index_t v =
663  conformal_mesh.edge_vertex( ElementLocalVertex( e, i ) );
664  edges_around_vertices[v].push_back( e );
665  }
666  }
667 
668  std::stack< OrientedEdge > S;
669  for( auto v : range( conformal_mesh.nb_vertices() ) )
670  {
671  const std::vector< index_t >& edges = edges_around_vertices[v];
672  if( edges.size() == 1 )
673  {
674  S.emplace( conformal_mesh, edges.front(), v );
675  }
676  }
677  if( S.empty() )
678  {
679  throw RINGMeshException( "Well",
680  "A well should have at least one starting or ending point" );
681  }
682 
683  GEO::Attribute< LineInstersection > vertex_info(
684  conformal_mesh.vertex_attribute_manager(), "info" );
685  std::vector< bool > edge_visited( conformal_mesh.nb_edges(), false );
686  do
687  {
688  OrientedEdge cur_edge = S.top();
689  S.pop();
690  if( edge_visited[cur_edge.edge_] )
691  {
692  continue;
693  }
694  edge_visited[cur_edge.edge_] = true;
695 
696  std::vector< vec3 > well_part_points;
697  std::stack< OrientedEdge > S_part;
698  S_part.push( cur_edge );
699  do
700  {
701  OrientedEdge cur_edge_part = S_part.top();
702  S_part.pop();
703  edge_visited[cur_edge_part.edge_] = true;
704  const vec3& v_from =
705  conformal_mesh.vertex( cur_edge_part.vertex_from_ );
706  index_t v_to_id = conformal_mesh.edge_vertex(
707  ElementLocalVertex( cur_edge_part.edge_,
708  ( cur_edge_part.edge_vertex_ + 1 ) % 2 ) );
709  const vec3& v_to = conformal_mesh.vertex( v_to_id );
710  well_part_points.push_back( v_from );
711 
712  const std::vector< index_t >& edges =
713  edges_around_vertices[v_to_id];
714  if( edges.size() == 2 )
715  {
716  index_t count = 0;
717  for( auto edge : edges )
718  {
719  if( !edge_visited[edge] )
720  {
721  S_part.emplace( conformal_mesh, edge, v_to_id );
722  count++;
723  }
724  }
725  ringmesh_assert( count == 1 );
726  }
727  else
728  {
729  well_part_points.push_back( v_to );
730  create_well_part_and_corners( *geomodel(), new_well,
731  well_part_points, vertex_info[cur_edge.vertex_from_],
732  vertex_info[v_to_id] );
733  for( auto edge : edges )
734  {
735  S.emplace( conformal_mesh, edge, v_to_id );
736  }
737  }
738  } while( !S_part.empty() );
739  } while( !S.empty() );
740  }
741 
742  template < index_t DIMENSION >
743  index_t WellGroup< DIMENSION >::find_well( const std::string& name ) const
744  {
745  for( auto w : range( nb_wells() ) )
746  {
747  if( well( w ).name() == name )
748  {
749  return w;
750  }
751  }
752  return NO_ID;
753  }
754  template class RINGMESH_API WellEntity< 2 >;
755  template class RINGMESH_API WellCorner< 2 >;
756  template class RINGMESH_API WellPart< 2 >;
757  template class RINGMESH_API Well< 2 >;
758  template class RINGMESH_API WellGroup< 2 >;
759 
760  template class RINGMESH_API WellEntity< 3 >;
761  template class RINGMESH_API WellCorner< 3 >;
762  template class RINGMESH_API WellPart< 3 >;
763  template class RINGMESH_API Well< 3 >;
764  template class RINGMESH_API WellGroup< 3 >;
765 } // namespace RINGMesh
index_t part_region_id(index_t part_id) const
Definition: well.h:344
index_t find_corner(const vecn< DIMENSION > &vertex, double epsilon) const
Definition: well.cpp:424
index_t find_well(const std::string &name) const
Definition: well.cpp:743
GEO::vecng< DIMENSION, double > vecn
Definition: types.h:74
void get_region_edges(index_t part_id, std::vector< Edge< DIMENSION > > &edges) const
Definition: well.cpp:490
static std::unique_ptr< LineMeshBuilder > create_builder(LineMesh< DIMENSION > &mesh)
std::vector< index_t > part_region_id_
Vector of the region id of the parts.
Definition: well.h:390
static std::unique_ptr< PointSetMeshBuilder< DIMENSION > > create_builder(PointSetMesh< DIMENSION > &mesh)
vecn< 3 > vec3
Definition: types.h:76
std::vector< Well< DIMENSION > *> wells_
Vector of the wells.
Definition: well.h:489
std::unique_ptr< LineMesh< DIMENSION > > mesh_
Definition: well.h:208
WellEntity(const Well< DIMENSION > *well)
Definition: well.cpp:290
void ringmesh_unused(const T &)
Definition: common.h:105
index_t create_part(index_t region)
Definition: well.h:314
index_t id_
The id of the corresponding surface or region.
Definition: well.h:119
index_t nb_edges() const
Definition: well.cpp:361
void copy_corners_and_informations(Well< DIMENSION > &well) const
Definition: well.cpp:438
std::array< index_t, 2 > corners_
id in the corners_ vector the the well
Definition: well.h:207
double length() const
Definition: well.cpp:393
GEO::AttributesManager & vertex_attribute_manager() const
Definition: well.cpp:405
const vecn< DIMENSION > & edge_vertex(const ElementLocalVertex &well_edge_local_vertex) const
Definition: well.cpp:379
const Well< DIMENSION > & well(index_t w) const
Definition: well.h:478
index_t corner(index_t c) const
Definition: well.h:153
void get_region_edges(index_t region, std::vector< Edge< DIMENSION > > &edges) const
Definition: well.cpp:510
void compute_conformal_mesh(const LineMesh< DIMENSION > &in, LineMesh< DIMENSION > &out)
const WellCorner< DIMENSION > & corner(index_t c) const
Definition: well.h:303
index_t nb_corners() const
Definition: well.h:353
void get_part_edges(index_t part_id, std::vector< Edge< DIMENSION > > &edges) const
Definition: well.cpp:478
const vecn< DIMENSION > & point() const
Definition: well.cpp:313
void set_points(const std::vector< vecn< DIMENSION > > &points)
Definition: well.cpp:339
void set_corner(index_t c, index_t id)
Definition: well.h:144
std::unique_ptr< PointSetMesh< DIMENSION > > mesh_
Definition: well.h:120
index_t nb_wells() const
Definition: well.h:469
const NNSearch< DIMENSION > & vertices_nn_search() const
Definition: well.cpp:387
index_t create_corner(const vecn< DIMENSION > &vertex, bool is_on_surface, index_t id)
Definition: well.h:281
std::tuple< bool, vec3 > RINGMESH_API segment_triangle(const Geometry::Segment3D &segment, const Geometry::Triangle3D &triangle)
Sign sign(T x)
Definition: geometry.h:85
#define ringmesh_assert(x)
index_t nb_vertices() const
Definition: well.cpp:367
const WellPart< DIMENSION > & part(index_t part_id) const
Definition: well.h:325
WellPart(const Well< DIMENSION > *well, index_t id)
Definition: well.cpp:328
std::string name_
Name of the well.
Definition: well.h:392
index_t nb_edges_
Number of edges in the well.
Definition: well.h:394
index_t nb_parts() const
Definition: well.h:360
index_t nb_edges() const
Definition: well.cpp:463
void create_wells(index_t nb_wells)
Definition: well.cpp:540
GEO::AttributesManager & edge_attribute_manager() const
Definition: well.cpp:411
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
const vecn< DIMENSION > & vertex(index_t v) const
Definition: well.cpp:373
const GeoModel< DIMENSION > * geomodel() const
Definition: well.h:432
std::vector< std::unique_ptr< WellPart< DIMENSION > > > parts_
Vector of the parts of the well.
Definition: well.h:388
void indirect_sort(std::vector< T1 > &input, std::vector< T2 > &output)
Bubble sorting of input and output vectors according to values of input.
Definition: algorithm.h:104
GeoModel< DIMENSION > * geomodel_
Associated GeoModel.
Definition: well.h:491
This template is a specialization of a gme_id to the GeoModelMeshEntity.
Definition: entity_type.h:285
bool inexact_equal(const vecn< DIMENSION > &v1, const vecn< DIMENSION > &v2, double epsilon)
Definition: geometry.h:67
GEO::AttributesManager & vertex_attribute_manager() const
Definition: well.cpp:320
void add_well(const LineMesh< DIMENSION > &mesh, const std::string &name)
std::vector< std::unique_ptr< WellCorner< DIMENSION > > > corners_
Vector of the corners of the well.
Definition: well.h:386
WellCorner(const Well< DIMENSION > *well, const vecn< DIMENSION > &point, bool is_on_surface, index_t id)
Definition: well.cpp:298