non_isothermal_axisym_nst_elements.h
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-2022 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 #define USE_FD_JACOBIAN_FOR_NONISOTHERMAL_AXISYMMETRIC_NAVIER_STOKES
27 
28 //======================class definition======================
45 //================================================================
47  public virtual QSteadyAxisymAdvectionDiffusionElement<3> ,
49 {
50 
51  public:
52 
53 
56  typedef void (*ViscosityRatioFctPt)(double& temperature,
57  double& result);
58 
65  {}
66 
67 
71  unsigned required_nvalue(const unsigned &n) const
72  {
74  AxisymmetricQCrouzeixRaviartElement::required_nvalue(n) );
75  }
76 
78  void output(ostream &outfile)
79  {
80  FiniteElement::output(outfile);
81  }
82 
85  // Start of output function
86  void output(ostream &outfile, const unsigned &nplot)
87  {
88  //vector of local coordinates
89  Vector<double> s(2);
90 
91  // Tecplot header info
92  outfile << this->tecplot_zone_string(nplot);
93 
94  // Loop over plot points
95  unsigned num_plot_points=this->nplot_points(nplot);
96  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
97  {
98  // Get local coordinates of plot point
99  this->get_s_plot(iplot,nplot,s);
100 
101  // Output the position (r,z) of the plot point
102  for(unsigned i=0;i<2;i++)
103  {
104  outfile << this->interpolated_x(s,i) << " ";
105  }
106 
107  // Output the fluid velocities (u,w,v) at the plot point
108  for(unsigned i=0;i<3;i++)
109  {
110  outfile << this->interpolated_u_axi_nst(s,i) << " ";
111  }
112 
113  // Output the fluid pressure at the plot point
114  outfile << this->interpolated_p_axi_nst(s) << " ";
115 
116  // Output the temperature (the advected variable) at the plot point
117  outfile << this->interpolated_u_adv_diff(s) << std::endl;
118  }
119  outfile << std::endl;
120 
121  // Write tecplot footer (e.g. FE connectivity lists)
122  this->write_tecplot_zone_footer(outfile,nplot);
123  } //End of output function
124 
125 
127  void output(FILE* file_pt)
128  {
129  FiniteElement::output(file_pt);
130  }
131 
133  void output(FILE* file_pt, const unsigned &n_plot)
134  {
135  FiniteElement::output(file_pt,n_plot);
136  }
137 
139  void output_fct(ostream &outfile,
140  const unsigned &Nplot,
141  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
142  {
143  FiniteElement::output_fct(outfile,Nplot,exact_soln_pt);
144  }
145 
146 
149  unsigned u_index_axisym_adv_diff() const
150  {
151  return 3;
152  }
153 
159  void compute_error(ostream &outfile,
160  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt,
161  double& error, double& norm)
162  {
163  FiniteElement::compute_error(outfile,exact_soln_pt,error,norm);
164  }
165 
166 
169 
172  {return Viscosity_ratio_fct_pt;}
173 
174 
178  inline virtual void get_viscosity_ratio_axisym_nst(const unsigned& ipt,
179  const Vector<double> &s,
180  const Vector<double> &x,
181  double &visco)
182  {
183  //If the function pointer is zero return zero
184  if (Viscosity_ratio_fct_pt == 0)
185  {
186  visco = *Viscosity_Ratio_pt;
187  }
188  //Otherwise call the function
189  else
190  {
191  //Get the temperature
192  double interpolated_t = this->interpolated_u_adv_diff(s);
193 
194  // Valuate viscosity ratio
195  (*Viscosity_ratio_fct_pt)(interpolated_t,visco);
196  }
197 
198 /* //Get the temperature */
199 /* const double interpolated_t = this->interpolated_u_adv_diff(s); */
200 
201 
202 /* // Parameters that modeling the viscosity */
203 /* double G = 1.0; */
204 /* double eta = 0.0; */
205 
206 /* visco = G*exp(eta*(1.0-interpolated_t)); */
207 
208  } // end of get_visco_axisym_nst
209 
210 
211 
215  void get_wind_axisym_adv_diff(const unsigned& ipt,
216  const Vector<double> &s,
217  const Vector<double>& x,
218  Vector<double>& wind) const
219  {
220  //The wind function is simply the velocity at the points
221  this->interpolated_u_axi_nst(s,wind);
222  } // end of get_wind_axisym_adv_diff
223 
229  void fill_in_contribution_to_residuals(Vector<double> &residuals)
230  {
231  //Fill in the residuals of the Navier-Stokes equations
233 
234  //Fill in the residuals of the advection-diffusion eqautions
236  }
237 
238 
239 //-----------Finite-difference the entire jacobian-----------------------
240 //-----------------------------------------------------------------------
241 #ifdef USE_FD_JACOBIAN_FOR_NONISOTHERMAL_AXISYMMETRIC_NAVIER_STOKES
242 
243 
246  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
247  DenseMatrix<double> &jacobian)
248  {
249  // This function computes the Jacobian by finite-differencing
251  }
252 
253 #else
254 
255 //--------Finite-difference off-diagonal-blocks in jacobian--------------
256 //-----------------------------------------------------------------------
257 #ifdef USE_OFF_DIAGONAL_FD_JACOBIAN_FOR_NONISOTHERMAL_AXISYMMETRIC_NAVIER_STOKES
258 
261  void fill_in_off_diagonal_jacobian_blocks_by_fd(Vector<double> &residuals,
262  DenseMatrix<double> &jacobian)
263  {
264  //Local storage for the index in the nodes at which the
265  //Navier-Stokes velocities are stored (we know that this should be 0,1,2)
266  unsigned u_nodal_nst[2];
267  for(unsigned i=0;i<2;i++)
268  {
269  u_nodal_nst[i] = this->u_index_axi_nst(i);
270  }
271 
272  //Local storage for the index at which the temperature is stored
273  unsigned u_nodal_adv_diff = this->u_index_axisym_adv_diff();
274 
275  //Find the total number of unknowns in the elements
276  unsigned n_dof = this->ndof();
277 
278  //Temporary storage for residuals
279  Vector<double> newres(n_dof);
280 
281  //Storage for local unknown and local equation
282  int local_unknown =0, local_eqn = 0;
283 
284  //Set the finite difference step
285  double fd_step = FiniteElement::Default_fd_jacobian_step;
286 
287  //Find the number of nodes
288  unsigned n_node = this->nnode();
289 
290  //Calculate the contribution of the Navier--Stokes velocities to the
291  //advection-diffusion equations
292 
293  //Loop over the nodes
294  for(unsigned n=0;n<n_node;n++)
295  {
296  //There are 2 values of the velocities
297  for(unsigned i=0;i<2;i++)
298  {
299  //Get the local velocity equation number
300  local_unknown = nodal_local_eqn(n,u_nodal_nst[i]);
301 
302  //If it's not pinned
303  if(local_unknown >= 0)
304  {
305  //Get a pointer to the velocity value
306  double *value_pt = this->node_pt(n)->value_pt(u_nodal_nst[i]);
307 
308  //Save the old value
309  double old_var = *value_pt;
310 
311  //Increment the value
312  *value_pt += fd_step;
313 
314  //Get the altered advection-diffusion residuals.
315  //which must be done using fill_in_contribution because
316  //get_residuals will always return the full residuals
317  //because the appropriate fill_in function is overloaded above
318  for(unsigned m=0;m<n_dof;m++) {newres[m] = 0.0;}
321 
322  //Now fill in the Advection-Diffusion sub-block
323  //of the jacobian
324  for(unsigned m=0;m<n_node;m++)
325  {
326  //Local equation for temperature
327  local_eqn = this->nodal_local_eqn(m,u_nodal_adv_diff);
328 
329  //If it's not a boundary condition
330  if(local_eqn >= 0)
331  {
332  double sum = (newres[local_eqn] - residuals[local_eqn])/fd_step;
333  jacobian(local_eqn,local_unknown) = sum;
334  }
335  }
336 
337  //Reset the nodal data
338  *value_pt = old_var;
339  }
340  }
341 
342 
343  //Calculate the contribution of the temperature to the Navier--Stokes
344  //equations
345  {
346  //Get the local equation number
347  local_unknown = this->nodal_local_eqn(n,u_nodal_adv_diff);
348 
349  //If it's not pinned
350  if(local_unknown >= 0)
351  {
352  //Get a pointer to the concentration value
353  double *value_pt = this->node_pt(n)->value_pt(u_nodal_adv_diff);
354 
355  //Save the old value
356  double old_var = *value_pt;
357 
358  //Increment the value (Really need access)
359  *value_pt += fd_step;
360 
361  //Get the altered Navier--Stokes residuals
362  //which must be done using fill_in_contribution because
363  //get_residuals will always return the full residuals
364  //because the appropriate fill_in function is overloaded above
365  for(unsigned m=0;m<n_dof;m++) {newres[m] = 0.0;}
368 
369  //Now fill in the Navier-Stokes sub-block
370  for(unsigned m=0;m<n_node;m++)
371  {
372  //Loop over the fluid velocities
373  for(unsigned j=0;j<2;j++)
374  {
375  //Local fluid equation
376  local_eqn = this->nodal_local_eqn(m,u_nodal_nst[j]);
377  if(local_eqn >= 0)
378  {
379  double sum = (newres[local_eqn] - residuals[local_eqn])/fd_step;
380  jacobian(local_eqn,local_unknown) = sum;
381  }
382  }
383  }
384 
385  //Reset the nodal data
386  *value_pt = old_var;
387  }
388  }
389 
390  } //End of loop over nodes
391  }
392 
393 
396  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
397  DenseMatrix<double> &jacobian)
398  {
399 
400  //Calculate the Navier-Stokes contributions (diagonal block and residuals)
402  fill_in_contribution_to_jacobian(residuals,jacobian);
403 
404  //Calculate the advection-diffusion contributions
405  //(diagonal block and residuals)
407  fill_in_contribution_to_jacobian(residuals,jacobian);
408 
409  //We now fill in the off-diagonal (interaction) blocks by finite
410  //differences.
411  fill_in_off_diagonal_jacobian_blocks_by_fd(residuals,jacobian);
412  } //End of jacobian calculation
413 
414 
415  //--------------------Analytic jacobian---------------------------------
416  //----------------------------------------------------------------------
417 #else
418 
421  void fill_in_off_diagonal_jacobian_blocks_analytic(Vector<double> &residuals,
422  DenseMatrix<double> &jacobian)
423  {
424  //We now fill in the off-diagonal (interaction) blocks analytically
425  //This requires knowledge of exactly how the residuals are assembled
426  //within the parent elements and involves yet another loop over
427  //the integration points!
428 
429  //Local storage for the index in the nodes at which the
430  //Navier-Stokes velocities are stored (we know that this should be 0,1,2)
431  unsigned u_nodal_nst[2];
432  for(unsigned i=0;i<2;i++)
433  {
434  u_nodal_nst[i] = this->u_index_axi_nst(i);
435  }
436 
437  //Local storage for the index at which the temperature is stored
438  const unsigned u_nodal_adv_diff = this->u_index_axisym_adv_diff();
439 
440  //Find out how many nodes there are
441  const unsigned n_node = this->nnode();
442 
443  //Set up memory for the shape and test functions and their derivatives
444  Shape psif(n_node), testf(n_node);
445  DShape dpsifdx(n_node,2), dtestfdx(n_node,2);
446 
447  //Number of integration points
448  const unsigned n_intpt = this->integral_pt()->nweight();
449 
450  //Get Physical Variables from Element
451  double Pe = this->pe();
452  Vector<double> gravity = this->g();
453 
454  //Integers to store the local equations and unknowns
455  int local_eqn=0, local_unknown=0;
456 
457  //Loop over the integration points
458  for(unsigned ipt=0;ipt<n_intpt;ipt++)
459  {
460  //Get the integral weight
461  double w = this->integral_pt()->weight(ipt);
462 
463  //Call the derivatives of the shape and test functions
464  double J = this->dshape_and_dtest_eulerian_at_knot_axi_nst(ipt,
465  psif,
466  dpsifdx,
467  testf,
468  dtestfdx);
469 
470  //Premultiply the weights and the Jacobian
471  double W = w*J;
472 
473  //Calculate local values of temperature derivatives
474  //Allocate
475  Vector<double> interpolated_du_adv_diff_dx(2,0.0);
476 
477  // Loop over nodes
478  for(unsigned l=0;l<n_node;l++)
479  {
480  //Get the nodal value
481  double u_value = this->raw_nodal_value(l,u_nodal_adv_diff);
482  //Loop over the derivative directions
483  for(unsigned j=0;j<2;j++)
484  {
485  interpolated_du_adv_diff_dx[j] += u_value*dpsifdx(l,j);
486  }
487  }
488 
489  //Assemble the jacobian terms
490 
491  //Loop over the test functions
492  for(unsigned l=0;l<n_node;l++)
493  {
494  //Assemble the contributions of the fluid velocities to the
495  //advection-diffusion equation for the temperature
496 
497  local_eqn = this->nodal_local_eqn(l,u_nodal_adv_diff);
498  //If it's not pinned
499  if(local_eqn >= 0)
500  {
501  //Loop over the shape functions again
502  for(unsigned l2=0;l2<n_node;l2++)
503  {
504  //Loop over the velocity degrees of freedom
505  for(unsigned i2=0;i2<2;i2++)
506  {
507  //Get the local unknown
508  local_unknown = this->nodal_local_eqn(l2,u_nodal_nst[i2]);
509  //If it's not pinned
510  if(local_unknown >= 0)
511  {
512  //Add the contribution to the jacobian matrix (It is necessary multiply by r)
513  jacobian(local_eqn,local_unknown)
514  -= Pe*psif(l2)*interpolated_du_adv_diff_dx[i2]*testf(l)*W;
515  }
516  }
517  }
518  }
519 
520  }
521  }
522  }
523 
524 
527  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
528  DenseMatrix<double> &jacobian)
529  {
530 
531  //Calculate the Navier-Stokes contributions (diagonal block and residuals)
533 
534  //Calculate the advection-diffusion contributions
535  //(diagonal block and residuals)
537 
538  //Fill in the off diagonal blocks analytically
539  fill_in_off_diagonal_jacobian_blocks_analytic(residuals,jacobian);
540  }
541 
542 
543 #endif
544 #endif
545 
546  private:
547 
548 
552 
553 };
554 
555 
559 
560 namespace oomph
561 {
562 
563 //=======================================================================
569 //=======================================================================
570 template<>
572  public virtual QElement<1,3>
573  {
574 
575  public:
576 
579  FaceGeometry() : QElement<1,3>() {}
580 
581  };
582 
583 template<>
585  public virtual PointElement
586  {
587  public:
589  };
590 
591 }
Matrix< Scalar, Dynamic, Dynamic > DenseMatrix
Definition: BenchSparseUtil.h:23
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
Definition: non_isothermal_axisym_nst_elements.h:49
virtual void get_viscosity_ratio_axisym_nst(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, double &visco)
Definition: non_isothermal_axisym_nst_elements.h:178
void output(ostream &outfile)
Overload the standard output function with the broken default.
Definition: non_isothermal_axisym_nst_elements.h:78
ViscosityRatioFctPt Viscosity_ratio_fct_pt
Definition: non_isothermal_axisym_nst_elements.h:551
void output(FILE *file_pt)
C-style output function: Broken default.
Definition: non_isothermal_axisym_nst_elements.h:127
void compute_error(ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Definition: non_isothermal_axisym_nst_elements.h:159
void output_fct(ostream &outfile, const unsigned &Nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: Broken default.
Definition: non_isothermal_axisym_nst_elements.h:139
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: Broken default.
Definition: non_isothermal_axisym_nst_elements.h:133
NonIsothermalAxisymmetricQCrouzeixRaviartElement()
Definition: non_isothermal_axisym_nst_elements.h:61
void get_wind_axisym_adv_diff(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &wind) const
Definition: non_isothermal_axisym_nst_elements.h:215
void(* ViscosityRatioFctPt)(double &temperature, double &result)
Definition: non_isothermal_axisym_nst_elements.h:56
unsigned u_index_axisym_adv_diff() const
Definition: non_isothermal_axisym_nst_elements.h:149
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Definition: non_isothermal_axisym_nst_elements.h:229
unsigned required_nvalue(const unsigned &n) const
Definition: non_isothermal_axisym_nst_elements.h:71
ViscosityRatioFctPt & viscosity_ratio_fct_pt()
Access function: Pointer to viscosity ratio function.
Definition: non_isothermal_axisym_nst_elements.h:168
ViscosityRatioFctPt viscosity_ratio_fct_pt() const
Access function: Pointer to viscosity ratio function. Const version.
Definition: non_isothermal_axisym_nst_elements.h:171
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: non_isothermal_axisym_nst_elements.h:246
void output(ostream &outfile, const unsigned &nplot)
Definition: non_isothermal_axisym_nst_elements.h:86
FaceGeometry()
Definition: non_isothermal_axisym_nst_elements.h:579
Definition: elements.h:4998
Definition: elements.h:3439
Definition: Qelements.h:459
RealScalar s
Definition: level1_cplx_impl.h:130
int * m
Definition: level2_cplx_impl.h:294
double Pe
Peclet number.
Definition: axisym_heat_sphere.cc:59
int error
Definition: calibrate.py:297
Definition: MortaringCantileverCompareToNonMortaring.cpp:176
@ W
Definition: quadtree.h:63
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: gen_axisym_advection_diffusion_elements.h:522
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: gen_axisym_advection_diffusion_elements.h:536
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: r,z,u_exact at nplot^2 plot points.
const double & pe() const
Peclet number.
Definition: gen_axisym_advection_diffusion_elements.h:284
list x
Definition: plotDoE.py:28
void output(std::ostream &outfile, const unsigned &nplot)
Overload output function.
Definition: overloaded_element_body.h:490
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2