one_d_mesh.template.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#ifndef OOMPH_ONE_D_MESH_TEMPLATE_HEADER
27#define OOMPH_ONE_D_MESH_TEMPLATE_HEADER
28
29#ifndef OOMPH_ONE_D_MESH_HEADER
30#error __FILE__ should only be included from one_d_mesh.h.
31#endif // OOMPH_ONE_D_MESH_HEADER
32
33namespace oomph
34{
35 /// The generic mesh construction routine --- this contains all the hard
36 /// work and is called by all constructors
37 template<class ELEMENT>
39 {
40 // Set the length of the domain
41 Length = Xmax - Xmin;
42
43 // Set the number of boundaries -- there are 2 boundaries in a 1D mesh
44 set_nboundary(2);
45
46 // Allocate storage for the pointers to the elements
47 Element_pt.resize(N);
48
49 // Allocate memory for the first element
50 Element_pt[0] = new ELEMENT;
51
52 // Read out the number of nodes in the element (the member function
53 // nnode_1d() is implemented in QElement)
54 const unsigned n_node =
55 dynamic_cast<ELEMENT*>(finite_element_pt(0))->nnode_1d();
56
57 // We can now allocate storage for the pointers to the nodes in the mesh
58 Node_pt.resize(1 + (n_node - 1) * N);
59
60 // Initialise the node counter
61 unsigned node_count = 0;
62
63 // Initialise the minimum x coordinate in the mesh
64 const double xinit = Xmin;
65
66 // Calculate the length of the element
67 const double el_length = Length / double(N);
68
69 // Allocate storage for the local coordinate in the element
71
72 // If the number of elements is 1, the first element is also the
73 // last element
74 if (N == 1)
75 {
76 // Set the first node
77 // ------------------
78
79 // Allocate memory for the node, using the element's own construct_node
80 // function -- only the element knows what type of nodes it needs!
82 finite_element_pt(0)->construct_boundary_node(0, time_stepper_pt);
83
84 // Set the position of the node
86
87 // Add the node to the boundary 0
88 add_boundary_node(0, Node_pt[node_count]);
89
90 // Increment the counter for the nodes
91 node_count++;
92
93 // Now build central nodes (ignore last one which needs special
94 // ------------------------------------------------------------
95 // treatment because it's on the boundary)
96 // ---------------------------------------
97 for (unsigned jnod = 1; jnod < (n_node - 1); jnod++)
98 {
99 // Allocate memory for nodes, as before
101 finite_element_pt(0)->construct_node(jnod, time_stepper_pt);
102
103 // Get the local coordinate of the node
104 finite_element_pt(0)->local_fraction_of_node(jnod, s_fraction);
105
106 // Set the position of the node (linear mapping)
108
109 // Increment the node counter
110 node_count++;
111 }
112
113 // New final node
114 // --------------
115
116 // Allocate memory for the node, as before
117 Node_pt[node_count] = finite_element_pt(0)->construct_boundary_node(
119
120 // Set the position of the node
121 node_pt(node_count)->x(0) = xinit + Length;
122
123 // Add the node to the boundary 1
124 add_boundary_node(1, Node_pt[node_count]);
125
126 // Increment the node counter
127 node_count++;
128 }
129
130 // Otherwise, i.e. if there is more than one element, build all elements
131 else
132 {
133 // -------------
134 // FIRST ELEMENT
135 // -------------
136
137 // Set the first node
138 // ------------------
139
140 // Allocate memory for the node, using the element's own construct_node
141 // function -- only the element knows what type of nodes it needs!
143 finite_element_pt(0)->construct_boundary_node(0, time_stepper_pt);
144
145 // Set the position of the node
146 node_pt(node_count)->x(0) = xinit;
147
148 // Add the node to the boundary 0
149 add_boundary_node(0, Node_pt[node_count]);
150
151 // Increment the counter for the nodes
152 node_count++;
153
154 // Now build the other nodes in the first element
155 // ----------------------------------------------
156
157 // Loop over the other nodes in the first element
158 for (unsigned jnod = 1; jnod < n_node; jnod++)
159 {
160 // Allocate memory for the nodes
162 finite_element_pt(0)->construct_node(jnod, time_stepper_pt);
163
164 // Get the local coordinate of the node
165 finite_element_pt(0)->local_fraction_of_node(jnod, s_fraction);
166
167 // Set the position of the node (linear mapping)
169
170 // Increment the node counter
171 node_count++;
172 }
173
174 // ----------------
175 // CENTRAL ELEMENTS
176 // ----------------
177
178 // Loop over central elements in mesh
179 for (unsigned e = 1; e < (N - 1); e++)
180 {
181 // Allocate memory for the new element
182 Element_pt[e] = new ELEMENT;
183
184 // The first node is the same as the last node in the neighbouring
185 // element on the left
186 finite_element_pt(e)->node_pt(0) =
187 finite_element_pt(e - 1)->node_pt((n_node - 1));
188
189 // Loop over the remaining nodes in the element
190 for (unsigned jnod = 1; jnod < n_node; jnod++)
191 {
192 // Allocate memory for the nodes, as before
194 finite_element_pt(e)->construct_node(jnod, time_stepper_pt);
195
196 // Get the local coordinate of the nodes
197 finite_element_pt(e)->local_fraction_of_node(jnod, s_fraction);
198
199 // Set the position of the node (linear mapping)
200 node_pt(node_count)->x(0) = xinit + el_length * (e + s_fraction[0]);
201
202 // Increment the node counter
203 node_count++;
204 }
205 } // End of loop over central elements
206
207 // FINAL ELEMENT
208 //--------------
209
210 // Allocate memory for element
211 Element_pt[N - 1] = new ELEMENT;
212
213 // The first node is the same as the last node in the neighbouring
214 // element on the left
215 finite_element_pt(N - 1)->node_pt(0) =
216 finite_element_pt(N - 2)->node_pt(n_node - 1);
217
218 // New central nodes (ignore last one which needs special treatment
219 // because it's on the boundary)
220 for (unsigned jnod = 1; jnod < (n_node - 1); jnod++)
221 {
222 // Allocate memory for nodes, as before
224 finite_element_pt(N - 1)->construct_node(jnod, time_stepper_pt);
225
226 // Get the local coordinate of the node
227 finite_element_pt(N - 1)->local_fraction_of_node(jnod, s_fraction);
228
229 // Set the position of the node
230 node_pt(node_count)->x(0) = xinit + el_length * (N - 1 + s_fraction[0]);
231
232 // Increment the node counter
233 node_count++;
234 }
235
236 // New final node
237 // --------------
238
239 // Allocate memory for the node, as before
240 Node_pt[node_count] = finite_element_pt(N - 1)->construct_boundary_node(
242
243 // Set the position of the node
244 node_pt(node_count)->x(0) = xinit + Length;
245
246 // Add the node to the boundary 1
247 add_boundary_node(1, Node_pt[node_count]);
248
249 // Increment the node counter
250 node_count++;
251 }
252 }
253
254} // namespace oomph
255
256#endif
e
Definition cfortran.h:571
Node ** Node_pt
Storage for pointers to the nodes in the element.
Definition elements.h:1323
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
TimeStepper *& time_stepper_pt()
Access function for pointer to time stepper: Null if object is not time-dependent.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition nodes.h:1060
void resize(const unsigned &n_value)
Resize the number of equations.
Definition nodes.cc:2167
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh constuction routine, called by all constructors.
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).