disk_oscillation.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 //Driver function for a simple test elasticity problem
27 
28 // oomph-lib includes
29 #include "generic.h"
30 #include "solid.h"
31 #include "oomph_crbond_bessel.h"
32 
33 //Need to instantiate templated mesh
34 #include "meshes/quarter_circle_sector_mesh.h"
35 
36 using namespace std;
37 
38 using namespace oomph;
39 
40 
41 /// ////////////////////////////////////////////////////////////////////
42 /// ////////////////////////////////////////////////////////////////////
43 /// ////////////////////////////////////////////////////////////////////
44 
45 
46 
47 //=======start_namespace==========================================
48 /// Global variables
49 //================================================================
51 {
52  /// Poisson's ratio
53  double Nu=0.3;
54 
55  /// Timescale ratio
56  double Lambda_sq=(1.0-Nu)/((1.0+Nu)*(1.0-2.0*Nu));
57 
58  /// Pointer to constitutive law
59  ConstitutiveLaw* Constitutive_law_pt=0;
60 
61  /// Multiplier for inertia terms (needed for consistent assignment
62  /// of initial conditions in Newmark scheme)
63  double multiplier(const Vector<double>& xi)
64  {
66  }
67 
68 
69 } // end namespace
70 
71 
72 /// ////////////////////////////////////////////////////////////////////
73 /// ////////////////////////////////////////////////////////////////////
74 // Axisymmetrically oscillating disk
75 /// ////////////////////////////////////////////////////////////////////
76 /// ////////////////////////////////////////////////////////////////////
77 
78 
79 
80 //================disk_as_geom_object======================================
81 /// Axisymmetrially oscillating disk with displacement
82 /// field according to linear elasticity.
83 //=========================================================================
84 class AxisymOscillatingDisk : public GeomObject
85 {
86 
87 public:
88 
89  /// Constructor: 2 Lagrangian coordinate, 2 Eulerian coords. Pass
90  /// amplitude of oscillation, Poisson ratio nu, and pointer to
91  /// global timestepper.
92  AxisymOscillatingDisk(const double& ampl, const double& nu,
93  TimeStepper* time_stepper_pt);
94 
95  /// Destructor (empty)
97 
98  /// Position vector at Lagrangian coordinate xi at present
99  /// time
100  void position(const Vector<double>& xi, Vector<double>& r) const;
101 
102  /// Parametrised velocity on object at current time: veloc = d r(xi)/dt.
103  void veloc(const Vector<double>& xi, Vector<double>& veloc);
104 
105  /// Parametrised acceleration on object at current time:
106  /// accel = d^2 r(xi)/dt^2.
107  void accel(const Vector<double>& xi, Vector<double>& accel);
108 
109  /// Parametrised j-th time-derivative on object at current time:
110  /// \f$ \frac{d^{j} r(\zeta)}{dt^j} \f$.
111  void dposition_dt(const Vector<double>& xi, const unsigned& j,
112  Vector<double>& drdt)
113  {
114  switch (j)
115  {
116  // Current position
117  case 0:
118  position(xi,drdt);
119  break;
120 
121  // Velocity:
122  case 1:
123  veloc(xi,drdt);
124  break;
125 
126  // Acceleration:
127  case 2:
128  accel(xi,drdt);
129  break;
130 
131  default:
132  std::ostringstream error_message;
133  error_message << j << "th derivative not implemented\n";
134 
135  throw OomphLibError(error_message.str(),
136  OOMPH_CURRENT_FUNCTION,
137  OOMPH_EXCEPTION_LOCATION);
138  }
139  }
140 
141 
142  /// Residual of dispersion relation for use in black-box Newton method
143  /// which requires global (or static) functions.
144  /// Poisson's ratio is passed as parameter.
145  static void residual_for_dispersion(const Vector<double>& param,
146  const Vector<double>& omega,
147  Vector<double>& residual);
148 
149 private:
150 
151  /// Amplitude of oscillation
152  double Ampl;
153 
154  /// Period of oscillation
155  double T;
156 
157  /// Poisson ratio nu
158  double Nu;
159 
160  /// Eigenfrequency
161  double Omega;
162 
163 }; // end disk_as_geom_object
164 
165 
166 
167 
168 //==============ic_constructor============================================
169 /// Constructor: 2 Lagrangian coordinates, 2 Eulerian coords. Pass
170 /// amplitude of oscillation, Poisson ratio nu, and pointer to
171 /// global timestepper.
172 //========================================================================
174  const double& nu,
175  TimeStepper* time_stepper_pt) :
176  GeomObject(2,2,time_stepper_pt), Ampl(ampl), Nu(nu)
177 {
178  // Parameters for dispersion relation
179  Vector<double> param(1);
180  param[0]=Nu;
181 
182  // Initial guess for eigenfrequency
183  Vector<double> omega(1);
184  omega[0]=2.0;
185 
186  // Find eigenfrequency from black box Newton solver
187  BlackBoxFDNewtonSolver::black_box_fd_newton_solve(residual_for_dispersion,
188  param,omega);
189 
190  // Assign eigenfrequency
191  Omega=omega[0];
192 
193  // Assign/doc period of oscillation
194  T=2.0*MathematicalConstants::Pi/Omega;
195 
196  std::cout << "Period of oscillation: " << T << std::endl;
197 
198 }
199 
200 
201 
202 //===============start_position===========================================
203 /// Position Vector at Lagrangian coordinate xi at present
204 /// time
205 //========================================================================
206 void AxisymOscillatingDisk::position(const Vector<double>& xi,
207  Vector<double>& r) const
208 {
209  // Parameter values at present time
210  double time=Geom_object_time_stepper_pt->time_pt()->time();
211 
212  // Radius in Lagrangian coordinates
213  double lagr_radius=sqrt( pow(xi[0],2) + pow(xi[1],2) );
214 
215  if (lagr_radius<1.0e-12)
216  {
217  // Position Vector
218  r[0]=0.0;
219  r[1]=0.0;
220  }
221  else
222  {
223  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
224  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
225  CRBond_Bessel::bessjy01a(Omega*lagr_radius,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
226 
227  // Displacement field
228  double u=Ampl*j1*sin(2.0*MathematicalConstants::Pi*time/T);
229 
230  // Position Vector
231  r[0]=(xi[0]+xi[0]/lagr_radius*u);
232  r[1]=(xi[1]+xi[1]/lagr_radius*u);
233  }
234 
235 } //end position
236 
237 
238 
239 
240 //========================================================================
241 /// Parametrised velocity on object at current time:
242 /// veloc = d r(xi)/dt.
243 //========================================================================
244 void AxisymOscillatingDisk::veloc(const Vector<double>& xi,
245  Vector<double>& veloc)
246 {
247  // Parameter values at present time
248  double time=Geom_object_time_stepper_pt->time_pt()->time();
249 
250  // Radius in Lagrangian coordinates
251  double lagr_radius=sqrt(pow(xi[0],2)+pow(xi[1],2));
252 
253  if (lagr_radius<1.0e-12)
254  {
255  // Veloc vector
256  veloc[0]=0.0;
257  veloc[1]=0.0;
258  }
259  else
260  {
261  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
262  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
263  CRBond_Bessel::bessjy01a(Omega*lagr_radius,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
264 
265  // Deriv of displacement field
266  double udot=2.0*MathematicalConstants::Pi/T*Ampl*j1*
267  cos(2.0*MathematicalConstants::Pi*time/T);
268 
269  // Veloc
270  veloc[0]=(xi[0]/lagr_radius*udot);
271  veloc[1]=(xi[1]/lagr_radius*udot);
272  }
273 }
274 
275 
276 
277 
278 
279 //========================================================================
280 /// Parametrised acceleration on object at current time:
281 /// accel = d^2 r(xi)/dt^2.
282 //========================================================================
283 void AxisymOscillatingDisk::accel(const Vector<double>& xi,
284  Vector<double>& accel)
285 {
286  // Parameter values at present time
287  double time=Geom_object_time_stepper_pt->time_pt()->time();
288 
289  // Radius in Lagrangian coordinates
290  double lagr_radius=sqrt(pow(xi[0],2)+pow(xi[1],2));
291 
292 
293  if (lagr_radius<1.0e-12)
294  {
295  // Veloc vector
296  accel[0]=0.0;
297  accel[1]=0.0;
298  }
299  else
300  {
301  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
302  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
303  CRBond_Bessel::bessjy01a(Omega*lagr_radius,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
304 
305  // Deriv of displacement field
306  double udotdot=-pow(2.0*MathematicalConstants::Pi/T,2)*Ampl*j1*
307  sin(2.0*MathematicalConstants::Pi*time/T);
308 
309  // Veloc
310  accel[0]=(xi[0]/lagr_radius*udotdot);
311  accel[1]=(xi[1]/lagr_radius*udotdot);
312 
313  }
314 }
315 
316 
317 
318 //======================start_of_dispersion===============================
319 /// Residual of dispersion relation for use in black box Newton method
320 /// which requires global (or static) functions.
321 /// Poisson's ratio is passed as parameter.
322 //========================================================================
324  const Vector<double>& param, const Vector<double>& omega,
325  Vector<double>& residual)
326 {
327  // Extract parameters
328  double nu=param[0];
329 
330  // Argument of various Bessel functions
331  double arg=omega[0];
332 
333  // Bessel fcts J_0(x), J_1(x), Y_0(x), Y_1(x) and their derivatives
334  double j0,j1,y0,y1,j0p,j1p,y0p,y1p;
335  CRBond_Bessel::bessjy01a(arg,j0,j1,y0,y1,j0p,j1p,y0p,y1p);
336 
337  // Residual of dispersion relation
338  residual[0]=nu/(1.0-2.0*nu)*(j1+(j0-j1/omega[0])*omega[0])+
339  (j0-j1/omega[0])*omega[0];
340 
341 }
342 
343 
344 
345 /// ////////////////////////////////////////////////////////////////////
346 /// ////////////////////////////////////////////////////////////////////
347 /// ////////////////////////////////////////////////////////////////////
348 
349 
350 
351 //======================start_mesh================================
352 /// Elastic quarter circle sector mesh: We "upgrade"
353 /// the RefineableQuarterCircleSectorMesh to become an
354 /// SolidMesh and equate the Eulerian and Lagrangian coordinates,
355 /// thus making the domain represented by the mesh the stress-free
356 /// configuration.
357 //================================================================
358 template <class ELEMENT>
360  public virtual RefineableQuarterCircleSectorMesh<ELEMENT>,
361  public virtual SolidMesh
362 {
363 
364 
365 public:
366 
367  /// Constructor: Build mesh and copy Eulerian coords to Lagrangian
368  /// ones so that the initial configuration is the stress-free one.
370  const double& xi_lo,
371  const double& fract_mid,
372  const double& xi_hi,
373  TimeStepper* time_stepper_pt=
374  &Mesh::Default_TimeStepper) :
375  RefineableQuarterCircleSectorMesh<ELEMENT>(wall_pt,xi_lo,fract_mid,xi_hi,
376  time_stepper_pt)
377  {
378 #ifdef PARANOID
379  /// Check that the element type is derived from the SolidFiniteElement
380  SolidFiniteElement* el_pt=dynamic_cast<SolidFiniteElement*>
381  (finite_element_pt(0));
382  if (el_pt==0)
383  {
384  throw OomphLibError(
385  "Element needs to be derived from SolidFiniteElement\n",
386  OOMPH_CURRENT_FUNCTION,
387  OOMPH_EXCEPTION_LOCATION);
388  }
389 #endif
390 
391  // Make the current configuration the undeformed one by
392  // setting the nodal Lagrangian coordinates to their current
393  // Eulerian ones
394  set_lagrangian_nodal_coordinates();
395  }
396 
397 };
398 
399 
400 
401 
402 
403 /// //////////////////////////////////////////////////////////////////////
404 /// //////////////////////////////////////////////////////////////////////
405 /// //////////////////////////////////////////////////////////////////////
406 
407 
408 
409 //========start_class===================================================
410 /// Problem class to simulate small-amplitude oscillations of
411 /// a circular disk.
412 //======================================================================
413 template<class ELEMENT>
414 class DiskOscillationProblem : public Problem
415 {
416 
417 public:
418 
419  /// Constructor
421 
422  /// Update function (empty)
424 
425  /// Update function (empty)
427 
428  /// Access function for the solid mesh
430  {
432  Problem::mesh_pt());
433  }
434 
435  /// Run the problem: Pass number of timesteps to be performed.
436  void run(const unsigned& nstep);
437 
438  /// Doc the solution
439  void doc_solution(DocInfo& doc_info);
440 
441 private:
442 
443  /// Trace file
444  ofstream Trace_file;
445 
446  /// Vector of pointers to nodes whose position we're tracing
447  Vector<Node*> Trace_node_pt;
448 
449  /// Geometric object that specifies the initial conditions
451 
452 }; // end class
453 
454 
455 
456 
457 
458 //============start_constructor=========================================
459 /// Constructor
460 //======================================================================
461 template<class ELEMENT>
463 {
464 
465  // Allocate the timestepper: The classical Newmark scheme with
466  // two history values.
467  add_time_stepper_pt(new Newmark<2>);
468 
469 
470 
471  // GeomObject that specifies the curvilinear boundary of the
472  // circular disk
473  GeomObject* curved_boundary_pt=new Ellipse(1.0,1.0);
474 
475  //The start and end intrinsic coordinates on the geometric object
476  // that defines the curvilinear boundary of the disk
477  double xi_lo=0.0;
478  double xi_hi=2.0*atan(1.0);
479 
480  // Fraction along geometric object at which the radial dividing line
481  // is placed
482  double fract_mid=0.5;
483 
484  //Now create the mesh
486  curved_boundary_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
487 
488 
489  // Setup trace nodes as the nodes on boundaries 0 (= horizontal symmetry
490  // boundary) and 1 (=curved boundary)
491  unsigned nnod0=mesh_pt()->nboundary_node(0);
492  unsigned nnod1=mesh_pt()->nboundary_node(1);
493  Trace_node_pt.resize(nnod0+nnod1);
494  for (unsigned j=0;j<nnod0;j++)
495  {
496 
497  Trace_node_pt[j]=mesh_pt()->boundary_node_pt(0,j);
498 
499  }
500  for (unsigned j=0;j<nnod1;j++)
501  {
502 
503  Trace_node_pt[j+nnod0]=mesh_pt()->boundary_node_pt(1,j);
504 
505  } //done choosing trace nodes
506 
507 
508  // Pin the horizontal boundary in the vertical direction
509  unsigned n_hor = mesh_pt()->nboundary_node(0);
510  for(unsigned i=0;i<n_hor;i++)
511  {
512  mesh_pt()->boundary_node_pt(0,i)->pin_position(1);
513  }
514 
515  // Pin the vertical boundary in the horizontal direction
516  unsigned n_vert = mesh_pt()->nboundary_node(2);
517  for(unsigned i=0;i<n_vert;i++)
518  {
519 
520  mesh_pt()->boundary_node_pt(2,i)->pin_position(0);
521 
522  } // done bcs
523 
524 
525  //Finish build of elements
526  unsigned n_element =mesh_pt()->nelement();
527  for(unsigned i=0;i<n_element;i++)
528  {
529  //Cast to a solid element
530  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
531 
532  //Set the constitutive law
533  el_pt->constitutive_law_pt() =
535 
536  // Set the timescale ratio
537  el_pt->lambda_sq_pt()=&Global_Physical_Variables::Lambda_sq;
538  }
539 
540  // Refine uniformly
541  mesh_pt()->refine_uniformly();
542 
543  // Assign equation numbers
544  assign_eqn_numbers();
545 
546 } // end constructor
547 
548 
549 
550 //=====================start_doc====================================
551 /// Doc the solution
552 //==================================================================
553 template<class ELEMENT>
555  DocInfo& doc_info)
556 {
557 
558  ofstream some_file, some_file2;
559  char filename[100];
560 
561  // Number of plot points
562  unsigned npts;
563  npts=5;
564 
565  // Output shape of deformed body
566  //------------------------------
567  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
568  doc_info.number());
569  some_file.open(filename);
570  mesh_pt()->output(some_file,npts);
571  some_file.close();
572 
573 
574  // Write trace file
575  //-----------------
576 
577  // Get position on IC object (exact solution)
578  Vector<double> r_exact(2);
579  Vector<double> xi(2);
580  xi[0]=1.0;
581  xi[1]=0.0;
582  IC_geom_object_pt->position(xi,r_exact);
583 
584  // Exact outer radius for linear elasticity
585  double exact_r=r_exact[0];
586 
587  // Add to trace file
588  Trace_file << time_pt()->time() << " "
589  << exact_r << " ";
590 
591  // Doc radii of control nodes
592  unsigned ntrace_node=Trace_node_pt.size();
593  for (unsigned j=0;j<ntrace_node;j++)
594  {
595  Trace_file << sqrt(pow(Trace_node_pt[j]->x(0),2)+
596  pow(Trace_node_pt[j]->x(1),2)) << " ";
597  }
598  Trace_file << std::endl;
599 
600 
601  // Get displacement as a function of the radial coordinate
602  //--------------------------------------------------------
603  // along boundary 0
604  //-----------------
605  {
606  // Number of elements along boundary 0:
607  unsigned nelem=mesh_pt()->nboundary_element(0);
608 
609  // Open files
610  sprintf(filename,"%s/displ_along_line%i.dat",doc_info.directory().c_str(),
611  doc_info.number());
612  some_file.open(filename);
613 
614  ofstream some_file2;
615  sprintf(filename,"%s/exact_displ_along_line%i.dat",
616  doc_info.directory().c_str(),
617  doc_info.number());
618  some_file2.open(filename);
619 
620  Vector<double> s(2);
621  Vector<double> x(2);
622  Vector<double> dxdt(2);
623  Vector<double> xi(2);
624  Vector<double> r_exact(2);
625  Vector<double> v_exact(2);
626 
627  for (unsigned e=0;e<nelem;e++)
628  {
629  some_file << "ZONE " << std::endl;
630  some_file2 << "ZONE " << std::endl;
631 
632  for (unsigned i=0;i<npts;i++)
633  {
634  // Move along bottom edge of element
635  s[0]=-1.0+2.0*double(i)/double(npts-1);
636  s[1]=-1.0;
637 
638  // Get pointer to element
639  SolidFiniteElement* el_pt=dynamic_cast<SolidFiniteElement*>
640  (mesh_pt()->boundary_element_pt(0,e));
641 
642  // Get Lagrangian coordinate
643  el_pt->interpolated_xi(s,xi);
644 
645  // Get Eulerian coordinate
646  el_pt->interpolated_x(s,x);
647 
648  // Get velocity
649  el_pt->interpolated_dxdt(s,1,dxdt);
650 
651  // Get exact Eulerian position
652  IC_geom_object_pt->position(xi,r_exact);
653 
654  // Get exact velocity
655  IC_geom_object_pt->veloc(xi,v_exact);
656 
657  // Plot radial distance and displacement
658  some_file << xi[0] << " " << x[0]-xi[0] << " "
659  << dxdt[0] << std::endl;
660 
661  some_file2 << xi[0] << " " << r_exact[0]-xi[0] << " "
662  << v_exact[0] << std::endl;
663 
664  }
665  }
666  some_file.close();
667  some_file2.close();
668 
669  } // end line output
670 
671 
672  // Get displacement (exact and computed) throughout domain
673  //--------------------------------------------------------
674  {
675  // Number of elements
676  unsigned nelem=mesh_pt()->nelement();
677 
678  // Open files
679  sprintf(filename,"%s/displ%i.dat",doc_info.directory().c_str(),
680  doc_info.number());
681  some_file.open(filename);
682 
683  sprintf(filename,"%s/exact_displ%i.dat",
684  doc_info.directory().c_str(),
685  doc_info.number());
686  some_file2.open(filename);
687 
688  Vector<double> s(2);
689  Vector<double> x(2);
690  Vector<double> dxdt(2);
691  Vector<double> xi(2);
692  Vector<double> r_exact(2);
693  Vector<double> v_exact(2);
694 
695  for (unsigned e=0;e<nelem;e++)
696  {
697  some_file << "ZONE I=" << npts << ", J="<< npts << std::endl;
698  some_file2 << "ZONE I=" << npts << ", J="<< npts << std::endl;
699 
700  for (unsigned i=0;i<npts;i++)
701  {
702  s[0]=-1.0+2.0*double(i)/double(npts-1);
703  for (unsigned j=0;j<npts;j++)
704  {
705  s[1]=-1.0+2.0*double(j)/double(npts-1);
706 
707  // Get pointer to element
708  SolidFiniteElement* el_pt=dynamic_cast<SolidFiniteElement*>
709  (mesh_pt()->element_pt(e));
710 
711  // Get Lagrangian coordinate
712  el_pt->interpolated_xi(s,xi);
713 
714  // Get Eulerian coordinate
715  el_pt->interpolated_x(s,x);
716 
717  // Get velocity
718  el_pt->interpolated_dxdt(s,1,dxdt);
719 
720  // Get exact Eulerian position
721  IC_geom_object_pt->position(xi,r_exact);
722 
723  // Get exact velocity
724  IC_geom_object_pt->veloc(xi,v_exact);
725 
726  // Plot Lagrangian position, displacement and velocity
727  some_file << xi[0] << " " << xi[1] << " "
728  << x[0]-xi[0] << " " << x[1]-xi[1] << " "
729  << dxdt[0] << " " << dxdt[1] << std::endl;
730 
731 
732  some_file2 << xi[0] << " " << xi[1] << " "
733  << r_exact[0]-xi[0] << " " << r_exact[1]-xi[1] << " "
734  << v_exact[0] << " " << v_exact[1] << std::endl;
735 
736  }
737  }
738  }
739  some_file.close();
740  some_file2.close();
741  }
742 
743 
744 }
745 
746 
747 
748 
749 //=====================start_run====================================
750 /// Run the problem: Pass number of timesteps to be performed.
751 //==================================================================
752 template<class ELEMENT>
753 void DiskOscillationProblem<ELEMENT>::run(const unsigned& nstep)
754 {
755 
756  // Output
757  DocInfo doc_info;
758 
759  // Output directory
760  doc_info.set_directory("RESLT");
761 
762  // Open trace file
763  char filename[100];
764  sprintf(filename,"%s/trace.dat",doc_info.directory().c_str());
765  Trace_file.open(filename);
766 
767  // Initialise time
768  double time0=1.0;
769  time_pt()->time()=time0;
770 
771  // Set timestep
772  double dt=0.01;
773  time_pt()->initialise_dt(dt);
774 
775  // Create geometric object that specifies the initial conditions:
776 
777  // Amplitude of the oscillation
778  double ampl=0.005;
779 
780  // Build the GeomObject
781  IC_geom_object_pt=new AxisymOscillatingDisk(ampl,
783  time_stepper_pt());
784 
785  // Turn into object that specifies the initial conditions:
786  SolidInitialCondition* IC_pt = new SolidInitialCondition(IC_geom_object_pt);
787 
788  // Assign initial condition
789  SolidMesh::Solid_IC_problem.set_newmark_initial_condition_consistently(
790  this,mesh_pt(),time_stepper_pt(),IC_pt,dt,
792 
793  // Doc initial state
794  doc_solution(doc_info);
795  doc_info.number()++;
796 
797  //Timestepping loop
798  for(unsigned i=0;i<nstep;i++)
799  {
800  unsteady_newton_solve(dt);
801  doc_solution(doc_info);
802  doc_info.number()++;
803  }
804 
805 } // end of run
806 
807 
808 
809 
810 
811 
812 //========start_main====================================================
813 /// Driver for disk oscillation problem
814 //======================================================================
815 int main(int argc, char* argv[])
816 {
817 
818  // Store command line arguments
819  CommandLineArgs::setup(argc,argv);
820 
821  // If there's a command line argument run the validation (i.e. do only
822  // 10 timesteps); otherwise do a few cycles
823  unsigned nstep=1000;
824  if (CommandLineArgs::Argc!=1)
825  {
826  nstep=10;
827  }
828 
829  // Hookean constitutive equations
831  new GeneralisedHookean(&Global_Physical_Variables::Nu);
832 
833  //Set up the problem
835 
836  //Run the simulation
837  problem.run(nstep);
838 
839 } // end of main
840 
841 
842 
843 
844 
845 
846 
847 
////////////////////////////////////////////////////////////////////
void dposition_dt(const Vector< double > &xi, const unsigned &j, Vector< double > &drdt)
Parametrised j-th time-derivative on object at current time: .
AxisymOscillatingDisk(const double &ampl, const double &nu, TimeStepper *time_stepper_pt)
Constructor: 2 Lagrangian coordinate, 2 Eulerian coords. Pass amplitude of oscillation,...
double T
Period of oscillation.
void veloc(const Vector< double > &xi, Vector< double > &veloc)
Parametrised velocity on object at current time: veloc = d r(xi)/dt.
void accel(const Vector< double > &xi, Vector< double > &accel)
Parametrised acceleration on object at current time: accel = d^2 r(xi)/dt^2.
double Ampl
Amplitude of oscillation.
double Omega
Eigenfrequency.
void position(const Vector< double > &xi, Vector< double > &r) const
Position vector at Lagrangian coordinate xi at present time.
~AxisymOscillatingDisk()
Destructor (empty)
double Nu
Poisson ratio nu.
static void residual_for_dispersion(const Vector< double > &param, const Vector< double > &omega, Vector< double > &residual)
Residual of dispersion relation for use in black-box Newton method which requires global (or static) ...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Vector< Node * > Trace_node_pt
Vector of pointers to nodes whose position we're tracing.
AxisymOscillatingDisk * IC_geom_object_pt
Geometric object that specifies the initial conditions.
ofstream Trace_file
Trace file.
DiskOscillationProblem()
Constructor.
void actions_after_newton_solve()
Update function (empty)
ElasticRefineableQuarterCircleSectorMesh< ELEMENT > * mesh_pt()
Access function for the solid mesh.
void run(const unsigned &nstep)
Run the problem: Pass number of timesteps to be performed.
void doc_solution(DocInfo &doc_info)
Doc the solution.
void actions_before_newton_solve()
Update function (empty)
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
int main(int argc, char *argv[])
Driver for disk oscillation problem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
double multiplier(const Vector< double > &xi)
Multiplier for inertia terms (needed for consistent assignment of initial conditions in Newmark schem...
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
double Nu
Poisson's ratio.
double Lambda_sq
Timescale ratio.