navier_stokes_surface_drag_torque_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-2025 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 specific surface elements
27
28#ifndef OOMPH_NAVIER_STOKES_SURFACE_DRAG_TORQUE_ELEMENTS_HEADER
29#define OOMPH_NAVIER_STOKES_SURFACE_DRAG_TORQUE_ELEMENTS_HEADER
30
31// Config header
32#ifdef HAVE_CONFIG_H
33#include <oomph-lib-config.h>
34#endif
35
36namespace oomph
37{
38 //======================================================================
39 /// A class of elements that allow the determination of the
40 /// drag and toque, relative to a given centre of rotation, along
41 /// a domain boundary.
42 /// The element operates as a FaceElement and attaches itself
43 /// to a bulk element of the type specified by the template
44 /// argument.
45 //======================================================================
46 template<class ELEMENT>
48 : public virtual FaceGeometry<ELEMENT>,
49 public virtual FaceElement,
50 public virtual ElementWithDragFunction
51 {
52 public:
53 /// Constructor, which takes a "bulk" element and the value of an
54 /// index describing to which face the element should be attached.
56 const int& face_index)
57 : FaceGeometry<ELEMENT>(), FaceElement()
58 {
59 // Attach the geometrical information to the element. N.B. This function
60 // also assigns nbulk_value from the required_nvalue of the bulk element
61 element_pt->build_face_element(face_index, this);
62
63 // Set the dimension from the dimension of the first node
64 this->Dim = node_pt(0)->ndim();
65
66 // Default centre of rotation is the origin
67 this->Centre_of_rotation.resize(this->Dim, 0.0);
68 }
69
70 /// Set the translation and rotation of the rigid object
71 /// as external data
73 {
74 this->Translation_index = this->add_external_data(object_data_pt);
75 }
76
77
78 /// Access function for the centre of rotation
79 double& centre_of_rotation(const unsigned& i)
80 {
81 return this->Centre_of_rotation[i];
82 }
83
84
85 /// Function that specifies the drag force and the torque about
86 /// the origin
87 virtual void get_drag_and_torque(Vector<double>& drag_force,
89 {
90 // Spatial dimension of element
91 unsigned ndim = dim();
92
93 // Initialise force
94 for (unsigned i = 0; i < ndim + 1; i++)
95 {
96 drag_force[i] = 0.0;
97 }
98
99 // Now there will be one torque component in 2D (1D surface element)
100 // and three in 3D (2D surface element)
101 for (unsigned i = 0; i < 2 * ndim - 1; i++)
102 {
103 drag_torque[i] = 0.0;
104 }
105
106 // Vector of local coordinates in face element
108
109 // Vector for global Eulerian coordinates
110 Vector<double> x(ndim + 1);
111
112 // Vector for local coordinates in bulk element
114
115 // Set the value of n_intpt
116 unsigned n_intpt = integral_pt()->nweight();
117
118 // Get pointer to assocated bulk element
119 ELEMENT* bulk_el_pt = dynamic_cast<ELEMENT*>(bulk_element_pt());
120
121 // Loop over the integration points
122 for (unsigned ipt = 0; ipt < n_intpt; ipt++)
123 {
124 // Assign values of s in FaceElement and local coordinates in bulk
125 // element
126 for (unsigned i = 0; i < ndim; i++)
127 {
128 s[i] = integral_pt()->knot(ipt, i);
129 }
130
131 // Get the bulk coordinates
133
134 // Get the integral weight
135 double w = integral_pt()->weight(ipt);
136
137 // Get jacobian of mapping
138 double J = J_eulerian(s);
139
140 // Premultiply the weights and the Jacobian
141 double W = w * J;
142
143 // Get x position as Vector
144 interpolated_x(s, x);
145
146#ifdef PARANOID
147
148 // Get x position as Vector from bulk element
151
152 double max_legal_error = 1.0e-5;
153 double error = 0.0;
154 for (unsigned i = 0; i < ndim + 1; i++)
155 {
156 error += fabs(x[i] - x_bulk[i]);
157 }
159 {
160 std::ostringstream error_stream;
161 error_stream << "difference in Eulerian posn from bulk and face: "
162 << error << " exceeds threshold " << max_legal_error
163 << std::endl;
164 throw OomphLibError(error_stream.str(),
167 }
168#endif
169
170 // Outer unit normal of the fluid
173
174 // Get velocity from bulk element
175 Vector<double> veloc(ndim + 1);
176 bulk_el_pt->interpolated_u_nst(s_bulk, veloc);
177
178 // Get traction from bulk element this is directed into the fluid
179 // so we need to reverse the sign
180 Vector<double> traction(ndim + 1);
181 bulk_el_pt->get_traction(s_bulk, normal, traction);
182
183 // Integrate (note the minus sign)
184 for (unsigned i = 0; i < ndim + 1; i++)
185 {
186 drag_force[i] -= traction[i] * W;
187 }
188
189 // Now Calculate the torque which is r x F
190 // Scale X relative to the centre of rotation
191 Vector<double> X(ndim + 1);
192 for (unsigned i = 0; i < ndim + 1; i++)
193 {
194 X[i] = x[i] - Centre_of_rotation[i] -
196 }
197
198 // In 2D it's just a single scalar
199 // again note the minus sign
200 if (ndim == 1)
201 {
202 drag_torque[0] -= (X[0] * traction[1] - X[1] * traction[0]) * W;
203 }
204 else if (ndim == 2)
205 {
206 drag_torque[0] -= (X[1] * traction[2] - X[2] * traction[1]) * W;
207 drag_torque[1] -= (X[2] * traction[0] - X[0] * traction[2]) * W;
208 drag_torque[2] -= (X[0] * traction[1] - X[1] * traction[0]) * W;
209 }
210 else
211 {
212 throw OomphLibError("Dimension of a surface element must be 1 or 2\n",
215 }
216 }
217
218 // std::cout << "Forces " << drag_force[0] << " " << drag_force[1] << " "
219 // << drag_torque[0] << "\n";
220 }
221
222
223 /// Specify the value of nodal zeta from the face geometry
224 /// The "global" intrinsic coordinate of the element when
225 /// viewed as part of a geometric object should be given by
226 /// the FaceElement representation, by default (needed to break
227 /// indeterminacy if bulk element is SolidElement)
228 double zeta_nodal(const unsigned& n,
229 const unsigned& k,
230 const unsigned& i) const
231 {
232 return FaceElement::zeta_nodal(n, k, i);
233 }
234
235
236 /// Output function
237 void output(std::ostream& outfile, const unsigned& n_plot)
238 {
239 // Get pointer to assocated bulk element
240 ELEMENT* bulk_el_pt = dynamic_cast<ELEMENT*>(bulk_element_pt());
241
242 // Elemental dimension
243 unsigned dim_el = dim();
244
245 // Local coordinates
247
249
250 // Calculate the Eulerian coordinates and Lagrange multiplier
251 Vector<double> x(dim_el + 1, 0.0);
252
253 // Outer unit normal of the fluid
255
256 // Velocity from bulk element
257 Vector<double> veloc(dim_el + 1);
258
259 // Tractions (from bulk element)
260 Vector<double> traction(dim_el + 1);
261
262 // Tecplot header info
263 outfile << this->tecplot_zone_string(n_plot);
264
265 // Loop over plot points
266 unsigned num_plot_points = this->nplot_points(n_plot);
267 for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
268 {
269 // Get local coordinates of plot point
270 this->get_s_plot(iplot, n_plot, s);
271
273
274 // Get x position from bulk
276 // Get outer unit normal
278 bulk_el_pt->interpolated_u_nst(s_bulk, veloc);
279 // Get traction from bulk element this is directed into the fluid
280 // so we need to reverse the sign
281 bulk_el_pt->get_traction(s_bulk, normal, traction);
282
283 // Now Calculate the torque which is r x F
284 // Scale X relative to the centre of rotation
285 Vector<double> X(dim_el + 1);
286 for (unsigned i = 0; i < dim_el + 1; i++)
287 {
288 X[i] = x[i] - Centre_of_rotation[i] -
290 }
291
292 for (unsigned i = 0; i < dim_el + 1; i++)
293 {
294 outfile << x[i] << " ";
295 }
296
297 for (unsigned i = 0; i < dim_el + 1; i++)
298 {
299 outfile << normal[i] << " ";
300 }
301
302 for (unsigned i = 0; i < dim_el + 1; i++)
303 {
304 outfile << veloc[i] << " ";
305 }
306
307 for (unsigned i = 0; i < dim_el + 1; i++)
308 {
309 outfile << -1.0 * traction[i] << " ";
310 }
311 outfile << -(X[0] * traction[1] - X[1] * traction[0]);
312
313 outfile << std::endl;
314 }
315
316 this->write_tecplot_zone_footer(outfile, n_plot);
317 }
318
319
320 private:
321 /// The highest dimension of the problem
322 unsigned Dim;
323
324 /// The centre of rotation for the torque calculation
326
327 /// The index of where the translation and rotation data is stored
329 };
330
331
332} // namespace oomph
333
334#endif
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
A class that represents a collection of data; each Data object may contain many different individual ...
Definition nodes.h:86
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
Definition nodes.h:293
Base class for elements that can specify a drag and torque (about the origin) – typically used for im...
Definition elements.h:5092
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
Definition elements.h:4342
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition elements.h:4630
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
Definition elements.cc:6037
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
In a FaceElement, the "global" intrinsic coordinate of the element along the boundary,...
Definition elements.h:4501
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s. Overloaded to get information from bulk...
Definition elements.h:4532
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition elements.h:4739
double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s....
Definition elements.cc:5273
void get_local_coordinate_in_bulk(const Vector< double > &s, Vector< double > &s_bulk) const
Calculate the vector of local coordinate in the bulk element given the local coordinates in this Face...
Definition elements.cc:6415
FaceGeometry class definition: This policy class is used to allow construction of face elements that ...
Definition elements.h:5002
A general Finite Element class.
Definition elements.h:1317
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition elements.h:1967
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction")
Definition elements.h:3165
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:3992
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition elements.h:2615
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
Definition elements.h:3152
virtual unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction")
Definition elements.h:3190
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement....
Definition elements.cc:5163
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Add tecplot zone "footer" to output stream (when plotting nplot points in each "coordinate direction"...
Definition elements.h:3178
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
Definition elements.h:642
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) external data object to the element and return its index (i....
Definition elements.cc:312
unsigned ndim() const
Access function to # of Eulerian coordinates.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
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.
A class of elements that allow the determination of the drag and toque, relative to a given centre of...
void set_translation_and_rotation(Data *const &object_data_pt)
Set the translation and rotation of the rigid object as external data.
unsigned Translation_index
The index of where the translation and rotation data is stored.
Vector< double > Centre_of_rotation
The centre of rotation for the torque calculation.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
virtual void get_drag_and_torque(Vector< double > &drag_force, Vector< double > &drag_torque)
Function that specifies the drag force and the torque about the origin.
NavierStokesSurfaceDragTorqueElement(FiniteElement *const &element_pt, const int &face_index)
Constructor, which takes a "bulk" element and the value of an index describing to which face the elem...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Specify the value of nodal zeta from the face geometry The "global" intrinsic coordinate of the eleme...
double & centre_of_rotation(const unsigned &i)
Access function for the centre of rotation.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition nodes.h:1054
An OomphLibError object which should be thrown when an run-time error is encountered....
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).