multi_domain_linearised_navier_stokes_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 an element that couples a linearised axisymmetric
27 // Navier-Stokes element to a non-linear axisymmetric Navier-Stokes
28 // element via a multi domain approach
29 
30 // oomph-lib headers
31 #include "generic.h"
32 #include "navier_stokes.h"
35 
36 // Use the oomph namespace
37 using namespace oomph;
38 
39 
43 
44 
45 //======================================================================
50 //======================================================================
52  : public virtual LinearisedQTaylorHoodElement,
53  public virtual ElementWithExternalElement
54 {
55 public:
59  {
60  // There are two interactions: the base flow velocities and their
61  // derivatives w.r.t. global coordinates
62  this->set_ninteraction(2);
63 
64  // Do not include any external interaction data when computing
65  // the element's Jacobian
66  // ElementWithExternalElement::ignore_external_interaction_data();
67 
71  }
72 
75  virtual void get_base_flow_u(const double& time,
76  const unsigned& ipt,
77  const Vector<double>& x,
78  Vector<double>& result) const
79  {
80  // Set interaction index to 0
81  const unsigned interaction = 0;
82 
83  // Get a pointer to the external element that computes the base flow.
84  // We know that it's an axisymmetric Navier-Stokes element.
85  const QTaylorHoodElement<DIM>* base_flow_el_pt =
86  dynamic_cast<QTaylorHoodElement<DIM>*>(
87  external_element_pt(interaction, ipt));
88 
89  // Provide storage for local coordinates in the external element
90  // which correspond to the integration point ipt
91  Vector<double> s_external(2);
92 
93  // Determine local coordinates in the external element which correspond
94  // to the integration point ipt
95  s_external = external_element_local_coord(interaction, ipt);
96 
97  // Get the DIM velocity components interpolated from the external element
98  for (unsigned i = 0; i < DIM; i++)
99  {
100  result[i] = base_flow_el_pt->interpolated_u_nst(s_external, i);
101  }
102 
103  } // End of overloaded get_base_flow_u function
104 
108  virtual void get_base_flow_dudx(const double& time,
109  const unsigned& ipt,
110  const Vector<double>& x,
111  DenseMatrix<double>& result) const
112  {
113  // Set interaction index to 1
114  const unsigned interaction = 1;
115 
116  // Get a pointer to the external element that computes the base flow.
117  // We know that it's an axisymmetric Navier-Stokes element.
118  const QTaylorHoodElement<DIM>* base_flow_el_pt =
119  dynamic_cast<QTaylorHoodElement<DIM>*>(
120  external_element_pt(interaction, ipt));
121 
122  // Provide storage for local coordinates in the external element
123  // which correspond to the integration point ipt
124  Vector<double> s_external(2);
125 
126  // Determine local coordinates in the external element which correspond
127  // to the integration point ipt
128  s_external = external_element_local_coord(interaction, ipt);
129 
130  // Loop over velocity components
131  for (unsigned i = 0; i < DIM; i++)
132  {
133  // Loop over coordinate directions and get derivatives of velocity
134  // components from the external element
135  for (unsigned j = 0; j < DIM; j++)
136  {
137  result(i, j) = base_flow_el_pt->interpolated_dudx_nst(s_external, i, j);
138  }
139  }
140 
141  } // End of overloaded get_base_flow_dudx function
142 
143 
146  DenseMatrix<double>& jacobian)
147  {
148  // Get the analytical contribution from the basic linearised element
150  jacobian);
151 
152  // Get the off-diagonal terms by finite differencing
153  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
154  }
155 };
156 
157 
161 
162 
163 //======================================================================
168 //======================================================================
170  : public virtual LinearisedQCrouzeixRaviartElement,
171  public virtual ElementWithExternalElement
172 {
173 public:
177  {
178  // There are two interactions: the base flow velocities and their
179  // derivatives w.r.t. global coordinates
180  this->set_ninteraction(2);
181 
182  // Do not include any external interaction data when computing
183  // the element's Jacobian
184  // ElementWithExternalElement::ignore_external_interaction_data();
185 
189  }
190 
193  virtual void get_base_flow_u(const double& time,
194  const unsigned& ipt,
195  const Vector<double>& x,
196  Vector<double>& result) const
197  {
198  // Set interaction index to 0
199  const unsigned interaction = 0;
200 
201  // Get a pointer to the external element that computes the base flow.
202  // We know that it's an axisymmetric Navier-Stokes element.
203  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
204  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
205  external_element_pt(interaction, ipt));
206 
207  // Provide storage for local coordinates in the external element
208  // which correspond to the integration point ipt
209  Vector<double> s_external(2);
210 
211  // Determine local coordinates in the external element which correspond
212  // to the integration point ipt
213  s_external = external_element_local_coord(interaction, ipt);
214 
215  // Get the DIM velocity components interpolated from the external element
216  for (unsigned i = 0; i < DIM; i++)
217  {
218  result[i] = base_flow_el_pt->interpolated_u_nst(s_external, i);
219  }
220 
221  } // End of overloaded get_base_flow_u function
222 
226  virtual void get_base_flow_dudx(const double& time,
227  const unsigned& ipt,
228  const Vector<double>& x,
229  DenseMatrix<double>& result) const
230  {
231  // Set interaction index to 1
232  const unsigned interaction = 1;
233 
234  // Get a pointer to the external element that computes the base flow.
235  // We know that it's an axisymmetric Navier-Stokes element.
236  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
237  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
238  external_element_pt(interaction, ipt));
239 
240  // Provide storage for local coordinates in the external element
241  // which correspond to the integration point ipt
242  Vector<double> s_external(2);
243 
244  // Determine local coordinates in the external element which correspond
245  // to the integration point ipt
246  s_external = external_element_local_coord(interaction, ipt);
247 
248  // Loop over velocity components
249  for (unsigned i = 0; i < DIM; i++)
250  {
251  // Loop over coordinate directions and get derivatives of velocity
252  // components from the external element
253  for (unsigned j = 0; j < DIM; j++)
254  {
255  result(i, j) = base_flow_el_pt->interpolated_dudx_nst(s_external, i, j);
256  }
257  }
258 
259  } // End of overloaded get_base_flow_dudx function
260 
261 
264  DenseMatrix<double>& jacobian)
265  {
266  // Get the analytical contribution from the basic linearised element
268  residuals, jacobian);
269 
270  // Get the off-diagonal terms by finite differencing
271  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
272  }
273 };
274 
275 
279 
280 
281 //======================================================================
287 //======================================================================
290  public virtual ElementWithExternalElement
291 {
292 public:
296  {
297  // There are two interactions: the base flow velocities and their
298  // derivatives w.r.t. global coordinates
299  this->set_ninteraction(2);
300 
301  // Do not include any external interaction data when computing
302  // the element's Jacobian
303  // ElementWithExternalElement::ignore_external_interaction_data();
304 
308  }
309 
312  virtual void get_base_flow_u(const double& time,
313  const unsigned& ipt,
314  const Vector<double>& x,
315  Vector<double>& result) const
316  {
317  // Set interaction index to 0
318  const unsigned interaction = 0;
319 
320  // Get a pointer to the external element that computes the base flow.
321  // We know that it's an axisymmetric Navier-Stokes element.
322  const QTaylorHoodElement<DIM>* base_flow_el_pt =
323  dynamic_cast<QTaylorHoodElement<DIM>*>(
324  external_element_pt(interaction, ipt));
325 
326  // Provide storage for local coordinates in the external element
327  // which correspond to the integration point ipt
328  Vector<double> s_external(2);
329 
330  // Determine local coordinates in the external element which correspond
331  // to the integration point ipt
332  s_external = external_element_local_coord(interaction, ipt);
333 
334  // Get the three velocity components interpolated from the external element
335  for (unsigned i = 0; i < DIM; i++)
336  {
337  result[i] = base_flow_el_pt->interpolated_u_nst(s_external, i);
338  }
339 
340  } // End of overloaded get_base_flow_u function
341 
345  virtual void get_base_flow_dudx(const double& time,
346  const unsigned& ipt,
347  const Vector<double>& x,
348  DenseMatrix<double>& result) const
349  {
350  // Set interaction index to 1
351  const unsigned interaction = 1;
352 
353  // Get a pointer to the external element that computes the base flow.
354  // We know that it's an axisymmetric Navier-Stokes element.
355  const QTaylorHoodElement<DIM>* base_flow_el_pt =
356  dynamic_cast<QTaylorHoodElement<DIM>*>(
357  external_element_pt(interaction, ipt));
358 
359  // Provide storage for local coordinates in the external element
360  // which correspond to the integration point ipt
361  Vector<double> s_external(2);
362 
363  // Determine local coordinates in the external element which correspond
364  // to the integration point ipt
365  s_external = external_element_local_coord(interaction, ipt);
366 
367  // Loop over velocity components
368  for (unsigned i = 0; i < DIM; i++)
369  {
370  // Loop over coordinate directions and get derivatives of velocity
371  // components from the external element
372  for (unsigned j = 0; j < DIM; j++)
373  {
374  result(i, j) = base_flow_el_pt->interpolated_dudx_nst(s_external, i, j);
375  }
376  }
377 
378  } // End of overloaded get_base_flow_dudx function
379 
380 
383  DenseMatrix<double>& jacobian)
384  {
385  // Get the analytical contribution from the basic patricklinearised element
387  residuals, jacobian);
388 
389  // Get the off-diagonal terms by finite differencing
390  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
391  }
392 };
393 
394 
398 
399 
400 //======================================================================
406 //======================================================================
409  public virtual ElementWithExternalElement
410 {
411 public:
416  {
417  // There are two interactions: the base flow velocities and their
418  // derivatives w.r.t. global coordinates
419  this->set_ninteraction(2);
420 
421  // Do not include any external interaction data when computing
422  // the element's Jacobian
423  // ElementWithExternalElement::ignore_external_interaction_data();
424 
428  }
429 
432  virtual void get_base_flow_u(const double& time,
433  const unsigned& ipt,
434  const Vector<double>& x,
435  Vector<double>& result) const
436  {
437  // Set interaction index to 0
438  const unsigned interaction = 0;
439 
440  // Get a pointer to the external element that computes the base flow.
441  // We know that it's an axisymmetric Navier-Stokes element.
442  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
443  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
444  external_element_pt(interaction, ipt));
445 
446  // Provide storage for local coordinates in the external element
447  // which correspond to the integration point ipt
448  Vector<double> s_external(2);
449 
450  // Determine local coordinates in the external element which correspond
451  // to the integration point ipt
452  s_external = external_element_local_coord(interaction, ipt);
453 
454  // Get the three velocity components interpolated from the external element
455  for (unsigned i = 0; i < DIM; i++)
456  {
457  result[i] = base_flow_el_pt->interpolated_u_nst(s_external, i);
458  }
459 
460  } // End of overloaded get_base_flow_u function
461 
465  virtual void get_base_flow_dudx(const double& time,
466  const unsigned& ipt,
467  const Vector<double>& x,
468  DenseMatrix<double>& result) const
469  {
470  // Set interaction index to 1
471  const unsigned interaction = 1;
472 
473  // Get a pointer to the external element that computes the base flow.
474  // We know that it's an axisymmetric Navier-Stokes element.
475  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
476  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
477  external_element_pt(interaction, ipt));
478 
479  // Provide storage for local coordinates in the external element
480  // which correspond to the integration point ipt
481  Vector<double> s_external(2);
482 
483  // Determine local coordinates in the external element which correspond
484  // to the integration point ipt
485  s_external = external_element_local_coord(interaction, ipt);
486 
487  // Loop over velocity components
488  for (unsigned i = 0; i < DIM; i++)
489  {
490  // Loop over coordinate directions and get derivatives of velocity
491  // components from the external element
492  for (unsigned j = 0; j < DIM; j++)
493  {
494  result(i, j) = base_flow_el_pt->interpolated_dudx_nst(s_external, i, j);
495  }
496  }
497 
498  } // End of overloaded get_base_flow_dudx function
499 
500 
503  DenseMatrix<double>& jacobian)
504  {
505  // Get the analytical contribution from the basic patricklinearised element
507  fill_in_contribution_to_jacobian(residuals, jacobian);
508 
509  // Get the off-diagonal terms by finite differencing
510  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
511  }
512 };
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: multi_domain_linearised_navier_stokes_elements.h:172
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:226
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
Definition: multi_domain_linearised_navier_stokes_elements.h:263
LinearisedQCrouzeixRaviartMultiDomainElement()
Constructor: call the underlying constructors.
Definition: multi_domain_linearised_navier_stokes_elements.h:175
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:193
Definition: multi_domain_linearised_navier_stokes_elements.h:54
LinearisedQTaylorHoodMultiDomainElement()
Constructor: call the underlying constructors.
Definition: multi_domain_linearised_navier_stokes_elements.h:57
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:108
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:75
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
Definition: multi_domain_linearised_navier_stokes_elements.h:145
Definition: multi_domain_linearised_navier_stokes_elements.h:410
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:432
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
Definition: multi_domain_linearised_navier_stokes_elements.h:502
RefineableLinearisedQCrouzeixRaviartMultiDomainElement()
Constructor: call the underlying constructors.
Definition: multi_domain_linearised_navier_stokes_elements.h:413
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:465
Definition: multi_domain_linearised_navier_stokes_elements.h:291
RefineableLinearisedQTaylorHoodMultiDomainElement()
Constructor: call the underlying constructors.
Definition: multi_domain_linearised_navier_stokes_elements.h:294
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:345
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Definition: multi_domain_linearised_navier_stokes_elements.h:312
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
Definition: multi_domain_linearised_navier_stokes_elements.h:382
Definition: element_with_external_element.h:56
void ignore_external_geometric_data()
Definition: element_with_external_element.h:271
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: elements.h:1735
Definition: linearised_navier_stokes_elements.h:597
Definition: linearised_navier_stokes_elements.h:927
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
double interpolated_dudx_nst(const Vector< double > &s, const unsigned &i, const unsigned &j) const
Definition: navier_stokes_elements.h:1684
Definition: navier_stokes_elements.h:1749
Definition: navier_stokes_elements.h:2308
Definition: refineable_linearised_navier_stokes_elements.h:243
Definition: refineable_linearised_navier_stokes_elements.h:609
#define DIM
Definition: linearised_navier_stokes_elements.h:44
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2