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-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 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
40using namespace oomph;
41using 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==============================
51template<unsigned DIM>
52class QThermalPVDElement : public virtual QPVDElement<DIM,3>,
53 public virtual QUnsteadyHeatElement<DIM,3>
54{
55private:
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
63public:
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 {
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//=========================================================================
218template<>
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//====================================================================
249template<class ELEMENT>
250class ThermalProblem : public Problem
251{
252
253public:
254
255 /// Constructor
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
282private:
283
284 /// DocInfo object
285 DocInfo Doc_info;
286
287}; // end of problem class
288
289//========================================================================
290/// Constructor for Convection problem
291//========================================================================
292template<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//========================================================================
381template<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 snprintf(filename, sizeof(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//====================================================================
406int 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
const double & alpha() const
Access function for the thermal expansion coefficient (const version)
Definition thermo.cc:81
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
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
double *& alpha_pt()
Access function for the pointer to the thermal expansion coefficientr.
Definition thermo.cc:84
2D Thermoelasticity problem on rectangular domain, discretised with refineable elements....
Definition thermo.cc:251
ThermalProblem()
Constructor.
Definition thermo.cc:293
void actions_before_adapt()
Actions before adapt:(empty)
Definition thermo.cc:268
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 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
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