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