hijacked_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$
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 //Header file for hijacked elements
31 
32 //Include guards to prevent multiple inclusion of the header
33 #ifndef OOMPH_HIJACKED_ELEMENTS_HEADER
34 #define OOMPH_HIJACKED_ELEMENTS_HEADER
35 
36 
37 //oomph-lib header
38 #include "elements.h"
39 #include "spines.h"
40 
41 namespace oomph
42 {
43 
44 //========================================================================
45 /// HijackedElement base class that provides storage and access funcitons
46 /// for pointers to the global equation numbers that are hijacked by
47 /// the HijackedElement. A default residuals multiplier is also provided.
48 //========================================================================
50 {
51  public:
52 
53  /// \short Constructor, initialise the pointer to the equation numbers
54  /// for the storage to zero
57  {
58  //Set the default value of the pointer to the residuals multiplier.
59  //The default value is zero, so that the element is "completely hijacked"
60  //and the exisiting contributions to the residuals and jacobian are
61  //totally wiped
63  }
64 
65  /// Destructor, destroy the storage for the equation numbers
66  virtual ~HijackedElementBase();
67 
68  /// \short Reset the hijacked data pt, so that none of the equations in the
69  /// element are hijacked.
71 
72  /// Return the value of the residual multiplier
73  inline const double &residual_multiplier() const
74  {return *Residual_multiplier_pt;}
75 
76  /// Return the pointer to the residual multiplier
77  inline double* &residual_multiplier_pt() {return Residual_multiplier_pt;}
78 
79  protected:
80 
81  /// Pointer to a Set of pointers to the equation numbers that will be
82  /// hijacked by this element. Note that these MUST be pointers because
83  /// hijacking information is set BEFORE global equation numbers have
84  /// been assigned.
86 
87  /// \short Pointer to a vector of integers
88  /// containing the local equation numbers of
89  /// any hijacked variables in the element.
91 
92  /// \short Pointer to a double that multiplies the contribution to
93  /// the residuals from the original element.
94  /// This is usually used as a homotopy parameter to permit a smooth
95  /// transition between different types of boundary conditions, rather than
96  /// switching them on or off abruptly
98 
99  /// Static default value for the double that multiplies the original residuals
101 
102  /// \short Mark the global equation, addressed by global_eqn_pt,
103  /// as hijacked by this element.
104  void hijack_global_eqn(long* const &global_eqn_pt);
105 
106  /// \short The global equation, addressed by global_eqn_pt,
107  /// is no longer hijacked by this element.
108  void unhijack_global_eqn(long* const &global_eqn_pt);
109 
110 };
111 
112 
113 //========================================================================
114 /// \short Hijacked elements are elements in which one or more
115 /// Data values that affect the element's residuals, are determined
116 /// by another element -- the data values are then said to have
117 /// been hijacked by another element. The main functionality
118 /// added by the Hijacked element class is that it wipes out
119 /// those entries in the element's residual vector and those rows in
120 /// the element's Jacobian matrix that are determined by the "other"
121 /// elements that have hijacked the values. Note that for continuation
122 /// in homotopy parameters, it may be desriable to multiply the residuals
123 /// and corresponding jacobian entries by a "homotopy parameter". The
124 /// value of this parameter can be set by assigning residual_multiplier_pt()
125 /// which has a default value of zero. Note: it would be possible to extend
126 /// the functionality so that different residuals are multiplied by
127 /// different values, but will this ever be required?
128 //========================================================================
129 template<class ELEMENT>
130 class Hijacked : public virtual ELEMENT, public virtual HijackedElementBase
131 {
132 
133 public:
134 
135  /// Constructor, call the constructors of the base elements
136  Hijacked() : ELEMENT(), HijackedElementBase() {}
137 
138  /// Constructor used for hijacking face elements
139  Hijacked(FiniteElement* const &element_pt, const int &face_index) :
140  ELEMENT(element_pt, face_index),
142 
143 
144  /// \short Constructor used for hijacking face elements with specification of
145  /// ID of additional variables
146  Hijacked(FiniteElement* const &element_pt,
147  const int &face_index,
148  const unsigned &id=0) :
149  ELEMENT(element_pt, face_index,id),
151 
152 
153  /// \short Hijack the i-th value stored at internal data n.
154  /// Optionally return a custom-made (copied) data object that contains only
155  /// the hijacked value. This can be used as the input to other elements.
156  /// Note that the calling program assumes responsibility for this
157  /// data object and must clean it up. The default is that
158  /// the data object is returned
159  Data *hijack_internal_value(const unsigned &n, const unsigned &i,
160  const bool &return_data=true)
161  {
162  //Initialise pointer to zero
163  Data *temp_data_pt = 0;
164 
165  //If desired,
166  //Create a new Data object containing only the value that is to be hijacked
167  if(return_data)
168  {temp_data_pt = new HijackedData(i,this->internal_data_pt(n));}
169 
170  //Mark the value as hijacked
171  hijack_global_eqn(this->internal_data_pt(n)->eqn_number_pt(i));
172 
173  //Return the pointer to the data
174  return temp_data_pt;
175  }
176 
177 
178  /// \short Hijack the i-th value stored at external data n.
179  /// Optionally return a custom-made (copied) data object that contains only
180  /// the hijacked value. Note that the calling program assumes
181  /// responsibility for this data object and must clean it up.
182  /// The default is that the data object is returned
183  Data *hijack_external_value(const unsigned &n, const unsigned &i,
184  const bool &return_data=true)
185  {
186  //Initialise pointer to zero
187  Data *temp_data_pt = 0;
188  //If desired
189  //create a new Data object containing only the value that is to be hijacked
190  if(return_data)
191  {temp_data_pt = new HijackedData(i,this->external_data_pt(n));}
192 
193  //Mark the value as hijacked
194  hijack_global_eqn(this->external_data_pt(n)->eqn_number_pt(i));
195 
196  //Return the pointer to the data
197  return temp_data_pt;
198  }
199 
200  /// \short Hijack the i-th value stored at node n.
201  /// Optionally return a custom-made (copied) data object that contains only
202  /// the hijacked value. Once again, the calling program must
203  /// clean up the allocated Data object.
204  /// The default is that the data object is returned
205  Data* hijack_nodal_value(const unsigned &n, const unsigned &i,
206  const bool &return_data=true)
207  {
208  //Initialise pointer to zero
209  Data *temp_data_pt = 0;
210  //If desired
211  //create a new Data object containing only the value that is to be hijacked
212  if(return_data)
213  {temp_data_pt = new HijackedData(i,this->node_pt(n));}
214 
215  //Mark the value as hijacked
216  hijack_global_eqn(this->node_pt(n)->eqn_number_pt(i));
217 
218  //Return the pointer to the data
219  return temp_data_pt;
220  }
221 
222  /// \short Hijack the i-th positional value stored at node n.
223  /// Optionaly return a custom-made (copied) data object that contains only
224  /// the hijacked value. Again, responsibility for the memory allocated
225  /// lies with the calling function.
226  /// The default is that the data object is returned
227  Data* hijack_nodal_position_value(const unsigned &n,
228  const unsigned &i,
229  const bool &return_data=true)
230  {
231  //Can we do the casting?
232  SolidNode* solid_node_pt = dynamic_cast<SolidNode*>(this->node_pt(n));
233  if(solid_node_pt == 0)
234  {
235  std::string error_message = "Failed to cast to SolidNode\n ";
236  error_message +=
237  "You may be trying to hijack a non-elastic element\n";
238 
239  throw OomphLibError(error_message,
240  OOMPH_CURRENT_FUNCTION,
241  OOMPH_EXCEPTION_LOCATION);
242  }
243 
244  //Initialise pointer to zero
245  Data *temp_data_pt = 0;
246  //If desired
247  //create a new Data object containing only the value that is to be hijacked
248  if(return_data)
249  {temp_data_pt =
250  new HijackedData(i,solid_node_pt->variable_position_pt());}
251 
252  //Mark the value as hijacked
254 
255  //Return the pointer to the data
256  return temp_data_pt;
257  }
258 
259  /// \short Hijack the i-th value stored at the spine that affects
260  /// local node n.
261  /// Optionally return a custom-made (copied) data object that contains only
262  /// the hijacked value. Deletion must be handled at the higher level
263  /// The default is that the data object is returned
264  Data* hijack_nodal_spine_value(const unsigned &n, const unsigned &i,
265  const bool &return_data=true)
266  {
267  //Can we actually do this casting
268  SpineNode* spine_node_pt = dynamic_cast<SpineNode*>(this->node_pt(n));
269  if(spine_node_pt == 0)
270  {
271  std::string error_message = "Failed to cast to SpineNode\n ";
272  error_message +=
273  "You may be trying to hijack a non-spine element\n";
274 
275  throw OomphLibError(error_message,
276  OOMPH_CURRENT_FUNCTION,
277  OOMPH_EXCEPTION_LOCATION);
278  }
279 
280  //Initialise pointer to zero
281  Data *temp_data_pt = 0;
282  //If desired
283  //create a new Data object containing only the value that is to be hijacked
284  if(return_data)
285  {
286  temp_data_pt = new HijackedData(i,spine_node_pt->
287  spine_pt()->spine_height_pt());
288  }
289 
290  //Mark the data as hijacked
291  hijack_global_eqn(spine_node_pt->spine_pt()->
292  spine_height_pt()->eqn_number_pt(i));
293 
294  //Return the pointer to the data
295  return temp_data_pt;
296  }
297 
298 
299  /// \short Set up the local equation numbers for the underlying element,
300  /// then set up the local arrays to hold the hijacked variables.
301  /// If the boolean argument is true then pointers to the associated degrees
302  /// of freedom are stored in the array Dof_pt
303  void assign_local_eqn_numbers(const bool &store_local_dof_pt)
304  {
305  //If things have already been allocated,
306  //clear the local hijacked array, so that if the equation numbers
307  //are reassigned after changes in the boundary conditions, the
308  //correct terms will be in the array.
310  {Hijacked_local_eqn_number_pt->clear();}
311  //Otherwise allocate it
312  else
314 
315 
316  //Call the hijacked element's assign_local_eqn_numbers
317  ELEMENT::assign_local_eqn_numbers(store_local_dof_pt);
318 
319  //If any values have been hijacked, we need to find the corresponding
320  //local equation numbers
322  {
323  //Now loop over the local array that stores GLOBAL equation numbers
324  //to check if any of the local values have in fact been hijacked
325  // by "somebody"
326  unsigned n_dof = this->ndof();
327  for(unsigned i=0;i<n_dof;i++)
328  {
329  //Loop over *all* hijacked data
330  for(std::set<long*>::iterator it=Hijacked_global_eqn_number_pt->begin();
331  it!=Hijacked_global_eqn_number_pt->end();++it)
332  {
333 
334  //If the hijacked (global!) equation is not pinned
335  if(*(*it) >= 0)
336  {
337  //Get the (unsigned) global equation number:
338  //Note that it is only unsigned AFTER the test above.
339  unsigned long hijacked_eqn_number= *(*it);
340 
341  //If a GLOBAL variable used by this element is hijacked add the
342  //variable's LOCAL index to the array
343  if(hijacked_eqn_number == this->eqn_number(i))
344  {
345  Hijacked_local_eqn_number_pt->push_back(i);
346  break;
347  }
348  }
349  }
350  }
351  }
352  }
353 
354  /// \short Get the residuals from the underlying element, but then wipe the
355  /// entries in the residual vector that correspond to hijacked
356  /// values -- they will be computed by other elements.
357  void get_residuals(Vector<double> &residuals)
358  {
359  //Get parent redisuals
360  ELEMENT::get_residuals(residuals);
361  //Multiply any hijacked dofs by the residual multiplier
362  //(default value is zero)
363  unsigned n_hijacked = Hijacked_local_eqn_number_pt->size();
364  for(unsigned i=0;i<n_hijacked;i++)
365  {
366  residuals[(*Hijacked_local_eqn_number_pt)[i]] *= residual_multiplier();
367  }
368  }
369 
370 
371  /// \short Get the residuals and Jacobian matrix from the underlying
372  /// element, but then wipe the entries in the residual vector and the
373  /// rows in the Jacobian matrix that correspond to hijacked
374  /// values -- they will be computed by other elements.
375  void get_jacobian(Vector<double> &residuals,
376  DenseMatrix<double> &jacobian)
377  {
378  //Call the element's get jacobian function
379  ELEMENT::get_jacobian(residuals,jacobian);
380  //Wipe any hijacked dofs
381  unsigned n_hijacked = Hijacked_local_eqn_number_pt->size();
382  unsigned n_dof = this->ndof();
383  for(unsigned i=0;i<n_hijacked;i++)
384  {
385  //Multiply any hijacked dofs by the residual multiplier
386  //(default value is zero)
387  residuals[(*Hijacked_local_eqn_number_pt)[i]] *= residual_multiplier();
388  //Multiply the row in the Jacobian matrix by the residual
389  //multiplier for consistency
390  for(unsigned j=0;j<n_dof;j++)
391  {
392  jacobian((*Hijacked_local_eqn_number_pt)[i],j) *= residual_multiplier();
393  }
394  }
395  }
396 
397 
398 };
399 
400 
401 
402 //============================================================================
403 ///\short Explicit definition of the face geometry of hijacked elements:
404 ///the same as the face geometry of the underlying element
405 //============================================================================
406 template<class ELEMENT>
407 class FaceGeometry<Hijacked<ELEMENT> >:
408 public virtual FaceGeometry<ELEMENT>
409 {
410  public:
411 
412  /// Constructor
413  FaceGeometry() : FaceGeometry<ELEMENT>() {}
414 
415  protected:
416 };
417 
418 //============================================================================
419 ///\short Explicit definition of the face geometry of hijacked elements:
420 ///the same as the face geometry of the underlying element
421 //============================================================================
422 template<class ELEMENT>
423 class FaceGeometry<FaceGeometry<Hijacked<ELEMENT> > >:
424 public virtual FaceGeometry<FaceGeometry<ELEMENT> >
425 {
426  public:
427 
428  /// Constructor
430 
431  protected:
432 };
433 
434 //============================================================================
435 ///\short Explicit definition of the face geometry of hijacked elements:
436 ///the same as the face geometry of the underlying element
437 //============================================================================
438 template<class ELEMENT>
439 class FaceGeometry<Hijacked<FaceGeometry<ELEMENT> > >:
440 public virtual FaceGeometry<FaceGeometry<ELEMENT> >
441 {
442  public:
443 
444  /// Constructor
446 
447  protected:
448 };
449 
450 
451 }
452 
453 #endif
Hijacked()
Constructor, call the constructors of the base elements.
void hijack_global_eqn(long *const &global_eqn_pt)
Mark the global equation, addressed by global_eqn_pt, as hijacked by this element.
long * eqn_number_pt(const unsigned &i)
Return the pointer to the equation number of the i-th stored variable.
Definition: nodes.h:356
cstr elem_len * i
Definition: cfortran.h:607
double * Residual_multiplier_pt
Pointer to a double that multiplies the contribution to the residuals from the original element...
const double & residual_multiplier() const
Return the value of the residual multiplier.
A general Finite Element class.
Definition: elements.h:1274
Custom Data class that is used when HijackingData. The class always contains a single value that is c...
Definition: nodes.h:530
Data * hijack_nodal_value(const unsigned &n, const unsigned &i, const bool &return_data=true)
Hijack the i-th value stored at node n. Optionally return a custom-made (copied) data object that con...
Vector< int > * Hijacked_local_eqn_number_pt
Pointer to a vector of integers containing the local equation numbers of any hijacked variables in th...
double *& residual_multiplier_pt()
Return the pointer to the residual multiplier.
static double Default_residual_multiplier
Static default value for the double that multiplies the original residuals.
void assign_local_eqn_numbers(const bool &store_local_dof_pt)
Set up the local equation numbers for the underlying element, then set up the local arrays to hold th...
virtual ~HijackedElementBase()
Destructor, destroy the storage for the equation numbers.
Data * hijack_internal_value(const unsigned &n, const unsigned &i, const bool &return_data=true)
Hijack the i-th value stored at internal data n. Optionally return a custom-made (copied) data object...
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:89
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
Definition: nodes.h:1655
Hijacked(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
Constructor used for hijacking face elements with specification of ID of additional variables...
Hijacked(FiniteElement *const &element_pt, const int &face_index)
Constructor used for hijacking face elements.
void get_residuals(Vector< double > &residuals)
Get the residuals from the underlying element, but then wipe the entries in the residual vector that ...
Data * hijack_external_value(const unsigned &n, const unsigned &i, const bool &return_data=true)
Hijack the i-th value stored at external data n. Optionally return a custom-made (copied) data object...
A Class for nodes that deform elastically (i.e. position is an unknown in the problem). The idea is that the Eulerian positions are stored in a Data object and the Lagrangian coordinates are stored in addition. The pointer that addresses the Eulerian positions is set to the pointer to Value in the Data object. Hence, SolidNode uses knowledge of the internal structure of Data and must be a friend of the Data class. In order to allow a mesh to deform via an elastic-style equation in deforming-domain problems, the positions are stored separately from the values, so that elastic problems may be combined with any other type of problem.
Definition: nodes.h:1569
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
Hijacked elements are elements in which one or more Data values that affect the element&#39;s residuals...
void unhijack_global_eqn(long *const &global_eqn_pt)
The global equation, addressed by global_eqn_pt, is no longer hijacked by this element.
Spine *& spine_pt()
Access function to spine.
Definition: spines.h:347
std::set< long * > * Hijacked_global_eqn_number_pt
Data * hijack_nodal_position_value(const unsigned &n, const unsigned &i, const bool &return_data=true)
Hijack the i-th positional value stored at node n. Optionaly return a custom-made (copied) data objec...
void unhijack_all_data()
Reset the hijacked data pt, so that none of the equations in the element are hijacked.
void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Get the residuals and Jacobian matrix from the underlying element, but then wipe the entries in the r...
HijackedElementBase()
Constructor, initialise the pointer to the equation numbers for the storage to zero.
Data * hijack_nodal_spine_value(const unsigned &n, const unsigned &i, const bool &return_data=true)
Hijack the i-th value stored at the spine that affects local node n. Optionally return a custom-made ...