multi_domain_linearised_axisym_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-2023 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 "axisym_navier_stokes.h"
35 
36 // Use the oomph namespace
37 using namespace oomph;
38 
39 
40 /// //////////////////////////////////////////////////////////////////////
41 /// //////////////////////////////////////////////////////////////////////
42 /// //////////////////////////////////////////////////////////////////////
43 
44 
45 //======================================================================
46 /// Build a LinearisedAxisymmetricQTaylorHood element that inherits from
47 /// ElementWithExternalElement so that it can "communicate" with an
48 /// axisymmetric Navier-Stokes element that provides the base flow
49 /// velocities and their derivatives w.r.t. global coordinates (r and z)
50 //======================================================================
53  public virtual ElementWithExternalElement
54 {
55 public:
56  /// Constructor: call the underlying constructors
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
67 
68  /// Do not include any external geometric data when computing
69  /// the element's Jacobian.
71  }
72 
73  /// Overload get_base_flow_u(...) to return the external
74  /// element's velocity components at the integration point
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 AxisymmetricQTaylorHoodElement* base_flow_el_pt =
86  dynamic_cast<AxisymmetricQTaylorHoodElement*>(
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 three velocity components interpolated from the external element
98  for (unsigned i = 0; i < 3; i++)
99  {
100  result[i] = base_flow_el_pt->interpolated_u_axi_nst(s_external, i);
101  }
102 
103  } // End of overloaded get_base_flow_u function
104 
105  /// Overload get_base_flow_dudx(...) to return the derivatives of
106  /// the external element's velocity components w.r.t. global coordinates
107  /// at the integration point
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 AxisymmetricQTaylorHoodElement* base_flow_el_pt =
119  dynamic_cast<AxisymmetricQTaylorHoodElement*>(
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 < 3; i++)
132  {
133  // Loop over coordinate directions and get derivatives of velocity
134  // components from the external element
135  for (unsigned j = 0; j < 2; j++)
136  {
137  result(i, j) =
138  base_flow_el_pt->interpolated_dudx_axi_nst(s_external, i, j);
139  }
140  }
141 
142  } // End of overloaded get_base_flow_dudx function
143 
144 
145  /// Compute the element's residual vector and the Jacobian matrix
147  DenseMatrix<double>& jacobian)
148  {
149  // Get the analytical contribution from the basic linearised element
151  residuals, jacobian);
152 
153  // Get the off-diagonal terms by finite differencing
154  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
155  }
156 };
157 
158 
159 /// //////////////////////////////////////////////////////////////////////
160 /// //////////////////////////////////////////////////////////////////////
161 /// //////////////////////////////////////////////////////////////////////
162 
163 
164 //======================================================================
165 /// Build a LinearisedAxisymmetricQCrouzeixRaviart element that inherits
166 /// from ElementWithExternalElement so that it can "communicate" with an
167 /// axisymmetric Navier-Stokes element that provides the base flow
168 /// velocities and their derivatives w.r.t. global coordinates (r and z)
169 //======================================================================
172  public virtual ElementWithExternalElement
173 {
174 public:
175  /// Constructor: call the underlying constructors
179  {
180  // There are two interactions: the base flow velocities and their
181  // derivatives w.r.t. global coordinates
182  this->set_ninteraction(2);
183 
184  // Do not include any external interaction data when computing
185  // the element's Jacobian
187 
188  /// Do not include any external geometric data when computing
189  /// the element's Jacobian.
191  }
192 
193  /// Overload get_base_flow_u(...) to return the external
194  /// element's velocity components at the integration point
195  virtual void get_base_flow_u(const double& time,
196  const unsigned& ipt,
197  const Vector<double>& x,
198  Vector<double>& result) const
199  {
200  // Set interaction index to 0
201  const unsigned interaction = 0;
202 
203  // Get a pointer to the external element that computes the base flow.
204  // We know that it's an axisymmetric Navier-Stokes element.
205  const AxisymmetricQCrouzeixRaviartElement* base_flow_el_pt =
207  external_element_pt(interaction, ipt));
208 
209  // Provide storage for local coordinates in the external element
210  // which correspond to the integration point ipt
211  Vector<double> s_external(2);
212 
213  // Determine local coordinates in the external element which correspond
214  // to the integration point ipt
215  s_external = external_element_local_coord(interaction, ipt);
216 
217  // Get the three velocity components interpolated from the external element
218  for (unsigned i = 0; i < 3; i++)
219  {
220  result[i] = base_flow_el_pt->interpolated_u_axi_nst(s_external, i);
221  }
222 
223  } // End of overloaded get_base_flow_u function
224 
225  /// Overload get_base_flow_dudx(...) to return the derivatives of
226  /// the external element's velocity components w.r.t. global coordinates
227  /// at the integration point
228  virtual void get_base_flow_dudx(const double& time,
229  const unsigned& ipt,
230  const Vector<double>& x,
231  DenseMatrix<double>& result) const
232  {
233  // Set interaction index to 1
234  const unsigned interaction = 1;
235 
236  // Get a pointer to the external element that computes the base flow.
237  // We know that it's an axisymmetric Navier-Stokes element.
238  const AxisymmetricQCrouzeixRaviartElement* base_flow_el_pt =
240  external_element_pt(interaction, ipt));
241 
242  // Provide storage for local coordinates in the external element
243  // which correspond to the integration point ipt
244  Vector<double> s_external(2);
245 
246  // Determine local coordinates in the external element which correspond
247  // to the integration point ipt
248  s_external = external_element_local_coord(interaction, ipt);
249 
250  // Loop over velocity components
251  for (unsigned i = 0; i < 3; i++)
252  {
253  // Loop over coordinate directions and get derivatives of velocity
254  // components from the external element
255  for (unsigned j = 0; j < 2; j++)
256  {
257  result(i, j) =
258  base_flow_el_pt->interpolated_dudx_axi_nst(s_external, i, j);
259  }
260  }
261 
262  } // End of overloaded get_base_flow_dudx function
263 
264 
265  /// Compute the element's residual vector and the Jacobian matrix
267  DenseMatrix<double>& jacobian)
268  {
269  // Get the analytical contribution from the basic linearised element
271  fill_in_contribution_to_jacobian(residuals, jacobian);
272 
273  // Get the off-diagonal terms by finite differencing
274  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
275  }
276 };
277 
278 
279 /// //////////////////////////////////////////////////////////////////////
280 /// //////////////////////////////////////////////////////////////////////
281 /// //////////////////////////////////////////////////////////////////////
282 
283 
284 //======================================================================
285 /// Build a RefineableLinearisedAxisymmetricQTaylorHood element
286 /// that inherits from ElementWithExternalElement so that it can
287 /// "communicate" with an axisymmetric Navier-Stokes element that
288 /// provides the base flow velocities and their derivatives w.r.t.
289 /// global coordinates (r and z)
290 //======================================================================
293  public virtual ElementWithExternalElement
294 {
295 public:
296  /// Constructor: call the underlying constructors
300  {
301  // There are two interactions: the base flow velocities and their
302  // derivatives w.r.t. global coordinates
303  this->set_ninteraction(2);
304 
305  // Do not include any external interaction data when computing
306  // the element's Jacobian
308 
309  /// Do not include any external geometric data when computing
310  /// the element's Jacobian.
312  }
313 
314  /// Overload get_base_flow_u(...) to return the external
315  /// element's velocity components at the integration point
316  virtual void get_base_flow_u(const double& time,
317  const unsigned& ipt,
318  const Vector<double>& x,
319  Vector<double>& result) const
320  {
321  // Set interaction index to 0
322  const unsigned interaction = 0;
323 
324  // Get a pointer to the external element that computes the base flow.
325  // We know that it's an axisymmetric Navier-Stokes element.
326  const AxisymmetricQTaylorHoodElement* base_flow_el_pt =
327  dynamic_cast<AxisymmetricQTaylorHoodElement*>(
328  external_element_pt(interaction, ipt));
329 
330  // Provide storage for local coordinates in the external element
331  // which correspond to the integration point ipt
332  Vector<double> s_external(2);
333 
334  // Determine local coordinates in the external element which correspond
335  // to the integration point ipt
336  s_external = external_element_local_coord(interaction, ipt);
337 
338  // Get the three velocity components interpolated from the external element
339  for (unsigned i = 0; i < 3; i++)
340  {
341  result[i] = base_flow_el_pt->interpolated_u_axi_nst(s_external, i);
342  }
343 
344  } // End of overloaded get_base_flow_u function
345 
346  /// Overload get_base_flow_dudx(...) to return the derivatives of
347  /// the external element's velocity components w.r.t. global coordinates
348  /// at the integration point
349  virtual void get_base_flow_dudx(const double& time,
350  const unsigned& ipt,
351  const Vector<double>& x,
352  DenseMatrix<double>& result) const
353  {
354  // Set interaction index to 1
355  const unsigned interaction = 1;
356 
357  // Get a pointer to the external element that computes the base flow.
358  // We know that it's an axisymmetric Navier-Stokes element.
359  const AxisymmetricQTaylorHoodElement* base_flow_el_pt =
360  dynamic_cast<AxisymmetricQTaylorHoodElement*>(
361  external_element_pt(interaction, ipt));
362 
363  // Provide storage for local coordinates in the external element
364  // which correspond to the integration point ipt
365  Vector<double> s_external(2);
366 
367  // Determine local coordinates in the external element which correspond
368  // to the integration point ipt
369  s_external = external_element_local_coord(interaction, ipt);
370 
371  // Loop over velocity components
372  for (unsigned i = 0; i < 3; i++)
373  {
374  // Loop over coordinate directions and get derivatives of velocity
375  // components from the external element
376  for (unsigned j = 0; j < 2; j++)
377  {
378  result(i, j) =
379  base_flow_el_pt->interpolated_dudx_axi_nst(s_external, i, j);
380  }
381  }
382 
383  } // End of overloaded get_base_flow_dudx function
384 
385 
386  /// Compute the element's residual vector and the Jacobian matrix
388  DenseMatrix<double>& jacobian)
389  {
390  // Get the analytical contribution from the basic patricklinearised element
392  fill_in_contribution_to_jacobian(residuals, jacobian);
393 
394  // Get the off-diagonal terms by finite differencing
395  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
396  }
397 };
398 
399 
400 /// //////////////////////////////////////////////////////////////////////
401 /// //////////////////////////////////////////////////////////////////////
402 /// //////////////////////////////////////////////////////////////////////
403 
404 
405 //======================================================================
406 /// Build a RefineableLinearisedAxisymmetricQCrouzeixRaviart element
407 /// that inherits from ElementWithExternalElement so that it can
408 /// "communicate" with an axisymmetric Navier-Stokes element that
409 /// provides the base flow velocities and their derivatives w.r.t.
410 /// global coordinates (r and z)
411 //======================================================================
414  public virtual ElementWithExternalElement
415 {
416 public:
417  /// Constructor: call the underlying constructors
421  {
422  // There are two interactions: the base flow velocities and their
423  // derivatives w.r.t. global coordinates
424  this->set_ninteraction(2);
425 
426  // Do not include any external interaction data when computing
427  // the element's Jacobian
429 
430  /// Do not include any external geometric data when computing
431  /// the element's Jacobian.
433  }
434 
435  /// Overload get_base_flow_u(...) to return the external
436  /// element's velocity components at the integration point
437  virtual void get_base_flow_u(const double& time,
438  const unsigned& ipt,
439  const Vector<double>& x,
440  Vector<double>& result) const
441  {
442  // Set interaction index to 0
443  const unsigned interaction = 0;
444 
445  // Get a pointer to the external element that computes the base flow.
446  // We know that it's an axisymmetric Navier-Stokes element.
447  const AxisymmetricQCrouzeixRaviartElement* base_flow_el_pt =
449  external_element_pt(interaction, ipt));
450 
451  // Provide storage for local coordinates in the external element
452  // which correspond to the integration point ipt
453  Vector<double> s_external(2);
454 
455  // Determine local coordinates in the external element which correspond
456  // to the integration point ipt
457  s_external = external_element_local_coord(interaction, ipt);
458 
459  // Get the three velocity components interpolated from the external element
460  for (unsigned i = 0; i < 3; i++)
461  {
462  result[i] = base_flow_el_pt->interpolated_u_axi_nst(s_external, i);
463  }
464 
465  } // End of overloaded get_base_flow_u function
466 
467  /// Overload get_base_flow_dudx(...) to return the derivatives of
468  /// the external element's velocity components w.r.t. global coordinates
469  /// at the integration point
470  virtual void get_base_flow_dudx(const double& time,
471  const unsigned& ipt,
472  const Vector<double>& x,
473  DenseMatrix<double>& result) const
474  {
475  // Set interaction index to 1
476  const unsigned interaction = 1;
477 
478  // Get a pointer to the external element that computes the base flow.
479  // We know that it's an axisymmetric Navier-Stokes element.
480  const AxisymmetricQCrouzeixRaviartElement* base_flow_el_pt =
482  external_element_pt(interaction, ipt));
483 
484  // Provide storage for local coordinates in the external element
485  // which correspond to the integration point ipt
486  Vector<double> s_external(2);
487 
488  // Determine local coordinates in the external element which correspond
489  // to the integration point ipt
490  s_external = external_element_local_coord(interaction, ipt);
491 
492  // Loop over velocity components
493  for (unsigned i = 0; i < 3; i++)
494  {
495  // Loop over coordinate directions and get derivatives of velocity
496  // components from the external element
497  for (unsigned j = 0; j < 2; j++)
498  {
499  result(i, j) =
500  base_flow_el_pt->interpolated_dudx_axi_nst(s_external, i, j);
501  }
502  }
503 
504  } // End of overloaded get_base_flow_dudx function
505 
506 
507  /// Compute the element's residual vector and the Jacobian matrix
509  DenseMatrix<double>& jacobian)
510  {
511  // Get the analytical contribution from the basic patricklinearised element
513  fill_in_contribution_to_jacobian(residuals, jacobian);
514 
515  // Get the off-diagonal terms by finite differencing
516  this->fill_in_jacobian_from_external_interaction_by_fd(residuals, jacobian);
517  }
518 };
cstr elem_len * i
Definition: cfortran.h:603
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
LinearisedAxisymmetricQCrouzeixRaviartMultiDomainElement()
Constructor: call the underlying constructors.
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Overload get_base_flow_dudx(...) to return the derivatives of the external element's velocity compone...
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Overload get_base_flow_u(...) to return the external element's velocity components at the integration...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Overload get_base_flow_u(...) to return the external element's velocity components at the integration...
LinearisedAxisymmetricQTaylorHoodMultiDomainElement()
Constructor: call the underlying constructors.
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Overload get_base_flow_dudx(...) to return the derivatives of the external element's velocity compone...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Overload get_base_flow_u(...) to return the external element's velocity components at the integration...
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Overload get_base_flow_dudx(...) to return the derivatives of the external element's velocity compone...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual vector and the Jacobian matrix.
virtual void get_base_flow_u(const double &time, const unsigned &ipt, const Vector< double > &x, Vector< double > &result) const
Overload get_base_flow_u(...) to return the external element's velocity components at the integration...
virtual void get_base_flow_dudx(const double &time, const unsigned &ipt, const Vector< double > &x, DenseMatrix< double > &result) const
Overload get_base_flow_dudx(...) to return the derivatives of the external element's velocity compone...
double interpolated_dudx_axi_nst(const Vector< double > &s, const unsigned &i, const unsigned &j) const
Return FE interpolated derivatives of velocity component u[i] w.r.t spatial global coordinate directi...
void interpolated_u_axi_nst(const Vector< double > &s, Vector< double > &veloc) const
Compute vector of FE interpolated velocity u at local coordinate s.
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
/////////////////////////////////////////////////////////////////////////
This is a base class for all elements that require external sources (e.g. FSI, multi-domain problems ...
void ignore_external_interaction_data()
Do not include any external interaction data when computing the element's Jacobian.
void ignore_external_geometric_data()
Do not include any external geometric data when computing the element's Jacobian. This function shoul...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element's residual Vector and the jacobian matrix. Virtual function can be overloaded by ...
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...