refineable_streamfunction_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 Refineable Streamfunction elements
27 #ifndef OOMPH_REFINEABLE_POLAR_STREAMFUNCTION
28 #define OOMPH_REFINEABLE_POLAR_STREAMFUNCTION
29 
30 //Oomph-lib headers
31 //Should already be looking in build/include/ for generic.h
36 
37 namespace oomph
38 {
39 
42 
43 //======================================================================
47 //======================================================================
49 public virtual PolarStreamfunctionEquations,
50 public virtual RefineableElement,
51 public virtual ElementWithZ2ErrorEstimator
52 {
53  public:
54 
60 
63  {
64  BrokenCopy::broken_copy("RefineablePolarStreamfunctionEquations");
65  }
66 
68  unsigned num_Z2_flux_terms() {return 2;}
69 
72  {this->get_flux(s,flux);}
73 
74 
80  {
81  // Set size of Vector: streamfunction, u and v
82  values.resize(3);
83 
84  //Find number of nodes
85  unsigned n_node = nnode();
86 
87  //Local shape function
88  Shape psi(n_node);
89 
90  //Find values of shape function
91  shape(s,psi);
92 
93  //Initialise values
94  values[0] = 0.0;
95  values[1] = 0.0;
96  values[2] = 0.0;
97 
98  //Find the index at which the unknowns are stored
99  unsigned s_nodal_index = this->u_index_streamfunction();
100  //Find the indices at which the local velocities are stored
101  unsigned u_nodal_index[2];
102  for(unsigned i=0;i<2;i++) {u_nodal_index[i] = u_index_velocity(i);}
103 
104 
105  //Loop over the local nodes and sum up the values
106  for(unsigned l=0;l<n_node;l++)
107  {
108  values[0] += this->nodal_value(l,s_nodal_index)*psi[l];
109  values[1] += this->nodal_value(l,u_nodal_index[0])*psi[l];
110  values[2] += this->nodal_value(l,u_nodal_index[1])*psi[l];
111  }
112  }
113 
118 void get_interpolated_values(const unsigned& t,
119  const Vector<double>&s,
120  Vector<double>& values)
121  {
122  if (t!=0)
123  {
124  std::string error_message =
125  "Time-dependent version of get_interpolated_values() ";
126  error_message += "not implemented for this element \n";
127  throw
128  OomphLibError(error_message,
129  "RefineablePolarStreamfunctionEquations::get_interpolated_values()",
131  }
132  else
133  {
134  //Make sure that we call this particular object's steady
135  //get_interpolated_values (it could get overloaded lower down)
137  }
138  }
139 
140 
143  {
144  //Find the father element
145  RefineablePolarStreamfunctionEquations* cast_father_element_pt
147  (this->father_element_pt());
148 
149  //Set pointer to alpha
150  this->Alpha_pt = cast_father_element_pt->alpha_pt();
151  }
152 
153  private:
154 
155 
161  DenseMatrix<double> &jacobian,
162  unsigned flag);
163 
164 };
165 
166 
167 //======================================================================
171 //======================================================================
175 public virtual RefineableQElement<2>
176 {
177  public:
178 
183  RefineableQElement<2>(),
185 
186 
189  dummy)
190  {
191  BrokenCopy::broken_copy("RefineableQuadStreamfunctionElement");
192  }
193 
195  unsigned ncont_interpolated_values() const {return 3;}
196 
198  unsigned nvertex_node() const
200 
202  Node* vertex_node_pt(const unsigned& j) const
204 
206  void rebuild_from_sons(Mesh* &mesh_pt) {}
207 
210  unsigned nrecovery_order() {return (2);}
211 
215 
216 };
217 
221 
222 //=======================================================================
227 //=======================================================================
228 template<>
230 public virtual FaceGeometry<PolarStreamfunctionElement >
231 {
232  public:
234 };
235 
239 
240 //========================================================================
245 //========================================================================
248  DenseMatrix<double> &jacobian,
249  unsigned flag)
250 {
251  //Find out how many nodes there are
252  const unsigned n_node = nnode();
253 
254  //Get Alpha
255  const double Alpha = alpha();
256 
257  //Set up memory for the shape and test functions
258  Shape psi(n_node), test(n_node);
259  DShape dpsidx(n_node,2), dtestdx(n_node,2);
260 
261  //Indicies at which the unknowns are stored
262  const unsigned s_nodal_index = u_index_streamfunction();
263 
264  //Find the indices at which the local velocities are stored
265  unsigned u_nodal_index[2];
266  for(unsigned i=0;i<2;i++) {u_nodal_index[i] = u_index_velocity(i);}
267 
268  //Set the value of n_intpt
269  const unsigned n_intpt = integral_pt()->nweight();
270 
271  //Integers to store the local equation and unknown numbers
272  int local_eqn=0, local_unknown=0;
273 
274  // Local storage for pointers to hang_info objects
275  HangInfo *hang_info_pt=0, *hang_info2_pt=0;
276 
277  //Loop over the integration points
278  for(unsigned ipt=0;ipt<n_intpt;ipt++)
279  {
280  //Get the integral weight
281  double w = integral_pt()->weight(ipt);
282 
283  //Call the derivatives of the shape and test functions
284  double J = dshape_and_dtest_eulerian_at_knot_poisson(ipt,psi,dpsidx,
285  test,dtestdx);
286 
287  //Premultiply the weights and the Jacobian
288  double W = w*J;
289 
290  //Allocate and initialise to zero
292  double interpolated_s=0.0;
293  Vector<double> interpolated_dsdx(2,0.0);
294  Vector<double> interpolated_u(2);
296 
297  //Calculate function value and derivatives:
298  //-----------------------------------------
299  // Loop over nodes
300  for(unsigned l=0;l<n_node;l++)
301  {
302  //Get the nodal value of the poisson unknown
303  double s_value = nodal_value(l,s_nodal_index);
304  interpolated_s += s_value*psi(l);
305  // Loop over directions1
306  for(unsigned i=0;i<2;i++)
307  {
308  interpolated_x[i] += nodal_position(l,i)*psi(l);
309  interpolated_dsdx[i] += s_value*dpsidx(l,i);
310  double u_value = this->nodal_value(l,u_nodal_index[i]);
311  interpolated_u[i] += u_value*psi(l);
312  // Loop over directions2
313  for(unsigned j=0;j<2;j++)
314  {
315  interpolated_dudx(i,j) += u_value*dpsidx(l,j);
316  }
317  }
318  }
319 
320  // Assemble residuals and Jacobian
321  //--------------------------------
322 
323  // Loop over the nodes for the test functions
324  for(unsigned l=0;l<n_node;l++)
325  {
326  //Local variables used to store the number of master nodes and the
327  //weight associated with the shape function if the node is hanging
328  unsigned n_master=1; double hang_weight=1.0;
329  //Local bool (is the node hanging)
330  bool is_node_hanging = this->node_pt(l)->is_hanging();
331 
332  //If the node is hanging, get the number of master nodes
333  if(is_node_hanging)
334  {
335  hang_info_pt = this->node_pt(l)->hanging_pt();
336  n_master = hang_info_pt->nmaster();
337  }
338  //Otherwise there is just one master node, the node itself
339  else
340  {
341  n_master = 1;
342  }
343 
344  //Loop over the master nodes
345  for(unsigned m=0;m<n_master;m++)
346  {
347  //Get the local equation number and hang_weight
348  //If the node is hanging
349  if(is_node_hanging)
350  {
351  //Read out the local equation number from the m-th master node
352  local_eqn = this->local_hang_eqn(hang_info_pt->master_node_pt(m),
353  s_nodal_index);
354  //Read out the weight from the master node
355  hang_weight = hang_info_pt->master_weight(m);
356  }
357  //If the node is not hanging
358  else
359  {
360  //The local equation number comes from the node itself
361  local_eqn = this->nodal_local_eqn(l,s_nodal_index);
362  //The hang weight is one
363  hang_weight = 1.0;
364  }
365 
366  //If the nodal equation is not a boundary condition
367  if(local_eqn >= 0)
368  {
369  // Laplacian of the streamfunction (integrated by parts)
370  residuals[local_eqn] += interpolated_dsdx[0]*dtestdx(l,0)*interpolated_x[0]*Alpha*W*hang_weight;
371  residuals[local_eqn] += (1./(interpolated_x[0]*Alpha))*interpolated_dsdx[1]
372  *(1./(interpolated_x[0]*Alpha))*dtestdx(l,1)
373  *interpolated_x[0]*Alpha*W*hang_weight;
374 
375  // Should equal the vorticity
376  residuals[local_eqn] -= (interpolated_dudx(1,0)+(interpolated_u[1]/interpolated_x[0]))*test(l)*interpolated_x[0]*Alpha*W*hang_weight;
377  residuals[local_eqn] += (1./(interpolated_x[0]*Alpha))*interpolated_dudx(0,1)*test(l)*interpolated_x[0]*Alpha*W*hang_weight;
378 
379  // Calculate the Jacobian
380  if(flag)
381  {
382  //Local variables to store the number of master nodes
383  //and the weights associated with each hanging node
384  unsigned n_master2=1; double hang_weight2=1.0;
385  //Loop over the nodes for the variables
386  for(unsigned l2=0;l2<n_node;l2++)
387  {
388  //Local bool (is the node hanging)
389  bool is_node2_hanging = this->node_pt(l2)->is_hanging();
390  //If the node is hanging, get the number of master nodes
391  if(is_node2_hanging)
392  {
393  hang_info2_pt = this->node_pt(l2)->hanging_pt();
394  n_master2 = hang_info2_pt->nmaster();
395  }
396  //Otherwise there is one master node, the node itself
397  else
398  {
399  n_master2 = 1;
400  }
401 
402  //Loop over the master nodes
403  for(unsigned m2=0;m2<n_master2;m2++)
404  {
405  //Get the local unknown and weight
406  //If the node is hanging
407  if(is_node2_hanging)
408  {
409  //Read out the local unknown from the master node
410  local_unknown =
411  this->local_hang_eqn(hang_info2_pt->master_node_pt(m2),
412  s_nodal_index);
413  //Read out the hanging weight from the master node
414  hang_weight2 = hang_info2_pt->master_weight(m2);
415  }
416  //If the node is not hanging
417  else
418  {
419  //The local unknown number comes from the node
420  local_unknown = this->nodal_local_eqn(l2,s_nodal_index);
421  //The hang weight is one
422  hang_weight2 = 1.0;
423  }
424 
425  //If the unknown is not pinned
426  if(local_unknown >= 0)
427  {
428  //Add contribution to Elemental Matrix
429  jacobian(local_eqn,local_unknown)
430  += dpsidx(l2,0)*dtestdx(l,0)*interpolated_x[0]*Alpha*W*hang_weight*hang_weight2;
431  jacobian(local_eqn,local_unknown)
432  += (1./(interpolated_x[0]*Alpha))*dpsidx(l2,1)*(1./(interpolated_x[0]*Alpha))*dtestdx(l,1)
433  *interpolated_x[0]*Alpha*W*hang_weight*hang_weight2;
434  }
435 
436  } //End of loop over master nodes
437 
438  } //End of loop over nodes
439  } //End of Jacobian calculation
440 
441  } //End of case when residual equation is not pinned
442 
443  } //End of loop over master nodes for residuals
444  } //End of loop over nodes
445 
446 } // End of loop over integration points
447 }
448 
449 }
450 
451 #endif
452 
int i
Definition: BiCGSTAB_step_by_step.cpp:9
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
MatrixType m2(n_dims)
Definition: shape.h:278
Definition: error_estimator.h:79
FaceGeometry()
Definition: refineable_streamfunction_elements.h:233
Definition: elements.h:4998
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual unsigned nvertex_node() const
Definition: elements.h:2491
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
virtual void shape(const Vector< double > &s, Shape &psi) const =0
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
virtual Node * vertex_node_pt(const unsigned &j) const
Definition: elements.h:2500
double nodal_position(const unsigned &n, const unsigned &i) const
Definition: elements.h:2317
Definition: nodes.h:742
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Definition: nodes.h:808
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
Definition: nodes.h:791
unsigned nmaster() const
Return the number of master nodes.
Definition: nodes.h:785
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
Definition: mesh.h:67
Definition: nodes.h:906
HangInfo *const & hanging_pt() const
Definition: nodes.h:1228
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1285
Definition: oomph_definitions.h:222
Definition: streamfunction_elements.h:298
A class for solving my poisson like streamfunction problem.
Definition: streamfunction_elements.h:37
const double & alpha() const
Alpha.
Definition: streamfunction_elements.h:46
double interpolated_dudx(const Vector< double > &s, const unsigned &i, const unsigned &j) const
Definition: streamfunction_elements.h:198
virtual unsigned u_index_streamfunction() const
Return the indicies at which the unknown values are stored.
Definition: streamfunction_elements.h:62
double * Alpha_pt
Pointer to the angle alpha.
Definition: streamfunction_elements.h:41
virtual double dshape_and_dtest_eulerian_at_knot_poisson(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
void get_flux(const Vector< double > &s, Vector< double > &flux) const
Definition: streamfunction_elements.h:91
virtual unsigned u_index_velocity(const unsigned &i) const
Return the indicies at which the (known) velocities are stored.
Definition: streamfunction_elements.h:65
double *& alpha_pt()
Pointer to Alpha.
Definition: streamfunction_elements.h:49
Definition: refineable_elements.h:97
virtual RefineableElement * father_element_pt() const
Return a pointer to the father element.
Definition: refineable_elements.h:539
int local_hang_eqn(Node *const &node_pt, const unsigned &i)
Definition: refineable_elements.h:278
Definition: refineable_streamfunction_elements.h:176
void rebuild_from_sons(Mesh *&mesh_pt)
Rebuild from sons: empty.
Definition: refineable_streamfunction_elements.h:206
void further_setup_hanging_nodes()
Definition: refineable_streamfunction_elements.h:214
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Definition: refineable_streamfunction_elements.h:202
RefineablePolarStreamfunctionElement()
Constructor, simply call the other constructors.
Definition: refineable_streamfunction_elements.h:180
unsigned nrecovery_order()
Definition: refineable_streamfunction_elements.h:210
unsigned nvertex_node() const
Number of vertex nodes in the element.
Definition: refineable_streamfunction_elements.h:198
RefineablePolarStreamfunctionElement(const RefineablePolarStreamfunctionElement &dummy)
Broken copy constructor.
Definition: refineable_streamfunction_elements.h:188
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 3.
Definition: refineable_streamfunction_elements.h:195
Definition: refineable_streamfunction_elements.h:52
void further_build()
Further build: Copy source function pointer from father element.
Definition: refineable_streamfunction_elements.h:142
RefineablePolarStreamfunctionEquations()
Constructor, simply call other constructors.
Definition: refineable_streamfunction_elements.h:56
void fill_in_generic_residual_contribution(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Definition: refineable_streamfunction_elements.h:247
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: refineable_streamfunction_elements.h:68
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Get 'flux' for Z2 error recovery: Standard flux.from Streamfunction equations.
Definition: refineable_streamfunction_elements.h:71
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
Definition: refineable_streamfunction_elements.h:118
RefineablePolarStreamfunctionEquations(const RefineablePolarStreamfunctionEquations &dummy)
Broken copy constructor.
Definition: refineable_streamfunction_elements.h:62
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Definition: refineable_streamfunction_elements.h:79
Definition: Qelements.h:2259
Definition: shape.h:76
RealScalar s
Definition: level1_cplx_impl.h:130
int * m
Definition: level2_cplx_impl.h:294
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square nearest sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round nearest integer not less than the given sa Eigen::floor DOXCOMMA ArrayBase::ceil not a number test
Definition: GlobalFunctions.h:109
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
double Alpha
Parameter for steepness of step.
Definition: two_d_adv_diff_adapt.cc:53
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Definition: oomph_utilities.cc:212
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
@ W
Definition: quadtree.h:63
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
t
Definition: plotPSD.py:36
Definition: indexed_view.cpp:20
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2