@@ -128,6 +128,35 @@ void TriangulatorInterface::elems_to_segments()
128128
129129
130130
131+ void TriangulatorInterface ::nodes_to_segments (dof_id_type max_node_id )
132+ {
133+ // Don't try to override manually specified segments, or try to add
134+ // segments if we're doing a convex hull
135+ if (!this -> segments .empty () || _triangulation_type != PSLG )
136+ return ;
137+
138+ for (auto node_it = _mesh .nodes_begin (),
139+ node_end = _mesh .nodes_end ();
140+ node_it != node_end ;)
141+ {
142+ Node * node = * node_it ;
143+
144+ // If we're out of boundary nodes, the rest are going to be
145+ // Steiner points or hole points
146+ if (node -> id () >= max_node_id )
147+ break ;
148+
149+ ++ node_it ;
150+
151+ Node * next_node = (node_it == node_end ) ?
152+ * _mesh .nodes_begin () : * node_it ;
153+
154+ this -> segments .emplace_back (node -> id (), next_node -> id ());
155+ }
156+ }
157+
158+
159+
131160void TriangulatorInterface ::insert_any_extra_boundary_points ()
132161{
133162 // If the initial PSLG is really simple, e.g. an L-shaped domain or
@@ -141,40 +170,38 @@ void TriangulatorInterface::insert_any_extra_boundary_points()
141170 const int n_interpolated = this -> get_interpolate_boundary_points ();
142171 if ((_triangulation_type == PSLG ) && n_interpolated )
143172 {
144- // Make a copy of the original points from the Mesh
145- std ::vector < Point > original_points ;
146- original_points .reserve (_mesh .n_nodes ());
147- for (auto & node : _mesh .node_ptr_range ())
148- original_points .push_back (* node );
173+ std ::vector < std ::pair < unsigned int , unsigned int >> old_segments =
174+ std ::move (this -> segments );
149175
150- // Clear out the mesh
151- _mesh .clear ();
176+ // We expect to have converted any elems and/or nodes into
177+ // segments by now.
178+ libmesh_assert (!old_segments .empty ());
152179
153- // Make sure the new Mesh will be 2D
154- _mesh .set_mesh_dimension (2 );
180+ this -> segments .clear ();
155181
156- // Insert a new point on each PSLG at evenly spaced locations
182+ // Insert a new point on each segment at evenly spaced locations
157183 // between existing boundary points.
158- // np=index into new points vector, also an explicit node index
159- // (to avoid the stride in automatic DistributedMesh indexing)
184+ // np=index into new points vector
160185 // n =index into original points vector
161- for (std :: size_t np = 0 , n = 0 , tops = n_interpolated * original_points . size (); np < tops ; ++ np )
186+ for (auto old_segment : old_segments )
162187 {
163- int offset = np % n_interpolated ;
164-
165- // Some entries are the original points
166- if (!offset )
167- _mesh .add_point (original_points [n ++ ], np );
168-
169- else // the odd entries are equispaced along the original PSLG segments
188+ Node * begin_node = _mesh .node_ptr (old_segment .first );
189+ Node * end_node = _mesh .node_ptr (old_segment .second );
190+ dof_id_type current_id = begin_node -> id ();
191+ for (auto i : make_range (n_interpolated ))
170192 {
171- libmesh_assert_less (n - 1 , original_points .size ());
172- const std ::size_t next_n = n % original_points .size ();
193+ // new points are equispaced along the original segments
173194 const Point new_point =
174- (offset * original_points [next_n ] +
175- (n_interpolated - offset )* original_points [n - 1 ])/n_interpolated ;
176- _mesh .add_point (new_point , np );
195+ ((n_interpolated - i ) * * (Point * )(begin_node ) +
196+ (i + 1 ) * * (Point * )(end_node )) /
197+ (n_interpolated + 1 );
198+ Node * next_node = _mesh .add_point (new_point );
199+ this -> segments .emplace_back (current_id ,
200+ next_node -> id ());
201+ current_id = next_node -> id ();
177202 }
203+ this -> segments .emplace_back (current_id ,
204+ end_node -> id ());
178205 }
179206 }
180207}
0 commit comments