thermo.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 for a multi-physics problem that couples the
31 //unsteady heat equation to the equations of large-displacement solid
32 //mechanics
33 
34 //Oomph-lib headers, we require the generic, unsteady heat
35 //and and elements.
36 #include "generic.h"
37 #include "solid.h"
38 #include "unsteady_heat.h"
39 
40 // The mesh is our standard rectangular quadmesh
41 #include "meshes/rectangular_quadmesh.h"
42 
43 // Use the oomph and std namespaces
44 using namespace oomph;
45 using namespace std;
46 
47 
48 
49 //=====================================================================
50 /// A class that solves the equations of steady thermoelasticity by
51 /// combining the UnsteadyHeat and PVD equations into a single element.
52 /// A temperature-dependent growth term is added to the PVD equations by
53 /// overloading the member function get_istotropic_growth()
54 //======================class definition==============================
55 template<unsigned DIM>
56 class QThermalPVDElement : public virtual QPVDElement<DIM,3>,
57  public virtual QUnsteadyHeatElement<DIM,3>
58 {
59 private:
60 
61  /// Pointer to a private data member, the thermal expansion coefficient
62  double* Alpha_pt;
63 
64  /// The static default value of Alpha
66 
67 public:
68  /// \short Constructor: call the underlying constructors and
69  /// initialise the pointer to Alpha to point
70  /// to the default value of 1.0.
71  QThermalPVDElement() : QPVDElement<DIM,3>(),
72  QUnsteadyHeatElement<DIM,3>()
73  {
74  Alpha_pt = &Default_Physical_Constant_Value;
75  }
76 
77  ///\short The required number of values stored at the nodes is the sum of the
78  ///required values of the two single-physics elements. Note that this step is
79  ///generic for any multi-physics element of this type.
80  unsigned required_nvalue(const unsigned &n) const
81  {return (QUnsteadyHeatElement<DIM,3>::required_nvalue(n) +
82  QPVDElement<DIM,3>::required_nvalue(n));}
83 
84  ///Access function for the thermal expansion coefficient (const version)
85  const double &alpha() const {return *Alpha_pt;}
86 
87  ///Access function for the pointer to the thermal expansion coefficientr
88  double* &alpha_pt() {return Alpha_pt;}
89 
90  /// Overload the standard output function with the broken default
91  void output(ostream &outfile) {FiniteElement::output(outfile);}
92 
93  /// \short Output function:
94  /// Output x, y, u, v, p, theta at Nplot^DIM plot points
95  // Start of output function
96  void output(ostream &outfile, const unsigned &nplot)
97  {
98  //vector of local coordinates
99  Vector<double> s(DIM);
100  Vector<double> xi(DIM);
101 
102  // Tecplot header info
103  outfile << this->tecplot_zone_string(nplot);
104 
105  // Loop over plot points
106  unsigned num_plot_points=this->nplot_points(nplot);
107  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
108  {
109  // Get local coordinates of plot point
110  this->get_s_plot(iplot,nplot,s);
111 
112  // Get the Lagrangian coordinate
113  this->interpolated_xi(s,xi);
114 
115  // Output the position of the plot point
116  for(unsigned i=0;i<DIM;i++)
117  {outfile << this->interpolated_x(s,i) << " ";}
118 
119  // Output the temperature (the advected variable) at the plot point
120  outfile << this->interpolated_u_ust_heat(s) << std::endl;
121  }
122  outfile << std::endl;
123 
124  // Write tecplot footer (e.g. FE connectivity lists)
125  this->write_tecplot_zone_footer(outfile,nplot);
126  } //End of output function
127 
128  /// \short C-style output function: Broken default
129  void output(FILE* file_pt)
130  {FiniteElement::output(file_pt);}
131 
132  /// \short C-style output function: Broken default
133  void output(FILE* file_pt, const unsigned &n_plot)
134  {FiniteElement::output(file_pt,n_plot);}
135 
136  /// \short Output function for an exact solution: Broken default
137  void output_fct(ostream &outfile, const unsigned &Nplot,
138  FiniteElement::SteadyExactSolutionFctPt
139  exact_soln_pt)
140  {FiniteElement::output_fct(outfile,Nplot,exact_soln_pt);}
141 
142 
143  /// \short Output function for a time-dependent exact solution:
144  /// Broken default.
145  void output_fct(ostream &outfile, const unsigned &Nplot,
146  const double& time,
147  FiniteElement::UnsteadyExactSolutionFctPt
148  exact_soln_pt)
149  {
150  FiniteElement::
151  output_fct(outfile,Nplot,time,exact_soln_pt);
152  }
153 
154  /// \short Compute norm of solution: use the version in the unsteady heat
155  /// class
156  void compute_norm(double& el_norm)
157  {
158  QUnsteadyHeatElement<DIM,3>::compute_norm(el_norm);
159  }
160 
161  /// \short Validate against exact solution at given time
162  /// Solution is provided via function pointer.
163  /// Plot at a given number of plot points and compute L2 error
164  /// and L2 norm of velocity solution over element
165  /// Call the broken default
166  void compute_error(ostream &outfile,
167  FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt,
168  const double& time,
169  double& error, double& norm)
170  {FiniteElement::compute_error(outfile,exact_soln_pt,
171  time,error,norm);}
172 
173  /// \short Validate against exact solution.
174  /// Solution is provided via function pointer.
175  /// Plot at a given number of plot points and compute L2 error
176  /// and L2 norm of velocity solution over element
177  /// Call the broken default
178  void compute_error(ostream &outfile,
179  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt,
180  double& error, double& norm)
181  {FiniteElement::compute_error(outfile,exact_soln_pt,error,norm);}
182 
183  /// \short Overload the growth function in the advection-diffusion equations.
184  /// to be temperature-dependent.
185  void get_isotropic_growth(const unsigned& ipt, const Vector<double> &s,
186  const Vector<double>& xi, double &gamma) const
187  {
188  //The growth is the undeformed coefficient plus linear thermal
189  //expansion
190  gamma = 1.0 + (*Alpha_pt)*this->interpolated_u_ust_heat(s);
191  }
192 
193  /// \short Calculate the contribution to the residual vector.
194  /// We assume that the vector has been initialised to zero
195  /// before this function is called.
196  void fill_in_contribution_to_residuals(Vector<double> &residuals)
197  {
198  //Call the residuals of the advection-diffusion eqautions
199  UnsteadyHeatEquations<DIM>::
200  fill_in_contribution_to_residuals(residuals);
201  //Call the residuals of the Navier-Stokes equations
202  PVDEquations<DIM>::
203  fill_in_contribution_to_residuals(residuals);
204  }
205 
206  ///\short Compute the element's residual Vector and the jacobian matrix
207  /// We assume that the residuals vector and jacobian matrix have been
208  /// initialised to zero before calling this function
209  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
210  DenseMatrix<double> &jacobian)
211  {
212  //Just call standard finite difference for a SolidFiniteElement so
213  //that variations in the nodal positions are taken into account
214  SolidFiniteElement::fill_in_contribution_to_jacobian(residuals,jacobian);
215  }
216 
217 };
218 
219 //=========================================================================
220 /// Set the default physical value to be one
221 //=========================================================================
222 template<>
224 
225 //======start_of_namespace============================================
226 /// Namespace for the physical parameters in the problem
227 //====================================================================
229 {
230  /// Thermal expansion coefficient
231  double Alpha=0.0;
232 
233  /// Young's modulus for solid mechanics
234  double E = 1.0; // ADJUST
235 
236  /// Poisson ratio for solid mechanics
237  double Nu = 0.3; // ADJUST
238 
239  /// We need a constitutive law for the solid mechanics
240  ConstitutiveLaw* Constitutive_law_pt;
241 
242 } // end_of_namespace
243 
244 //////////////////////////////////////////////////////////////////////
245 //////////////////////////////////////////////////////////////////////
246 //////////////////////////////////////////////////////////////////////
247 
248 //====== start_of_problem_class=======================================
249 /// 2D Thermoelasticity problem on rectangular domain, discretised
250 /// with refineable elements. The specific type
251 /// of element is specified via the template parameter.
252 //====================================================================
253 template<class ELEMENT>
254 class ThermalProblem : public Problem
255 {
256 
257 public:
258 
259  ///Constructor
260  ThermalProblem();
261 
262  /// Destructor. Empty
264 
265  /// \short Update the problem specs before solve (empty)
267 
268  /// Update the problem after solve (empty)
270 
271  /// Actions before adapt:(empty)
273 
274  /// \short Doc the solution.
275  void doc_solution();
276 
277  /// \short Overloaded version of the problem's access function to
278  /// the mesh. Recasts the pointer to the base Mesh object to
279  /// the actual mesh type.
280  ElasticRectangularQuadMesh<ELEMENT>* mesh_pt()
281  {
282  return dynamic_cast<ElasticRectangularQuadMesh<ELEMENT>*>(
283  Problem::mesh_pt());
284  }
285 
286 private:
287 
288  /// DocInfo object
289  DocInfo Doc_info;
290 
291 }; // end of problem class
292 
293 //========================================================================
294 /// \short Constructor for Convection problem
295 //========================================================================
296 template<class ELEMENT>
298 {
299  // Set output directory
300  Doc_info.set_directory("RESLT");
301 
302  // # of elements in x-direction
303  unsigned n_x=8;
304 
305  // # of elements in y-direction
306  unsigned n_y=8;
307 
308  // Domain length in x-direction
309  double l_x=3.0;
310 
311  // Domain length in y-direction
312  double l_y=1.0;
313 
314  // Build a standard rectangular quadmesh
315  Problem::mesh_pt() =
316  new ElasticRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
317 
318  // Set the boundary conditions for this problem: All nodes are
319  // free by default -- only need to pin the ones that have Dirichlet
320  // conditions here
321  {
322  //The temperature is prescribed on the lower boundary
323  unsigned n_boundary_node = mesh_pt()->nboundary_node(0);
324  for(unsigned n=0;n<n_boundary_node;n++)
325  {
326  //Get the pointer to the node
327  Node* nod_pt = mesh_pt()->boundary_node_pt(0,n);
328  //Pin the temperature at the node
329  nod_pt->pin(0);
330  //Set the temperature to 0.0 (cooled)
331  nod_pt->set_value(0,0.0);
332  }
333 
334  //The temperature is prescribed on the upper boundary
335  n_boundary_node = mesh_pt()->nboundary_node(2);
336  for(unsigned n=0;n<n_boundary_node;n++)
337  {
338  Node* nod_pt = mesh_pt()->boundary_node_pt(2,n);
339  //Pin the temperature at the node
340  nod_pt->pin(0);
341  //Set the temperature to 1.0 (heated)
342  nod_pt->set_value(0,1.0);
343  }
344 
345  //The horizontal-position is fixed on the vertical boundary (symmetry)
346  n_boundary_node = mesh_pt()->nboundary_node(1);
347  for(unsigned n=0;n<n_boundary_node;n++)
348  {
349  static_cast<SolidNode*>(mesh_pt()->boundary_node_pt(1,n))->pin_position(0);
350  }
351 
352  //We need to completely fix the lower-right corner of the block to
353  //prevent vertical rigid-body motions
354  static_cast<SolidNode*>(mesh_pt()->boundary_node_pt(1,0))->pin_position(1);
355  }
356 
357  // Complete the build of all elements so they are fully functional
358 
359  // Loop over the elements to set up element-specific
360  // things that cannot be handled by the (argument-free!) ELEMENT
361  // constructor.
362  unsigned n_element = mesh_pt()->nelement();
363  for(unsigned int i=0;i<n_element;i++)
364  {
365  // Upcast from GeneralsedElement to the present element
366  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
367 
368  // Set the coefficient of thermal expansion
369  el_pt->alpha_pt() = &Global_Physical_Variables::Alpha;
370 
371  // Set a constitutive law
372  el_pt->constitutive_law_pt() =
374  }
375 
376  // Setup equation numbering scheme
377  cout <<"Number of equations: " << assign_eqn_numbers() << endl;
378 
379 } // end of constructor
380 
381 
382 //========================================================================
383 /// Doc the solution
384 //========================================================================
385 template<class ELEMENT>
387 {
388  //Declare an output stream and filename
389  ofstream some_file;
390  char filename[100];
391 
392  // Number of plot points: npts x npts
393  unsigned npts=5;
394 
395  // Output solution
396  //-----------------
397  sprintf(filename,"%s/soln%i.dat",Doc_info.directory().c_str(),
398  Doc_info.number());
399  some_file.open(filename);
400  mesh_pt()->output(some_file,npts);
401  some_file.close();
402 
403  Doc_info.number()++;
404 } // end of doc
405 
406 
407 //=====================================================================
408 /// Driver code for 2D Thermoelasticity problem
409 //====================================================================
410 int main(int argc, char **argv)
411 {
412 
413  // "Big G" Linear constitutive equations:
415  new GeneralisedHookean(&Global_Physical_Variables::Nu,
417 
418  //Construct our problem
420 
421  //Number of quasi-steady steps
422  unsigned n_steps = 11;
423  //If we have additional command line arguemnts, take fewer steps
424  if(argc > 1) {n_steps = 2;}
425  for(unsigned i=0;i<n_steps;i++)
426  {
427  //Increase the thermal expansion coefficient
429 
430  //Perform a single steady newton solve
431  problem.newton_solve();
432  //Document the solution
433  problem.doc_solution();
434  }
435 } // end of main
436 
437 
438 
439 
440 
441 
442 
443 
444 
const double & alpha() const
Access function for the thermal expansion coefficient (const version)
Definition: thermo.cc:85
void output_fct(ostream &outfile, const unsigned &Nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: Broken default.
Definition: thermo.cc:137
void compute_error(ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Validate against exact solution. Solution is provided via function pointer. Plot at a given number of...
Definition: thermo.cc:178
void actions_before_newton_solve()
Update the problem specs before solve (empty)
Definition: thermo.cc:266
void actions_before_adapt()
Actions before adapt:(empty)
Definition: thermo.cc:272
double * Alpha_pt
Pointer to a private data member, the thermal expansion coefficient.
Definition: thermo.cc:62
unsigned required_nvalue(const unsigned &n) const
The required number of values stored at the nodes is the sum of the required values of the two single...
Definition: thermo.cc:80
void actions_after_newton_solve()
Update the problem after solve (empty)
Definition: thermo.cc:269
void get_isotropic_growth(const unsigned &ipt, const Vector< double > &s, const Vector< double > &xi, double &gamma) const
Overload the growth function in the advection-diffusion equations. to be temperature-dependent.
Definition: thermo.cc:185
ConstitutiveLaw * Constitutive_law_pt
We need a constitutive law for the solid mechanics.
Definition: thermo.cc:240
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Calculate the contribution to the residual vector. We assume that the vector has been initialised to ...
Definition: thermo.cc:196
void output(ostream &outfile)
Overload the standard output function with the broken default.
Definition: thermo.cc:91
ElasticRectangularQuadMesh< ELEMENT > * mesh_pt()
Overloaded version of the problem&#39;s access function to the mesh. Recasts the pointer to the base Mesh...
Definition: thermo.cc:280
void output_fct(ostream &outfile, const unsigned &Nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output function for a time-dependent exact solution: Broken default.
Definition: thermo.cc:145
DocInfo Doc_info
DocInfo object.
Definition: thermo.cc:289
void output(ostream &outfile, const unsigned &nplot)
Output function: Output x, y, u, v, p, theta at Nplot^DIM plot points.
Definition: thermo.cc:96
void doc_solution()
Doc the solution.
Definition: thermo.cc:386
void compute_error(ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Validate against exact solution at given time Solution is provided via function pointer. Plot at a given number of plot points and compute L2 error and L2 norm of velocity solution over element Call the broken default.
Definition: thermo.cc:166
void output(FILE *file_pt)
C-style output function: Broken default.
Definition: thermo.cc:129
Namespace for the physical parameters in the problem.
Definition: thermo.cc:228
int main(int argc, char **argv)
Driver code for 2D Thermoelasticity problem.
Definition: thermo.cc:410
static double Default_Physical_Constant_Value
The static default value of Alpha.
Definition: thermo.cc:65
ThermalProblem()
Constructor.
Definition: thermo.cc:297
void compute_norm(double &el_norm)
Compute norm of solution: use the version in the unsteady heat class.
Definition: thermo.cc:156
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: Broken default.
Definition: thermo.cc:133
QThermalPVDElement()
Constructor: call the underlying constructors and initialise the pointer to Alpha to point to the def...
Definition: thermo.cc:71
double *& alpha_pt()
Access function for the pointer to the thermal expansion coefficientr.
Definition: thermo.cc:88
~ThermalProblem()
Destructor. Empty.
Definition: thermo.cc:263
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element&#39;s residual Vector and the jacobian matrix We assume that the residuals vector and...
Definition: thermo.cc:209
double Nu
Poisson ratio for solid mechanics.
Definition: thermo.cc:237
double Alpha
Thermal expansion coefficient.
Definition: thermo.cc:231
double E
Young&#39;s modulus for solid mechanics.
Definition: thermo.cc:234