beam_elements.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-2026 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// Non-inline functions for Kirchhoff Love beam elements
27
28#include "beam_elements.h"
29
30namespace oomph
31{
32 //================================================================
33 /// Static default value for 2nd Piola Kirchhoff prestress (zero)
34 //================================================================
36
37 //=====================================================================
38 /// Static default value for timescale ratio (1.0 for natural scaling)
39 //=====================================================================
41
42 //=========================================================
43 /// Static default value for non-dim wall thickness (1/20)
44 //=========================================================
45 // i.e. the reference thickness 'h_0'
47
48 //=======================================================================
49 /// Default load function (zero traction)
50 //=======================================================================
52 const Vector<double>& x,
53 const Vector<double>& N,
55 {
56 unsigned n_dim = load.size();
57 for (unsigned i = 0; i < n_dim; i++)
58 {
59 load[i] = 0.0;
60 }
61 }
62
63 //=======================================================================
64 /// Default wall profile function (constant thickness h_0)
65 //=======================================================================
67 const Vector<double>& x,
68 double& h_ratio)
69 {
70 h_ratio = 1.0;
71 }
72
73
74 //=======================================================================
75 /// Get position vector to and normal vector on wall
76 //=======================================================================
80 {
81#ifdef PARANOID
82 if (N.size() != 2)
83 {
84 std::ostringstream error_message;
85 error_message << "Normal vector should have dimension 2, not" << N.size()
86 << std::endl;
87
88 throw OomphLibError(
90 }
91 if (r.size() != 2)
92 {
93 std::ostringstream error_message;
94 error_message << "Position vector should have dimension 2, not"
95 << r.size() << std::endl;
96
97 throw OomphLibError(
99 }
100
101 if (s.size() != 1)
102 {
103 std::ostringstream error_message;
104 error_message << "Local coordinate should have dimension 1, not"
105 << s.size() << std::endl;
106
107 throw OomphLibError(
109 }
110#endif
111
112 // Set the dimension of the global coordinates
113 unsigned n_dim = Undeformed_beam_pt->ndim();
114
115 // Set the number of lagrangian coordinates
117
118 // Find out how many nodes there are
119 unsigned n_node = nnode();
120
121 // Find out how many positional dofs there are
123
124 // Set up memory for the shape functions:
125
126 // # of nodes, # of positional dofs
128
129 // # of nodes, # of positional dofs, # of lagrangian coords (for deriv)
131
132 // Call the derivatives of the shape functions w.r.t. Lagrangian coords
134
135 // Base Vector
137
138 // Initialise to zero
139
140 // Loop over coordinate directions/components of Vector
141 for (unsigned i = 0; i < n_dim; i++)
142 {
143 r[i] = 0.0;
144 // Loop over derivatives/base Vectors (just one here)
145 for (unsigned j = 0; j < n_lagrangian; j++)
146 {
147 interpolated_A(j, i) = 0.0;
148 }
149 }
150
151 // Loop over directions
152 for (unsigned i = 0; i < n_dim; i++)
153 {
154 // Loop over nodes
155 for (unsigned l = 0; l < n_node; l++)
156 {
157 // Loop over positional dofs
158 for (unsigned k = 0; k < n_position_type; k++)
159 {
160 r[i] += raw_nodal_position_gen(l, k, i) * psi(l, k);
161
162 // Loop over derivative directions (just one here)
163 for (unsigned j = 0; j < n_lagrangian; j++)
164 {
165 interpolated_A(j, i) +=
167 }
168 }
169 }
170 }
171
172 // Calculate the length of the normal vector
173 double length = pow(interpolated_A(0, 0), 2) + pow(interpolated_A(0, 1), 2);
174
175 // Calculate the normal
176 N[0] = -interpolated_A(0, 1) / sqrt(length);
177 N[1] = interpolated_A(0, 0) / sqrt(length);
178 }
179
180
181 //=======================================================================
182 /// Get position vector to and non-unit tangent vector on wall: dr/ds
183 //=======================================================================
187 {
188#ifdef PARANOID
189 if (drds.size() != 2)
190 {
191 std::ostringstream error_message;
192 error_message << "Tangent vector should have dimension 2, not"
193 << drds.size() << std::endl;
194
195 throw OomphLibError(
197 }
198 if (r.size() != 2)
199 {
200 std::ostringstream error_message;
201 error_message << "Position vector should have dimension 2, not"
202 << r.size() << std::endl;
203
204 throw OomphLibError(
206 }
207
208 if (s.size() != 1)
209 {
210 std::ostringstream error_message;
211 error_message << "Local coordinate should have dimension 1, not"
212 << s.size() << std::endl;
213
214 throw OomphLibError(
216 }
217#endif
218
219 // Set the dimension of the global coordinates
220 unsigned n_dim = Undeformed_beam_pt->ndim();
221
222 // Set the number of lagrangian coordinates
224
225 // Find out how many nodes there are
226 unsigned n_node = nnode();
227
228 // Find out how many positional dofs there are
230
231 // Set up memory for the shape functions:
232
233 // # of nodes, # of positional dofs
235
236 // # of nodes, # of positional dofs, # of lagrangian coords (for deriv)
238
239 // Call the derivatives of the shape functions w.r.t. local coords
241
242 // Initialise to zero
243
244 // Loop over coordinate directions/components of Vector
245 for (unsigned i = 0; i < n_dim; i++)
246 {
247 r[i] = 0.0;
248 drds[i] = 0.0;
249 }
250
251 // Loop over directions
252 for (unsigned i = 0; i < n_dim; i++)
253 {
254 // Loop over nodes
255 for (unsigned l = 0; l < n_node; l++)
256 {
257 // Loop over positional dofs
258 for (unsigned k = 0; k < n_position_type; k++)
259 {
260 r[i] += raw_nodal_position_gen(l, k, i) * psi(l, k);
261 // deriv w.r.t. to zero-th (and only) local coordiate
262 drds[i] += raw_nodal_position_gen(l, k, i) * dpsids(l, k, 0);
263 }
264 }
265 }
266 }
267
268
269 //=======================================================================
270 /// Return the residuals for the equations of Kirchhoff-Love beam
271 /// theory with linear constitutive equations; if Solid_ic_pt!=0, we
272 /// assign residuals which force the assignement of an initial shape/
273 /// veloc/accel to the dofs.
274 //=======================================================================
277 {
278 // Set up the initial conditions, if an IC pointer has been set
279 if (Solid_ic_pt != 0)
280 {
282 return;
283 }
284
285 // Set the dimension of the global coordinates
286 const unsigned n_dim = Undeformed_beam_pt->ndim();
287
288 // Set the number of lagrangian coordinates
289 const unsigned n_lagrangian = Undeformed_beam_pt->nlagrangian();
290
291 // Find out how many nodes there are
292 const unsigned n_node = nnode();
293
294 // Find out how many positional dofs there are
295 const unsigned n_position_type = nnodal_position_type();
296
297 // Integer to store the local equation number
298 int local_eqn = 0;
299
300 // Setup memory for accelerations
301 Vector<double> accel(2);
302
303 // Set up memory for the shape functions:
304
305 // # of nodes, # of positional dofs
307
308 // # of nodes, # of positional dofs, # of lagrangian coords (for deriv)
310
311 // # of nodes, # of positional dofs, # of derivs)
313
314 // Set # of integration points
315 const unsigned n_intpt = integral_pt()->nweight();
316
317 // Get Physical Variables from Element
318
319 // Thickness h_0/R, axial prestress, timescale ratio (density)
320 const double HoR_0 = h(); // i.e. refers to reference thickness 'h_0'
321 const double sigma_0 = sigma0();
322 const double Lambda_sq = lambda_sq();
323
324 // Loop over the integration points
325 for (unsigned ipt = 0; ipt < n_intpt; ipt++)
326 {
327 // Get the integral weight
328 double w = integral_pt()->weight(ipt);
329
330 // Call the derivatives of the shape functions w.r.t. Lagrangian coords
332
333 // Premultiply the weights and the Jacobian
334 double W = w * J;
335
336 // Calculate local values of lagrangian position and
337 // the derivative of global position wrt lagrangian coordinates
339 interpolated_x(n_dim, 0.0);
342
343 // Initialise to zero
344 // Loop over coordinate directions/components of Vector
345 for (unsigned i = 0; i < n_dim; i++)
346 {
347 // Initialise acclerations
348 accel[i] = 0.0;
349 // Loop over derivatives/base Vectors (just one here)
350 for (unsigned j = 0; j < n_lagrangian; j++)
351 {
352 interpolated_A(j, i) = 0.0;
353 }
354 // Loop over derivatives of base Vector (just one here)
355 for (unsigned j = 0; j < n_lagrangian; j++)
356 {
357 interpolated_dAdxi(j, i) = 0.0;
358 }
359 }
360
361 // Calculate displacements, accelerations and spatial derivatives
362 for (unsigned l = 0; l < n_node; l++)
363 {
364 // Loop over positional dofs
365 for (unsigned k = 0; k < n_position_type; k++)
366 {
367 // Loop over Lagrangian coordinate directions [xi_gen[] are the
368 // the *gen*eralised Lagrangian coordinates: node, type, direction]
369 for (unsigned i = 0; i < n_lagrangian; i++)
370 {
373 }
374
375 // Loop over components of the deformed position Vector
376 for (unsigned i = 0; i < n_dim; i++)
377 {
379
380 accel[i] += raw_dnodal_position_gen_dt(2, l, k, i) * psi(l, k);
381
382 // Loop over derivative directions (just one here)
383 for (unsigned j = 0; j < n_lagrangian; j++)
384 {
385 interpolated_A(j, i) +=
387 }
388
389 // Loop over the second derivative directions (just one here)
390 for (unsigned j = 0; j < n_lagrangian; j++)
391 {
394 }
395 }
396 }
397 }
398
399 // Setup position Vector and derivatives of undeformed config
403
404 // Get the undeformed geometry
406
407 // Declare and calculate the undeformed and deformed metric tensor
408 // and the strain tensor (these are just scalars)
409 double amet = 0.0, Amet = 0.0;
410
411 // Now calculate the dot product
412 for (unsigned k = 0; k < n_dim; k++)
413 {
414 amet += a(0, k) * a(0, k);
415 Amet += interpolated_A(0, k) * interpolated_A(0, k);
416 }
417
418 double gamma = 0.5 * (Amet - amet);
419
420 // Calculate the contravariant metric tensors
421 double adet = amet; // double aup = 1.0/amet;
422 double Adet = Amet; // double Aup = 1.0/Amet;
423
424 // Calculate the unit normal Vectors
425 Vector<double> n(2);
426 Vector<double> N(2);
427 n[0] = -a(0, 1) / sqrt(adet);
428 n[1] = a(0, 0) / sqrt(adet);
429
430 N[0] = -interpolated_A(0, 1) / sqrt(Adet);
431 N[1] = interpolated_A(0, 0) / sqrt(Adet);
432
433 // Square root of deformed determinant
434 double sqrt_Adet = sqrt(Adet);
435
436 // Calculate the curvature tensors
437 double b = n[0] * dadxi(0, 0, 0) + n[1] * dadxi(0, 0, 1);
438 double B =
439 N[0] * interpolated_dAdxi(0, 0) + N[1] * interpolated_dAdxi(0, 1);
440
441 // Set up the change of curvature tensor
442 double kappa = b - B;
443
444 // Define the load Vector
446
447 // Get load Vector
449
450 // Define the wall thickness ratio profile
451 double h_ratio = 0;
452
453 // Get wall thickness ratio profile
455
456 // Thickness h/R
457 double HoR = HoR_0 * h_ratio;
458
459 // Allocate storage for variations of normal Vector
460 double normal_var[n_dim][n_dim];
461
462 // Geometrically nonlinear beam equations from
463 //--------------------------------------------
464 // principle of virtual displacements
465 //-----------------------------------
466
467 // Loop over the number of nodes
468 for (unsigned n = 0; n < n_node; n++)
469 {
470 // Loop over the type of degree of freedom
471 for (unsigned k = 0; k < n_position_type; k++)
472 {
473 // Setup components of variation of normal Vector:
474 // ...(variation w.r.t. direction, component)
475
476 normal_var[0][0] = interpolated_A(0, 0) * interpolated_A(0, 1) *
477 dpsidxi(n, k, 0) /
479
480 normal_var[1][0] =
481 (interpolated_A(0, 1) * interpolated_A(0, 1) / Adet - 1.0) *
482 dpsidxi(n, k, 0) / (sqrt_Adet);
483
484 normal_var[0][1] =
485 (1.0 - interpolated_A(0, 0) * interpolated_A(0, 0) / Adet) *
486 dpsidxi(n, k, 0) / (sqrt_Adet);
487
488 normal_var[1][1] = -interpolated_A(0, 0) * interpolated_A(0, 1) *
489 dpsidxi(n, k, 0) /
491
492
493 // Correction factor for non-arclength coordinate.
494 // Remember that (undeformed) metric tensor features
495 // in elasticity tensor!
497 1.0 / (adet * adet);
498
499 // Correction factor for non-arclength coordinate.
500 // Remember that the pre-stress is a second Piola Kirchhoff
501 // stress and in the undeformed configuration the product of
502 // of its magnitude with the undeformed (but stretched!)
503 // tangent basis vector must give the actual pre-stress.
505 1.0 / (adet);
506
507 // Loop over the coordinate directions
508 for (unsigned i = 0; i < n_dim; i++)
509 {
510 // Find the equation number
512
513 // If it's not a boundary condition
514 if (local_eqn >= 0)
515 {
516 // Premultiply by thickness profile
517
518 // External forcing
520 h_ratio * (1.0 / HoR) * f[i] * psi(n, k) * W * sqrt(Adet);
521
523 h_ratio * Lambda_sq * accel[i] * psi(n, k) * W * sqrt(adet);
524
525 // Membrane term with axial prestress
527 h_ratio *
528 (sigma_0 *
531 interpolated_A(0, i) * dpsidxi(n, k, 0) * W * sqrt(adet);
532
533 // Bending term: Minus sign because \delta \kappa = - \delta B
535 h_ratio * (1.0 / 12.0) * HoR * HoR * kappa *
537 (N[i] * d2psidxi(n, k, 0) +
538 normal_var[i][0] * interpolated_dAdxi(0, 0) +
539 normal_var[i][1] * interpolated_dAdxi(0, 1)) *
540 W * sqrt(adet);
541 }
542 }
543 }
544 }
545
546 } // End of loop over the integration points
547 }
548
549
550 //=======================================================================
551 /// Get FE jacobian and residuals (Jacobian done by finite differences)
552 //=======================================================================
555 {
556 // Call the element's residuals vector
558
559 // Solve for the consistent acceleration in Newmark scheme?
561 {
563 return;
564 }
565
566 // Allocate storage for the full residuals of the element
567 unsigned n_dof = ndof();
569
570 // Call the full residuals
572
573 // Get the solid entries in the jacobian using finite differences
575 full_residuals, jacobian);
576
577 // Get the entries from the external data, usually load terms
579 jacobian);
580 }
581
582
583 //=======================================================================
584 /// Compute the potential (strain) and kinetic energy of the
585 /// element (wrapper function).
586 //=======================================================================
588 {
589 // Initialise
590 double stretch = 0.0;
591 double bend = 0.0;
592 kin_en = 0.0;
593
594 // Compute energy
596
597 // Sum components of potential energy
598 pot_en = stretch + bend;
599 }
600
601
602 //=======================================================================
603 /// Compute the potential (strain) and kinetic energy of the
604 /// element, breaking down the potential energy into stretching and
605 /// bending components.
606 //=======================================================================
608 double& bend,
609 double& kin_en)
610 {
611 // Initialise
612 stretch = 0.0;
613 bend = 0.0;
614 kin_en = 0.0;
615
616 // Set the dimension of the global coordinates
617 unsigned n_dim = Undeformed_beam_pt->ndim();
618
619 // Set the number of lagrangian coordinates
621
622 // Find out how many nodes there are
623 unsigned n_node = nnode();
624
625 // Find out how many positional dofs there are
627
628 // Setup memory for veloc
629 Vector<double> veloc(2);
630
631 // Set up memory for the shape functions:
632
633 // # of nodes, # of positional dofs
635
636 // # of nodes, # of positional dofs, # of lagrangian coords (for deriv)
638
639 // # of nodes, # of positional dofs, # of derivs)
641
642 // Set # of integration points
643 unsigned n_intpt = integral_pt()->nweight();
644
645 // Get Physical Variables from Element
646
647 // Thickness h_0/R, axial prestress, timescale ratio (density)
648 double HoR_0 = h(); // i.e. refers to reference thickness 'h_0'
649 double sigma_0 = sigma0();
650
651 double Lambda_sq = lambda_sq();
652
653 // Loop over the integration points
654 for (unsigned ipt = 0; ipt < n_intpt; ipt++)
655 {
656 // Get the integral weight
657 double w = integral_pt()->weight(ipt);
658
659 // Call the derivatives of the shape functions w.r.t. Lagrangian coords
661
662 // Premultiply the weights and the Jacobian
663 double W = w * J;
664
665 // Calculate local values of lagrangian position and
666 // the derivative of global position wrt lagrangian coordinates
668 interpolated_x(n_dim, 0.0);
669
672
673 // Initialise to zero
674
675 // Loop over coordinate directions/components of Vector
676 for (unsigned i = 0; i < n_dim; i++)
677 {
678 // Initialise veloc
679 veloc[i] = 0.0;
680
681 // Loop over derivatives/base Vectors (just one here)
682 for (unsigned j = 0; j < n_lagrangian; j++)
683 {
684 interpolated_A(j, i) = 0.0;
685 }
686 // Loop over derivatives of base Vector (just one here)
687 for (unsigned j = 0; j < n_lagrangian; j++)
688 {
689 interpolated_dAdxi(j, i) = 0.0;
690 }
691 }
692
693 // Calculate displacements, accelerations and spatial derivatives
694 for (unsigned l = 0; l < n_node; l++)
695 {
696 // Loop over positional dofs
697 for (unsigned k = 0; k < n_position_dofs; k++)
698 {
699 // Loop over Lagrangian coordinate directions [xi_gen[] are the
700 // the *gen*eralised Lagrangian coordinates: node, type, direction]
701 for (unsigned i = 0; i < n_lagrangian; i++)
702 {
705 }
706
707 // Loop over components of the deformed position Vector
708 for (unsigned i = 0; i < n_dim; i++)
709 {
710 // Need this for wall thickness ratio profile
712
713 veloc[i] += raw_dnodal_position_gen_dt(1, l, k, i) * psi(l, k);
714
715 // Loop over derivative directions (just one here)
716 for (unsigned j = 0; j < n_lagrangian; j++)
717 {
718 interpolated_A(j, i) +=
720 }
721
722 // Loop over the second derivative directions (just one here)
723 for (unsigned j = 0; j < n_lagrangian; j++)
724 {
727 }
728 }
729 }
730 }
731
732 // Get square of veloc
733 double veloc_sq = 0;
734 for (unsigned i = 0; i < n_dim; i++)
735 {
736 veloc_sq += veloc[i] * veloc[i];
737 }
738
739 // Setup position Vector and derivatives of undeformed config
743
744 // Get the undeformed geometry
746
747 // Declare and calculate the undeformed and deformed metric tensor
748 // and the strain tensor (these are 1d tensors, i.e. scalars)
749 double amet = 0.0, Amet = 0.0;
750
751 // Work out metric and strain tensors
752 // Now calculate the dot product
753 for (unsigned k = 0; k < n_dim; k++)
754 {
755 amet += a(0, k) * a(0, k);
756 Amet += interpolated_A(0, k) * interpolated_A(0, k);
757 }
758
759 // Calculate strain tensor
760 double gamma = 0.5 * (Amet - amet);
761
762 // Calculate the contravariant metric tensors
763 double adet = amet; // aup = 1.0/amet;
764 double Adet = Amet; // Aup = 1.0/Amet;
765
766 // Calculate the unit normal Vectors
767 Vector<double> n(2);
768 Vector<double> N(2);
769 n[0] = -a(0, 1) / sqrt(adet);
770 n[1] = a(0, 0) / sqrt(adet);
771
772 N[0] = -interpolated_A(0, 1) / sqrt(Adet);
773 N[1] = interpolated_A(0, 0) / sqrt(Adet);
774
775 // Calculate the curvature tensors
776 double b = n[0] * dadxi(0, 0, 0) + n[1] * dadxi(0, 0, 1);
777 double B =
778 N[0] * interpolated_dAdxi(0, 0) + N[1] * interpolated_dAdxi(0, 1);
779
780 // Set up the change of curvature tensor
781 double kappa = b - B;
782
783 // Define the wall thickness ratio profile
784 double h_ratio = 0;
785
786 // Get wall thickness ratio profile
788
789 // Thickness h/R
790 double HoR = HoR_0 * h_ratio;
791
792 // Add contributions
793 stretch +=
794 h_ratio * 0.5 * (gamma + sigma_0) * (gamma + sigma_0) * W * sqrt(adet);
795 bend += h_ratio * 0.5 * (1.0 / 12.0) * HoR * HoR * kappa * kappa * W *
796 sqrt(adet);
797 kin_en += h_ratio * 0.5 * Lambda_sq * veloc_sq * W * sqrt(adet);
798 } // End of loop over the integration points
799 }
800
801 //=======================================================================
802 /// Output position at previous time (t=0: present; t>0: previous)
803 /// with specified number of plot points.
804 //=======================================================================
805 void HermiteBeamElement::output(const unsigned& t,
806 std::ostream& outfile,
807 const unsigned& n_plot) const
808 {
809#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
810 // Warn about time argument being moved to the front
812 "Order of function arguments has changed between versions 0.8 and 0.85",
813 "HermiteBeamElement::output(...)",
815#endif
816
817 // Local variables
818 Vector<double> s(1);
819
820 // Tecplot header info
821 outfile << "ZONE I=" << n_plot << std::endl;
822
823 // Find the dimension of the first node
824 unsigned n_dim = this->node_pt(0)->ndim();
825
826 // Loop over plot points
827 for (unsigned l = 0; l < n_plot; l++)
828 {
829 s[0] = -1.0 + l * 2.0 / (n_plot - 1);
830
831 // Output the Eulerian coordinates
832 for (unsigned i = 0; i < n_dim; i++)
833 {
834 outfile << interpolated_x(t, s, i) << " ";
835 }
836 outfile << std::endl;
837 }
838 }
839
840
841 //=======================================================================
842 /// Output function
843 //=======================================================================
844 void HermiteBeamElement::output(std::ostream& outfile, const unsigned& n_plot)
845 {
846 // Local variables
847 Vector<double> s(1);
848
849 // Tecplot header info
850 outfile << "ZONE I=" << n_plot << std::endl;
851
852 // Set the number of lagrangian coordinates
854
855 // Set the dimension of the global coordinates
856 unsigned n_dim = Undeformed_beam_pt->ndim();
857
858 // Find out how many nodes there are
859 unsigned n_node = nnode();
860
861 // Find out how many positional dofs there are
863
864 Vector<double> veloc(n_dim);
865 Vector<double> accel(n_dim);
867
868 // # of nodes, # of positional dofs
870
871 // Loop over element plot points
872 for (unsigned l1 = 0; l1 < n_plot; l1++)
873 {
874 s[0] = -1.0 + l1 * 2.0 / (n_plot - 1);
875
876 // Get shape functions
877 shape(s, psi);
878
880 interpolated_xi[0] = 0.0;
881
882 // Loop over coordinate directions/components of Vector
883 for (unsigned i = 0; i < n_dim; i++)
884 {
885 // Initialise acclerations and veloc
886 accel[i] = 0.0;
887 veloc[i] = 0.0;
888 posn[i] = 0.0;
889 }
890
891
892 // Calculate displacements, accelerations and spatial derivatives
893 for (unsigned l = 0; l < n_node; l++)
894 {
895 // Loop over positional dofs
896 for (unsigned k = 0; k < n_position_dofs; k++)
897 {
898 // Loop over Lagrangian coordinate directions [xi_gen[] are the
899 // the *gen*eralised Lagrangian coordinates: node, type, direction]
900 for (unsigned i = 0; i < n_lagrangian; i++)
901 {
904 }
905
906 // Loop over components of the deformed position Vector
907 for (unsigned i = 0; i < n_dim; i++)
908 {
909 accel[i] += raw_dnodal_position_gen_dt(2, l, k, i) * psi(l, k);
910 veloc[i] += raw_dnodal_position_gen_dt(1, l, k, i) * psi(l, k);
911 posn[i] += raw_dnodal_position_gen_dt(0, l, k, i) * psi(l, k);
912 }
913 }
914 }
915
916 double scalar_accel = 0.0;
917 double scalar_veloc = 0.0;
918 double scalar_posn = 0.0;
919
920 // Output position etc.
921 for (unsigned i = 0; i < n_dim; i++)
922 {
923 outfile << posn[i] << " ";
924 scalar_posn += pow(posn[i], 2);
925 }
926 outfile << interpolated_xi[0] << " ";
927 for (unsigned i = 0; i < n_dim; i++)
928 {
929 outfile << veloc[i] << " ";
930 scalar_veloc += pow(veloc[i], 2);
931 }
932 for (unsigned i = 0; i < n_dim; i++)
933 {
934 outfile << accel[i] << " ";
935 scalar_accel += pow(accel[i], 2);
936 }
937 outfile << sqrt(scalar_posn) << " ";
938 outfile << sqrt(scalar_veloc) << " ";
939 outfile << sqrt(scalar_accel) << " ";
940 outfile << std::endl;
941 }
942 }
943
944
945 //=======================================================================
946 /// Output function
947 //=======================================================================
949 {
950 unsigned n_plot = 5;
952 }
953
954
955 //=======================================================================
956 /// C-style output position at previous time (t=0: present; t>0: previous)
957 /// with specified number of plot points.
958 //=======================================================================
959 void HermiteBeamElement::output(const unsigned& t,
960 FILE* file_pt,
961 const unsigned& n_plot) const
962 {
963#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
964 // Warn about time argument being moved to the front
966 "Order of function arguments has changed between versions 0.8 and 0.85",
967 "HermiteBeamElement::output(...)",
969#endif
970
971 // Local variables
972 Vector<double> s(1);
973
974 // Tecplot header info
975 // outfile << "ZONE I=" << n_plot << std::endl;
976 fprintf(file_pt, "ZONE I=%i \n", n_plot);
977
978 // Find the dimension of the first node
979 unsigned n_dim = this->node_pt(0)->ndim();
980
981 // Loop over plot points
982 for (unsigned l = 0; l < n_plot; l++)
983 {
984 s[0] = -1.0 + l * 2.0 / (n_plot - 1);
985
986 // Output the Eulerian coordinates
987 for (unsigned i = 0; i < n_dim; i++)
988 {
989 // outfile << interpolated_x(s,t,i) << " " ;
990 fprintf(file_pt, "%g ", interpolated_x(t, s, i));
991 }
992 // outfile << std::endl;
993 fprintf(file_pt, "\n");
994 }
995 }
996
997
998 //=======================================================================
999 /// Output function
1000 //=======================================================================
1002 {
1003 // Local variables
1004 Vector<double> s(1);
1005
1006 // Tecplot header info
1007 // outfile << "ZONE I=" << n_plot << std::endl;
1008 fprintf(file_pt, "ZONE I=%i \n", n_plot);
1009
1010 // Set the number of lagrangian coordinates
1012
1013 // Set the dimension of the global coordinates
1014 unsigned n_dim = Undeformed_beam_pt->ndim();
1015
1016 // Find out how many nodes there are
1017 unsigned n_node = nnode();
1018
1019 // Find out how many positional dofs there are
1021
1022 Vector<double> veloc(n_dim);
1023 Vector<double> accel(n_dim);
1025
1026 // # of nodes, # of positional dofs
1028
1029 // Loop over element plot points
1030 for (unsigned l1 = 0; l1 < n_plot; l1++)
1031 {
1032 s[0] = -1.0 + l1 * 2.0 / (n_plot - 1);
1033
1034 // Get shape functions
1035 shape(s, psi);
1036
1038 interpolated_xi[0] = 0.0;
1039
1040 // Loop over coordinate directions/components of Vector
1041 for (unsigned i = 0; i < n_dim; i++)
1042 {
1043 // Initialise acclerations and veloc
1044 accel[i] = 0.0;
1045 veloc[i] = 0.0;
1046 posn[i] = 0.0;
1047 }
1048
1049
1050 // Calculate displacements, accelerations and spatial derivatives
1051 for (unsigned l = 0; l < n_node; l++)
1052 {
1053 // Loop over positional dofs
1054 for (unsigned k = 0; k < n_position_dofs; k++)
1055 {
1056 // Loop over Lagrangian coordinate directions [xi_gen[] are the
1057 // the *gen*eralised Lagrangian coordinates: node, type, direction]
1058 for (unsigned i = 0; i < n_lagrangian; i++)
1059 {
1060 interpolated_xi[i] +=
1062 }
1063
1064 // Loop over components of the deformed position Vector
1065 for (unsigned i = 0; i < n_dim; i++)
1066 {
1067 accel[i] += raw_dnodal_position_gen_dt(2, l, k, i) * psi(l, k);
1068 veloc[i] += raw_dnodal_position_gen_dt(1, l, k, i) * psi(l, k);
1069 posn[i] += raw_dnodal_position_gen_dt(0, l, k, i) * psi(l, k);
1070 }
1071 }
1072 }
1073
1074 double scalar_accel = 0.0;
1075 double scalar_veloc = 0.0;
1076 double scalar_posn = 0.0;
1077
1078 // Output position etc.
1079 for (unsigned i = 0; i < n_dim; i++)
1080 {
1081 // outfile << posn[i] << " " ;
1082 fprintf(file_pt, "%g ", posn[i]);
1083 scalar_posn += pow(posn[i], 2);
1084 }
1085 // outfile << interpolated_xi[0] << " ";
1086 fprintf(file_pt, "%g ", interpolated_xi[0]);
1087 for (unsigned i = 0; i < n_dim; i++)
1088 {
1089 // outfile << veloc[i] << " " ;
1090 fprintf(file_pt, "%g ", veloc[i]);
1091 scalar_veloc += pow(veloc[i], 2);
1092 }
1093 for (unsigned i = 0; i < n_dim; i++)
1094 {
1095 // outfile << accel[i] << " " ;
1096 fprintf(file_pt, "%g ", accel[i]);
1097 scalar_accel += pow(accel[i], 2);
1098 }
1099 // outfile << sqrt(scalar_posn) << " ";
1100 fprintf(file_pt, "%g ", sqrt(scalar_posn));
1101 // outfile << sqrt(scalar_veloc) << " ";
1102 fprintf(file_pt, "%g ", sqrt(scalar_veloc));
1103 // outfile << sqrt(scalar_accel) << " ";
1104 fprintf(file_pt, "%g ", sqrt(scalar_accel));
1105 // outfile << std::endl;
1106 fprintf(file_pt, "\n");
1107 }
1108 }
1109
1110
1111 //=======================================================================
1112 /// C-style output function
1113 //=======================================================================
1115 {
1116 unsigned n_plot = 5;
1118 }
1119
1120 ///////////////////////////////////////////////////////////////////////////
1121 ///////////////////////////////////////////////////////////////////////////
1122 ///////////////////////////////////////////////////////////////////////////
1123
1124
1125 //=======================================================================
1126 /// Function used to find the local coordinate s that corresponds to the
1127 /// "global" intrinsic coordinate zeta (in the element's incarnation
1128 /// as a GeomObject). For this element, zeta is equal to the Lagrangian
1129 /// coordinate xi. If the required zeta is located within this
1130 /// element, geom_object_pt points to "this" element. If zeta
1131 /// is not located within the element it is set to NULL.
1132 //======================================================================
1134 const Vector<double>& zeta,
1135 GeomObject*& geom_object_pt,
1138 {
1139 // Assumed that the first node has a lower xi coordinate than the second
1140 unsigned lo = 0, hi = 1;
1141
1142 // If the first node has a higher xi then swap
1144 {
1145 lo = 1;
1146 hi = 0;
1147 }
1148
1149 // Tolerance for finding zeta
1150 double epsilon = 1.0e-13;
1151
1152 // If zeta is not in the element, then return a null pointer
1153 // Correct for rounding errors here
1154 if ((zeta[0] - raw_lagrangian_position(lo, 0) < -epsilon) ||
1155 (zeta[0] - raw_lagrangian_position(hi, 0) > epsilon))
1156 {
1157 geom_object_pt = 0;
1158 return;
1159 }
1160
1161 // Otherwise, zeta is located in this element. For now assume
1162 // that the relationship between zeta and s is linear as it will
1163 // be for uniform node spacing... We'll trap this further down.
1164 // In general we'll need a Newton method here and we'll implement
1165 // this as soon as we have an example with non-uniformly spaced
1166 // FSIHermiteBeamElements...
1167
1168 // The GeomObject that contains the zeta coordinate is "this":
1169 geom_object_pt = this;
1170
1171
1172 // Find the fraction along the element
1173 double zeta_fraction =
1174 (zeta[0] - raw_lagrangian_position(lo, 0)) /
1176
1177 s[0] = -1.0 + zeta_fraction * 2.0;
1178
1179#ifdef PARANOID
1180 // Check if we've really ended where we wanted to be...
1183 if (std::fabs(zeta[0] - zeta_test[0]) > epsilon)
1184 {
1185 std::ostringstream error_stream;
1187 << "The zeta coordinate " << zeta_test[0] << " \n"
1188 << "computed by interpolated_zeta() for s[0]=" << s[0] << " \n"
1189 << "differs by more than the tolerance (" << epsilon << ") from \n "
1190 << "the required value " << zeta_test[0] << " \n\n"
1191 << "You're probably using a mesh with non-uniformly \n "
1192 << "spaced FSIHermiteBeamElements. For such cases the root finding"
1193 << "in FSIHermiteBeamElement::locate_zeta() must be replaced "
1194 << "by a proper Newton method or some such thing...\n";
1196 "FSIHermiteBeamElement::locate_zeta()",
1198 }
1199#endif
1200
1201
1202 // Check for rounding error
1203 if (s[0] > 1.0)
1204 {
1205 s[0] = 1.0;
1206 }
1207 if (s[0] < -1.0)
1208 {
1209 s[0] = -1.0;
1210 }
1211 }
1212
1213
1214 //=========================================================================
1215 /// Define the dposition function. This is used to set no-slip boundary
1216 /// conditions in FSI problems.
1217 //=========================================================================
1220 {
1221#ifdef PARANOID
1222 if (Undeformed_beam_pt == 0)
1223 {
1224 throw OomphLibError(
1225 "Undeformed_beam_pt has not been set",
1226 "FSIHermiteBeamElement::dposition_dlagrangian_at_local_coordinate()",
1228 }
1229#endif
1230
1231 // Find the dimension of the global coordinate
1232 unsigned n_dim = Undeformed_beam_pt->ndim();
1233 // Find the number of lagrangian coordinates
1235 // Find out how many nodes there are
1236 unsigned n_node = nnode();
1237 // Find out how many positional dofs there are
1238 unsigned n_position_type = this->nnodal_position_type();
1239
1240 // Set up memory for the shape functions
1243
1244 // Get the derivatives of the shape functions w.r.t local coordinates
1245 // at this point
1247
1248 // Initialise the derivatives to zero
1249 drdxi.initialise(0.0);
1250
1251 // Loop over the nodes
1252 for (unsigned l = 0; l < n_node; l++)
1253 {
1254 // Loop over the positional types
1255 for (unsigned k = 0; k < n_position_type; k++)
1256 {
1257 // Loop over the dimensions
1258 for (unsigned i = 0; i < n_dim; i++)
1259 {
1260 // Loop over the lagrangian coordinates
1261 for (unsigned j = 0; j < n_lagrangian; j++)
1262 {
1263 // Add the contribution to the derivative
1264 drdxi(j, i) += nodal_position_gen(l, k, i) * dpsidxi(l, k, j);
1265 }
1266 }
1267 }
1268 }
1269 }
1270
1271 //=============================================================================
1272 /// Create a list of pairs for all unknowns in this element,
1273 /// so that the first entry in each pair contains the global equation
1274 /// number of the unknown, while the second one contains the number
1275 /// of the "DOF type" that this unknown is associated with.
1276 /// (Function can obviously only be called if the equation numbering
1277 /// scheme has been set up.)
1278 /// This element is only in charge of the solid dofs.
1279 //=============================================================================
1281 std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
1282 {
1283 // temporary pair (used to store dof lookup prior to being added to list)
1284 std::pair<unsigned, unsigned> dof_lookup;
1285
1286 // number of nodes
1287 const unsigned n_node = this->nnode();
1288
1289 // Get the number of position dofs and dimensions at the node
1290 const unsigned n_position_type = nnodal_position_type();
1291 const unsigned nodal_dim = nodal_dimension();
1292
1293 // Integer storage for local unknown
1294 int local_unknown = 0;
1295
1296 // Loop over the nodes
1297 for (unsigned n = 0; n < n_node; n++)
1298 {
1299 // Loop over position dofs
1300 for (unsigned k = 0; k < n_position_type; k++)
1301 {
1302 // Loop over dimension
1303 for (unsigned i = 0; i < nodal_dim; i++)
1304 {
1305 // If the variable is free
1307
1308 // ignore pinned values
1309 if (local_unknown >= 0)
1310 {
1311 // store dof lookup in temporary pair: First entry in pair
1312 // is global equation number; second entry is dof type
1313 dof_lookup.first = this->eqn_number(local_unknown);
1314 dof_lookup.second = 0;
1315
1316 // add to list
1317 dof_lookup_list.push_front(dof_lookup);
1318 }
1319 }
1320 }
1321 }
1322 }
1323
1324
1325 //////////////////////////////////////////////////////////////////////
1326 //////////////////////////////////////////////////////////////////////
1327 //////////////////////////////////////////////////////////////////////
1328
1329
1330 //===========================================================================
1331 /// Constructor, takes the pointer to the "bulk" element, the
1332 /// index of the fixed local coordinate and its value represented
1333 /// by an integer (+/- 1), indicating that the face is located
1334 /// at the max. or min. value of the "fixed" local coordinate
1335 /// in the bulk element.
1336 //===========================================================================
1339 FiniteElement* const& bulk_el_pt, const int& face_index)
1341 {
1342 // Number of nodal position types: 2
1344
1345 // Let the bulk element build the FaceElement, i.e. setup the pointers
1346 // to its nodes (by referring to the appropriate nodes in the bulk
1347 // element), etc.
1349
1350 // Resize vector to some point on the symmetry line along which the
1351 // end of the beam is sliding. Initialise for symmetry line = y-axis
1352 Vector_to_symmetry_line.resize(2);
1353 Vector_to_symmetry_line[0] = 0.0;
1354 Vector_to_symmetry_line[1] = 0.0;
1355
1356 // Resize normal vector to the symmetry line along which the
1357 // end of the beam is sliding. Initialise for symmetry line = y-axis
1358 Normal_to_symmetry_line.resize(2);
1359 Normal_to_symmetry_line[0] = -1.0;
1360 Normal_to_symmetry_line[1] = 0.0;
1361
1362 // Resize number of dofs at the element's one and only node by two
1363 // to accomodate the Lagrange multipliers
1364
1365 // We need two additional values at the one-and-only node in this element
1369 }
1370
1371
1372 //===========================================================================
1373 /// Add the element's contribution to its residual vector
1374 //===========================================================================
1377 {
1378 // Get position vector to and normal & tangent vectors on wall (from
1379 // bulk element)
1381 dynamic_cast<HermiteBeamElement*>(bulk_element_pt());
1382
1383 // Get the value of the constant local coordinate in the bulk element
1384 // Dummy local coordinate of size zero
1385 Vector<double> s(0);
1388
1389 // Get position vector to and normal on wall
1390 Vector<double> r(2);
1391 Vector<double> n(2);
1392 bulk_el_pt->get_normal(s_bulk, r, n);
1393
1394 // Get (non-unit) tangent vector
1396 bulk_el_pt->get_non_unit_tangent(s_bulk, r, drds);
1397
1398 // Residual corresponding to: Point must be on symmetry line
1399 double res0 =
1402
1403 // Work out tangent to symmetry line
1407
1408 // Residual corresponding to: Beam must meet symmetry line at right angle
1409 double res1 = drds[0] * tangent_to_symmetry_line[0] +
1411
1412 // The first Lagrange multiplier enforces the along-the-beam displacement:
1413 int j_local = nodal_local_eqn(0, Nbulk_value[0]);
1415
1416 // Second Lagrange multiplier enforces the derivative of the
1417 // transverse displacement:
1418 j_local = nodal_local_eqn(0, Nbulk_value[0] + 1);
1420
1421 // Add Lagrange multiplier contribution to the bulk equations
1422
1423 // Lagrange multipliers
1424 double lambda0 = node_pt(0)->value(Nbulk_value[0]);
1425 double lambda1 = node_pt(0)->value(Nbulk_value[0] + 1);
1426
1427 // Loop over the solid dofs
1428
1429 // How many positional values are there?
1430 unsigned n_dim = nodal_dimension();
1431 unsigned n_type = nnodal_position_type();
1432
1433 /// Loop over directions
1434 for (unsigned i = 0; i < n_dim; i++)
1435 {
1436 // Loop over types
1437 for (unsigned k = 0; k < n_type; k++)
1438 {
1439 // Get local equation number
1440 int j_local = position_local_eqn(0, k, i);
1441
1442 // Real dof?
1443 if (j_local >= 0)
1444 {
1445 // Derivative of first residual w.r.t. to discrete displacements:
1446 // Only the type-zero dofs make a contribution:
1447 double dres0dxik = 0.0;
1448 if (k == 0)
1449 {
1451 }
1452
1453 // Derivative of second residual w.r.t. to discrete displacements:
1454 // Only the type-one dofs make a contribution:
1455 double dres1dxik = 0.0;
1456 if (k == 1)
1457 {
1459 }
1460
1461 // Add to the residual
1463 }
1464 }
1465 }
1466 }
1467
1468
1469} // namespace oomph
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
char t
Definition cfortran.h:568
Vector< double > Vector_to_symmetry_line
Vector to some point on the symmetry line along which the end of the beam is sliding.
Vector< double > Normal_to_symmetry_line
Normal vector to the symmetry line along which the end of the beam is sliding.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the element's contribution to its residual vector.
ClampedSlidingHermiteBeamBoundaryConditionElement()
Broken empty constructor.
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
Definition shape.h:278
void dposition_dlagrangian_at_local_coordinate(const Vector< double > &s, DenseMatrix< double > &drdxi) const
Derivative of position vector w.r.t. the SolidFiniteElement's Lagrangian coordinates; evaluated at cu...
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &dof_lookup_list) const
Create a list of pairs for all unknowns in this element, so that the first entry in each pair contain...
void locate_zeta(const Vector< double > &zeta, GeomObject *&geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
Find the local coordinate s in this element that corresponds to the global "intrinsic" coordinate (h...
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
Definition elements.h:4342
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition elements.h:4630
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition elements.h:4739
Vector< unsigned > Nbulk_value
A vector that will hold the number of data values at the nodes that are associated with the "bulk" el...
Definition elements.h:4417
void get_local_coordinate_in_bulk(const Vector< double > &s, Vector< double > &s_bulk) const
Calculate the vector of local coordinate in the bulk element given the local coordinates in this Face...
Definition elements.cc:6415
void resize_nodes(Vector< unsigned > &nadditional_data_values)
Provide additional storage for a specified number of values at the nodes of the FaceElement....
Definition elements.h:4886
FaceGeometry class definition: This policy class is used to allow construction of face elements that ...
Definition elements.h:5002
A general Finite Element class.
Definition elements.h:1317
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition elements.h:1967
void set_nnodal_position_type(const unsigned &nposition_type)
Set the number of types required to interpolate the coordinate.
Definition elements.h:1400
unsigned nnodal_position_type() const
Return the number of coordinate types that the element requires to interpolate the geometry between t...
Definition elements.h:2467
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
Definition elements.cc:4705
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
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:3992
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node.
Definition elements.h:1436
double nodal_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return the value of the k-th type of the i-th positional variable at the local node n.
Definition elements.h:2353
unsigned nnode() const
Return the number of nodes.
Definition elements.h:2214
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition elements.h:2179
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Function to compute the geometric shape functions and derivatives w.r.t. local coordinates at local c...
Definition elements.h:1985
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement....
Definition elements.cc:5163
double raw_dnodal_position_gen_dt(const unsigned &n, const unsigned &k, const unsigned &i) const
i-th component of time derivative (velocity) of the generalised position, dx(k,i)/dt at local node n....
Definition elements.h:2298
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
Definition elements.h:2488
double raw_nodal_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return the value of the k-th type of the i-th positional variable at the local node n....
Definition elements.h:2276
void fill_in_jacobian_from_external_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Calculate the contributions to the jacobian from the external degrees of freedom using finite differe...
Definition elements.cc:1227
unsigned ndof() const
Return the number of equations/dofs in the element.
Definition elements.h:822
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:691
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:967
A geometric object is an object that provides a parametrised description of its shape via the functio...
unsigned ndim() const
Access function to # of Eulerian coordinates.
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
unsigned nlagrangian() const
Access function to # of Lagrangian coordinates.
Hermite Kirchhoff Love beam. Implements KirchhoffLoveBeamEquations using 2-node Hermite elements as t...
void output(std::ostream &outfile)
Output function.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
static double Default_sigma0_value
Static default value for 2nd Piola Kirchhoff prestress.
static void Zero_traction_fct(const Vector< double > &xi, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
Default load function (zero traction)
GeomObject * Undeformed_beam_pt
Pointer to the GeomObject that specifies the beam's undeformed midplane.
const double & h() const
Return the non-dimensional wall thickness.
static void Unit_profile_fct(const Vector< double > &xi, const Vector< double > &x, double &h_ratio)
Default profile function (constant thickness 'h_0')
void fill_in_contribution_to_residuals_beam(Vector< double > &residuals)
Return the residuals for the equations of Kirchhoff-Love beam theory with linear constitutive equatio...
void get_non_unit_tangent(const Vector< double > &s, Vector< double > &r, Vector< double > &drds)
Get position vector to and non-unit tangent vector on wall: dr/ds.
const double & lambda_sq() const
Return the timescale ratio (non-dimensional density)
static double Default_h_value
Static default value for non-dim wall thickness.
void get_normal(const Vector< double > &s, Vector< double > &N)
Get normal vector on wall.
static double Default_lambda_sq_value
Static default value for timescale ratio (1.0 – for natural scaling)
void wall_profile(const Vector< double > &xi, const Vector< double > &x, double &h_ratio)
Get the wall profile: Pass Lagrangian & Eulerian coordinate and return the wall profile (not all of t...
const double & sigma0() const
Return the axial prestress.
void get_energy(double &pot_en, double &kin_en)
Get potential (strain) and kinetic energy of the element.
virtual void load_vector(const unsigned &intpt, const Vector< double > &xi, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
Get the load vector: Pass number of integration point (dummy), Lagr. and Eulerian coordinate and norm...
virtual void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Get FE jacobian and residuals (Jacobian done by finite differences)
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition nodes.h:1054
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation....
Definition nodes.cc:2408
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
void shape(const Vector< double > &s, Shape &psi) const
Function to calculate the geometric shape functions at local coordinate s.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
Definition shape.h:76
double raw_lagrangian_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return Generalised Lagrangian coordinate at local node n. ‘Direction’ i, ‘Type’ k....
Definition elements.h:3901
double dshape_lagrangian(const Vector< double > &s, Shape &psi, DShape &dpsidxi) const
Calculate shape functions and derivatives w.r.t. Lagrangian coordinates at local coordinate s....
Definition elements.cc:6741
double raw_lagrangian_position(const unsigned &n, const unsigned &i) const
Return i-th Lagrangian coordinate at local node n without using the hanging representation.
Definition elements.h:3894
bool Solve_for_consistent_newmark_accel_flag
Flag to indicate which system of equations to solve when assigning initial conditions for time-depend...
Definition elements.h:4306
SolidInitialCondition * Solid_ic_pt
Pointer to object that specifies the initial condition.
Definition elements.h:4135
void fill_in_residuals_for_solid_ic(Vector< double > &residuals)
Fill in the residuals for the setup of an initial condition. The global equations are:
Definition elements.h:4022
virtual double d2shape_lagrangian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidxi, DShape &d2psidxi) const
Return the geometric shape functions and also first and second derivatives w.r.t. Lagrangian coordina...
Definition elements.cc:6863
int position_local_eqn(const unsigned &n, const unsigned &k, const unsigned &j) const
Access function that returns the local equation number that corresponds to the j-th coordinate of the...
Definition elements.h:4141
virtual double interpolated_xi(const Vector< double > &s, const unsigned &i) const
Return i-th FE-interpolated Lagrangian coordinate xi[i] at local coordinate s.
Definition elements.cc:7135
virtual void fill_in_jacobian_from_solid_position_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Use finite differences to calculate the Jacobian entries corresponding to the solid positions....
Definition elements.cc:7016
void fill_in_jacobian_for_newmark_accel(DenseMatrix< double > &jacobian)
Fill in the contributions of the Jacobian matrix for the consistent assignment of the initial "accele...
Definition elements.cc:7258
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).