circle_as_generalised_element.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$
7 //LIC//
8 //LIC// $LastChangedDate$
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 #ifndef CIRCLE_AS_GEN_ELEMENT_HEADER
31 #define CIRCLE_AS_GEN_ELEMENT_HEADER
32 
33 #include "circle.h"
34 
35 
36 namespace oomph
37 {
38 
39 //////////////////////////////////////////////////////////////////////////
40 //////////////////////////////////////////////////////////////////////////
41 //////////////////////////////////////////////////////////////////////////
42 
43 
44 //===========start_of_general_circle=========================================
45 /// \short GeneralCircle "upgraded" to a GeneralisedElement: Circular
46 /// ring whose position is given by
47 /// \f[ x = X_c + R \cos(\zeta) \f]
48 /// \f[ y = Y_c + R \sin(\zeta) \f]
49 /// The ring's vertical position \f$ Y_c \f$ is
50 /// determined by "pseudo elasticity":
51 /// \f[
52 /// 0 = f_{load} - Y_c \ k_{stiff}
53 /// \f]
54 /// This simulates the case where the centre of the ring is mounted on
55 /// an elastic spring of stiffness \f$ k_{stiff} \f$ and loaded by
56 /// the force \f$ f_{load}. \f$ The "load" is specified by the
57 /// Data object \c load_pt().
58 //=========================================================================
59 class ElasticallySupportedRingElement : public GeneralisedElement,
60  public GeneralCircle
61 {
62 
63 public:
64 
65  /// \short Constructor: Build ring from doubles that describe
66  /// the geometry: x and y positions of centre and the radius.
67  /// Initialise stiffness to 1.0. By default, no load is set.
68  ElasticallySupportedRingElement(const double& x_c, const double& y_c,
69  const double& r) :
70  GeneralCircle(x_c,y_c,r), K_stiff(1.0), Load_data_has_been_set(false)
71  {
72  // The geometric data is internal to the element -- we copy the pointers
73  // to the GeomObject's geometric data to the element's internal
74  // data to ensure that any unknown values of geometric data are
75  // given global equation numbers. The add_internal_data(...)
76  // function returns the index by which the added Data item
77  // is accessible from internal_data_pt(...).
78  Internal_geometric_data_index=add_internal_data(Geom_data_pt[0]);
79 
80  // Geometric Data for the GeomObject has been set up (and pinned) in
81  // constructor for geometric object. Now free the y-position
82  // of the centre because we want to determine it as an unknown
83  internal_data_pt(Internal_geometric_data_index)->unpin(1);
84 
85  // Change cleanup responsibilities: The GeomData will now be killed
86  // by the GeneralisedElement when it wipes its internal Data
87  Must_clean_up=false;
88  }
89 
90 
91  /// Destructor:
93  {
94  // The GeomObject's GeomData is mirrored in the element's
95  // Internal Data and therefore gets wiped in the
96  // destructor of GeneralisedElement --> No need to kill it here
97  }
98 
99 
100  /// \short Set pointer to Data object that specifies the "load"
101  /// on the ElasticallySupportedRingElement
102  void set_load_pt(Data* load_pt)
103  {
104 #ifdef PARANOID
105  if (load_pt->nvalue()!=1)
106  {
107  std::ostringstream error_stream;
108  error_stream << "The data object that stores the load on the "
109  << "ElasticallySupportedRingElement\n"
110  << "should only contain a single data value\n"
111  << "This one contains " << load_pt->nvalue() << std::endl;
112 
113  throw OomphLibError(error_stream.str(),
114  OOMPH_CURRENT_FUNCTION,
115  OOMPH_EXCEPTION_LOCATION);
116  }
117 #endif
118 
119  // Add load to the element's external data and store
120  // its index within that storage scheme: Following this assignment,
121  // the load Data is accessible from
122  // GeneralisedElement::external_data_pt(External_load_index)
123  External_load_index = add_external_data(load_pt);
124 
125  // Load has now been set
127 
128  } // end of set_load_pt(...)
129 
130 
131  /// "Load" acting on the ring
132  double load()
133  {
134  // Return the load if it has been set
136  {
137  return external_data_pt(External_load_index)->value(0);
138  }
139  // ...otherwise return zero load
140  else
141  {
142  return 0.0;
143  }
144  } // end of load()
145 
146 
147  /// Access function for the spring stiffness
148  double& k_stiff() {return K_stiff;}
149 
150 
151  /// Pin the vertical displacement
152  void pin_yc()
153  {
154  // Vertical position of centre is stored as value 1 in the
155  // element's one and only internal Data object.
156  internal_data_pt(Internal_geometric_data_index)->pin(1);
157  }
158 
159 
160  /// Unpin the vertical displacement
161  void unpin_yc()
162  {
163  // Vertical position of centre is stored as value 1 in the
164  // element's one and only internal Data object.
165  internal_data_pt(Internal_geometric_data_index)->unpin(1);
166 
167  } // end of unpin_yc()
168 
169 
170  /// Compute element residual vector (wrapper)
171  void get_residuals(Vector<double> &residuals)
172  {
173  //Initialise residuals to zero
174  residuals.initialise(0.0);
175  //Create a dummy matrix
176  DenseMatrix<double> dummy(1);
177  //Call the generic residuals function with flag set to 0
178  fill_in_generic_residual_contribution(residuals,dummy,0);
179  }
180 
181 
182  /// Compute element residual Vector and element Jacobian matrix (wrapper)
183  void get_jacobian(Vector<double> &residuals,
184  DenseMatrix<double> &jacobian)
185  {
186  //Initialise residuals to zero
187  residuals.initialise(0.0);
188  //Initialise the jacobian matrix to zero
189  jacobian.initialise(0.0);
190  //Call the generic routine with the flag set to 1
191  fill_in_generic_residual_contribution(residuals,jacobian,1);
192 
193  } // end of get_jacobian(...)
194 
195 
196  protected:
197 
198 
199  /// \short Compute element residual Vector (only if flag=0) and also
200  /// the element Jacobian matrix (if flag=1)
201  void fill_in_generic_residual_contribution(Vector<double> &residuals,
202  DenseMatrix<double> &jacobian,
203  unsigned flag)
204  {
205  //Find out how may dofs there are in the element
206  unsigned n_dof = ndof();
207  //If everything is pinned return straight away
208  if (n_dof==0) return;
209 
210  // Pseudo-elastic force balance to determine the position of the
211  // ring's centre for a given load.
212 
213  // What's the local equation number of the force balance equation
214  // [It's the equation that "determines" the value of the internal
215  // dof, y_c, which is stored as the second value of the one-and-only
216  // internal data object in this element]
217  int local_eqn_number_for_yc =
218  internal_local_eqn(Internal_geometric_data_index,1);
219 
220  // Add residual to appropriate entry in the element's residual
221  // vector:
222  residuals[local_eqn_number_for_yc]=load()-K_stiff*y_c();
223 
224  // Work out Jacobian:
225  if (flag)
226  {
227  // Derivative of residual w.r.t. the internal dof, i.e. the vertical
228  // position of the ring's centre: d residual[0]/d y_c
229  jacobian(local_eqn_number_for_yc,local_eqn_number_for_yc) = -K_stiff;
230 
231 
232  // Derivative with respect to external dof, i.e. the applied
233  // load: d residual[0]/d load -- but only if the load is an unknown
234  if (n_dof==2)
235  {
236  // What's the local equation number of the load parameter?
237  // It's stored as the 0th value in the the element's
238  // one-and-only external data item:
239  int local_eqn_number_for_load =
240  external_local_eqn(External_load_index,0);
241 
242 #ifdef PARANOID
243  if (local_eqn_number_for_load<0)
244  {
245  throw OomphLibError(
246  "Load is pinned and yet n_dof=2?\n This is very fishy!\n",
247  OOMPH_CURRENT_FUNCTION,
248  OOMPH_EXCEPTION_LOCATION);
249  }
250 #endif
251 
252  // Add entry into element Jacobian
253  jacobian(local_eqn_number_for_yc,local_eqn_number_for_load) = 1.0;
254  }
255  }
256  } // end of get_residuals_generic(...)
257 
258 
259 private:
260 
261  /// Stiffness of the ring's "elastic" support
262  double K_stiff;
263 
264  /// \short Index of the location of the load Data in the element's
265  /// array of external data
267 
268  /// \short Index of the location of the geometric Data in the element's
269  /// array of internal data
271 
272  /// Flag to indicate that load data has been set
274 
275 };
276 
277 }
278 
279 #endif
void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute element residual Vector and element Jacobian matrix (wrapper)
void set_load_pt(Data *load_pt)
Set pointer to Data object that specifies the "load" on the ElasticallySupportedRingElement.
double & k_stiff()
Access function for the spring stiffness.
GeneralCircle in 2D space. The three parameters and are represented by Data and can therefore be ...
Definition: circle.h:99
bool Load_data_has_been_set
Flag to indicate that load data has been set.
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object&#39;s shape.
Definition: circle.h:228
bool Must_clean_up
Do I need to clean up?
Definition: circle.h:231
Definition: circle.h:37
unsigned External_load_index
Index of the location of the load Data in the element&#39;s array of external data.
void get_residuals(Vector< double > &residuals)
Compute element residual vector (wrapper)
void pin_yc()
Pin the vertical displacement.
unsigned Internal_geometric_data_index
Index of the location of the geometric Data in the element&#39;s array of internal data.
double K_stiff
Stiffness of the ring&#39;s "elastic" support.
ElasticallySupportedRingElement(const double &x_c, const double &y_c, const double &r)
Constructor: Build ring from doubles that describe the geometry: x and y positions of centre and the ...
double & x_c()
Access function to x-coordinate of centre of circle.
Definition: circle.h:209
double & y_c()
Access function to y-coordinate of centre of circle.
Definition: circle.h:212
void unpin_yc()
Unpin the vertical displacement.
GeneralCircle "upgraded" to a GeneralisedElement: Circular ring whose position is given by The ring...
void fill_in_generic_residual_contribution(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Compute element residual Vector (only if flag=0) and also the element Jacobian matrix (if flag=1) ...