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