element_with_external_element.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 ElementWithExternalElement class
27 
29 
30 namespace oomph
31 {
32  //======================================================================
33  /// Destructor, clean up any memory allocated for the equation
34  /// numbering schemes and storage for the external elements
35  //======================================================================
37  {
38  // If storage has been allocated for external geometric data,
39  // delete it
41  {
43  }
45  {
47  }
49  {
51  }
52 
53  // If storage has been allocated for external field data,
54  // delete it
56  {
58  }
60  {
62  }
64  {
66  }
67 
68  // Flush the storage associated with the external elements
70  }
71 
72  //========================================================================
73  /// Initialise storage for source elements and their
74  /// associated local coordinates for the specified number of interactions
75  //========================================================================
77  {
78  // Find the number of interactions
79  const unsigned n_interaction = this->Ninteraction;
80  // Find the number of integration points
81  const unsigned n_intpt = this->integral_pt()->nweight();
82 
83  // Work out the required storage
84  const unsigned n_external_element_storage = n_interaction * n_intpt;
85 
86  // If we have not allocated the correct amount of memory,
87  // then do so
88  if (Nexternal_element_storage != n_external_element_storage)
89  {
90  // Allocate storage for the pointers to the elements
91  // Delete old storage, if needed
93  {
94  delete[] External_element_pt;
95  }
96  // Allocate new memory
97  External_element_pt = new FiniteElement*[n_external_element_storage];
98 
99  // Initialise all new pointers to zero
100  for (unsigned i = 0; i < n_external_element_storage; i++)
101  {
102  External_element_pt[i] = 0;
103  }
104 
105  // Alloacte storage for local coordinates
106  // Delete old storage, if needed
108  {
110  }
111  // Allocate the new memory
113  new Vector<double>[n_external_element_storage];
114 
115  // Finally record how much memory we have allocated
116  Nexternal_element_storage = n_external_element_storage;
117  Nintpt = n_intpt;
118  }
119  }
120 
121  //========================================================================
122  /// Clear the storage for pointers to external elements and their
123  /// associated local coordinates.
124  //========================================================================
126  {
127  // Delete the memory if it has been allocated
129  {
130  delete[] External_element_pt;
132  }
133 
135  {
138  }
139 
140  // Reset the number of stored values to zero
142  }
143 
144 
145  //================================================================
146  /// Function that must return all the data involved
147  /// in the desired interactions from the external element
148  /// Default is to call the identify_field_data_for_interaction()
149  /// for each element.
150  //================================================================
153  Vector<std::set<FiniteElement*>> const& external_elements_pt,
154  std::set<std::pair<Data*, unsigned>>& paired_interaction_data)
155  {
156  // Loop over each interaction
157  const unsigned n_interaction = this->ninteraction();
158  for (unsigned i = 0; i < n_interaction; i++)
159  {
160  // Loop over each element in the set
161  for (std::set<FiniteElement*>::const_iterator it =
162  external_elements_pt[i].begin();
163  it != external_elements_pt[i].end();
164  it++)
165  {
166  (*it)->identify_field_data_for_interactions(paired_interaction_data);
167  }
168  } // End of loop over interactions
169  }
170 
171  //=======================================================================
172  /// Function that must return all geometric data involved
173  /// in the desired interactions from the external element
174  /// Default is to add all geometric data for each element for each
175  /// interaction
176  //=======================================================================
179  Vector<std::set<FiniteElement*>> const& external_elements_pt,
180  std::set<Data*>& external_geometric_data_pt)
181  {
182  // Loop over each interaction
183  const unsigned n_interaction = this->ninteraction();
184  for (unsigned i = 0; i < n_interaction; i++)
185  {
186  // Loop over each element in the set
187  for (std::set<FiniteElement*>::const_iterator it =
188  external_elements_pt[i].begin();
189  it != external_elements_pt[i].end();
190  it++)
191  {
192  (*it)->identify_geometric_data(external_geometric_data_pt);
193  }
194  } // End of loop over interactions
195  }
196 
197  /// Function to describe the local dofs of the element. The ostream
198  /// specifies the output stream to which the description
199  /// is written; the string stores the currently
200  /// assembled output that is ultimately written to the
201  /// output stream by Data::describe_dofs(...); it is typically
202  /// built up incrementally as we descend through the
203  /// call hierarchy of this function when called from
204  /// Problem::describe_dofs(...)
206  std::ostream& out, const std::string& current_string) const
207  {
208  // Find the number of external field data
209  const unsigned n_external_field_data = nexternal_interaction_field_data();
210  // Now loop over the field data again to assign local equation numbers
211  for (unsigned i = 0; i < n_external_field_data; i++)
212  {
213  std::stringstream conversion;
214  conversion << " of External Interaction Field Data " << i
215  << current_string;
216  std::string in(conversion.str());
218  }
219 
220  // Find the number of external geometric data
221  unsigned n_external_geom_data = nexternal_interaction_geometric_data();
222 
223  // Now loop over the field data again assign local equation numbers
224  for (unsigned i = 0; i < n_external_geom_data; i++)
225  {
226  std::stringstream conversion;
227  conversion << " of External Interaction Geometric Data " << i
228  << current_string;
229  std::string in(conversion.str());
231  }
232  GeneralisedElement::describe_local_dofs(out, current_string);
233  }
234 
235  //==========================================================================
236  /// This function determines the all Data in external elemetns that
237  /// affects the residuals of the element
238  /// and adds their global equation numbers to the
239  /// local-to-global look-up scheme. Note that we only include
240  /// Data items into the element's External_interaction_data
241  /// if they are not already
242  /// included in the element's nodal positional Data, its internal
243  /// or external Data.
244  //==========================================================================
247  const bool& store_local_dof_pt)
248  {
249  // Reset number of stored field data to zero
251  // Clear all the internal field data storage, if it's been allocated
253  {
256  }
258  {
261  }
263  {
266  }
267 
268  // Reset number of stored geometric data to zero
270  // Clear all internal external data storage, if it's been allocated
272  {
275  }
277  {
280  }
282  {
285  }
286 
287  // Only bother with non-halo elements
288 #ifdef OOMPH_HAS_MPI
289  if (!this->is_halo())
290 #endif
291  {
292  // If desired, determine the Data that affects the interactions but is not
293  // already included in elements other generic Data.
294  // The conditional test is done here, so that the vectors are cleared
295  // and not re-filled if Add_external_interaction_data is false
297  {
298  // Number of interactions
299  const unsigned n_interaction = this->ninteraction();
300  // Number of integration points
301  const unsigned n_intpt = integral_pt()->nweight();
302 
303  // Sets of all (external) FiniteElements that affect the interactions
304  // One set per interaction
305  Vector<std::set<FiniteElement*>> external_interaction_elements_pt(
306  n_interaction);
307 
308  // Loop over the interactions
309  for (unsigned i = 0; i < n_interaction; i++)
310  {
311  // Loop over the integration points and the adjacent element at
312  // each integration point to the set
313  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
314  {
315  // Add the element adjacent to the element into the set
316  external_interaction_elements_pt[i].insert(
317  external_element_pt(i, ipt));
318  }
319  // For safety erase any null pointers
320  external_interaction_elements_pt[i].erase(0);
321  }
322 
323  // Storage for a pairs of interaction data (pointer to Data and the
324  // index of the value within this Data object) affecting the element.
325  std::set<std::pair<Data*, unsigned>> paired_field_data;
326 
327  // Determine the field data that affects the external interactions
328  // for all sets of external elements
330  external_interaction_elements_pt, paired_field_data);
331 
332  // It's just possible that some of the field data could be internal
333  // or nodal data, so we should remove it if that's the case
334  // Loop over all internal data
335  const unsigned n_internal = this->ninternal_data();
336  for (unsigned n = 0; n < n_internal; n++)
337  {
338  // Cache the data pointer
339  Data* const dat_pt = this->internal_data_pt(n);
340  // Find the number of data values stored in the data object
341  const unsigned n_value = dat_pt->nvalue();
342  // Add the index of each data value and the pointer to the set
343  // of pairs
344  for (unsigned i = 0; i < n_value; i++)
345  {
346  paired_field_data.erase(std::make_pair(dat_pt, i));
347  }
348  }
349 
350  // Loop over all the nodes
351  const unsigned n_node = this->nnode();
352  for (unsigned n = 0; n < n_node; n++)
353  {
354  // Find the node point
355  Node* const nod_pt = this->node_pt(n);
356  // Find the number of values stored at the node
357  const unsigned n_value = nod_pt->nvalue();
358  // Loop over values and erase all pairs from the set
359  for (unsigned i = 0; i < n_value; i++)
360  {
361  paired_field_data.erase(std::make_pair(nod_pt, i));
362  }
363  SolidNode* solid_nod_pt = dynamic_cast<SolidNode*>(nod_pt);
364  if (solid_nod_pt != 0)
365  {
366  Data* pos_data_pt = solid_nod_pt->variable_position_pt();
367  // Find the number of positional values stored at the node
368  const unsigned n_value = pos_data_pt->nvalue();
369  // Loop over values and erase all pairs from the set
370  for (unsigned i = 0; i < n_value; i++)
371  {
372  paired_field_data.erase(std::make_pair(pos_data_pt, i));
373  }
374  }
375  }
376 
377  // Now allocate storage for the external field data
378  // associated indices and local equation numbers
379  const unsigned n_external_interaction_field_data =
380  paired_field_data.size();
381  Nexternal_interaction_field_data = n_external_interaction_field_data;
383  new Data*[n_external_interaction_field_data];
385  new unsigned[n_external_interaction_field_data];
386 
387  // Add the pairs of data to the field data vectors
388  {
389  unsigned count = 0;
390  for (std::set<std::pair<Data*, unsigned>>::iterator it =
391  paired_field_data.begin();
392  it != paired_field_data.end();
393  it++)
394  {
395  External_interaction_field_data_pt[count] = it->first;
396  External_interaction_field_data_index[count] = it->second;
397  ++count;
398  }
399  }
400 
401 
402  // Only bother to add geometric data if we're told to
404  {
405  // Storage for a set of external geometric Data affecting the element
406  std::set<Data*> external_geometric_data_pt;
407 
408  // Determine the geometric data that affects the external interactions
409  // for all sets of external elements
411  external_interaction_elements_pt, external_geometric_data_pt);
412 
413  // Now loop over any geometric data of the Element itself
414  // and erase them from the external_geometric_data_pt
415  // because these data are actually intrinsic
416  // data of this element and are counted and numbered elsewhere
417  unsigned n_geom_data = ngeom_data();
418  for (unsigned j = 0; j < n_geom_data; j++)
419  {
420  external_geometric_data_pt.erase(geom_data_pt(j));
421  }
422 
423  // It is possible that the geometric data may have already been added
424  // as external data. We should erase any common entries from the
425  // External_interaction_data
426  // but not touch the external data that has been set up by a
427  //"knowledgeable" user
428  unsigned n_external = nexternal_data();
429  for (unsigned j = 0; j < n_external; j++)
430  {
431  external_geometric_data_pt.erase(external_data_pt(j));
432  }
433 
434  // Loop over all the nodes of present element to avoid double counting
435  const unsigned n_node = this->nnode();
436  for (unsigned n = 0; n < n_node; n++)
437  {
438  Node* const nod_pt = this->node_pt(n);
439  external_geometric_data_pt.erase(nod_pt);
440 
441  SolidNode* solid_nod_pt = dynamic_cast<SolidNode*>(nod_pt);
442  if (solid_nod_pt != 0)
443  {
444  Data* pos_data_pt = solid_nod_pt->variable_position_pt();
445  // std::ostringstream junk;
446  // junk << "Erasing ";
447  // unsigned nval=pos_data_pt->nvalue();
448  // for (unsigned i=0;i<nval;i++)
449  // {
450  // junk << pos_data_pt->eqn_number(i) << " ";
451  // }
452  // oomph_info << junk.str() << std::endl;
453  external_geometric_data_pt.erase(pos_data_pt);
454  }
455  }
456 
457 
458  // Next allocate storage for the geometric field data
459  // Find out how many individual data we have
460  unsigned n_external_interaction_geometric_data = 0;
461  for (std::set<Data*>::iterator it =
462  external_geometric_data_pt.begin();
463  it != external_geometric_data_pt.end();
464  it++)
465  {
466  // Add the number of values stored in each geometric datum
467  n_external_interaction_geometric_data += (*it)->nvalue();
468  }
469 
470  // Now allocate storage
472  n_external_interaction_geometric_data;
474  new Data*[n_external_interaction_geometric_data];
476  new unsigned[n_external_interaction_geometric_data];
477 
478  // Now we can add all the geometric data to the geometric data vectors
479  {
480  unsigned count = 0;
481  for (std::set<Data*>::iterator it =
482  external_geometric_data_pt.begin();
483  it != external_geometric_data_pt.end();
484  it++)
485  {
486  // Find the number of values stored in the geometric data
487  unsigned n_value = (*it)->nvalue();
488  // Loop over the values
489  for (unsigned j = 0; j < n_value; j++)
490  {
491  // Add data to the external geometric data
494  ++count;
495  }
496  }
497  }
498  }
499  }
500 
501  // All external interaction data has now been specified
502 
503  // Find the number of external field data
504  const unsigned n_external_field_data = nexternal_interaction_field_data();
505 
506  // If there are interaction data fill in the internal storage
507  if (n_external_field_data > 0)
508  {
509  // Allocate storage for the local equation numbers associated with
510  // external field data
512  new int[n_external_field_data];
513 
514  // Find the number of local equations assigned so far
515  unsigned local_eqn_number = ndof();
516 
517  // A local queue to store the global equation numbers
518  std::deque<unsigned long> global_eqn_number_queue;
519 
520  // Now loop over the field data again to assign local equation numbers
521  for (unsigned i = 0; i < n_external_field_data; i++)
522  {
523  // Get the GLOBAL equation number
526 
527  // If the GLOBAL equation number is positive (i.e. not pinned)
528  if (eqn_number >= 0)
529  {
530  // std::ostringstream junk;
531  // junk << "Adding global eqn " << eqn_number << " (";
532  // if (!(External_interaction_field_data_pt[i]->is_halo()))
533  // {
534  // junk << "not";
535  // }
536  // oomph_info << junk.str() << " halo" << std::endl;
537 
538  // Add the GLOBAL equation number to the local queue
539  global_eqn_number_queue.push_back(eqn_number);
540  // Add pointer to the dof to the queue if required
541  if (store_local_dof_pt)
542  {
546  }
547 
548  // Add the local equation number to the local scheme
550  // Increase the local number
552  }
553  else
554  {
555  // Set the local scheme to be pinned
557  }
558  }
559  // Now add our global equations numbers to the internal element storage
560  add_global_eqn_numbers(global_eqn_number_queue,
562  // Clear the memory used in the deque
563  if (store_local_dof_pt)
564  {
565  std::deque<double*>().swap(GeneralisedElement::Dof_pt_deque);
566  }
567  }
568 
569  // Find the number of external geometric data
570  unsigned n_external_geom_data = nexternal_interaction_geometric_data();
571 
572  // If there are external geometric data fill in the internal storage
573  if (n_external_geom_data > 0)
574  {
575  // Allocate storage for the local equation numbers associated with
576  // external geometric data
578  new int[n_external_geom_data];
579 
580  // Find the number of local equations assigned so far
581  unsigned local_eqn_number = ndof();
582 
583  // A local queue to store the global equation numbers
584  std::deque<unsigned long> global_eqn_number_queue;
585 
586  // Now loop over the field data again assign local equation numbers
587  for (unsigned i = 0; i < n_external_geom_data; i++)
588  {
589  // Get the GLOBAL equation number
590  long eqn_number =
593 
594  // If the GLOBAL equation number is positive (a free variable)
595  if (eqn_number >= 0)
596  {
597  // Add the GLOBAL equation number to the local queue
598  global_eqn_number_queue.push_back(eqn_number);
599  // Add pointer to the dof to the queue if required
600  if (store_local_dof_pt)
601  {
605  }
606 
607  // Add the local equation number to the local scheme
609  // Increase the local number
611  }
612  else
613  {
614  // Set the local scheme to be pinned
616  }
617  }
618  // Now add our global equations numbers to the internal element storage
619  add_global_eqn_numbers(global_eqn_number_queue,
621  // Clear the memory used in the deque
622  if (store_local_dof_pt)
623  {
624  std::deque<double*>().swap(GeneralisedElement::Dof_pt_deque);
625  }
626  }
627  }
628  }
629 
630  //============================================================================
631  /// This function calculates the entries of Jacobian matrix, used in
632  /// the Newton method, associated with the external interaction
633  /// degrees of freedom for external fields.
634  /// It does this using finite differences,
635  /// rather than an analytical formulation, so can be done in total generality.
636  //==========================================================================
639  Vector<double>& residuals, DenseMatrix<double>& jacobian)
640  {
641  // Locally cache the number of data
642  const unsigned n_external_interaction_field_data =
644 
645  // If there is no such data return
646  if (n_external_interaction_field_data == 0)
647  {
648  return;
649  }
650 
651  // Call the update function to ensure that the element is in a
652  // consistent state before finite differencing
654 
655  // Find the number of dofs in the element
656  const unsigned n_dof = ndof();
657 
658  // Create newres vector
659  Vector<double> newres(n_dof);
660 
661  // Integer storage for local unknown
662  int local_unknown = 0;
663 
664  // Use the default finite difference step
665  const double fd_step = Default_fd_jacobian_step;
666 
667  // Loop over the data
668  for (unsigned i = 0; i < n_external_interaction_field_data; i++)
669  {
670  // Find the value of the local unknown
672  // If it's not a boundary condition
673  if (local_unknown >= 0)
674  {
675  // Store a pointer to the field value
676  double* value_pt = External_interaction_field_data_pt[i]->value_pt(
678 
679  // Save the old value of the field value
680  double old_var = *value_pt;
681 
682  // Increment the value
683  *value_pt += fd_step;
684 
685  // Now update any dependent variables
687 
688  // Calculate the new residuals
689  get_residuals(newres);
690 
691  // Do forward finite differences
692  for (unsigned m = 0; m < n_dof; m++)
693  {
694  // Stick the entry into the Jacobian matrix
695  jacobian(m, local_unknown) = (newres[m] - residuals[m]) / fd_step;
696  }
697 
698  // Reset the variables
699  *value_pt = old_var;
700 
701  // Reset any dependent variables
703  }
704  } // End of loop over external interaction data
705 
706  // End of finite difference loop
707  // Final reset of any dependent data
709  }
710 
711 
712  //============================================================================
713  /// This function calculates the entries of Jacobian matrix, used in
714  /// the Newton method, associated with the external interaction
715  /// degrees of freedom for external geometric data.
716  /// It does this using finite differences,
717  /// rather than an analytical formulation, so can be done in total generality.
718  //==========================================================================
721  Vector<double>& residuals, DenseMatrix<double>& jacobian)
722  {
723  // Locally cache the number of data
724  const unsigned n_external_interaction_geometric_data =
726  // If there is no such data return
727  if (n_external_interaction_geometric_data == 0)
728  {
729  return;
730  }
731 
732  // Call the update function to ensure that the element is in a
733  // consistent state before finite differencing
735 
736  // Find the number of dofs in the element
737  const unsigned n_dof = ndof();
738 
739  // Create newres vector
740  Vector<double> newres(n_dof);
741 
742  // Integer storage for local unknown
743  int local_unknown = 0;
744 
745  // Use the default finite difference step
746  const double fd_step = Default_fd_jacobian_step;
747 
748  // Loop over the data
749  for (unsigned i = 0; i < n_external_interaction_geometric_data; i++)
750  {
751  // Find the value of the local unknown
753  // If it's not a boundary condition
754  if (local_unknown >= 0)
755  {
756  // Store a pointer to the geometric value
759 
760  // Save the old value of the geometric value
761  double old_var = *value_pt;
762 
763  // Increment the value
764  *value_pt += fd_step;
765 
766  // Now update any dependent variables
768 
769  // Calculate the new residuals
770  get_residuals(newres);
771 
772  // Do forward finite differences
773  for (unsigned m = 0; m < n_dof; m++)
774  {
775  // Stick the entry into the Jacobian matrix
776  jacobian(m, local_unknown) = (newres[m] - residuals[m]) / fd_step;
777  }
778 
779  // Reset the variables
780  *value_pt = old_var;
781 
782  // Reset any dependent variables
784  }
785  } // End of loop over external interaction data
786 
787  // End of finite difference loop
788  // Final reset of any dependent data
790  }
791 
792 
793  //============================================================================
794  /// Output by plotting vector from integration point to
795  /// corresponding point in external element for specified interaction
796  /// index
797  //==========================================================================
799  std::ostream& outfile, const unsigned& interaction_index)
800  {
801  // Dimension of element
802  unsigned n_dim_el = dim();
803  Vector<double> s(n_dim_el);
804 
805  // Vectors for coordintes
806  unsigned n_dim = node_pt(0)->ndim();
807  Vector<double> x(n_dim);
808  Vector<double> x_ext(n_dim);
809 
810  // Loop over the integration points
811  const unsigned n_intpt = this->integral_pt()->nweight();
812  outfile << "ZONE I=" << n_intpt << std::endl;
813  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
814  {
815  for (unsigned i = 0; i < n_dim_el; i++)
816  {
817  s[i] = integral_pt()->knot(ipt, i);
818  }
819 
820  // Eulerian coordinates of integration point
821  interpolated_x(s, x);
822 
823  // Get pointer to external element
824  FiniteElement* ext_el_pt = external_element_pt(interaction_index, ipt);
825  // Get local coordinate in external element
826  Vector<double> s_ext(
827  external_element_local_coord(interaction_index, ipt));
828 
829  // Eulerian coordinates of point in external element
830  ext_el_pt->interpolated_x(s_ext, x_ext);
831 
832  // Output coords of interation point
833  for (unsigned i = 0; i < n_dim; i++)
834  {
835  outfile << x[i] << " ";
836  }
837  // Write vector to point in external element
838  for (unsigned i = 0; i < n_dim; i++)
839  {
840  outfile << x_ext[i] - x[i] << " ";
841  }
842  outfile << std::endl;
843  }
844  }
845 
846 
847 } // namespace oomph
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
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
virtual void update_before_external_interaction_field_fd()
Function that is called before the finite differencing of any external interaction data associated wi...
void output_external_elements(std::ostream &outfile, const unsigned &interaction_index)
Output by plotting vector from integration point to corresponding point in external element for speci...
unsigned Nexternal_interaction_field_data
Number of external interaction field data.
Vector< double > & external_element_local_coord(const unsigned &interaction_index, const unsigned &ipt)
Access function to get source element's local coords for specified interaction index at specified int...
void initialise_external_element_storage()
Initialise storage for pointers to external elements and their local coordinates. This must be called...
unsigned Nexternal_element_storage
Number of entries in the external element storage schemes (Nintergation_pt * Ninteraction)
virtual void update_before_external_interaction_geometric_fd()
Function that is called before the finite differencing of any external interaction data associated wi...
void describe_local_dofs(std::ostream &out, const std::string &curr_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
virtual void reset_in_external_interaction_geometric_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after the values in t...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
unsigned Nexternal_interaction_geometric_data
Number of external interaction geometric data.
virtual void reset_after_external_interaction_field_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
virtual void identify_all_geometric_data_for_external_interaction(Vector< std::set< FiniteElement * >> const &external_elements_pt, std::set< Data * > &external_geometric_data_pt)
Function that must return all geometric data involved in the desired interactions from the external e...
unsigned nexternal_interaction_geometric_data() const
Return the number of geometric Data items that affect the external interactions in this element: i....
unsigned * External_interaction_field_data_index
Storage for the index of the values in the external field data that affect the interactions in the el...
unsigned nexternal_interaction_field_data() const
Return the number of Data items that affect the external interactions in this element....
virtual void reset_in_external_interaction_field_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after the values in t...
virtual ~ElementWithExternalElement()
The destructor, clean up any allocated memory.
void fill_in_jacobian_from_external_interaction_field_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from the external interaction degrees of freedom associat...
FiniteElement ** External_element_pt
Storage for pointers to elements that provide contributions to the residuals of the current element....
Data ** External_interaction_field_data_pt
/ Storage for pointers to external field Data that affect the interactions in the elemenet
Vector< double > * External_element_local_coord
Storage for vectors of local coordinates in external elements that correspond to the appropriate inte...
int * External_interaction_field_data_local_eqn
Storage for the local equation number associated with the external field data the affect the interact...
virtual void reset_after_external_interaction_geometric_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
bool Add_external_geometric_data
Boolean flag to indicate whether to include the external geometric data.
virtual void update_in_external_interaction_geometric_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after a change in any...
Data ** External_interaction_geometric_data_pt
/ Storage for pointers to external geometric Data that affect the interactions in the elemenet
unsigned * External_interaction_geometric_data_index
Storage for the index of the values in the external geometric data that affect the interactions in th...
bool Add_external_interaction_data
Boolean flag to indicate whether to include the external data.
void fill_in_jacobian_from_external_interaction_geometric_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from the external interaction degrees of freedom associat...
virtual void identify_all_field_data_for_external_interaction(Vector< std::set< FiniteElement * >> const &external_elements_pt, std::set< std::pair< Data *, unsigned >> &paired_interaction_data)
Function that must return all the data involved in the desired interactions from the external element...
unsigned ninteraction() const
Return the number of interactions in the element.
void assign_external_interaction_data_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers for those Data values involved in the external interactions that af...
unsigned Nintpt
Number of intergation point in the element.
unsigned Ninteraction
Number of interactions.
int * External_interaction_geometric_data_local_eqn
Storage for the local equation number associated with the external geometric data the affect the inte...
virtual void update_in_external_interaction_field_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after a change in any...
void flush_all_external_element_storage()
Flush the storage for external elements.
A general Finite Element class.
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
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:3962
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
Data * geom_data_pt(const unsigned &j)
A standard FiniteElement is fixed, so there are no geometric data when viewed in its GeomObject incar...
Definition: elements.h:2667
unsigned ngeom_data() const
A standard FiniteElement is fixed, so there are no geometric data when viewed in its GeomObject incar...
Definition: elements.h:2660
unsigned nexternal_data() const
Return the number of external data objects.
Definition: elements.h:829
bool is_halo() const
Is this element a halo?
Definition: elements.h:1163
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
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
Definition: elements.h:659
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
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
unsigned ninternal_data() const
Return the number of internal data objects.
Definition: elements.h:823
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
virtual 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 ...
Definition: elements.cc:573
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
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.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:906
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Definition: nodes.h:1686
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
Definition: nodes.h:1765
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...