boussinesq_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 // Header for a multi-physics elements that couple the Navier--Stokes
27 // and advection diffusion elements via a multi domain approach,
28 // giving Boussinesq convection
29 
30 #ifndef OOMPH_BOUSSINESQ_ELEMENTS_HEADER
31 #define OOMPH_BOUSSINESQ_ELEMENTS_HEADER
32 
33 // Oomph-lib headers, we require the generic, advection-diffusion
34 // and navier-stokes elements.
35 #include "generic.h"
36 #include "advection_diffusion.h"
37 #include "navier_stokes.h"
38 
39 
40 namespace oomph
41 {
45 
46 
47  //======================class definition==============================
63  //=========================================================================
64  template<unsigned DIM>
66  : public virtual QAdvectionDiffusionElement<DIM, 3>,
67  public virtual QCrouzeixRaviartElement<DIM>
68  {
69  private:
71  double* Ra_pt;
72 
75 
76  public:
82  {
84  }
85 
87  void unfix_pressure(const unsigned& p_dof)
88  {
89  this->internal_data_pt(this->P_nst_internal_index)->unpin(p_dof);
90  }
91 
95  unsigned required_nvalue(const unsigned& n) const
96  {
99  }
100 
102  const double& ra() const
103  {
104  return *Ra_pt;
105  }
106 
108  double*& ra_pt()
109  {
110  return Ra_pt;
111  }
112 
114  void disable_ALE()
115  {
116  // Disable ALE in both sets of equations
119  }
120 
122  void enable_ALE()
123  {
124  // Enable ALE in both sets of equations
127  }
128 
132  unsigned nscalar_paraview() const
133  {
134  throw OomphLibError(
135  "This function hasn't been implemented for this element",
138 
139  // Dummy unsigned
140  return 0;
141  }
142 
146  void scalar_value_paraview(std::ofstream& file_out,
147  const unsigned& i,
148  const unsigned& nplot) const
149  {
150  throw OomphLibError(
151  "This function hasn't been implemented for this element",
154  }
155 
156 
160  std::string scalar_name_paraview(const unsigned& i) const
161  {
162  return "V" + StringConversion::to_string(i);
163  }
164 
165 
167  void output(std::ostream& outfile)
168  {
169  FiniteElement::output(outfile);
170  }
171 
174  // Start of output function
175  void output(std::ostream& outfile, const unsigned& nplot)
176  {
177  // vector of local coordinates
179 
180  // Tecplot header info
181  outfile << this->tecplot_zone_string(nplot);
182 
183  // Loop over plot points
184  unsigned num_plot_points = this->nplot_points(nplot);
185  for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
186  {
187  // Get local coordinates of plot point
188  this->get_s_plot(iplot, nplot, s);
189 
190  // Output the position of the plot point
191  for (unsigned i = 0; i < DIM; i++)
192  {
193  outfile << this->interpolated_x(s, i) << " ";
194  }
195 
196  // Output the fluid velocities at the plot point
197  for (unsigned i = 0; i < DIM; i++)
198  {
199  outfile << this->interpolated_u_nst(s, i) << " ";
200  }
201 
202  // Output the fluid pressure at the plot point
203  outfile << this->interpolated_p_nst(s) << " ";
204 
205  // Output the temperature (the advected variable) at the plot point
206  outfile << this->interpolated_u_adv_diff(s) << std::endl;
207  }
208  outfile << std::endl;
209 
210  // Write tecplot footer (e.g. FE connectivity lists)
211  this->write_tecplot_zone_footer(outfile, nplot);
212  } // End of output function
213 
214 
216  void output(FILE* file_pt)
217  {
218  FiniteElement::output(file_pt);
219  }
220 
222  void output(FILE* file_pt, const unsigned& n_plot)
223  {
224  FiniteElement::output(file_pt, n_plot);
225  }
226 
228  void output_fct(std::ostream& outfile,
229  const unsigned& Nplot,
231  {
232  FiniteElement::output_fct(outfile, Nplot, exact_soln_pt);
233  }
234 
235 
238  void output_fct(std::ostream& outfile,
239  const unsigned& Nplot,
240  const double& time,
242  {
243  FiniteElement::output_fct(outfile, Nplot, time, exact_soln_pt);
244  }
245 
248  inline unsigned u_index_adv_diff() const
249  {
250  return DIM;
251  }
252 
258  void compute_error(std::ostream& outfile,
260  const double& time,
261  double& error,
262  double& norm)
263  {
264  FiniteElement::compute_error(outfile, exact_soln_pt, time, error, norm);
265  }
266 
272  void compute_error(std::ostream& outfile,
274  double& error,
275  double& norm)
276  {
277  FiniteElement::compute_error(outfile, exact_soln_pt, error, norm);
278  }
279 
283  void get_wind_adv_diff(const unsigned& ipt,
284  const Vector<double>& s,
285  const Vector<double>& x,
286  Vector<double>& wind) const
287  {
288  // The wind function is simply the velocity at the points
289  this->interpolated_u_nst(s, wind);
290  }
291 
292 
298  void get_body_force_nst(const double& time,
299  const unsigned& ipt,
300  const Vector<double>& s,
301  const Vector<double>& x,
302  Vector<double>& result)
303  {
304  // Get the temperature
305  const double interpolated_t = this->interpolated_u_adv_diff(s);
306 
307  // Get vector that indicates the direction of gravity from
308  // the Navier-Stokes equations
310 
311  // Temperature-dependent body force:
312  for (unsigned i = 0; i < DIM; i++)
313  {
314  result[i] = -gravity[i] * interpolated_t * ra();
315  }
316  } // end of get_body_force
317 
324  {
325  // Fill in the residuals of the Navier-Stokes equations
327 
328  // Fill in the residuals of the advection-diffusion eqautions
330  residuals);
331  }
332 
333 
334 //-----------Finite-difference the entire jacobian-----------------------
335 //-----------------------------------------------------------------------
336 #ifdef USE_FD_JACOBIAN_FOR_BUOYANT_Q_ELEMENT
337 
338 
342  DenseMatrix<double>& jacobian)
343  {
344  // This function computes the Jacobian by finite-differencing
346  }
347 
351  Vector<double>& residuals,
352  DenseMatrix<double>& jacobian,
353  DenseMatrix<double>& mass_matrix)
354  {
355  // Call the standard (Broken) function
356  // which will prevent these elements from being used
357  // in eigenproblems until replaced.
359  residuals, jacobian, mass_matrix);
360  }
361 
362 #else
363 //--------Finite-difference off-diagonal-blocks in jacobian--------------
364 //-----------------------------------------------------------------------
365 #ifdef USE_OFF_DIAGONAL_FD_JACOBIAN_FOR_BUOYANT_Q_ELEMENT
366 
369  void fill_in_off_diagonal_jacobian_blocks_by_fd(
370  Vector<double>& residuals, DenseMatrix<double>& jacobian)
371  {
372  // Local storage for the index in the nodes at which the
373  // Navier-Stokes velocities are stored (we know that this should be 0,1,2)
374  unsigned u_nodal_nst[DIM];
375  for (unsigned i = 0; i < DIM; i++)
376  {
377  u_nodal_nst[i] = this->u_index_nst(i);
378  }
379 
380  // Local storage for the index at which the temperature is stored
381  unsigned u_nodal_adv_diff = this->u_index_adv_diff();
382 
383  // Find the total number of unknowns in the elements
384  unsigned n_dof = this->ndof();
385 
386  // Temporary storage for residuals
387  Vector<double> newres(n_dof);
388 
389  // Storage for local unknown and local equation
390  int local_unknown = 0, local_eqn = 0;
391 
392  // Set the finite difference step
394 
395  // Find the number of nodes
396  unsigned n_node = this->nnode();
397 
398  // Calculate the contribution of the Navier--Stokes velocities to the
399  // advection-diffusion equations
400 
401  // Loop over the nodes
402  for (unsigned n = 0; n < n_node; n++)
403  {
404  // There are DIM values of the velocities
405  for (unsigned i = 0; i < DIM; i++)
406  {
407  // Get the local velocity equation number
408  local_unknown = this->nodal_local_eqn(n, u_nodal_nst[i]);
409 
410  // If it's not pinned
411  if (local_unknown >= 0)
412  {
413  // Get a pointer to the velocity value
414  double* value_pt = this->node_pt(n)->value_pt(u_nodal_nst[i]);
415 
416  // Save the old value
417  double old_var = *value_pt;
418 
419  // Increment the value
420  *value_pt += fd_step;
421 
422  // Get the altered advection-diffusion residuals.
423  // which must be done using fill_in_contribution because
424  // get_residuals will always return the full residuals
425  // because the appropriate fill_in function is overloaded above
426  for (unsigned m = 0; m < n_dof; m++)
427  {
428  newres[m] = 0.0;
429  }
431  newres);
432 
433  // AdvectionDiffusionEquations<DIM>::get_residuals(newres);
434 
435  // Now fill in the Advection-Diffusion sub-block
436  // of the jacobian
437  for (unsigned m = 0; m < n_node; m++)
438  {
439  // Local equation for temperature
440  local_eqn = this->nodal_local_eqn(m, u_nodal_adv_diff);
441 
442  // If it's not a boundary condition
443  if (local_eqn >= 0)
444  {
445  double sum =
446  (newres[local_eqn] - residuals[local_eqn]) / fd_step;
447  jacobian(local_eqn, local_unknown) = sum;
448  }
449  }
450 
451  // Reset the nodal data
452  *value_pt = old_var;
453  }
454  }
455 
456 
457  // Calculate the contribution of the temperature to the Navier--Stokes
458  // equations
459  {
460  // Get the local equation number
461  local_unknown = this->nodal_local_eqn(n, u_nodal_adv_diff);
462 
463  // If it's not pinned
464  if (local_unknown >= 0)
465  {
466  // Get a pointer to the concentration value
467  double* value_pt = this->node_pt(n)->value_pt(u_nodal_adv_diff);
468 
469  // Save the old value
470  double old_var = *value_pt;
471 
472  // Increment the value (Really need access)
473  *value_pt += fd_step;
474 
475  // Get the altered Navier--Stokes residuals
476  // which must be done using fill_in_contribution because
477  // get_residuals will always return the full residuals
478  // because the appropriate fill_in function is overloaded above
479  for (unsigned m = 0; m < n_dof; m++)
480  {
481  newres[m] = 0.0;
482  }
484  newres);
485 
486  // NavierStokesEquations<DIM>::get_residuals(newres);
487 
488  // Now fill in the Navier-Stokes sub-block
489  for (unsigned m = 0; m < n_node; m++)
490  {
491  // Loop over the fluid velocities
492  for (unsigned j = 0; j < DIM; j++)
493  {
494  // Local fluid equation
495  local_eqn = this->nodal_local_eqn(m, u_nodal_nst[j]);
496  if (local_eqn >= 0)
497  {
498  double sum =
499  (newres[local_eqn] - residuals[local_eqn]) / fd_step;
500  jacobian(local_eqn, local_unknown) = sum;
501  }
502  }
503  }
504 
505  // Reset the nodal data
506  *value_pt = old_var;
507  }
508  }
509 
510  } // End of loop over nodes
511  }
512 
513 
516  void fill_in_contribution_to_jacobian(Vector<double>& residuals,
517  DenseMatrix<double>& jacobian)
518  {
519  // Calculate the Navier-Stokes contributions (diagonal block and
520  // residuals)
522  jacobian);
523 
524  // Calculate the advection-diffusion contributions
525  //(diagonal block and residuals)
527  residuals, jacobian);
528 
529  // We now fill in the off-diagonal (interaction) blocks by finite
530  // differences.
531  fill_in_off_diagonal_jacobian_blocks_by_fd(residuals, jacobian);
532  } // End of jacobian calculation
533 
534 
538  Vector<double>& residuals,
539  DenseMatrix<double>& jacobian,
540  DenseMatrix<double>& mass_matrix)
541  {
542  // Get the analytic diagonal terms
545  jacobian,
546  mass_matrix);
547 
550  jacobian,
551  mass_matrix);
552 
553  // Now fill in the off-diagonal blocks
554  fill_in_off_diagonal_jacobian_blocks_by_fd(residuals, jacobian);
555  }
556 
557 
558  //--------------------Analytic jacobian---------------------------------
559 //-----------------------------------------------------------------------
560 #else
561 
565  Vector<double>& residuals, DenseMatrix<double>& jacobian)
566  {
567  // We now fill in the off-diagonal (interaction) blocks analytically
568  // This requires knowledge of exactly how the residuals are assembled
569  // within the parent elements and involves yet another loop over
570  // the integration points!
571 
572  // Local storage for the index in the nodes at which the
573  // Navier-Stokes velocities are stored (we know that this should be 0,1,2)
574  unsigned u_nodal_nst[DIM];
575  for (unsigned i = 0; i < DIM; i++)
576  {
577  u_nodal_nst[i] = this->u_index_nst(i);
578  }
579 
580  // Local storage for the index at which the temperature is stored
581  const unsigned u_nodal_adv_diff = this->u_index_adv_diff();
582 
583  // Find out how many nodes there are
584  const unsigned n_node = this->nnode();
585 
586  // Set up memory for the shape and test functions and their derivatives
587  Shape psif(n_node), testf(n_node);
588  DShape dpsifdx(n_node, DIM), dtestfdx(n_node, DIM);
589 
590  // Number of integration points
591  const unsigned n_intpt = this->integral_pt()->nweight();
592 
593  // Get Physical Variables from Element
594  double Ra = this->ra();
595  double Pe = this->pe();
596  Vector<double> gravity = this->g();
597 
598  // Integers to store the local equations and unknowns
599  int local_eqn = 0, local_unknown = 0;
600 
601  // Loop over the integration points
602  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
603  {
604  // Get the integral weight
605  double w = this->integral_pt()->weight(ipt);
606 
607  // Call the derivatives of the shape and test functions
609  ipt, psif, dpsifdx, testf, dtestfdx);
610 
611  // Premultiply the weights and the Jacobian
612  double W = w * J;
613 
614  // Calculate local values of temperature derivatives
615  // Allocate
616  Vector<double> interpolated_du_adv_diff_dx(DIM, 0.0);
617 
618  // Loop over nodes
619  for (unsigned l = 0; l < n_node; l++)
620  {
621  // Get the nodal value
622  double u_value = this->raw_nodal_value(l, u_nodal_adv_diff);
623  // Loop over the derivative directions
624  for (unsigned j = 0; j < DIM; j++)
625  {
626  interpolated_du_adv_diff_dx[j] += u_value * dpsifdx(l, j);
627  }
628  }
629 
630  // Assemble the jacobian terms
631 
632  // Loop over the test functions
633  for (unsigned l = 0; l < n_node; l++)
634  {
635  // Assemble the contributions of the temperature to
636  // the Navier--Stokes equations (which arise through the buoyancy
637  // body-force term)
638 
639  // Loop over the velocity components in the Navier--Stokes equtions
640  for (unsigned i = 0; i < DIM; i++)
641  {
642  // If it's not a boundary condition
643  local_eqn = this->nodal_local_eqn(l, u_nodal_nst[i]);
644  if (local_eqn >= 0)
645  {
646  // Loop over the velocity shape functions again
647  for (unsigned l2 = 0; l2 < n_node; l2++)
648  {
649  // We have only the temperature degree of freedom to consider
650  // If it's non-zero add in the contribution
651  local_unknown = this->nodal_local_eqn(l2, u_nodal_adv_diff);
652  if (local_unknown >= 0)
653  {
654  // Add contribution to jacobian matrix
655  jacobian(local_eqn, local_unknown) +=
656  -gravity[i] * psif(l2) * Ra * testf(l) * W;
657  }
658  }
659  }
660  }
661 
662  // Assemble the contributions of the fluid velocities to the
663  // advection-diffusion equation for the temperature
664  {
665  local_eqn = this->nodal_local_eqn(l, u_nodal_adv_diff);
666  // If it's not pinned
667  if (local_eqn >= 0)
668  {
669  // Loop over the shape functions again
670  for (unsigned l2 = 0; l2 < n_node; l2++)
671  {
672  // Loop over the velocity degrees of freedom
673  for (unsigned i2 = 0; i2 < DIM; i2++)
674  {
675  // Get the local unknown
676  local_unknown = this->nodal_local_eqn(l2, u_nodal_nst[i2]);
677  // If it's not pinned
678  if (local_unknown >= 0)
679  {
680  // Add the contribution to the jacobian matrix
681  jacobian(local_eqn, local_unknown) -=
682  Pe * psif(l2) * interpolated_du_adv_diff_dx[i2] *
683  testf(l) * W;
684  }
685  }
686  }
687  }
688  }
689  }
690  }
691  }
692 
693 
697  DenseMatrix<double>& jacobian)
698  {
699  // Calculate the Navier-Stokes contributions (diagonal block and
700  // residuals)
702  jacobian);
703 
704  // Calculate the advection-diffusion contributions
705  //(diagonal block and residuals)
707  residuals, jacobian);
708 
709  // Fill in the off diagonal blocks analytically
711  }
712 
713 
717  Vector<double>& residuals,
718  DenseMatrix<double>& jacobian,
719  DenseMatrix<double>& mass_matrix)
720  {
721  // Get the analytic diagonal terms for the jacobian and mass matrix
724  jacobian,
725  mass_matrix);
726 
729  jacobian,
730  mass_matrix);
731 
732  // Now fill in the off-diagonal blocks in the jacobian matrix
734  }
735 
736 #endif
737 #endif
738  };
739 
740  //=========================================================================
742  //=========================================================================
743  template<>
745  0.0;
746  template<>
748  0.0;
749 
750 
751  //=======================================================================
753  //=======================================================================
754  template<unsigned int DIM>
756  : public virtual QElement<DIM - 1, 3>
757  {
758  public:
759  FaceGeometry() : QElement<DIM - 1, 3>() {}
760  };
761 
762  //=======================================================================
764  //=======================================================================
765  template<>
767  : public virtual PointElement
768  {
769  public:
771  };
772 
773 
777 
778 
779  //============start_element_class============================================
798  //==========================================================================
799  template<unsigned DIM>
801  : public virtual RefineableQAdvectionDiffusionElement<DIM, 3>,
802  public virtual RefineableQCrouzeixRaviartElement<DIM>
803  {
804  private:
806  double* Ra_pt;
807 
810 
811  public:
818  {
820  }
821 
825  inline unsigned required_nvalue(const unsigned& n) const
826  {
829  }
830 
832  const double& ra() const
833  {
834  return *Ra_pt;
835  }
836 
838  double*& ra_pt()
839  {
840  return Ra_pt;
841  }
842 
843 
845  void disable_ALE()
846  {
847  // Disable ALE in both sets of equations
850  }
851 
853  void enable_ALE()
854  {
855  // Enable ALE in both sets of equations
858  }
859 
860 
864  unsigned nscalar_paraview() const
865  {
866  throw OomphLibError(
867  "This function hasn't been implemented for this element",
870 
871  // Dummy unsigned
872  return 0;
873  }
874 
878  void scalar_value_paraview(std::ofstream& file_out,
879  const unsigned& i,
880  const unsigned& nplot) const
881  {
882  throw OomphLibError(
883  "This function hasn't been implemented for this element",
886  }
887 
888 
892  std::string scalar_name_paraview(const unsigned& i) const
893  {
894  return "V" + StringConversion::to_string(i);
895  }
896 
898  void output(std::ostream& outfile)
899  {
900  FiniteElement::output(outfile);
901  }
902 
905  void output(std::ostream& outfile, const unsigned& nplot)
906  {
907  // vector of local coordinates
909 
910  // Tecplot header info
911  outfile << this->tecplot_zone_string(nplot);
912 
913  // Loop over plot points
914  unsigned num_plot_points = this->nplot_points(nplot);
915  for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
916  {
917  // Get local coordinates of plot point
918  this->get_s_plot(iplot, nplot, s);
919 
920  // Output the position of the plot point
921  for (unsigned i = 0; i < DIM; i++)
922  {
923  outfile << this->interpolated_x(s, i) << " ";
924  }
925 
926  // Output the fluid velocities at the plot point
927  for (unsigned i = 0; i < DIM; i++)
928  {
929  outfile << this->interpolated_u_nst(s, i) << " ";
930  }
931 
932  // Output the fluid pressure at the plot point
933  outfile << this->interpolated_p_nst(s) << " ";
934 
935  // Output the temperature at the plot point
936  outfile << this->interpolated_u_adv_diff(s) << " " << std::endl;
937  }
938  outfile << std::endl;
939 
940  // Write tecplot footer (e.g. FE connectivity lists)
941  this->write_tecplot_zone_footer(outfile, nplot);
942  }
943 
945  void output(FILE* file_pt)
946  {
947  FiniteElement::output(file_pt);
948  }
949 
951  void output(FILE* file_pt, const unsigned& n_plot)
952  {
953  FiniteElement::output(file_pt, n_plot);
954  }
955 
957  void output_fct(std::ostream& outfile,
958  const unsigned& Nplot,
960  {
961  FiniteElement::output_fct(outfile, Nplot, exact_soln_pt);
962  }
963 
964 
967  void output_fct(std::ostream& outfile,
968  const unsigned& Nplot,
969  const double& time,
971  {
972  FiniteElement::output_fct(outfile, Nplot, time, exact_soln_pt);
973  }
974 
977  unsigned u_index_adv_diff() const
978  {
979  return DIM;
980  }
981 
984  unsigned nvertex_node() const
985  {
987  }
988 
991  Node* vertex_node_pt(const unsigned& j) const
992  {
994  }
995 
998  unsigned ncont_interpolated_values() const
999  {
1000  return DIM + 1;
1001  }
1002 
1003 
1008  Vector<double>& values)
1009  {
1010  // Storage for the fluid velocities
1011  Vector<double> nst_values;
1012 
1013  // Get the fluid velocities from the fluid element
1015  s, nst_values);
1016 
1017  // Storage for the temperature
1018  Vector<double> advection_values;
1019 
1020  // Get the temperature from the advection-diffusion element
1022  s, advection_values);
1023 
1024  // Add the fluid velocities to the values vector
1025  for (unsigned i = 0; i < DIM; i++)
1026  {
1027  values.push_back(nst_values[i]);
1028  }
1029 
1030  // Add the concentration to the end
1031  values.push_back(advection_values[0]);
1032  }
1033 
1034 
1039  void get_interpolated_values(const unsigned& t,
1040  const Vector<double>& s,
1041  Vector<double>& values)
1042  {
1043  // Storage for the fluid velocities
1044  Vector<double> nst_values;
1045 
1046  // Get the fluid velocities from the fluid element
1048  t, s, nst_values);
1049 
1050  // Storage for the temperature
1051  Vector<double> advection_values;
1052 
1053  // Get the temperature from the advection-diffusion element
1055  s, advection_values);
1056 
1057  // Add the fluid velocities to the values vector
1058  for (unsigned i = 0; i < DIM; i++)
1059  {
1060  values.push_back(nst_values[i]);
1061  }
1062 
1063  // Add the concentration to the end
1064  values.push_back(advection_values[0]);
1065 
1066  } // end of get_interpolated_values
1067 
1068 
1072  {
1076  }
1077 
1078 
1081  void rebuild_from_sons(Mesh*& mesh_pt)
1082  {
1085  }
1086 
1087 
1092  {
1095 
1096  // Cast the pointer to the father element to the specific
1097  // element type
1098  RefineableBuoyantQCrouzeixRaviartElement<DIM>* cast_father_element_pt =
1100  this->father_element_pt());
1101 
1102  // Set the pointer to the Rayleigh number to be the same as that in
1103  // the father
1104  this->Ra_pt = cast_father_element_pt->ra_pt();
1105  } // end of further build
1106 
1107 
1109  unsigned nrecovery_order()
1110  {
1112  }
1113 
1117  {
1118  return (
1121  }
1122 
1123 
1127  {
1128  // Find the number of fluid fluxes
1129  unsigned n_fluid_flux =
1131 
1132  // Fill in the first flux entries as the velocity entries
1134 
1135  // Find the number of temperature fluxes
1136  unsigned n_temp_flux =
1138  Vector<double> temp_flux(n_temp_flux);
1139 
1140  // Get the temperature flux
1142 
1143  // Add the temperature flux to the end of the flux vector
1144  for (unsigned i = 0; i < n_temp_flux; i++)
1145  {
1146  flux[n_fluid_flux + i] = temp_flux[i];
1147  }
1148 
1149  } // end of get_Z2_flux
1150 
1153  unsigned ncompound_fluxes()
1154  {
1155  return 2;
1156  }
1157 
1161  {
1162  // Find the number of fluid fluxes
1163  unsigned n_fluid_flux =
1165  // Find the number of temperature fluxes
1166  unsigned n_temp_flux =
1168 
1169  // The fluid fluxes are first
1170  // The values of the flux_index vector are zero on entry, so we
1171  // could omit this line
1172  for (unsigned i = 0; i < n_fluid_flux; i++)
1173  {
1174  flux_index[i] = 0;
1175  }
1176 
1177  // Set the temperature fluxes (the last set of fluxes
1178  for (unsigned i = 0; i < n_temp_flux; i++)
1179  {
1180  flux_index[n_fluid_flux + i] = 1;
1181  }
1182 
1183  } // end of get_Z2_compound_flux_indices
1184 
1185 
1191  void compute_error(std::ostream& outfile,
1193  const double& time,
1194  double& error,
1195  double& norm)
1196  {
1197  FiniteElement::compute_error(outfile, exact_soln_pt, time, error, norm);
1198  }
1199 
1205  void compute_error(std::ostream& outfile,
1207  double& error,
1208  double& norm)
1209  {
1210  FiniteElement::compute_error(outfile, exact_soln_pt, error, norm);
1211  }
1212 
1216  void get_wind_adv_diff(const unsigned& ipt,
1217  const Vector<double>& s,
1218  const Vector<double>& x,
1219  Vector<double>& wind) const
1220  {
1221  // The wind function is simply the velocity at the points
1222  this->interpolated_u_nst(s, wind);
1223  }
1224 
1225 
1231  void get_body_force_nst(const double& time,
1232  const unsigned& ipt,
1233  const Vector<double>& s,
1234  const Vector<double>& x,
1235  Vector<double>& result)
1236  {
1237  // Get the temperature
1238  const double interpolated_t = this->interpolated_u_adv_diff(s);
1239 
1240  // Get vector that indicates the direction of gravity from
1241  // the Navier-Stokes equations
1243 
1244  // Temperature-dependent body force:
1245  for (unsigned i = 0; i < DIM; i++)
1246  {
1247  result[i] = -gravity[i] * interpolated_t * ra();
1248  }
1249  }
1250 
1253  {
1254  // Call the residuals of the Navier-Stokes equations
1256  residuals);
1257 
1258  // Call the residuals of the advection-diffusion equations
1261  }
1262 
1263 
1267  DenseMatrix<double>& jacobian)
1268  {
1269 #ifdef USE_FD_JACOBIAN_FOR_REFINEABLE_BUOYANT_Q_ELEMENT
1271 #else
1272  // Calculate the Navier-Stokes contributions (diagonal block and
1273  // residuals)
1275  residuals, jacobian);
1276 
1277  // Calculate the advection-diffusion contributions
1278  //(diagonal block and residuals)
1280  DIM>::fill_in_contribution_to_jacobian(residuals, jacobian);
1281 
1282  // We now fill in the off-diagonal (interaction) blocks analytically
1283  this->fill_in_off_diagonal_jacobian_blocks_analytic(residuals, jacobian);
1284 #endif
1285  } // End of jacobian calculation
1286 
1290  Vector<double>& residuals,
1291  DenseMatrix<double>& jacobian,
1292  DenseMatrix<double>& mass_matrix)
1293  {
1294  // Call the (broken) version in the base class
1296  residuals, jacobian, mass_matrix);
1297  }
1298 
1302  Vector<double>& residuals, DenseMatrix<double>& jacobian)
1303  {
1304  // Perform another loop over the integration loops using the information
1305  // from the original elements' residual assembly loops to determine
1306  // the conributions to the jacobian
1307 
1308  // Local storage for pointers to hang_info objects
1309  HangInfo *hang_info_pt = 0, *hang_info2_pt = 0;
1310 
1311  // Local storage for the index in the nodes at which the
1312  // Navier-Stokes velocities are stored (we know that this should be 0,1,2)
1313  unsigned u_nodal_nst[DIM];
1314  for (unsigned i = 0; i < DIM; i++)
1315  {
1316  u_nodal_nst[i] = this->u_index_nst(i);
1317  }
1318 
1319  // Local storage for the index at which the temperature is stored
1320  const unsigned u_nodal_adv_diff = this->u_index_adv_diff();
1321 
1322  // Find out how many nodes there are
1323  const unsigned n_node = this->nnode();
1324 
1325  // Set up memory for the shape and test functions and their derivatives
1326  Shape psif(n_node), testf(n_node);
1327  DShape dpsifdx(n_node, DIM), dtestfdx(n_node, DIM);
1328 
1329  // Number of integration points
1330  const unsigned n_intpt = this->integral_pt()->nweight();
1331 
1332  // Get Physical Variables from Element
1333  double Ra = this->ra();
1334  double Pe = this->pe();
1335  Vector<double> gravity = this->g();
1336 
1337  // Integers to store the local equations and unknowns
1338  int local_eqn = 0, local_unknown = 0;
1339 
1340  // Loop over the integration points
1341  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
1342  {
1343  // Get the integral weight
1344  double w = this->integral_pt()->weight(ipt);
1345 
1346  // Call the derivatives of the shape and test functions
1348  ipt, psif, dpsifdx, testf, dtestfdx);
1349 
1350  // Premultiply the weights and the Jacobian
1351  double W = w * J;
1352 
1353  // Calculate local values of temperature derivatives
1354  // Allocate
1355  Vector<double> interpolated_du_adv_diff_dx(DIM, 0.0);
1356 
1357  // Loop over nodes
1358  for (unsigned l = 0; l < n_node; l++)
1359  {
1360  // Get the nodal value
1361  double u_value = this->nodal_value(l, u_nodal_adv_diff);
1362  // Loop over the derivative directions
1363  for (unsigned j = 0; j < DIM; j++)
1364  {
1365  interpolated_du_adv_diff_dx[j] += u_value * dpsifdx(l, j);
1366  }
1367  }
1368 
1369  // Assemble the Jacobian terms
1370  //---------------------------
1371 
1372  // Loop over the test functions/eqns
1373  for (unsigned l = 0; l < n_node; l++)
1374  {
1375  // Local variables to store the number of master nodes and
1376  // the weight associated with the shape function if the node is
1377  // hanging
1378  unsigned n_master = 1;
1379  double hang_weight = 1.0;
1380 
1381  // Local bool (is the node hanging)
1382  bool is_node_hanging = this->node_pt(l)->is_hanging();
1383 
1384  // If the node is hanging, get the number of master nodes
1385  if (is_node_hanging)
1386  {
1387  hang_info_pt = this->node_pt(l)->hanging_pt();
1388  n_master = hang_info_pt->nmaster();
1389  }
1390  // Otherwise there is just one master node, the node itself
1391  else
1392  {
1393  n_master = 1;
1394  }
1395 
1396  // Loop over the master nodes
1397  for (unsigned m = 0; m < n_master; m++)
1398  {
1399  // If the node is hanging get weight from master node
1400  if (is_node_hanging)
1401  {
1402  // Get the hang weight from the master node
1403  hang_weight = hang_info_pt->master_weight(m);
1404  }
1405  else
1406  {
1407  // Node contributes with full weight
1408  hang_weight = 1.0;
1409  }
1410 
1411 
1412  // Assemble derivatives of Navier Stokes momentum w.r.t. temperature
1413  //-----------------------------------------------------------------
1414 
1415  // Loop over velocity components for equations
1416  for (unsigned i = 0; i < DIM; i++)
1417  {
1418  // Get the equation number
1419  if (is_node_hanging)
1420  {
1421  // Get the equation number from the master node
1422  local_eqn = this->local_hang_eqn(
1423  hang_info_pt->master_node_pt(m), u_nodal_nst[i]);
1424  }
1425  else
1426  {
1427  // Local equation number
1428  local_eqn = this->nodal_local_eqn(l, u_nodal_nst[i]);
1429  }
1430 
1431  if (local_eqn >= 0)
1432  {
1433  // Local variables to store the number of master nodes
1434  // and the weights associated with each hanging node
1435  unsigned n_master2 = 1;
1436  double hang_weight2 = 1.0;
1437 
1438  // Loop over the nodes for the unknowns
1439  for (unsigned l2 = 0; l2 < n_node; l2++)
1440  {
1441  // Local bool (is the node hanging)
1442  bool is_node2_hanging = this->node_pt(l2)->is_hanging();
1443 
1444  // If the node is hanging, get the number of master nodes
1445  if (is_node2_hanging)
1446  {
1447  hang_info2_pt = this->node_pt(l2)->hanging_pt();
1448  n_master2 = hang_info2_pt->nmaster();
1449  }
1450  // Otherwise there is one master node, the node itself
1451  else
1452  {
1453  n_master2 = 1;
1454  }
1455 
1456  // Loop over the master nodes
1457  for (unsigned m2 = 0; m2 < n_master2; m2++)
1458  {
1459  if (is_node2_hanging)
1460  {
1461  // Read out the local unknown from the master node
1462  local_unknown = this->local_hang_eqn(
1463  hang_info2_pt->master_node_pt(m2), u_nodal_adv_diff);
1464  // Read out the hanging weight from the master node
1465  hang_weight2 = hang_info2_pt->master_weight(m2);
1466  }
1467  else
1468  {
1469  // The local unknown number comes from the node
1470  local_unknown =
1471  this->nodal_local_eqn(l2, u_nodal_adv_diff);
1472  // The hang weight is one
1473  hang_weight2 = 1.0;
1474  }
1475 
1476  if (local_unknown >= 0)
1477  {
1478  // Add contribution to jacobian matrix
1479  jacobian(local_eqn, local_unknown) +=
1480  -gravity[i] * psif(l2) * Ra * testf(l) * W *
1481  hang_weight * hang_weight2;
1482  }
1483  }
1484  }
1485  }
1486  }
1487 
1488 
1489  // Assemble derivative of adv diff eqn w.r.t. fluid veloc
1490  //------------------------------------------------------
1491  {
1492  // Get the equation number
1493  if (is_node_hanging)
1494  {
1495  // Get the equation number from the master node
1496  local_eqn = this->local_hang_eqn(
1497  hang_info_pt->master_node_pt(m), u_nodal_adv_diff);
1498  }
1499  else
1500  {
1501  // Local equation number
1502  local_eqn = this->nodal_local_eqn(l, u_nodal_adv_diff);
1503  }
1504 
1505  // If it's not pinned
1506  if (local_eqn >= 0)
1507  {
1508  // Local variables to store the number of master nodes
1509  // and the weights associated with each hanging node
1510  unsigned n_master2 = 1;
1511  double hang_weight2 = 1.0;
1512 
1513  // Loop over the nodes for the unknowns
1514  for (unsigned l2 = 0; l2 < n_node; l2++)
1515  {
1516  // Local bool (is the node hanging)
1517  bool is_node2_hanging = this->node_pt(l2)->is_hanging();
1518 
1519  // If the node is hanging, get the number of master nodes
1520  if (is_node2_hanging)
1521  {
1522  hang_info2_pt = this->node_pt(l2)->hanging_pt();
1523  n_master2 = hang_info2_pt->nmaster();
1524  }
1525  // Otherwise there is one master node, the node itself
1526  else
1527  {
1528  n_master2 = 1;
1529  }
1530 
1531  // Loop over the master nodes
1532  for (unsigned m2 = 0; m2 < n_master2; m2++)
1533  {
1534  // If the node is hanging
1535  if (is_node2_hanging)
1536  {
1537  // Read out the hanging weight from the master node
1538  hang_weight2 = hang_info2_pt->master_weight(m2);
1539  }
1540  // If the node is not hanging
1541  else
1542  {
1543  // The hang weight is one
1544  hang_weight2 = 1.0;
1545  }
1546 
1547  // Loop over the velocity degrees of freedom
1548  for (unsigned i2 = 0; i2 < DIM; i2++)
1549  {
1550  // If the node is hanging
1551  if (is_node2_hanging)
1552  {
1553  // Read out the local unknown from the master node
1554  local_unknown = this->local_hang_eqn(
1555  hang_info2_pt->master_node_pt(m2), u_nodal_nst[i2]);
1556  }
1557  else
1558  {
1559  // The local unknown number comes from the node
1560  local_unknown =
1561  this->nodal_local_eqn(l2, u_nodal_nst[i2]);
1562  }
1563 
1564  // If it's not pinned
1565  if (local_unknown >= 0)
1566  {
1567  // Add the contribution to the jacobian matrix
1568  jacobian(local_eqn, local_unknown) -=
1569  Pe * psif(l2) * interpolated_du_adv_diff_dx[i2] *
1570  testf(l) * W * hang_weight * hang_weight2;
1571  }
1572  }
1573  }
1574  }
1575  }
1576  }
1577  }
1578  }
1579  }
1580  } // End of function
1581  };
1582 
1583 
1584  //===================================================================
1586  //===================================================================
1587  template<>
1590 
1591  template<>
1594 
1595 
1596 } // namespace oomph
1597 
1598 #endif
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
MatrixType m2(n_dims)
Definition: 3d_ref_b_convect.cc:533
Definition: advection_diffusion_elements.h:52
AdvectionDiffusionEquations()
Definition: advection_diffusion_elements.h:68
double interpolated_u_adv_diff(const Vector< double > &s) const
Return FE representation of function value u(s) at local coordinate s.
Definition: advection_diffusion_elements.h:458
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: advection_diffusion_elements.h:435
void enable_ALE()
Definition: advection_diffusion_elements.h:135
void disable_ALE()
Definition: advection_diffusion_elements.h:125
const double & pe() const
Peclet number.
Definition: advection_diffusion_elements.h:318
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: advection_diffusion_elements.h:421
Definition: boussinesq_elements.h:68
double * Ra_pt
Pointer to a private data member, the Rayleigh number.
Definition: boussinesq_elements.h:71
std::string scalar_name_paraview(const unsigned &i) const
Definition: boussinesq_elements.h:160
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Definition: boussinesq_elements.h:272
static double Default_Physical_Constant_Value
The static default value of the Rayleigh number.
Definition: boussinesq_elements.h:74
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Definition: boussinesq_elements.h:146
void output(std::ostream &outfile)
Overload the standard output function with the broken default.
Definition: boussinesq_elements.h:167
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: Broken default.
Definition: boussinesq_elements.h:222
unsigned nscalar_paraview() const
Definition: boussinesq_elements.h:132
void disable_ALE()
Final override for disable ALE.
Definition: boussinesq_elements.h:114
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Definition: boussinesq_elements.h:258
const double & ra() const
Access function for the Rayleigh number (const version)
Definition: boussinesq_elements.h:102
unsigned required_nvalue(const unsigned &n) const
Definition: boussinesq_elements.h:95
double *& ra_pt()
Access function for the pointer to the Rayleigh number.
Definition: boussinesq_elements.h:108
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: boussinesq_elements.h:696
void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Definition: boussinesq_elements.h:716
void output(std::ostream &outfile, const unsigned &nplot)
Definition: boussinesq_elements.h:175
void unfix_pressure(const unsigned &p_dof)
Unpin p_dof-th pressure dof.
Definition: boussinesq_elements.h:87
BuoyantQCrouzeixRaviartElement()
Definition: boussinesq_elements.h:80
void output(FILE *file_pt)
C-style output function: Broken default.
Definition: boussinesq_elements.h:216
void fill_in_off_diagonal_jacobian_blocks_analytic(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: boussinesq_elements.h:564
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Definition: boussinesq_elements.h:323
unsigned u_index_adv_diff() const
Definition: boussinesq_elements.h:248
void output_fct(std::ostream &outfile, const unsigned &Nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: Broken default.
Definition: boussinesq_elements.h:228
void get_wind_adv_diff(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &wind) const
Definition: boussinesq_elements.h:283
void output_fct(std::ostream &outfile, const unsigned &Nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: boussinesq_elements.h:238
void get_body_force_nst(const double &time, const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &result)
Definition: boussinesq_elements.h:298
void enable_ALE()
Final override for enable ALE.
Definition: boussinesq_elements.h:122
Definition: shape.h:278
void unpin(const unsigned &i)
Unpin the i-th stored variable.
Definition: nodes.h:391
double * value_pt(const unsigned &i) const
Definition: nodes.h:324
FaceGeometry()
Definition: boussinesq_elements.h:759
Definition: elements.h:4998
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: elements.h:1735
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output an exact solution over the element.
Definition: elements.h:3104
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void output(std::ostream &outfile)
Definition: elements.h:3050
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Definition: elements.h:3161
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
Definition: elements.cc:3962
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual void compute_error(FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Calculate the norm of the error and that of the exact solution.
Definition: elements.h:3198
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Definition: elements.h:1759
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Definition: elements.h:3148
virtual unsigned nplot_points(const unsigned &nplot) const
Definition: elements.h:3186
double raw_nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2576
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Definition: elements.h:3174
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Definition: elements.h:1765
static double Default_fd_jacobian_step
Definition: elements.h:1198
unsigned ndof() const
Return the number of equations/dofs in the element.
Definition: elements.h:835
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
virtual void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Definition: elements.cc:1322
Definition: nodes.h:742
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Definition: nodes.h:808
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
Definition: nodes.h:791
unsigned nmaster() const
Return the number of master nodes.
Definition: nodes.h:785
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
Definition: mesh.h:67
Definition: navier_stokes_elements.h:395
void disable_ALE()
Definition: navier_stokes_elements.h:909
virtual unsigned u_index_nst(const unsigned &i) const
Definition: navier_stokes_elements.h:866
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Compute the element's residual Vector.
Definition: navier_stokes_elements.h:1260
void interpolated_u_nst(const Vector< double > &s, Vector< double > &veloc) const
Compute vector of FE interpolated velocity u at local coordinate s.
Definition: navier_stokes_elements.h:1505
void enable_ALE()
Definition: navier_stokes_elements.h:918
virtual double interpolated_p_nst(const Vector< double > &s) const
Return FE interpolated pressure at local coordinate s.
Definition: navier_stokes_elements.h:1639
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: navier_stokes_elements.h:1273
NavierStokesEquations()
Definition: navier_stokes_elements.h:677
const Vector< double > & g() const
Vector of gravitational components.
Definition: navier_stokes_elements.h:765
Definition: nodes.h:906
HangInfo *const & hanging_pt() const
Definition: nodes.h:1228
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1285
Definition: oomph_definitions.h:222
Definition: elements.h:3439
Definition: advection_diffusion_elements.h:610
Definition: navier_stokes_elements.h:1749
double dshape_and_dtest_eulerian_at_knot_nst(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: navier_stokes_elements.h:1981
unsigned P_nst_internal_index
Definition: navier_stokes_elements.h:1757
Definition: Qelements.h:459
Definition: refineable_advection_diffusion_elements.h:58
void further_build()
Further build: Copy source function pointer from father element.
Definition: refineable_advection_diffusion_elements.h:177
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: refineable_advection_diffusion_elements.h:77
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: refineable_advection_diffusion_elements.h:84
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Definition: refineable_advection_diffusion_elements.h:94
Definition: boussinesq_elements.h:803
void rebuild_from_sons(Mesh *&mesh_pt)
Definition: boussinesq_elements.h:1081
void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Definition: boussinesq_elements.h:1289
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Definition: boussinesq_elements.h:1205
void get_wind_adv_diff(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &wind) const
Definition: boussinesq_elements.h:1216
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: boussinesq_elements.h:1266
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the constituent elements' contribution to the residual vector.
Definition: boussinesq_elements.h:1252
RefineableBuoyantQCrouzeixRaviartElement()
Definition: boussinesq_elements.h:815
unsigned nrecovery_order()
The recovery order is that of the NavierStokes elements.
Definition: boussinesq_elements.h:1109
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: boussinesq_elements.h:1126
unsigned nscalar_paraview() const
Definition: boussinesq_elements.h:864
static double Default_Physical_Constant_Value
The static default value of the Rayleigh number.
Definition: boussinesq_elements.h:809
void output(std::ostream &outfile, const unsigned &nplot)
Definition: boussinesq_elements.h:905
unsigned ncompound_fluxes()
Definition: boussinesq_elements.h:1153
Node * vertex_node_pt(const unsigned &j) const
Definition: boussinesq_elements.h:991
const double & ra() const
Access function for the Rayleigh number (const version)
Definition: boussinesq_elements.h:832
void further_build()
Definition: boussinesq_elements.h:1091
unsigned num_Z2_flux_terms()
Definition: boussinesq_elements.h:1116
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: Broken default.
Definition: boussinesq_elements.h:951
double * Ra_pt
Pointer to a new physical variable, the Rayleigh number.
Definition: boussinesq_elements.h:806
unsigned required_nvalue(const unsigned &n) const
Definition: boussinesq_elements.h:825
void get_body_force_nst(const double &time, const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &result)
Definition: boussinesq_elements.h:1231
void fill_in_off_diagonal_jacobian_blocks_analytic(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: boussinesq_elements.h:1301
void enable_ALE()
Final override for enable ALE.
Definition: boussinesq_elements.h:853
void disable_ALE()
Final override for disable ALE.
Definition: boussinesq_elements.h:845
double *& ra_pt()
Access function for the pointer to the Rayleigh number.
Definition: boussinesq_elements.h:838
unsigned nvertex_node() const
Definition: boussinesq_elements.h:984
void output(FILE *file_pt)
C-style output function: Broken default.
Definition: boussinesq_elements.h:945
unsigned ncont_interpolated_values() const
Definition: boussinesq_elements.h:998
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Definition: boussinesq_elements.h:878
void output_fct(std::ostream &outfile, const unsigned &Nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: Broken default.
Definition: boussinesq_elements.h:957
void output_fct(std::ostream &outfile, const unsigned &Nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: boussinesq_elements.h:967
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Definition: boussinesq_elements.h:1007
void further_setup_hanging_nodes()
Definition: boussinesq_elements.h:1071
void output(std::ostream &outfile)
Overload the standard output function with the broken default.
Definition: boussinesq_elements.h:898
unsigned u_index_adv_diff() const
Definition: boussinesq_elements.h:977
void get_Z2_compound_flux_indices(Vector< unsigned > &flux_index)
Definition: boussinesq_elements.h:1160
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Definition: boussinesq_elements.h:1191
std::string scalar_name_paraview(const unsigned &i) const
Definition: boussinesq_elements.h:892
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
Definition: boussinesq_elements.h:1039
virtual RefineableElement * father_element_pt() const
Return a pointer to the father element.
Definition: refineable_elements.h:539
int local_hang_eqn(Node *const &node_pt, const unsigned &i)
Definition: refineable_elements.h:278
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: refineable_navier_stokes_elements.h:395
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: refineable_navier_stokes_elements.h:403
Definition: refineable_advection_diffusion_elements.h:355
void rebuild_from_sons(Mesh *&mesh_pt)
Rebuild from sons: empty.
Definition: refineable_advection_diffusion_elements.h:395
Refineable version of Crouzeix Raviart elements. Generic class definitions.
Definition: refineable_navier_stokes_elements.h:1109
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Definition: refineable_navier_stokes_elements.h:1178
unsigned nrecovery_order()
Definition: refineable_navier_stokes_elements.h:1157
void further_setup_hanging_nodes()
Definition: refineable_navier_stokes_elements.h:1234
Definition: shape.h:76
RealScalar s
Definition: level1_cplx_impl.h:130
int * m
Definition: level2_cplx_impl.h:294
#define DIM
Definition: linearised_navier_stokes_elements.h:44
double Pe
Peclet number.
Definition: axisym_heat_sphere.cc:59
double Ra
Rayleigh number.
Definition: axisym_heat_sphere.cc:62
void gravity(const double &t, const Vector< double > &xi, Vector< double > &b)
Definition: ConstraintElementsUnitTest.cpp:20
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
int error
Definition: calibrate.py:297
Definition: MortaringCantileverCompareToNonMortaring.cpp:176
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
double Default_Physical_Constant_Value
Default value for physical constants.
Definition: multi_domain_boussinesq_elements.h:48
@ W
Definition: quadtree.h:63
std::string to_string(T object, unsigned float_precision=8)
Definition: oomph_utilities.h:189
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2