line_mesh.cc
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2025 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26// oomph-lib headers
27#include "map_matrix.h"
28#include "line_mesh.h"
29
30namespace oomph
31{
32 //=======================================================================
33 /// Set up lookup schemes which establish which elements are located
34 /// next to which boundaries (doc to outfile if it's open)
35 //=======================================================================
37 {
38 // Initialise documentation flag
39 bool doc = false;
40
41 // Set this to true if an open file has been passed to the function
42 if (outfile)
43 {
44 doc = true;
45 }
46
47 // Determine number of boundaries in mesh
48 const unsigned n_bound = nboundary();
49
50 // Wipe/allocate storage for arrays
51 Boundary_element_pt.clear();
55
56 // Matrix map for working out the fixed local coord for elements on boundary
58
59 // Determine number of elements in the mesh
60 const unsigned n_element = nelement();
61
62 // Loop over elements
63 for (unsigned e = 0; e < n_element; e++)
64 {
65 // Get pointer to element
67
68 // Output information to output file
69 if (doc)
70 {
71 outfile << "Element: " << e << " " << fe_pt << std::endl;
72 }
73
74 // Only include 1D elements! Some meshes contain interface elements too.
75 if (fe_pt->dim() == 1)
76 {
77 // Loop over the element's nodes and find out which boundaries they're
78 // on
79 // ----------------------------------------------------------------------
80
81 // Determine number of nodes in the element
82 const unsigned n_node = fe_pt->nnode_1d();
83
84 // Loop over nodes in order
85 for (unsigned n = 0; n < n_node; n++)
86 {
87 // Allocate storage for pointer to set of boundaries that node lives
88 // on
89 std::set<unsigned>* boundaries_pt = 0;
90
91 // Get pointer to vector of boundaries that this node lives on
93
94 // If the node lives on some boundaries....
95 if (boundaries_pt != 0)
96 {
97 // Determine number of boundaries which node lives on
98 const unsigned n_bound_node_lives_on = (*boundaries_pt).size();
99
100 // Throw an error if the node lives on more than one boundary
101 if (n_bound_node_lives_on > 1)
102 {
103 std::string error_message =
104 "In a 1D mesh a node shouldn't be able to live on more than\n";
105 error_message += "one boundary, yet this node claims to.";
106
107 throw OomphLibError(error_message,
110 }
111 // If the node lives on just one boundary
112 else if (n_bound_node_lives_on == 1)
113 {
114 // Determine which boundary the node lives on
115 const std::set<unsigned>::iterator boundary =
116 boundaries_pt->begin();
117
118 // In 1D if an element has any nodes on a boundary then it must
119 // be a boundary element. This means that (unlike in the 2D and
120 // 3D cases) we can immediately add this element to permanent
121 // storage.
122 Boundary_element_pt[*boundary].push_back(fe_pt);
123
124 // Record information required for FaceElements.
125 // `Face_index_at_boundary' = -/+1 for nodes on the left/right
126 // boundary. This allows us to decide which edge of the element
127 // coincides with the boundary since the line element must have
128 // precisely one vertex node on the boundary.
129
130 // Are we at the left-hand vertex node? (left face)
131 if (n == 0)
132 {
133 Face_index_at_boundary[*boundary].push_back(-1);
134 }
135
136 // Are we at the right-hand vertex node? (right face)
137 else if (n == n_node - 1)
138 {
139 Face_index_at_boundary[*boundary].push_back(1);
140 }
141 }
142 } // End of if node lives on some boundaries
143
144 } // End of loop over nodes
145 }
146 } // End of loop over elements
147
148#ifdef PARANOID
149
150 // Check each boundary only has precisely one element next to it
151 // -------------------------------------------------------------
152 // Only if not distributed
153#ifdef OOMPH_HAS_MPI
154 if (Comm_pt == 0)
155#endif
156 {
157 // Loop over boundaries
158 for (unsigned b = 0; b < n_bound; b++)
159 {
160 // Evaluate number of elements adjacent to boundary b
161 const unsigned n_element = Boundary_element_pt[b].size();
162
163 switch (n_element)
164 {
165 // Boundary b has no adjacent elements
166 case 0:
167 {
168 std::ostringstream error_stream;
169 error_stream << "Boundary " << b
170 << " has no element adjacent to it\n";
171 throw OomphLibError(error_stream.str(),
174 break;
175 }
176 // Boundary b has one adjacent element (this is good!)
177 case 1:
178 break;
179
180 // Boundary b has more than one adjacent element
181 default:
182 {
183 std::ostringstream error_stream;
184 error_stream << "Boundary " << b << " has " << n_element
185 << " elements adjacent to it.\n"
186 << "This shouldn't occur in a 1D mesh.\n";
187 throw OomphLibError(error_stream.str(),
190 break;
191 }
192 } // End of switch
193
194 // Because each boundary should only have one element adjacent to it,
195 // each `Face_index_at_boundary[b]' should be of size one.
196
197 const unsigned face_index_at_boundary_size =
199
201 {
202 std::ostringstream error_stream;
204 << "Face_index_at_boundary[" << b << "] has size"
205 << face_index_at_boundary_size << " which does not make sense.\n"
206 << "In a 1D mesh its size should always be one since only\n"
207 << "one element can be adjacent to any particular boundary";
208 throw OomphLibError(error_stream.str(),
211 }
212 } // End of loop over boundaries
213 }
214#endif
215
216 // Doc?
217 // ----
218 if (doc)
219 {
220 // Loop over boundaries
221 for (unsigned b = 0; b < n_bound; b++)
222 {
223 const unsigned n_element = Boundary_element_pt[b].size();
224 outfile << "Boundary: " << b << " is adjacent to " << n_element
225 << " elements" << std::endl;
226
227 // Loop over elements on given boundary
228 for (unsigned e = 0; e < n_element; e++)
229 {
231 outfile << "Boundary element:" << fe_pt
232 << " Face index on boundary is "
233 << Face_index_at_boundary[b][e] << std::endl;
234 }
235 }
236 } // End of if(doc)
237
238
239 // Lookup scheme has now been set up
241
242 } // End of setup_boundary_element_info()
243
244} // namespace oomph
e
Definition cfortran.h:571
A general Finite Element class.
Definition elements.h:1317
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition elements.h:2615
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
Definition elements.h:2222
void setup_boundary_element_info()
Set up lookup schemes which establish which elements are located next to mesh's boundaries (wrapper t...
Definition line_mesh.h:70
Vector< Vector< FiniteElement * > > Boundary_element_pt
Vector of Vector of pointers to elements on the boundaries: Boundary_element_pt(b,...
Definition mesh.h:91
bool Lookup_for_elements_next_boundary_is_setup
Flag to indicate that the lookup schemes for elements that are adjacent to the boundaries has been se...
Definition mesh.h:87
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition mesh.h:477
Vector< Vector< int > > Face_index_at_boundary
For the e-th finite element on boundary b, this is the index of the face that lies along that boundar...
Definition mesh.h:95
OomphCommunicator * Comm_pt
Pointer to communicator – set to NULL if mesh is not distributed.
Definition mesh.h:119
unsigned nboundary() const
Return number of boundaries.
Definition mesh.h:835
unsigned long nelement() const
Return number of elements in the mesh.
Definition mesh.h:598
virtual void get_boundaries_pt(std::set< unsigned > *&boundaries_pt)
Return a pointer to set of mesh boundaries that this node occupies; this will be overloaded by Bounda...
Definition nodes.h:1365
An OomphLibError object which should be thrown when an run-time error is encountered....
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).