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-2022 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
30namespace 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 {
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
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
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
Definition: nodes.h:367
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
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...
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 ...
unsigned nexternal_interaction_geometric_data() const
Return the number of geometric Data items that affect the external interactions in this element: i....
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 * 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 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...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
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...
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
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
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
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
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
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
Definition: elements.h:659
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
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
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
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.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...