my_taylor_hood_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 #ifndef OOMPH_MY_TAYLOR_HOOD_ELEMENTS
27 #define OOMPH_MY_TAYLOR_HOOD_ELEMENTS
28 
29 namespace oomph
30 {
31 
32 //==============================================================
33 /// Overload TaylorHood element to modify output
34 //==============================================================
36  public virtual PseudoSolidNodeUpdateElement<TTaylorHoodElement<2>,
37  TPVDElement<2,3> >
38  {
39 
40  private:
41 
42  /// Storage for elemental error estimate -- used for post-processing
43  double Error;
44 
45  public:
46 
47  /// Constructor initialise error
49  {
50  Error=0.0;
51  }
52 
53  /// Set error value for post-processing
54  void set_error(const double& error){Error=error;}
55 
56  /// Return variable identifier
57  std::string variable_identifier()
58  {
59  std::string txt="VARIABLES=";
60  txt+="\"x\",";
61  txt+="\"y\",";
62  txt+="\"u\",";
63  txt+="\"v\",";
64  txt+="\"p\",";
65  txt+="\"du/dt\",";
66  txt+="\"dv/dt\",";
67  txt+="\"u_m\",";
68  txt+="\"v_m\",";
69  txt+="\"x_h1\",";
70  txt+="\"y_h1\",";
71  txt+="\"x_h2\",";
72  txt+="\"y_h2\",";
73  txt+="\"u_h1\",";
74  txt+="\"v_h1\",";
75  txt+="\"u_h2\",";
76  txt+="\"v_h2\",";
77  txt+="\"error\",";
78  txt+="\"size\",";
79  txt+="\n";
80  return txt;
81  }
82 
83 
84  /// Overload output function
85  void output(std::ostream &outfile,
86  const unsigned &nplot)
87  {
88 
89  // Assign dimension
90  unsigned el_dim=2;
91 
92  // Vector of local coordinates
93  Vector<double> s(el_dim);
94 
95  // Acceleration
96  Vector<double> dudt(el_dim);
97 
98  // Mesh elocity
99  Vector<double> mesh_veloc(el_dim,0.0);
100 
101  // Tecplot header info
102  outfile << tecplot_zone_string(nplot);
103 
104  // Find out how many nodes there are
105  unsigned n_node = nnode();
106 
107  //Set up memory for the shape functions
108  Shape psif(n_node);
109  DShape dpsifdx(n_node,el_dim);
110 
111  // Loop over plot points
112  unsigned num_plot_points=nplot_points(nplot);
113  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
114  {
115 
116  // Get local coordinates of plot point
117  get_s_plot(iplot,nplot,s);
118 
119  //Call the derivatives of the shape and test functions
120  dshape_eulerian(s,psif,dpsifdx);
121 
122  //Allocate storage
123  Vector<double> mesh_veloc(el_dim);
124  Vector<double> dudt(el_dim);
125  Vector<double> dudt_ALE(el_dim);
126  DenseMatrix<double> interpolated_dudx(el_dim,el_dim);
127 
128  //Initialise everything to zero
129  for(unsigned i=0;i<el_dim;i++)
130  {
131  mesh_veloc[i]=0.0;
132  dudt[i]=0.0;
133  dudt_ALE[i]=0.0;
134  for(unsigned j=0;j<el_dim;j++)
135  {
136  interpolated_dudx(i,j) = 0.0;
137  }
138  }
139 
140  //Calculate velocities and derivatives
141 
142  //Loop over directions
143  for(unsigned i=0;i<el_dim;i++)
144  {
145  //Get the index at which velocity i is stored
146  unsigned u_nodal_index = u_index_nst(i);
147  // Loop over nodes
148  for(unsigned l=0;l<n_node;l++)
149  {
150  dudt[i]+=du_dt_nst(l,u_nodal_index)*psif[l];
151  mesh_veloc[i]+=dnodal_position_dt(l,i)*psif[l];
152 
153  //Loop over derivative directions for velocity gradients
154  for(unsigned j=0;j<el_dim;j++)
155  {
156  interpolated_dudx(i,j) += nodal_value(l,u_nodal_index)*
157  dpsifdx(l,j);
158  }
159  }
160  }
161 
162 
163  // Get dudt in ALE form (incl mesh veloc)
164  for(unsigned i=0;i<el_dim;i++)
165  {
166  dudt_ALE[i]=dudt[i];
167  for (unsigned k=0;k<el_dim;k++)
168  {
169  dudt_ALE[i]-=mesh_veloc[k]*interpolated_dudx(i,k);
170  }
171  }
172 
173 
174  // Coordinates
175  for(unsigned i=0;i<el_dim;i++)
176  {
177  outfile << interpolated_x(s,i) << " ";
178  }
179 
180  // Velocities
181  for(unsigned i=0;i<el_dim;i++)
182  {
183  outfile << interpolated_u_nst(s,i) << " ";
184  }
185 
186  // Pressure
187  outfile << interpolated_p_nst(s) << " ";
188 
189  // Accelerations
190  for(unsigned i=0;i<el_dim;i++)
191  {
192  outfile << dudt_ALE[i] << " ";
193  }
194 
195  // Mesh velocity
196  for(unsigned i=0;i<el_dim;i++)
197  {
198  outfile << mesh_veloc[i] << " ";
199  }
200 
201  // History values of coordinates
202  unsigned n_prev=node_pt(0)->position_time_stepper_pt()->ntstorage();
203  for (unsigned t=1;t<n_prev;t++)
204  {
205  for(unsigned i=0;i<el_dim;i++)
206  {
207  outfile << interpolated_x(t,s,i) << " ";
208  }
209  }
210 
211  // History values of velocities
212  n_prev=node_pt(0)->time_stepper_pt()->ntstorage();
213  for (unsigned t=1;t<n_prev;t++)
214  {
215  for(unsigned i=0;i<el_dim;i++)
216  {
217  outfile << interpolated_u_nst(t,s,i) << " ";
218  }
219  }
220 
221  outfile << Error << " "
222  << size() << std::endl;
223  }
224 
225  // Write tecplot footer (e.g. FE connectivity lists)
226  write_tecplot_zone_footer(outfile,nplot);
227  }
228 
229 
230  /// Get square of L2 norm of velocity
232  {
233 
234  // Assign dimension
235  unsigned el_dim=2;
236  // Initalise
237  double sum=0.0;
238 
239  //Find out how many nodes there are
240  unsigned n_node = nnode();
241 
242  //Find the indices at which the local velocities are stored
243  unsigned u_nodal_index[el_dim];
244  for(unsigned i=0;i<el_dim;i++) {u_nodal_index[i] = u_index_nst(i);}
245 
246  //Set up memory for the velocity shape fcts
247  Shape psif(n_node);
248  DShape dpsidx(n_node,el_dim);
249 
250  //Number of integration points
251  unsigned n_intpt = integral_pt()->nweight();
252 
253  //Set the Vector to hold local coordinates
254  Vector<double> s(el_dim);
255 
256  //Loop over the integration points
257  for(unsigned ipt=0;ipt<n_intpt;ipt++)
258  {
259  //Assign values of s
260  for(unsigned i=0;i<el_dim;i++) s[i] = integral_pt()->knot(ipt,i);
261 
262  //Get the integral weight
263  double w = integral_pt()->weight(ipt);
264 
265  // Call the derivatives of the veloc shape functions
266  // (Derivs not needed but they are free)
267  double J = this->dshape_eulerian_at_knot(ipt,psif,dpsidx);
268 
269  //Premultiply the weights and the Jacobian
270  double W = w*J;
271 
272  //Calculate velocities
273  Vector<double> interpolated_u(el_dim,0.0);
274 
275  // Loop over nodes
276  for(unsigned l=0;l<n_node;l++)
277  {
278  //Loop over directions
279  for(unsigned i=0;i<el_dim;i++)
280  {
281  //Get the nodal value
282  double u_value = raw_nodal_value(l,u_nodal_index[i]);
283  interpolated_u[i] += u_value*psif[l];
284  }
285  }
286 
287  //Assemble square of L2 norm
288  for(unsigned i=0;i<el_dim;i++)
289  {
290  sum+=interpolated_u[i]*interpolated_u[i]*W;
291  }
292  }
293 
294  return sum;
295 
296  }
297 
298  };
299 
300 
301 
302 
303 
304 //=======================================================================
305 /// Face geometry for element is the same as that for the underlying
306 /// wrapped element
307 //=======================================================================
308  template<>
309  class FaceGeometry<MyTaylorHoodElement>
310  : public virtual SolidTElement<1,3>
311  {
312  public:
313  FaceGeometry() : SolidTElement<1,3>() {}
314  };
315 
316 //=======================================================================
317 /// Face geometry for element is the same as that for the underlying
318 /// wrapped element
319 //=======================================================================
320  template<>
321  class FaceGeometry<FaceGeometry<MyTaylorHoodElement> >
322  : public virtual PointElement
323  {
324  public:
325  FaceGeometry() : PointElement() {}
326  };
327 
328 
329 }
330 #endif
Overload TaylorHood element to modify output.
double Error
Storage for elemental error estimate – used for post-processing.
std::string variable_identifier()
Return variable identifier.
void output(std::ostream &outfile, const unsigned &nplot)
Overload output function.
MyTaylorHoodElement()
Constructor initialise error.
double square_of_l2_norm()
Get square of L2 norm of velocity.
void set_error(const double &error)
Set error value for post-processing.