element_with_moving_nodes.cc
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: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
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 //Functions for the ElementWithMovingNode class
32 #include "geom_objects.h"
33 #include "algebraic_elements.h"
34 
35 namespace oomph
36 {
37 
38  /////////////////////////////////////////////////////////////////////
39  ///////////////////////////////////////////////////////////////////
40  //Functions for the ElementWithMovingNodes class
41  ///////////////////////////////////////////////////////////////////
42  ///////////////////////////////////////////////////////////////////
43 
44  //====================================================================
45  /// Return a set of all geometric data associated with the element's node
46  /// update function
47  //======================================================================
49  std::set<Data*> &unique_geom_data_pt)
50  {
51  //First clear the set (just in case)
52  unique_geom_data_pt.clear();
53 
54  //Get number of nodes
55  const unsigned n_node = this->nnode();
56 
57  // Loop over all nodes
58  for(unsigned n=0;n<n_node;n++)
59  {
60  //Cache pointer to the Node
61  Node* const nod_pt = this->node_pt(n);
62 
63  //Is the node hanging
64  const bool node_is_hanging = nod_pt->is_hanging();
65 
66  // Default number of master nodes
67  unsigned nmaster=1;
68 
69  // Default: Node isn't hanging so it's its own master node
70  Node* master_node_pt=nod_pt;
71 
72  // Cache the hanging point
73  HangInfo* hang_info_pt = 0;
74 
75  // Find the number of master nodes if the node is hanging
76  if (node_is_hanging)
77  {
78  hang_info_pt = nod_pt->hanging_pt();
79  nmaster = hang_info_pt->nmaster();
80  }
81 
82  // Loop over all master nodes
83  for (unsigned imaster=0;imaster<nmaster;imaster++)
84  {
85  //Get the master node
86  if (node_is_hanging)
87  {master_node_pt = hang_info_pt->master_node_pt(imaster);}
88 
89 
90  //Find the number of data
91  const unsigned n_geom_data = master_node_pt->ngeom_data();
92  //If there are geometric data add them to the set
93  if(n_geom_data > 0)
94  {
95  //Get vector of geometric data involved in the geometric
96  //change of this node
97  Data** node_geom_data_pt = master_node_pt->all_geom_data_pt();
98 
99  for(unsigned i=0;i<n_geom_data;i++)
100  {
101  unique_geom_data_pt.insert(node_geom_data_pt[i]);
102  }
103  }
104 
105  // Find the number of geometric objects
106  unsigned n_geom_obj = master_node_pt->ngeom_object();
107 
108  //If there are geometric objects, add them to the set
109  if(n_geom_obj > 0)
110  {
111  // Get vector of geometric objects involved in the default
112  // update function for this (master) node.
113  // Vector is constructed by copy operation.
114  GeomObject** geom_object_pt = master_node_pt->all_geom_object_pt();
115 
116  //Loop over the geometric objects
117  for(unsigned i=0;i<n_geom_obj;i++)
118  {
119  //Get the next geometric object
120  GeomObject* geom_obj_pt=geom_object_pt[i];
121 
122  // Number of items of geometric data that the geometric
123  // object depends on
124  unsigned n_geom_data=geom_obj_pt->ngeom_data();
125 
126  // Loop over geometric data and add to set (use set to ensure
127  // that each one is only counted once)
128  for (unsigned idata=0;idata<n_geom_data;idata++)
129  {
130  unique_geom_data_pt.insert(geom_obj_pt->geom_data_pt(idata));
131  }
132  }
133  } //End of add geom object loop
134  }
135  }
136  }
137 
138  //=================================================================
139  /// Construct the vector of (unique) geometric data
140  //=================================================================
142  {
143  // This set will hold the pointers to all the unique (geometric) Data that
144  // affects the shape of this element
145  std::set<Data*> unique_geom_data_pt;
146  //Assemble that data
147  this->assemble_set_of_all_geometric_data(unique_geom_data_pt);
148 
149  // Resize storage for the pointers to the Data items that are
150  //involved in the element's node update operation.
151  Geom_data_pt.clear();
152 
153  // Loop over all the unique remaining Data items involved in the
154  // node update operations
155  typedef std::set<Data*>::iterator IT;
156  for (IT it=unique_geom_data_pt.begin();it!=unique_geom_data_pt.end();it++)
157  {
158  Geom_data_pt.push_back(*it);
159  }
160  }
161 
162  //==================================================================
163  /// \short Function to describe the local dofs of the element[s]. The ostream
164  /// specifies the output stream to which the description
165  /// is written; the string stores the currently
166  /// assembled output that is ultimately written to the
167  /// output stream by Data::describe_dofs(...); it is typically
168  /// built up incrementally as we descend through the
169  /// call hierarchy of this function when called from
170  /// Problem::describe_dofs(...)
171  //==================================================================
173  describe_local_dofs(std::ostream& out,const std::string& current_string) const
174  {
175  // Call the standard finite element classification.
176  FiniteElement::describe_local_dofs(out,current_string);
177 
178  //Set the number of data
179  const unsigned n_geom_data = ngeom_data();
180 
181  //Loop over the node update data
182  for(unsigned i=0;i<n_geom_data;i++)
183  {
184  // Pointer to geometric Data
185  Data* data_pt=Geom_data_pt[i];
186 
187  std::stringstream conversion;
188  conversion<<" of Geometric Data "<<i<<current_string;
189  std::string in(conversion.str());
190  data_pt->describe_dofs(out,in);
191  }
192  }
193 
194 
195  //==================================================================
196  /// Assign local equation numbers for the geometric data associated
197  ///with the element.
198  //==================================================================
200  const bool &store_local_dof_pt)
201  {
202  //Get local number of dofs so far
203  unsigned local_eqn_number = this->ndof();
204 
205  //Set the number of data
206  const unsigned n_geom_data = ngeom_data();
207 
208  // Reset number of geometric dofs
209  Ngeom_dof=0;
210 
211  //If we have any geometric data
212  if(n_geom_data > 0)
213  {
214  // Work out total number of values involved
215  // Initialise from the first object
216  unsigned n_total_values = Geom_data_pt[0]->nvalue();
217 
218  //Add the values from the other data
219  for(unsigned i=1;i<n_geom_data;i++)
220  {n_total_values += Geom_data_pt[i]->nvalue();}
221 
222  //If allocated delete the old storage
224  {
225  delete[] Geometric_data_local_eqn[0];
226  delete[] Geometric_data_local_eqn;
227  }
228 
229  //If there are no values, we are done, null out the storage and
230  //return
231  if(n_total_values==0) {Geometric_data_local_eqn=0; return;}
232 
233  //Resize the storage for the geometric data local equation numbers
234  //Firstly allocate the row pointers
235  Geometric_data_local_eqn = new int*[n_geom_data];
236 
237  //Now allocate storage for all the equation numbers
238  Geometric_data_local_eqn[0] = new int[n_total_values];
239 
240  //Initially all local equations are unclassified
241  for(unsigned i=0;i<n_total_values;i++)
243 
244  //Loop over the remaining rows and set their pointers
245  for(unsigned i=1;i<n_geom_data;++i)
246  {
247  //Initially set the pointer to the i-th row to the pointer
248  //to the i-1th row
250 
251  //Now increase the row pointer by the number of values
252  //stored at the i-1th geometric data
253  Geometric_data_local_eqn[i] += Geom_data_pt[i-1]->nvalue();
254  }
255 
256  //A local queue to store the global equation numbers
257  std::deque<unsigned long> global_eqn_number_queue;
258 
259  //Loop over the node update data
260  for(unsigned i=0;i<n_geom_data;i++)
261  {
262  // Pointer to geometric Data
263  Data* data_pt=Geom_data_pt[i];
264 
265  // Loop over values at this Data item
266  unsigned n_value= data_pt->nvalue();
267  for (unsigned j=0;j<n_value;j++)
268  {
269  // Get global equation number
270  long eqn_number=data_pt->eqn_number(j);
271 
272  //If equation number positive
273  if (eqn_number>=0)
274  {
275  //Add the global equation number to our queue
276  global_eqn_number_queue.push_back(eqn_number);
277  //Add pointer to the dof to the queue if required
278  if(store_local_dof_pt)
279  {
281  data_pt->value_pt(j));
282  }
283 
284  //Add to local value
286  local_eqn_number++;
287 
288  // Bump up number of geometric dofs
289  Ngeom_dof++;
290 
291  }
292  else
293  {
294  //Set the local scheme to be pinned
296  }
297  }
298  }
299 
300  //Now add our global equations numbers to the internal element storage
301  this->add_global_eqn_numbers(global_eqn_number_queue,
303  //Clear the memory used in the deque
304  if(store_local_dof_pt)
305  {std::deque<double*>().swap(GeneralisedElement::Dof_pt_deque);}
306  }
307  }
308 
309 
310 
311  //==================================================================
312  /// Calculate the node-update--related entries in the
313  /// Jacobian. The vector passed
314  /// in residuals has to contain the nonlinear residuals,
315  /// evaluated for the current values of the unknowns, in
316  /// case FDing is used to computed the derivatives.
317  //==================================================================
319  Vector<double> &residuals, DenseMatrix<double> &jacobian)
320  {
322  {
323  //Get number of Data items involved in node update operations
324  const unsigned n_geometric_data = ngeom_data();
325 
326  //If there is nothing to be done, then leave
327  if(n_geometric_data == 0) return;
328 
329  // Number of dofs
330  const unsigned n_dof = this->ndof();
331 
332  // Number of nodes
333  unsigned n_nod=this->nnode();
334 
335  // If there are no dofs, return
336  if (n_nod==0) return;
337 
338  // Get nodal dimension from first node
339  const unsigned dim_nod=node_pt(0)->ndim();
340 
341  // Number of shape controlling nodes for nonrefineable elements
342  unsigned n_shape_controlling_node=nnode();
343 
344  // Are we dealing with a refineable element?
345  RefineableElement* ref_el_pt=dynamic_cast<RefineableElement*>(this);
346  if (ref_el_pt!=0)
347  {
348  // Adjust number of shape controlling nodes
349  n_shape_controlling_node=ref_el_pt->nshape_controlling_nodes();
350  }
351 
352  // How are we going to evaluate the shape derivs?
353  unsigned method=0;
355  {
356  method=0;
357  }
359  {
360  method=1;
361  }
363  {
364  // Direct FD-ing of residuals w.r.t. geometric dofs is likely to be
365  //faster if there are fewer geometric dofs than total nodal coordinates
366  // (nodes x dim) in element:
367  if (Ngeom_dof<(n_shape_controlling_node*dim_nod))
368  {
369  method=0;
370  }
371  else
372  {
373  method=1;
374  }
375 
376  }
377 
378  // Choose method
379  //===============
380  switch(method)
381  {
382 
383  // Direct FD:
384  //-----------
385  case 0:
386 
387  {
388  //Create newres vector
389  Vector<double> newres(n_dof);
390 
391  //Use the default finite difference step
392  const double fd_step = GeneralisedElement::Default_fd_jacobian_step;
393 
394  //Integer storage for the local unknown
395  int local_unknown=0;
396 
397  //Loop over the Data items that affect the node update operations
398  for(unsigned i=0;i<n_geometric_data;i++)
399  {
400  //Loop over values
401  unsigned n_value = Geom_data_pt[i]->nvalue();
402  for(unsigned j=0;j<n_value;j++)
403  {
404  local_unknown = geometric_data_local_eqn(i,j);
405 
406  //If the value is free
407  if(local_unknown >= 0)
408  {
409  //Get a pointer to the geometric data value
410  double *value_pt = Geom_data_pt[i]->value_pt(j);
411 
412  //Save the old value
413  double old_var = *value_pt;
414 
415  //Increment the variable
416  *value_pt += fd_step;
417 
418  //Update the whole element (Bit inefficient)
419  this->node_update();
420 
421  //Calculate the new residuals
422  this->get_residuals(newres);
423 
424  //Now do finite differences
425  for(unsigned m=0;m<n_dof;m++)
426  {
427  //Stick the entry into the Jacobian matrix
428  jacobian(m,local_unknown) = (newres[m] - residuals[m])/fd_step;
429  }
430 
431  //Reset the variable
432  *value_pt = old_var;
433 
434  //We're relying on the total node update in the next loop
435  }
436  }
437  }
438 
439  // Node update the element one final time to get things back to
440  // the original state
441  this->node_update();
442  }
443 
444  break;
445 
446  // Chain rule
447  //-----------
448  case 1:
449 
450  {
451  // Get derivatives of residuals w.r.t. all nodal coordinates
452  RankThreeTensor<double> dresidual_dnodal_coordinates(
453  n_dof,
454  dim_nod,
455  n_shape_controlling_node,
456  0.0);
457 
458  // Use FD-version in base class?
460  {
461  if (ref_el_pt!=0)
462  {
463  ref_el_pt->RefineableElement::get_dresidual_dnodal_coordinates(
464  dresidual_dnodal_coordinates);
465  }
466  else
467  {
469  dresidual_dnodal_coordinates);
470  }
471  }
472  // Otherwise use the overloaded analytical version in derived
473  // class (if it exists -- if it doesn't this just drops through
474  // to the default implementation in FiniteElement).
475  else
476  {
477  this->get_dresidual_dnodal_coordinates(dresidual_dnodal_coordinates);
478  }
479 
480  // Get derivatives of nodal coordinates w.r.t. geometric dofs
481  RankThreeTensor<double> dnodal_coordinates_dgeom_dofs(
482  n_dof,
483  dim_nod,
484  n_shape_controlling_node,
485  0.0);
486 
487  get_dnodal_coordinates_dgeom_dofs(dnodal_coordinates_dgeom_dofs);
488 
489  // Assemble Jacobian via chain rule
490  for (unsigned l=0;l<n_dof;l++)
491  {
492  //Loop over the Data items that affect the node update operations
493  for(unsigned i_data=0;i_data<n_geometric_data;i_data++)
494  {
495  //Loop over values
496  unsigned n_value = Geom_data_pt[i_data]->nvalue();
497  for(unsigned j_val=0;j_val<n_value;j_val++)
498  {
499  int k = geometric_data_local_eqn(i_data,j_val);
500 
501  //If the value is free
502  if(k >= 0)
503  {
504  jacobian(l,k)=0.0;
505  for (unsigned i=0;i<dim_nod;i++)
506  {
507  for (unsigned j=0;j<n_shape_controlling_node;j++)
508  {
509  jacobian(l,k)+=
510  dresidual_dnodal_coordinates(l,i,j)*
511  dnodal_coordinates_dgeom_dofs(k,i,j);
512  }
513  }
514  }
515  }
516  }
517  }
518  }
519 
520  break;
521 
522  default:
523 
524  std::ostringstream error_message;
525  error_message << "Never get here: method " << method;
526  throw OomphLibError(
527  error_message.str(),
528  OOMPH_CURRENT_FUNCTION,
529  OOMPH_EXCEPTION_LOCATION);
530 
531  }
532  }
533 
534  }
535 
536 
537 //======================================================================
538 /// \short Compute derivatives of the nodal coordinates w.r.t.
539 /// to the geometric dofs. Default implementation by FD can be overwritten
540 /// for specific elements.
541 /// dnodal_coordinates_dgeom_dofs(l,i,j) = dX_{ij} / d s_l
542 //======================================================================
544  RankThreeTensor<double>& dnodal_coordinates_dgeom_dofs)
545  {
546  //Get number of Data items involved in node update operations
547  const unsigned n_geometric_data = ngeom_data();
548 
549  //If there is nothing to be done, then leave
550  if(n_geometric_data == 0) {return;}
551 
552  // Number of nodes
553  const unsigned n_nod=nnode();
554 
555  // If the element has no nodes (why??!!) return straightaway
556  if (n_nod==0) return;
557 
558  // Get dimension from first node
559  unsigned dim_nod=node_pt(0)->ndim();
560 
561  // Number of shape controlling nodes for nonrefineable elements
562  unsigned n_shape_controlling_node=n_nod;
563 
564  // Are we dealing with a refineable element?
565  RefineableElement* ref_el_pt=dynamic_cast<RefineableElement*>(this);
566  if (ref_el_pt!=0)
567  {
568  // Adjust number of shape controlling nodes
569  n_shape_controlling_node=ref_el_pt->nshape_controlling_nodes();
570  }
571 
572  // Current and advanced nodal positions
573  DenseMatrix<double> pos(dim_nod,n_shape_controlling_node);
574 
575  // Shape controlling nodes
576  std::map<Node*,unsigned> local_shape_controlling_node_lookup;
577 
578  // Refineable element:
579  if (ref_el_pt!=0)
580  {
581  local_shape_controlling_node_lookup=
582  ref_el_pt->shape_controlling_node_lookup();
583  }
584  // Non-refineable element: the nodes themselves
585  else
586  {
587  unsigned count=0;
588  for (unsigned j=0;j<n_nod;j++)
589  {
590  local_shape_controlling_node_lookup[node_pt(j)]=count;
591  count++;
592  }
593  }
594 
595  // Loop over all shape-controlling nodes to backup their original position
596  for (std::map<Node*,unsigned>::iterator it=
597  local_shape_controlling_node_lookup.begin();
598  it!=local_shape_controlling_node_lookup.end();
599  it++)
600  {
601  // Get node
602  Node* nod_pt=it->first;
603 
604  // Get its number
605  unsigned node_number=it->second;
606 
607  // Backup
608  for (unsigned i=0;i<dim_nod;i++)
609  {
610  pos(i,node_number)=nod_pt->position(i);
611  }
612  }
613 
614 
615  //Integer storage for the local unknown
616  int local_unknown=0;
617 
618  //Use the default finite difference step
619  const double fd_step = GeneralisedElement::Default_fd_jacobian_step;
620 
621  //Loop over the Data items that affect the node update operations
622  for(unsigned i=0;i<n_geometric_data;i++)
623  {
624  //Loop over values
625  unsigned n_value = Geom_data_pt[i]->nvalue();
626  for(unsigned j=0;j<n_value;j++)
627  {
628  local_unknown = geometric_data_local_eqn(i,j);
629 
630  //If the value is free
631  if(local_unknown >= 0)
632  {
633  //Get a pointer to the geometric data value
634  double *value_pt = Geom_data_pt[i]->value_pt(j);
635 
636  //Save the old value
637  double old_var = *value_pt;
638 
639  //Increment the variable
640  *value_pt += fd_step;
641 
642  //Update the whole element
643  this->node_update();
644 
645  // Loop over all shape-controlling nodes
646  for (std::map<Node*,unsigned>::iterator it=
647  local_shape_controlling_node_lookup.begin();
648  it!=local_shape_controlling_node_lookup.end();
649  it++)
650  {
651  // Get node
652  Node* nod_pt=it->first;
653 
654  // Get its number
655  unsigned node_number=it->second;
656 
657  // Get advanced position and FD
658  for (unsigned ii=0;ii<dim_nod;ii++)
659  {
660  dnodal_coordinates_dgeom_dofs(local_unknown,ii,node_number)=
661  (nod_pt->position(ii)-pos(ii,node_number))/fd_step;
662  }
663  }
664 
665  //Reset the variable
666  *value_pt = old_var;
667 
668  //We're relying on the total node update in the next loop
669  }
670  }
671  }
672  // Node update the element one final time to get things back to
673  // the original state
674  this->node_update();
675 
676  }
677 
678 }
void describe_local_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
virtual void get_residuals(Vector< double > &residuals)
Calculate the vector of residuals of the equations in the element. By default initialise the vector t...
Definition: elements.h:975
Vector< Data * > Geom_data_pt
Vector that stores pointers to all Data that affect the node update operations, i.e. the variables that can affect the position of the node.
bool Bypass_fill_in_jacobian_from_geometric_data
Set flag to true to bypass calculation of Jacobain entries resulting from geometric data...
virtual Data ** all_geom_data_pt()
Return a pointer to an array of all (geometric) data that affect the nodal position. The default value is zero (node is stationary)
Definition: nodes.h:1523
cstr elem_len * i
Definition: cfortran.h:607
bool Evaluate_dresidual_dnodal_coordinates_by_fd
Boolean to decide if shape derivatives are to be evaluated by fd (using FiniteElement::get_dresidual_...
int local_eqn_number(const unsigned long &ieqn_global) const
Return the local equation number corresponding to the ieqn_global-th global equation number...
Definition: elements.h:731
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number...
Definition: elements.h:709
int ** Geometric_data_local_eqn
Array to hold local eqn number information for the geometric Data variables.
int Method_for_shape_derivs
Choose method for evaluation of shape derivatives (this takes one of the values in the enumeration) ...
double * value_pt(const unsigned &i) const
Return the pointer to the i-the stored value. Typically this is required when direct access to the st...
Definition: nodes.h:322
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:852
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
Definition: nodes.h:1148
void add_global_eqn_numbers(std::deque< unsigned long > const &global_eqn_numbers, std::deque< double * > const &global_dof_pt)
Add the contents of the queue global_eqn_numbers to the local storage for the local-to-global transla...
Definition: elements.cc:149
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
Definition: nodes.h:365
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:448
unsigned ngeom_data() const
Return the number of geometric data upon which the shape of the element depends.
virtual GeomObject ** all_geom_object_pt()
Return a pointer to an array of all (geometric) objects that affect the nodal position. The default value is zero (node is stationary)
Definition: nodes.h:1531
unsigned nmaster() const
Return the number of master nodes.
Definition: nodes.h:733
bool is_hanging() const
Test whether the node is geometrically hanging.
Definition: nodes.h:1207
unsigned nshape_controlling_nodes()
Number of shape-controlling nodes = the number of non-hanging nodes plus the number of master nodes a...
A Rank 3 Tensor class.
Definition: matrices.h:1337
static long Is_pinned
Static "Magic number" used in place of the equation number to indicate that the value is pinned...
Definition: nodes.h:192
virtual void describe_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the dofs of the Node. The ostream specifies the output stream to which the descr...
Definition: nodes.cc:905
virtual unsigned ngeom_data() const
How many items of Data does the shape of the object depend on? This is implemented as a broken virtua...
Definition: geom_objects.h:208
virtual unsigned ngeom_object() const
Return the number of geometric objects that affect the nodal position. The default value is zero (nod...
Definition: nodes.h:1527
virtual void assign_all_generic_local_eqn_numbers(const bool &store_local_dof_pt)
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:89
int geometric_data_local_eqn(const unsigned &n, const unsigned &i)
Return the local equation number corresponding to the i-th value at the n-th geometric data object...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2097
Class that contains data for hanging nodes.
Definition: nodes.h:684
virtual void get_dnodal_coordinates_dgeom_dofs(RankThreeTensor< double > &dnodal_coordinates_dgeom_dofs)
Compute derivatives of the nodal coordinates w.r.t. to the geometric dofs. Default implementation by ...
std::map< Node *, unsigned > shape_controlling_node_lookup()
Return lookup scheme for unique number associated with any of the nodes that actively control the sha...
unsigned ndof() const
Return the number of equations/dofs in the element.
Definition: elements.h:834
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
static long Is_unclassified
Static "Magic number" used in place of the equation number to denote a value that hasn't been class...
Definition: nodes.h:201
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2134
unsigned Ngeom_dof
Number of geometric dofs (computed on the fly when equation numbers are set up)
static std::deque< double * > Dof_pt_deque
Static storage for deque used to add_global_equation_numbers when pointers to the dofs in each elemen...
Definition: elements.h:232
void assemble_set_of_all_geometric_data(std::set< Data * > &unique_geom_data_pt)
Return a set of all geometric data associated with the element.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
Definition: nodes.h:736
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:992
virtual void describe_local_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the local dofs of the element[s]. The ostream specifies the output stream to whi...
Definition: elements.cc:1680
virtual Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on. This is implemented as a bro...
Definition: geom_objects.h:230
void fill_in_jacobian_from_geometric_data(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the Jacobian matrix from the geometric data. This version assumes that...
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.
Definition: elements.h:1164
void complete_setup_of_dependencies()
Construct the vector of (unique) geometric data.
void position(Vector< double > &pos) const
Compute Vector of nodal positions either directly or via hanging node representation.
Definition: nodes.cc:2399
virtual void get_dresidual_dnodal_coordinates(RankThreeTensor< double > &dresidual_dnodal_coordinates)
Compute derivatives of elemental residual vector with respect to nodal coordinates. Default implementation by FD can be overwritten for specific elements. dresidual_dnodal_coordinates(l,i,j) = d res(l) / dX_{ij}.
Definition: elements.cc:3664
virtual unsigned ngeom_data() const
Return the number of geometric data that affect the nodal position. The default value is zero (node i...
Definition: nodes.h:1519
virtual void node_update()
Update the positions of all nodes in the element using each node update function. The default impleme...
Definition: elements.cc:4865