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