scalar_advection_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 file for scalar advection elements
27 
28 #ifndef OOMPH_SCALAR_ADVECTION_ELEMENTS_HEADER
29 #define OOMPH_SCALAR_ADVECTION_ELEMENTS_HEADER
30 
31 // Config header generated by autoconfig
32 #ifdef HAVE_CONFIG_H
33 #include <oomph-lib-config.h>
34 #endif
35 
37 #include "../generic/Qelements.h"
38 #include "../generic/Qspectral_elements.h"
39 #include "../generic/dg_elements.h"
40 
41 namespace oomph
42 {
43  //==============================================================
45  //=============================================================
46  template<unsigned DIM>
48  {
50  typedef void (*ScalarAdvectionWindFctPt)(const Vector<double>& x,
51  Vector<double>& wind);
52 
55 
56  protected:
58  inline unsigned nflux() const
59  {
60  return 1;
61  }
62 
64  void flux(const Vector<double>& u, DenseMatrix<double>& f);
65 
67  void dflux_du(const Vector<double>& u, RankThreeTensor<double>& df_du);
68 
70  inline virtual void get_wind_scalar_adv(const unsigned& ipt,
71  const Vector<double>& s,
72  const Vector<double>& x,
73  Vector<double>& wind) const
74  {
75  // If no wind function has been set, return zero
76  if (Wind_fct_pt == 0)
77  {
78  for (unsigned i = 0; i < DIM; i++)
79  {
80  wind[i] = 0.0;
81  }
82  }
83  else
84  {
85  // Get wind
86  (*Wind_fct_pt)(x, wind);
87  }
88  }
89 
90  public:
93  {
94  }
95 
98  {
99  return Wind_fct_pt;
100  }
101 
104  {
105  return Wind_fct_pt;
106  }
107 
109  unsigned required_nvalue(const unsigned& n) const
110  {
111  return 1;
112  }
113 
117  std::ostream& outfile,
118  FiniteElement::UnsteadyExactSolutionFctPt initial_condition_pt,
119  const double& t,
121  Vector<double>& norm)
122  {
123  // Find the number of fluxes
124  const unsigned n_flux = this->nflux();
125  // Find the number of nodes
126  const unsigned n_node = this->nnode();
127  // Storage for the shape function and derivatives of shape function
128  Shape psi(n_node);
129  DShape dpsidx(n_node, DIM);
130 
131  // Find the number of integration points
132  unsigned n_intpt = this->integral_pt()->nweight();
133 
134  error.resize(n_flux);
135  norm.resize(n_flux);
136  for (unsigned i = 0; i < n_flux; i++)
137  {
138  error[i] = 0.0;
139  norm[i] = 0.0;
140  }
141 
143 
144  // Loop over the integration points
145  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
146  {
147  // Get the shape functions at the knot
148  double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
149 
150  // Get the integral weight
151  double W = this->integral_pt()->weight(ipt) * J;
152 
153  // Storage for the local functions
155  Vector<double> interpolated_u(n_flux, 0.0);
156 
157  // Loop over the shape functions
158  for (unsigned l = 0; l < n_node; l++)
159  {
160  // Locally cache the shape function
161  const double psi_ = psi(l);
162  for (unsigned i = 0; i < DIM; i++)
163  {
164  interpolated_x[i] += this->nodal_position(l, i) * psi_;
165  }
166 
167  for (unsigned i = 0; i < n_flux; i++)
168  {
169  // Calculate the velocity and tangent vector
170  interpolated_u[i] += this->nodal_value(l, i) * psi_;
171  }
172  }
173 
174  // Get the global wind
175  Vector<double> wind(DIM);
176  this->get_wind_scalar_adv(ipt, s, interpolated_x, wind);
177 
178  // Rescale the position
179  for (unsigned i = 0; i < DIM; i++)
180  {
181  interpolated_x[i] -= wind[i] * t;
182  }
183 
184  // Now get the initial condition at this value of x
185  Vector<double> exact_u(n_flux, 0.0);
186  (*initial_condition_pt)(0.0, interpolated_x, exact_u);
187 
188  // Loop over the unknowns
189  for (unsigned i = 0; i < n_flux; i++)
190  {
191  error[i] += pow((interpolated_u[i] - exact_u[i]), 2.0) * W;
192  norm[i] += interpolated_u[i] * interpolated_u[i] * W;
193  }
194  }
195  }
196  };
197 
198 
199  template<unsigned DIM, unsigned NNODE_1D>
201  : public virtual QSpectralElement<DIM, NNODE_1D>,
202  public virtual ScalarAdvectionEquations<DIM>
203  {
204  public:
209  {
210  }
211 
214  const QSpectralScalarAdvectionElement<DIM, NNODE_1D>& dummy) = delete;
215 
217  // Commented out broken assignment operator because this can lead to a
218  // conflict warning when used in the virtual inheritence hierarchy.
219  // Essentially the compiler doesn't realise that two separate
220  // implementations of the broken function are the same and so, quite
221  // rightly, it shouts.
222  /*void operator=(
223  const QSpectralScalarAdvectionElement<DIM,NNODE_1D>&) = delete;*/
224 
227  inline unsigned required_nvalue(const unsigned& n) const
228  {
229  return 1;
230  }
231 
234  void output(std::ostream& outfile)
235  {
237  }
238 
241  void output(std::ostream& outfile, const unsigned& n_plot)
242  {
243  ScalarAdvectionEquations<DIM>::output(outfile, n_plot);
244  }
245 
246 
247  /*/// C-style output function:
249  void output(FILE* file_pt)
250  {
251  ScalarAdvectionEquations<NFLUX,DIM>::output(file_pt);
252  }
253 
256  void output(FILE* file_pt, const unsigned &n_plot)
257  {
258  ScalarAdvectionEquations<NFLUX,DIM>::output(file_pt,n_plot);
259  }
260 
263  void output_fct(std::ostream &outfile, const unsigned &n_plot,
264  FiniteElement::SteadyExactSolutionFctPt
265  exact_soln_pt)
266  {
267  ScalarAdvectionEquations<NFLUX,DIM>::
268  output_fct(outfile,n_plot,exact_soln_pt);}
269 
270 
274  void output_fct(std::ostream &outfile, const unsigned &n_plot,
275  const double& time,
276  FiniteElement::UnsteadyExactSolutionFctPt
277  exact_soln_pt)
278  {
279  ScalarAdvectionEquations<NFLUX,DIM>::
280  output_fct(outfile,n_plot,time,exact_soln_pt);
281  }*/
282 
283 
284  protected:
288  const Vector<double>& s,
289  Shape& psi,
290  DShape& dpsidx,
291  Shape& test,
292  DShape& dtestdx) const;
293 
297  const unsigned& ipt,
298  Shape& psi,
299  DShape& dpsidx,
300  Shape& test,
301  DShape& dtestdx) const;
302  };
303 
304  // Inline functions:
305 
306 
307  //======================================================================
312  //======================================================================
313  template<unsigned DIM, unsigned NNODE_1D>
316  Shape& psi,
317  DShape& dpsidx,
318  Shape& test,
319  DShape& dtestdx) const
320  {
321  // Call the geometrical shape functions and derivatives
322  double J = this->dshape_eulerian(s, psi, dpsidx);
323 
324  // Loop over the test functions and derivatives and set them equal to the
325  // shape functions
326  for (unsigned i = 0; i < NNODE_1D; i++)
327  {
328  test[i] = psi[i];
329  for (unsigned j = 0; j < DIM; j++)
330  {
331  dtestdx(i, j) = dpsidx(i, j);
332  }
333  }
334 
335  // Return the jacobian
336  return J;
337  }
338 
339 
340  //======================================================================
345  //======================================================================
346  template<unsigned DIM, unsigned NNODE_1D>
349  Shape& psi,
350  DShape& dpsidx,
351  Shape& test,
352  DShape& dtestdx) const
353  {
354  // Call the geometrical shape functions and derivatives
355  double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
356 
357  // Set the test functions equal to the shape functions (pointer copy)
358  test = psi;
359  dtestdx = dpsidx;
360 
361  // Return the jacobian
362  return J;
363  }
364 
365 
369 
370 
371  //=======================================================================
376  //=======================================================================
377  template<unsigned DIM, unsigned NNODE_1D>
379  : public virtual QSpectralElement<DIM - 1, NNODE_1D>
380  {
381  public:
384  FaceGeometry() : QSpectralElement<DIM - 1, NNODE_1D>() {}
385  };
386 
387 
388  //======================================================================
390  //======================================================================
391  template<class ELEMENT>
392  class DGScalarAdvectionFaceElement : public virtual FaceGeometry<ELEMENT>,
393  public virtual DGFaceElement
394  {
395  public:
398  const int& face_index)
399  : FaceGeometry<ELEMENT>(), DGFaceElement()
400  {
401  // Attach geometric information to the element
402  // N.B. This function also assigns nbulk_value from required_nvalue
403  // of the bulk element.
404  element_pt->build_face_element(face_index, this);
405  }
406 
407 
408  // There is a single required n_flux
409  unsigned required_nflux()
410  {
411  return 1;
412  }
413 
416  void numerical_flux(const Vector<double>& n_out,
417  const Vector<double>& u_int,
418  const Vector<double>& u_ext,
420  {
421  const unsigned dim = this->nodal_dimension();
422  Vector<double> Wind(dim);
423  Vector<double> s, x;
424  // Dummy integration point
425  unsigned ipt = 0;
426  dynamic_cast<ELEMENT*>(this->bulk_element_pt())
427  ->get_wind_scalar_adv(ipt, s, x, Wind);
428 
429  // Now we can work this out for standard upwind advection
430  double dot = 0.0;
431  for (unsigned i = 0; i < dim; i++)
432  {
433  dot += Wind[i] * n_out[i];
434  }
435 
436  const unsigned n_value = this->required_nflux();
437  if (dot >= 0.0)
438  {
439  for (unsigned n = 0; n < n_value; n++)
440  {
441  flux[n] = dot * u_int[n];
442  }
443  }
444  else
445  {
446  for (unsigned n = 0; n < n_value; n++)
447  {
448  flux[n] = dot * u_ext[n];
449  }
450  }
451 
452  // flux[0] = 0.5*(u_int[0]+u_ext[0])*n_out[0];
453  }
454  };
455 
456  //=================================================================
458  //===================================================================
459  template<unsigned DIM, unsigned NNODE_1D>
461  {
462  };
463 
464 
465  //==================================================================
466  // Specialization for 1D DG Advection element
467  //==================================================================
468  template<unsigned NNODE_1D>
470  : public QSpectralScalarAdvectionElement<1, NNODE_1D>, public DGElement
471  {
472  friend class DGScalarAdvectionFaceElement<
473  DGSpectralScalarAdvectionElement<1, NNODE_1D>>;
474 
476 
477  public:
478  // There is a single required n_flux
479  unsigned required_nflux()
480  {
481  return 1;
482  }
483 
484  // Calculate averages
485  void calculate_element_averages(double*& average_value)
486  {
488  }
489 
490  // Constructor
492  : QSpectralScalarAdvectionElement<1, NNODE_1D>(), DGElement()
493  {
494  }
495 
497 
499  {
500  // Make the two faces
501  Face_element_pt.resize(2);
502  // Make the face on the left
503  Face_element_pt[0] = new DGScalarAdvectionFaceElement<
505  // Make the face on the right
506  Face_element_pt[1] = new DGScalarAdvectionFaceElement<
508  }
509 
510 
514  Vector<double>& residuals,
515  DenseMatrix<double>& jacobian,
516  DenseMatrix<double>& mass_matrix,
517  unsigned flag)
518  {
521  residuals, jacobian, mass_matrix, flag);
522 
523  this->add_flux_contributions_to_residuals(residuals, jacobian, flag);
524  }
525 
526 
527  //============================================================================
532  //============================================================================
534  {
535  // If there are external data this is not going to work
536  if (nexternal_data() > 0)
537  {
538  std::ostringstream error_stream;
539  error_stream
540  << "Cannot use a discontinuous formulation for the mass matrix when\n"
541  << "there are external data.\n "
542  << "Do not call Problem::enable_discontinuous_formulation()\n";
543 
544  throw OomphLibError(
545  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
546  }
547 
548 
549  // Now let's assemble stuff
550  const unsigned n_dof = this->ndof();
551 
552  // Resize and initialise the vector that will holds the residuals
553  minv_res.resize(n_dof);
554  for (unsigned n = 0; n < n_dof; n++)
555  {
556  minv_res[n] = 0.0;
557  }
558 
559  // If we are recycling the mass matrix
560  if (Mass_matrix_reuse_is_enabled && Mass_matrix_has_been_computed)
561  {
562  // Get the residuals
563  this->fill_in_contribution_to_residuals(minv_res);
564  }
565  // Otherwise
566  else
567  {
568  // Temporary mass matrix
569  DenseDoubleMatrix M(n_dof, n_dof, 0.0);
570 
571  // Get the local mass matrix and residuals
572  this->fill_in_contribution_to_mass_matrix(minv_res, M);
573 
574  // Store the diagonal entries
575  Inverse_mass_diagonal.clear();
576  for (unsigned n = 0; n < n_dof; n++)
577  {
578  Inverse_mass_diagonal.push_back(1.0 / M(n, n));
579  }
580 
581  // The mass matrix has been computed
582  Mass_matrix_has_been_computed = true;
583  }
584 
585  for (unsigned n = 0; n < n_dof; n++)
586  {
587  minv_res[n] *= Inverse_mass_diagonal[n];
588  }
589  }
590  };
591 
592 
593  //=======================================================================
595  //=======================================================================
596  template<unsigned NNODE_1D>
598  : public virtual PointElement
599  {
600  public:
602  };
603 
604 
605  //==================================================================
607  //==================================================================
608  template<unsigned NNODE_1D>
610  : public QSpectralScalarAdvectionElement<2, NNODE_1D>, public DGElement
611  {
612  friend class DGScalarAdvectionFaceElement<
613  DGSpectralScalarAdvectionElement<2, NNODE_1D>>;
614 
615  public:
616  // Calculate averages
617  void calculate_element_averages(double*& average_value)
618  {
620  }
621 
622  // There is a single required n_flux
623  unsigned required_nflux()
624  {
625  return 1;
626  }
627 
628  // Constructor
630  : QSpectralScalarAdvectionElement<2, NNODE_1D>(), DGElement()
631  {
632  }
633 
635 
637  {
638  Face_element_pt.resize(4);
639  Face_element_pt[0] = new DGScalarAdvectionFaceElement<
641  Face_element_pt[1] = new DGScalarAdvectionFaceElement<
643  Face_element_pt[2] = new DGScalarAdvectionFaceElement<
645  Face_element_pt[3] = new DGScalarAdvectionFaceElement<
647  }
648 
649 
653  Vector<double>& residuals,
654  DenseMatrix<double>& jacobian,
655  DenseMatrix<double>& mass_matrix,
656  unsigned flag)
657  {
660  residuals, jacobian, mass_matrix, flag);
661 
662  this->add_flux_contributions_to_residuals(residuals, jacobian, flag);
663  }
664  };
665 
666 
667  //=======================================================================
669  //=======================================================================
670  template<unsigned NNODE_1D>
672  : public virtual QSpectralElement<1, NNODE_1D>
673  {
674  public:
675  FaceGeometry() : QSpectralElement<1, NNODE_1D>() {}
676  };
677 
678 
679  //=============================================================
681  //============================================================
682  template<unsigned DIM, unsigned NNODE_1D>
683  class QScalarAdvectionElement : public virtual QElement<DIM, NNODE_1D>,
684  public virtual ScalarAdvectionEquations<DIM>
685  {
686  public:
690  : QElement<DIM, NNODE_1D>(), ScalarAdvectionEquations<DIM>()
691  {
692  }
693 
696  const QScalarAdvectionElement<DIM, NNODE_1D>& dummy) = delete;
697 
699  /*void operator=(
700  const QScalarAdvectionElement<DIM,NNODE_1D>&) = delete;*/
701 
704  inline unsigned required_nvalue(const unsigned& n) const
705  {
706  return 1;
707  }
708 
711  void output(std::ostream& outfile)
712  {
714  }
715 
718  void output(std::ostream& outfile, const unsigned& n_plot)
719  {
720  ScalarAdvectionEquations<DIM>::output(outfile, n_plot);
721  }
722 
723 
724  /*/// C-style output function:
726  void output(FILE* file_pt)
727  {
728  ScalarAdvectionEquations<NFLUX,DIM>::output(file_pt);
729  }
730 
733  void output(FILE* file_pt, const unsigned &n_plot)
734  {
735  ScalarAdvectionEquations<NFLUX,DIM>::output(file_pt,n_plot);
736  }
737 
740  void output_fct(std::ostream &outfile, const unsigned &n_plot,
741  FiniteElement::SteadyExactSolutionFctPt
742  exact_soln_pt)
743  {
744  ScalarAdvectionEquations<NFLUX,DIM>::
745  output_fct(outfile,n_plot,exact_soln_pt);}
746 
747 
751  void output_fct(std::ostream &outfile, const unsigned &n_plot,
752  const double& time,
753  FiniteElement::UnsteadyExactSolutionFctPt
754  exact_soln_pt)
755  {
756  ScalarAdvectionEquations<NFLUX,DIM>::
757  output_fct(outfile,n_plot,time,exact_soln_pt);
758  }*/
759 
760 
761  protected:
765  const Vector<double>& s,
766  Shape& psi,
767  DShape& dpsidx,
768  Shape& test,
769  DShape& dtestdx) const;
770 
774  const unsigned& ipt,
775  Shape& psi,
776  DShape& dpsidx,
777  Shape& test,
778  DShape& dtestdx) const;
779  };
780 
781  // Inline functions:
782 
783 
784  //======================================================================
789  //======================================================================
790  template<unsigned DIM, unsigned NNODE_1D>
793  Shape& psi,
794  DShape& dpsidx,
795  Shape& test,
796  DShape& dtestdx) const
797  {
798  // Call the geometrical shape functions and derivatives
799  double J = this->dshape_eulerian(s, psi, dpsidx);
800 
801  // Loop over the test functions and derivatives and set them equal to the
802  // shape functions
803  for (unsigned i = 0; i < NNODE_1D; i++)
804  {
805  test[i] = psi[i];
806  for (unsigned j = 0; j < DIM; j++)
807  {
808  dtestdx(i, j) = dpsidx(i, j);
809  }
810  }
811 
812  // Return the jacobian
813  return J;
814  }
815 
816 
817  //======================================================================
822  //======================================================================
823  template<unsigned DIM, unsigned NNODE_1D>
826  Shape& psi,
827  DShape& dpsidx,
828  Shape& test,
829  DShape& dtestdx) const
830  {
831  // Call the geometrical shape functions and derivatives
832  double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
833 
834  // Set the test functions equal to the shape functions (pointer copy)
835  test = psi;
836  dtestdx = dpsidx;
837 
838  // Return the jacobian
839  return J;
840  }
841 
842 
846 
847 
848  //=======================================================================
853  //=======================================================================
854  template<unsigned DIM, unsigned NNODE_1D>
856  : public virtual QElement<DIM - 1, NNODE_1D>
857  {
858  public:
861  FaceGeometry() : QElement<DIM - 1, NNODE_1D>() {}
862  };
863 
864 
865  //=================================================================
867  //===================================================================
868  template<unsigned DIM, unsigned NNODE_1D>
870  {
871  };
872 
873 
874  //==================================================================
875  // Specialization for 1D DG Advection element
876  //==================================================================
877  template<unsigned NNODE_1D>
878  class DGScalarAdvectionElement<1, NNODE_1D>
879  : public QScalarAdvectionElement<1, NNODE_1D>, public DGElement
880  {
881  friend class DGScalarAdvectionFaceElement<
882  DGScalarAdvectionElement<1, NNODE_1D>>;
883 
884  public:
885  // There is a single required n_flux
886  unsigned required_nflux()
887  {
888  return 1;
889  }
890 
891  // Calculate averages
892  void calculate_element_averages(double*& average_value)
893  {
895  }
896 
897  // Constructor
899  : QScalarAdvectionElement<1, NNODE_1D>(), DGElement()
900  {
901  }
902 
904 
906  {
907  // Make the two faces
908  Face_element_pt.resize(2);
909  // Make the face on the left
910  Face_element_pt[0] =
912  this, -1);
913  // Make the face on the right
914  Face_element_pt[1] =
916  this, +1);
917  }
918 
919 
923  Vector<double>& residuals,
924  DenseMatrix<double>& jacobian,
925  DenseMatrix<double>& mass_matrix,
926  unsigned flag)
927  {
930  residuals, jacobian, mass_matrix, flag);
931 
932  this->add_flux_contributions_to_residuals(residuals, jacobian, flag);
933  }
934  };
935 
936 
937  //=======================================================================
939  //=======================================================================
940  template<unsigned NNODE_1D>
942  : public virtual PointElement
943  {
944  public:
946  };
947 
948 
949  //==================================================================
951  //==================================================================
952  template<unsigned NNODE_1D>
953  class DGScalarAdvectionElement<2, NNODE_1D>
954  : public QScalarAdvectionElement<2, NNODE_1D>, public DGElement
955  {
956  friend class DGScalarAdvectionFaceElement<
957  DGScalarAdvectionElement<2, NNODE_1D>>;
958 
959  public:
960  // There is a single required n_flux
961  unsigned required_nflux()
962  {
963  return 1;
964  }
965 
966  // Calculate averages
967  void calculate_element_averages(double*& average_value)
968  {
970  }
971 
972  // Constructor
974  : QScalarAdvectionElement<2, NNODE_1D>(), DGElement()
975  {
976  }
977 
979 
981  {
982  Face_element_pt.resize(4);
983  Face_element_pt[0] =
985  this, 2);
986  Face_element_pt[1] =
988  this, 1);
989  Face_element_pt[2] =
991  this, -2);
992  Face_element_pt[3] =
994  this, -1);
995  }
996 
997 
1001  Vector<double>& residuals,
1002  DenseMatrix<double>& jacobian,
1003  DenseMatrix<double>& mass_matrix,
1004  unsigned flag)
1005  {
1008  residuals, jacobian, mass_matrix, flag);
1009 
1010  this->add_flux_contributions_to_residuals(residuals, jacobian, flag);
1011  }
1012  };
1013 
1014 
1015  //=======================================================================
1017  //=======================================================================
1018  template<unsigned NNODE_1D>
1020  : public virtual QElement<1, NNODE_1D>
1021  {
1022  public:
1023  FaceGeometry() : QElement<1, NNODE_1D>() {}
1024  };
1025 
1026 
1027 } // namespace oomph
1028 
1029 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:50
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
A Base class for DGElements.
Definition: dg_elements.h:161
Definition: dg_elements.h:50
void build_all_faces()
Definition: scalar_advection_elements.h:905
~DGScalarAdvectionElement()
Definition: scalar_advection_elements.h:903
DGScalarAdvectionElement()
Definition: scalar_advection_elements.h:898
unsigned required_nflux()
Set the number of flux components.
Definition: scalar_advection_elements.h:886
void calculate_element_averages(double *&average_value)
Calculate the averages in the element.
Definition: scalar_advection_elements.h:892
void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Definition: scalar_advection_elements.h:922
void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Definition: scalar_advection_elements.h:1000
unsigned required_nflux()
Set the number of flux components.
Definition: scalar_advection_elements.h:961
~DGScalarAdvectionElement()
Definition: scalar_advection_elements.h:978
void build_all_faces()
Definition: scalar_advection_elements.h:980
void calculate_element_averages(double *&average_value)
Calculate the averages in the element.
Definition: scalar_advection_elements.h:967
DGScalarAdvectionElement()
Definition: scalar_advection_elements.h:973
General DGScalarAdvectionClass. Establish the template parameters.
Definition: scalar_advection_elements.h:870
FaceElement for Discontinuous Galerkin Problems.
Definition: scalar_advection_elements.h:394
DGScalarAdvectionFaceElement(FiniteElement *const &element_pt, const int &face_index)
Constructor.
Definition: scalar_advection_elements.h:397
unsigned required_nflux()
Set the number of flux components.
Definition: scalar_advection_elements.h:409
void numerical_flux(const Vector< double > &n_out, const Vector< double > &u_int, const Vector< double > &u_ext, Vector< double > &flux)
Definition: scalar_advection_elements.h:416
Definition: scalar_advection_elements.h:471
unsigned required_nflux()
Set the number of flux components.
Definition: scalar_advection_elements.h:479
DGSpectralScalarAdvectionElement()
Definition: scalar_advection_elements.h:491
Vector< double > Inverse_mass_diagonal
Definition: scalar_advection_elements.h:475
void calculate_element_averages(double *&average_value)
Calculate the averages in the element.
Definition: scalar_advection_elements.h:485
~DGSpectralScalarAdvectionElement()
Definition: scalar_advection_elements.h:496
void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Definition: scalar_advection_elements.h:513
void build_all_faces()
Definition: scalar_advection_elements.h:498
void get_inverse_mass_matrix_times_residuals(Vector< double > &minv_res)
Definition: scalar_advection_elements.h:533
Specialisation for 2D DG Elements.
Definition: scalar_advection_elements.h:611
unsigned required_nflux()
Set the number of flux components.
Definition: scalar_advection_elements.h:623
DGSpectralScalarAdvectionElement()
Definition: scalar_advection_elements.h:629
void calculate_element_averages(double *&average_value)
Calculate the averages in the element.
Definition: scalar_advection_elements.h:617
void build_all_faces()
Definition: scalar_advection_elements.h:636
void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Definition: scalar_advection_elements.h:652
~DGSpectralScalarAdvectionElement()
Definition: scalar_advection_elements.h:634
General DGScalarAdvectionClass. Establish the template parameters.
Definition: scalar_advection_elements.h:461
Definition: shape.h:278
Definition: matrices.h:1271
int & face_index()
Definition: elements.h:4626
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4735
FaceGeometry()
Definition: scalar_advection_elements.h:1023
FaceGeometry()
Definition: scalar_advection_elements.h:675
FaceGeometry()
Definition: scalar_advection_elements.h:384
Definition: elements.h:4998
Definition: elements.h:1313
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Definition: elements.cc:5132
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
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
double nodal_position(const unsigned &n, const unsigned &i) const
Definition: elements.h:2317
virtual double dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Definition: elements.cc:3325
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
Definition: elements.h:2484
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Definition: elements.h:1765
Definition: flux_transport_elements.h:49
virtual void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Definition: flux_transport_elements.cc:90
void calculate_element_averages(double *&average_values)
Compute the average values of the fluxes.
Definition: flux_transport_elements.cc:308
void output(std::ostream &outfile)
Definition: flux_transport_elements.h:175
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: oomph_definitions.h:222
Definition: elements.h:3439
Definition: Qelements.h:459
Non-spectral version of the classes.
Definition: scalar_advection_elements.h:685
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: scalar_advection_elements.h:718
QScalarAdvectionElement(const QScalarAdvectionElement< DIM, NNODE_1D > &dummy)=delete
Broken copy constructor.
unsigned required_nvalue(const unsigned &n) const
Broken assignment operator.
Definition: scalar_advection_elements.h:704
double dshape_and_dtest_eulerian_flux_transport(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: scalar_advection_elements.h:792
double dshape_and_dtest_eulerian_at_knot_flux_transport(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: scalar_advection_elements.h:825
QScalarAdvectionElement()
Definition: scalar_advection_elements.h:689
void output(std::ostream &outfile)
Definition: scalar_advection_elements.h:711
Definition: Qspectral_elements.h:363
Definition: scalar_advection_elements.h:203
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: scalar_advection_elements.h:241
QSpectralScalarAdvectionElement()
Definition: scalar_advection_elements.h:207
double dshape_and_dtest_eulerian_flux_transport(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: scalar_advection_elements.h:315
unsigned required_nvalue(const unsigned &n) const
Broken assignment operator.
Definition: scalar_advection_elements.h:227
QSpectralScalarAdvectionElement(const QSpectralScalarAdvectionElement< DIM, NNODE_1D > &dummy)=delete
Broken copy constructor.
void output(std::ostream &outfile)
Definition: scalar_advection_elements.h:234
double dshape_and_dtest_eulerian_at_knot_flux_transport(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: scalar_advection_elements.h:348
A Rank 3 Tensor class.
Definition: matrices.h:1370
Base class for advection equations.
Definition: scalar_advection_elements.h:48
ScalarAdvectionWindFctPt Wind_fct_pt
Function pointer to the wind function.
Definition: scalar_advection_elements.h:54
unsigned required_nvalue(const unsigned &n) const
The number of unknowns at each node is the number of values.
Definition: scalar_advection_elements.h:109
ScalarAdvectionWindFctPt wind_fct_pt() const
Access function: Pointer to wind function. Const version.
Definition: scalar_advection_elements.h:103
ScalarAdvectionWindFctPt & wind_fct_pt()
Access function: Pointer to wind function.
Definition: scalar_advection_elements.h:97
unsigned nflux() const
A single flux is interpolated.
Definition: scalar_advection_elements.h:58
virtual void get_wind_scalar_adv(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &wind) const
Return the wind at a given position.
Definition: scalar_advection_elements.h:70
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt initial_condition_pt, const double &t, Vector< double > &error, Vector< double > &norm)
Definition: scalar_advection_elements.h:116
ScalarAdvectionEquations()
Constructor.
Definition: scalar_advection_elements.h:92
void dflux_du(const Vector< double > &u, RankThreeTensor< double > &df_du)
Return the flux derivatives as a function of the unknowns.
Definition: scalar_advection_elements.cc:57
void flux(const Vector< double > &u, DenseMatrix< double > &f)
Return the flux as a function of the unknown.
Definition: scalar_advection_elements.cc:36
void(* ScalarAdvectionWindFctPt)(const Vector< double > &x, Vector< double > &wind)
Typedef for a wind function as a possible function of position.
Definition: scalar_advection_elements.h:50
Definition: shape.h:76
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
RealScalar s
Definition: level1_cplx_impl.h:130
Scalar EIGEN_BLAS_FUNC_NAME() dot(int *n, Scalar *px, int *incx, Scalar *py, int *incy)
Definition: level1_real_impl.h:52
#define DIM
Definition: linearised_navier_stokes_elements.h:44
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
double exact_u(const double &time, const Vector< double > &x)
Exact solution.
Definition: two_d_linear_wave.cc:58
int error
Definition: calibrate.py:297
@ 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
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
Definition: indexed_view.cpp:20
#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