tensioned_string.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//Driver function for a simple beam proble
27
28//OOMPH-LIB includes
29#include "generic.h"
30#include "beam.h"
31#include "meshes/one_d_lagrangian_mesh.h"
32
33using namespace std;
34
35using namespace oomph;
36
37//========start_of_namespace========================
38/// Namespace for physical parameters
39//==================================================
41{
42 /// Non-dimensional thickness
43 double H;
44
45 /// 2nd Piola Kirchhoff pre-stress
46 double Sigma0;
47
48 /// Pressure load
49 double P_ext;
50
51 /// Load function: Apply a constant external pressure to the beam
52 void load(const Vector<double>& xi, const Vector<double> &x,
53 const Vector<double>& N, Vector<double>& load)
54 {
55 for(unsigned i=0;i<2;i++) {load[i] = -P_ext*N[i];}
56 }
57
58} // end of namespace
59
60//======start_of_problem_class==========================================
61/// Beam problem object
62//======================================================================
63class ElasticBeamProblem : public Problem
64{
65public:
66
67 /// Constructor: The arguments are the number of elements,
68 /// the length of domain
69 ElasticBeamProblem(const unsigned &n_elem, const double &length);
70
71 /// Conduct a parameter study
72 void parameter_study();
73
74 /// Return pointer to the mesh
75 OneDLagrangianMesh<HermiteBeamElement>* mesh_pt()
76 {return dynamic_cast<OneDLagrangianMesh<HermiteBeamElement>*>
77 (Problem::mesh_pt());}
78
79 /// No actions need to be performed after a solve
81
82 /// No actions need to be performed before a solve
84
85private:
86
87 /// Pointer to the node whose displacement is documented
89
90 /// Length of domain (in terms of the Lagrangian coordinates)
91 double Length;
92
93 /// Pointer to geometric object that represents the beam's undeformed shape
94 GeomObject* Undef_beam_pt;
95
96}; // end of problem class
97
98
99//=============start_of_constructor=====================================
100/// Constructor for elastic beam problem
101//======================================================================
103 const double &length) : Length(length)
104{
105 // Set the undeformed beam to be a straight line at y=0
106 Undef_beam_pt=new StraightLine(0.0);
107
108 // Create the (Lagrangian!) mesh, using the geometric object
109 // Undef_beam_pt to specify the initial (Eulerian) position of the
110 // nodes.
111 Problem::mesh_pt() =
112 new OneDLagrangianMesh<HermiteBeamElement>(n_elem,length,Undef_beam_pt);
113
114 // Set the boundary conditions: Each end of the beam is fixed in space
115 // Loop over the boundaries (ends of the beam)
116 for(unsigned b=0;b<2;b++)
117 {
118 // Pin displacements in both x and y directions
119 // [Note: The mesh_pt() function has been overloaded
120 // to return a pointer to the actual mesh, rather than
121 // a pointer to the Mesh base class. The current mesh is derived
122 // from the SolidMesh class. In such meshes, all access functions
123 // to the nodes, such as boundary_node_pt(...), are overloaded
124 // to return pointers to SolidNodes (whose position can be
125 // pinned) rather than "normal" Nodes.]
126 mesh_pt()->boundary_node_pt(b,0)->pin_position(0);
127 mesh_pt()->boundary_node_pt(b,0)->pin_position(1);
128 }
129
130 //Find number of elements in the mesh
131 unsigned n_element = mesh_pt()->nelement();
132
133 //Loop over the elements to set physical parameters etc.
134 for(unsigned e=0;e<n_element;e++)
135 {
136 // Upcast to the specific element type
137 HermiteBeamElement *elem_pt =
138 dynamic_cast<HermiteBeamElement*>(mesh_pt()->element_pt(e));
139
140 // Set physical parameters for each element:
141 elem_pt->sigma0_pt() = &Global_Physical_Variables::Sigma0;
142 elem_pt->h_pt() = &Global_Physical_Variables::H;
143
144 // Set the load Vector for each element
145 elem_pt->load_vector_fct_pt() = &Global_Physical_Variables::load;
146
147 // Set the undeformed shape for each element
148 elem_pt->undeformed_beam_pt() = Undef_beam_pt;
149 } // end of loop over elements
150
151 // Choose node at which displacement is documented (halfway along -- provided
152 // we have an odd number of nodes; complain if this is not the
153 // case because the comparison with the exact solution will be wrong
154 // otherwise!)
155 unsigned n_nod=mesh_pt()->nnode();
156 if (n_nod%2!=1)
157 {
158 cout << "Warning: Even number of nodes " << n_nod << std::endl;
159 cout << "Comparison with exact solution will be misleading..." << std::endl;
160 }
161 Doc_node_pt=mesh_pt()->node_pt((n_nod+1)/2-1);
162
163 // Assign the global and local equation numbers
164 cout << "# of dofs " << assign_eqn_numbers() << std::endl;
165
166} // end of constructor
167
168
169//=======start_of_parameter_study==========================================
170/// Solver loop to perform parameter study
171//=========================================================================
173{
174 // Over-ride the default maximum value for the residuals
175 Problem::Max_residuals = 1.0e10;
176
177 // Set the increments in control parameters
178 double pext_increment = 0.001;
179
180 // Set initial values for control parameters
181 Global_Physical_Variables::P_ext = 0.0 - pext_increment;
182
183 // Create label for output
184 DocInfo doc_info;
185
186 // Set output directory -- this function checks if the output
187 // directory exists and issues a warning if it doesn't.
188 doc_info.set_directory("RESLT");
189
190 // Open a trace file
191 ofstream trace("RESLT/trace_beam.dat");
192
193 // Write a header for the trace file
194 trace <<
195 "VARIABLES=\"p_e_x_t\",\"d\"" <<
196 ", \"p_e_x_t_(_e_x_a_c_t_)\"" << std::endl;
197
198 // Output file stream used for writing results
199 ofstream file;
200 // String used for the filename
201 char filename[100];
202
203 // Loop over parameter increments
204 unsigned nstep=10;
205 for(unsigned i=1;i<=nstep;i++)
206 {
207 // Increment pressure
208 Global_Physical_Variables::P_ext += pext_increment;
209
210 // Solve the system
211 newton_solve();
212
213 // Calculate exact solution for `string under tension' (applicable for
214 // small wall thickness and pinned ends)
215
216 // The tangent of the angle beta
217 double tanbeta =-2.0*Doc_node_pt->x(1)/Length;
218
219 double exact_pressure = 0.0;
220 //If the beam has deformed, calculate the pressure required
221 if(tanbeta!=0)
222 {
223
224 //Calculate the opening angle alpha
225 double alpha = 2.0*atan(2.0*tanbeta/(1.0-tanbeta*tanbeta));
226
227 // Jump back onto the main branch if alpha>180 degrees
228 if (alpha<0) alpha+=2.0*MathematicalConstants::Pi;
229
230 // Green strain:
231 double gamma=0.5*(0.25*alpha*alpha/(sin(0.5*alpha)*sin(0.5*alpha))-1.0);
232
233 //Calculate the exact pressure
234 exact_pressure=Global_Physical_Variables::H*
236 }
237
238 // Document the solution
239 snprintf(filename, sizeof(filename), "RESLT/beam%i.dat",i);
240 file.open(filename);
241 mesh_pt()->output(file,5);
242 file.close();
243
244 // Write trace file: Pressure, displacement and exact solution
245 // (for string under tension)
246 trace << Global_Physical_Variables::P_ext << " "
247 << abs(Doc_node_pt->x(1))
248 << " " << exact_pressure
249 << std::endl;
250 }
251
252} // end of parameter study
253
254//========start_of_main================================================
255/// Driver for beam (string under tension) test problem
256//=====================================================================
257int main()
258{
259
260 // Set the non-dimensional thickness
262
263 // Set the 2nd Piola Kirchhoff prestress
265
266 // Set the length of domain
267 double L = 10.0;
268
269 // Number of elements (choose an even number if you want the control point
270 // to be located at the centre of the beam)
271 unsigned n_element = 10;
272
273 // Construst the problem
274 ElasticBeamProblem problem(n_element,L);
275
276 // Check that we're ready to go:
277 cout << "\n\n\nProblem self-test ";
278 if (problem.self_test()==0)
279 {
280 cout << "passed: Problem can be solved." << std::endl;
281 }
282 else
283 {
284 throw OomphLibError("Self test failed",
285 OOMPH_CURRENT_FUNCTION,
286 OOMPH_EXCEPTION_LOCATION);
287 }
288
289 // Conduct parameter study
290 problem.parameter_study();
291
292} // end of main
293
Beam problem object.
GeomObject * Undef_beam_pt
Pointer to geometric object that represents the beam's undeformed shape.
ElasticBeamProblem(const unsigned &n_elem, const double &length)
Constructor: The arguments are the number of elements, the length of domain.
void parameter_study()
Conduct a parameter study.
void actions_after_newton_solve()
No actions need to be performed after a solve.
void actions_before_newton_solve()
No actions need to be performed before a solve.
OneDLagrangianMesh< HermiteBeamElement > * mesh_pt()
Return pointer to the mesh.
Node * Doc_node_pt
Pointer to the node whose displacement is documented.
double Length
Length of domain (in terms of the Lagrangian coordinates)
Namespace for physical parameters.
double P_ext
Pressure load.
void load(const Vector< double > &xi, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
Load function: Apply a constant external pressure to the beam.
double Sigma0
2nd Piola Kirchhoff pre-stress
double H
Non-dimensional thickness.
int main()
Driver for beam (string under tension) test problem.