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// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 // Header for an element that couples a linearised axisymmetric
31 // Navier-Stokes element to a non-linear axisymmetric Navier-Stokes
32 // element via a multi domain approach
33 
34 // oomph-lib headers
35 #include "generic.h"
36 #include "navier_stokes.h"
39 
40 // Use the oomph namespace
41 using namespace oomph;
42 
43 
44 
45 /////////////////////////////////////////////////////////////////////////
46 /////////////////////////////////////////////////////////////////////////
47 /////////////////////////////////////////////////////////////////////////
48 
49 
50 
51 //======================================================================
52 /// Build a LinearisedQTaylorHood element that inherits from
53 /// ElementWithExternalElement so that it can "communicate" with an
54 /// axisymmetric Navier-Stokes element that provides the base flow
55 /// velocities and their derivatives w.r.t. global coordinates (r and z)
56 //======================================================================
58 public virtual LinearisedQTaylorHoodElement,
59  public virtual ElementWithExternalElement
60 {
61  public:
62 
63  /// Constructor: call the underlying constructors
67  {
68  // There are two interactions: the base flow velocities and their
69  // derivatives w.r.t. global coordinates
70  this->set_ninteraction(2);
71 
72  // Do not include any external interaction data when computing
73  // the element's Jacobian
74  //ElementWithExternalElement::ignore_external_interaction_data();
75 
76  /// Do not include any external geometric data when computing
77  /// the element's Jacobian.
79  }
80 
81  /// \short Overload get_base_flow_u(...) to return the external
82  /// element's velocity components at the integration point
83  virtual void get_base_flow_u(const double& time,
84  const unsigned& ipt,
85  const Vector<double>& x,
86  Vector<double>& result) const
87  {
88  // Set interaction index to 0
89  const unsigned interaction = 0;
90 
91  // Get a pointer to the external element that computes the base flow.
92  // We know that it's an axisymmetric Navier-Stokes element.
93  const QTaylorHoodElement<DIM>* base_flow_el_pt =
94  dynamic_cast<QTaylorHoodElement<DIM>*>(
95  external_element_pt(interaction,ipt));
96 
97  // Provide storage for local coordinates in the external element
98  // which correspond to the integration point ipt
99  Vector<double> s_external(2);
100 
101  // Determine local coordinates in the external element which correspond
102  // to the integration point ipt
103  s_external = external_element_local_coord(interaction,ipt);
104 
105  // Get the DIM velocity components interpolated from the external element
106  for(unsigned i=0;i<DIM;i++)
107  {
108  result[i] = base_flow_el_pt->interpolated_u_nst(s_external,i);
109  }
110 
111  } // End of overloaded get_base_flow_u function
112 
113  /// \short Overload get_base_flow_dudx(...) to return the derivatives of
114  /// the external element's velocity components w.r.t. global coordinates
115  /// at the integration point
116  virtual void get_base_flow_dudx(const double& time,
117  const unsigned& ipt,
118  const Vector<double>& x,
119  DenseMatrix<double>& result) const
120  {
121  // Set interaction index to 1
122  const unsigned interaction = 1;
123 
124  // Get a pointer to the external element that computes the base flow.
125  // We know that it's an axisymmetric Navier-Stokes element.
126  const QTaylorHoodElement<DIM>* base_flow_el_pt =
127  dynamic_cast<QTaylorHoodElement<DIM>*>(
128  external_element_pt(interaction,ipt));
129 
130  // Provide storage for local coordinates in the external element
131  // which correspond to the integration point ipt
132  Vector<double> s_external(2);
133 
134  // Determine local coordinates in the external element which correspond
135  // to the integration point ipt
136  s_external = external_element_local_coord(interaction,ipt);
137 
138  // Loop over velocity components
139  for(unsigned i=0;i<DIM;i++)
140  {
141  // Loop over coordinate directions and get derivatives of velocity
142  // components from the external element
143  for(unsigned j=0;j<DIM;j++)
144  {
145  result(i,j)
146  = base_flow_el_pt->interpolated_dudx_nst(s_external,i,j);
147  }
148  }
149 
150  } // End of overloaded get_base_flow_dudx function
151 
152 
153 
154  /// \short Compute the element's residual vector and the Jacobian matrix
156  DenseMatrix<double> &jacobian)
157  {
158  // Get the analytical contribution from the basic linearised element
160  fill_in_contribution_to_jacobian(residuals,jacobian);
161 
162  // Get the off-diagonal terms by finite differencing
163  this->fill_in_jacobian_from_external_interaction_by_fd(residuals,jacobian);
164  }
165 
166 };
167 
168 
169 
170 /////////////////////////////////////////////////////////////////////////
171 /////////////////////////////////////////////////////////////////////////
172 /////////////////////////////////////////////////////////////////////////
173 
174 
175 
176 //======================================================================
177 /// Build a LinearisedQCrouzeixRaviart element that inherits
178 /// from ElementWithExternalElement so that it can "communicate" with an
179 /// axisymmetric Navier-Stokes element that provides the base flow
180 /// velocities and their derivatives w.r.t. global coordinates (r and z)
181 //======================================================================
183 public virtual LinearisedQCrouzeixRaviartElement,
184  public virtual ElementWithExternalElement
185 {
186 public:
187 
188  /// Constructor: call the underlying constructors
192  {
193  // There are two interactions: the base flow velocities and their
194  // derivatives w.r.t. global coordinates
195  this->set_ninteraction(2);
196 
197  // Do not include any external interaction data when computing
198  // the element's Jacobian
199  //ElementWithExternalElement::ignore_external_interaction_data();
200 
201  /// Do not include any external geometric data when computing
202  /// the element's Jacobian.
204  }
205 
206  /// \short Overload get_base_flow_u(...) to return the external
207  /// element's velocity components at the integration point
208  virtual void get_base_flow_u(const double& time,
209  const unsigned& ipt,
210  const Vector<double>& x,
211  Vector<double>& result) const
212  {
213  // Set interaction index to 0
214  const unsigned interaction = 0;
215 
216  // Get a pointer to the external element that computes the base flow.
217  // We know that it's an axisymmetric Navier-Stokes element.
218  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
219  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
220  external_element_pt(interaction,ipt));
221 
222  // Provide storage for local coordinates in the external element
223  // which correspond to the integration point ipt
224  Vector<double> s_external(2);
225 
226  // Determine local coordinates in the external element which correspond
227  // to the integration point ipt
228  s_external = external_element_local_coord(interaction,ipt);
229 
230  // Get the DIM velocity components interpolated from the external element
231  for(unsigned i=0;i<DIM;i++)
232  {
233  result[i] = base_flow_el_pt->interpolated_u_nst(s_external,i);
234  }
235 
236  } // End of overloaded get_base_flow_u function
237 
238  /// \short Overload get_base_flow_dudx(...) to return the derivatives of
239  /// the external element's velocity components w.r.t. global coordinates
240  /// at the integration point
241  virtual void get_base_flow_dudx(const double& time,
242  const unsigned& ipt,
243  const Vector<double>& x,
244  DenseMatrix<double>& result) const
245  {
246  // Set interaction index to 1
247  const unsigned interaction = 1;
248 
249  // Get a pointer to the external element that computes the base flow.
250  // We know that it's an axisymmetric Navier-Stokes element.
251  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
252  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
253  external_element_pt(interaction,ipt));
254 
255  // Provide storage for local coordinates in the external element
256  // which correspond to the integration point ipt
257  Vector<double> s_external(2);
258 
259  // Determine local coordinates in the external element which correspond
260  // to the integration point ipt
261  s_external = external_element_local_coord(interaction,ipt);
262 
263  // Loop over velocity components
264  for(unsigned i=0;i<DIM;i++)
265  {
266  // Loop over coordinate directions and get derivatives of velocity
267  // components from the external element
268  for(unsigned j=0;j<DIM;j++)
269  {
270  result(i,j)
271  = base_flow_el_pt->interpolated_dudx_nst(s_external,i,j);
272  }
273  }
274 
275  } // End of overloaded get_base_flow_dudx function
276 
277 
278 
279  /// \short Compute the element's residual vector and the Jacobian matrix
281  DenseMatrix<double> &jacobian)
282  {
283  // Get the analytical contribution from the basic linearised element
285  fill_in_contribution_to_jacobian(residuals,jacobian);
286 
287  // Get the off-diagonal terms by finite differencing
288  this->fill_in_jacobian_from_external_interaction_by_fd(residuals,jacobian);
289  }
290 
291 };
292 
293 
294 
295 /////////////////////////////////////////////////////////////////////////
296 /////////////////////////////////////////////////////////////////////////
297 /////////////////////////////////////////////////////////////////////////
298 
299 
300 
301 //======================================================================
302 /// \short Build a RefineableLinearisedQTaylorHood element
303 /// that inherits from ElementWithExternalElement so that it can
304 /// "communicate" with an axisymmetric Navier-Stokes element that
305 /// provides the base flow velocities and their derivatives w.r.t.
306 /// global coordinates (r and z)
307 //======================================================================
310  public virtual ElementWithExternalElement
311 {
312  public:
313 
314  /// Constructor: call the underlying constructors
318  {
319  // There are two interactions: the base flow velocities and their
320  // derivatives w.r.t. global coordinates
321  this->set_ninteraction(2);
322 
323  // Do not include any external interaction data when computing
324  // the element's Jacobian
325  //ElementWithExternalElement::ignore_external_interaction_data();
326 
327  /// Do not include any external geometric data when computing
328  /// the element's Jacobian.
330  }
331 
332  /// \short Overload get_base_flow_u(...) to return the external
333  /// element's velocity components at the integration point
334  virtual void get_base_flow_u(const double& time,
335  const unsigned& ipt,
336  const Vector<double>& x,
337  Vector<double>& result) const
338  {
339  // Set interaction index to 0
340  const unsigned interaction = 0;
341 
342  // Get a pointer to the external element that computes the base flow.
343  // We know that it's an axisymmetric Navier-Stokes element.
344  const QTaylorHoodElement<DIM>* base_flow_el_pt =
345  dynamic_cast<QTaylorHoodElement<DIM>*>(
346  external_element_pt(interaction,ipt));
347 
348  // Provide storage for local coordinates in the external element
349  // which correspond to the integration point ipt
350  Vector<double> s_external(2);
351 
352  // Determine local coordinates in the external element which correspond
353  // to the integration point ipt
354  s_external = external_element_local_coord(interaction,ipt);
355 
356  // Get the three velocity components interpolated from the external element
357  for(unsigned i=0;i<DIM;i++)
358  {
359  result[i] = base_flow_el_pt->interpolated_u_nst(s_external,i);
360  }
361 
362  } // End of overloaded get_base_flow_u function
363 
364  /// \short Overload get_base_flow_dudx(...) to return the derivatives of
365  /// the external element's velocity components w.r.t. global coordinates
366  /// at the integration point
367  virtual void get_base_flow_dudx(const double& time,
368  const unsigned& ipt,
369  const Vector<double>& x,
370  DenseMatrix<double>& result) const
371  {
372  // Set interaction index to 1
373  const unsigned interaction = 1;
374 
375  // Get a pointer to the external element that computes the base flow.
376  // We know that it's an axisymmetric Navier-Stokes element.
377  const QTaylorHoodElement<DIM>* base_flow_el_pt =
378  dynamic_cast<QTaylorHoodElement<DIM>*>(
379  external_element_pt(interaction,ipt));
380 
381  // Provide storage for local coordinates in the external element
382  // which correspond to the integration point ipt
383  Vector<double> s_external(2);
384 
385  // Determine local coordinates in the external element which correspond
386  // to the integration point ipt
387  s_external = external_element_local_coord(interaction,ipt);
388 
389  // Loop over velocity components
390  for(unsigned i=0;i<DIM;i++)
391  {
392  // Loop over coordinate directions and get derivatives of velocity
393  // components from the external element
394  for(unsigned j=0;j<DIM;j++)
395  {
396  result(i,j)
397  = base_flow_el_pt->interpolated_dudx_nst(s_external,i,j);
398  }
399  }
400 
401  } // End of overloaded get_base_flow_dudx function
402 
403 
404 
405  /// \short Compute the element's residual vector and the Jacobian matrix
407  DenseMatrix<double> &jacobian)
408  {
409  // Get the analytical contribution from the basic patricklinearised element
411  fill_in_contribution_to_jacobian(residuals,jacobian);
412 
413  // Get the off-diagonal terms by finite differencing
414  this->fill_in_jacobian_from_external_interaction_by_fd(residuals,jacobian);
415  }
416 
417 };
418 
419 
420 
421 /////////////////////////////////////////////////////////////////////////
422 /////////////////////////////////////////////////////////////////////////
423 /////////////////////////////////////////////////////////////////////////
424 
425 
426 
427 //======================================================================
428 /// \short Build a RefineableLinearisedQCrouzeixRaviart element
429 /// that inherits from ElementWithExternalElement so that it can
430 /// "communicate" with an axisymmetric Navier-Stokes element that
431 /// provides the base flow velocities and their derivatives w.r.t.
432 /// global coordinates (r and z)
433 //======================================================================
436  public virtual ElementWithExternalElement
437 {
438  public:
439 
440  /// Constructor: call the underlying constructors
444  {
445  // There are two interactions: the base flow velocities and their
446  // derivatives w.r.t. global coordinates
447  this->set_ninteraction(2);
448 
449  // Do not include any external interaction data when computing
450  // the element's Jacobian
451  //ElementWithExternalElement::ignore_external_interaction_data();
452 
453  /// Do not include any external geometric data when computing
454  /// the element's Jacobian.
456  }
457 
458  /// \short Overload get_base_flow_u(...) to return the external
459  /// element's velocity components at the integration point
460  virtual void get_base_flow_u(const double& time,
461  const unsigned& ipt,
462  const Vector<double>& x,
463  Vector<double>& result) const
464  {
465  // Set interaction index to 0
466  const unsigned interaction = 0;
467 
468  // Get a pointer to the external element that computes the base flow.
469  // We know that it's an axisymmetric Navier-Stokes element.
470  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
471  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
472  external_element_pt(interaction,ipt));
473 
474  // Provide storage for local coordinates in the external element
475  // which correspond to the integration point ipt
476  Vector<double> s_external(2);
477 
478  // Determine local coordinates in the external element which correspond
479  // to the integration point ipt
480  s_external = external_element_local_coord(interaction,ipt);
481 
482  // Get the three velocity components interpolated from the external element
483  for(unsigned i=0;i<DIM;i++)
484  {
485  result[i] = base_flow_el_pt->interpolated_u_nst(s_external,i);
486  }
487 
488  } // End of overloaded get_base_flow_u function
489 
490  /// \short Overload get_base_flow_dudx(...) to return the derivatives of
491  /// the external element's velocity components w.r.t. global coordinates
492  /// at the integration point
493  virtual void get_base_flow_dudx(const double& time,
494  const unsigned& ipt,
495  const Vector<double>& x,
496  DenseMatrix<double>& result) const
497  {
498  // Set interaction index to 1
499  const unsigned interaction = 1;
500 
501  // Get a pointer to the external element that computes the base flow.
502  // We know that it's an axisymmetric Navier-Stokes element.
503  const QCrouzeixRaviartElement<DIM>* base_flow_el_pt =
504  dynamic_cast<QCrouzeixRaviartElement<DIM>*>(
505  external_element_pt(interaction,ipt));
506 
507  // Provide storage for local coordinates in the external element
508  // which correspond to the integration point ipt
509  Vector<double> s_external(2);
510 
511  // Determine local coordinates in the external element which correspond
512  // to the integration point ipt
513  s_external = external_element_local_coord(interaction,ipt);
514 
515  // Loop over velocity components
516  for(unsigned i=0;i<DIM;i++)
517  {
518  // Loop over coordinate directions and get derivatives of velocity
519  // components from the external element
520  for(unsigned j=0;j<DIM;j++)
521  {
522  result(i,j)
523  = base_flow_el_pt->interpolated_dudx_nst(s_external,i,j);
524  }
525  }
526 
527  } // End of overloaded get_base_flow_dudx function
528 
529 
530 
531  /// \short Compute the element's residual vector and the Jacobian matrix
533  DenseMatrix<double> &jacobian)
534  {
535  // Get the analytical contribution from the basic patricklinearised element
537  fill_in_contribution_to_jacobian(residuals,jacobian);
538 
539  // Get the off-diagonal terms by finite differencing
540  this->fill_in_jacobian_from_external_interaction_by_fd(residuals,jacobian);
541  }
542 
543 };
double interpolated_dudx_nst(const Vector< double > &s, const unsigned &i, const unsigned &j) const
w.r.t spatial global coordinate direction x[j] at local coordinate s
Build a RefineableLinearisedQCrouzeixRaviart element that inherits from ElementWithExternalElement so...
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&#39;s velocity compone...
LinearisedQTaylorHoodMultiDomainElement()
Constructor: call the underlying constructors.
cstr elem_len * i
Definition: cfortran.h:607
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&#39;s velocity components at the integration...
RefineableLinearisedQTaylorHoodMultiDomainElement()
Constructor: call the underlying constructors.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element&#39;s residual vector and the Jacobian matrix.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element&#39;s residual vector and the Jacobian matrix.
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&#39;s velocity compone...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element&#39;s residual vector and the Jacobian matrix.
void interpolated_u_nst(const Vector< double > &s, Vector< double > &veloc) const
Compute vector of FE interpolated velocity u at local coordinate s.
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&#39;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&#39;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&#39;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&#39;s velocity components at the integration...
void ignore_external_geometric_data()
Do not include any external geometric data when computing the element&#39;s Jacobian. This function shoul...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute the element&#39;s residual vector and the Jacobian matrix.
Refineable version of linearised axisymmetric quadratic Crouzeix-Raviart elements.
LinearisedQCrouzeixRaviartMultiDomainElement()
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&#39;s velocity compone...
Refineable version of linearised axisymmetric quadratic Taylor-Hood elements.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Add the elemental contribution to the jacobian matrix. and the residuals vector. Note that this funct...
Definition: elements.h:1697
RefineableLinearisedQCrouzeixRaviartMultiDomainElement()
Constructor: call the underlying constructors.
Build a RefineableLinearisedQTaylorHood element that inherits from ElementWithExternalElement so that...