periodic_orbit_handler.h
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 #ifndef OOMPH_PERIODIC_ORBIT_HANDLER_CLASS_HEADER
27 #define OOMPH_PERIODIC_ORBIT_HANDLER_CLASS_HEADER
28 
29 // Config header generated by autoconfig
30 #ifdef HAVE_CONFIG_H
31 #include <oomph-lib-config.h>
32 #endif
33 
34 // OOMPH-LIB headers
35 #include "matrices.h"
36 #include "linear_solver.h"
38 #include "problem.h"
39 #include "assembly_handler.h"
41 #include "../meshes/one_d_mesh.template.h"
42 #include "../meshes/one_d_mesh.template.cc"
43 
44 namespace oomph
45 {
46  class PeriodicOrbitEquations;
47 
48  class PeriodicOrbitAssemblyHandlerBase;
49 
50  //====================================================================
55  //====================================================================
57  {
58  friend class PeriodicOrbitEquations;
59 
60  public:
62  PeriodicOrbitTimeDiscretisation(const unsigned& n_tstorage)
63  : TimeStepper(n_tstorage, 1)
64  {
65  Type = "PeriodicOrbitTimeDiscretisation";
66  }
67 
68 
71  delete;
72 
75 
77  unsigned order() const
78  {
79  return 1;
80  }
81 
84  void assign_initial_values_impulsive(Data* const& data_pt)
85  {
86  throw OomphLibError(
87  "Cannot perform impulsive start for PeriodicOrbitTimeDiscretisation",
90  }
91 
95  {
96  throw OomphLibError(
97  "Cannot perform impulsive start for PeriodicOrbitTimeDiscretisation",
100  }
101 
102 
105  typedef double (*InitialConditionFctPt)(const double& t);
106 
111  Data* const& data_pt, Vector<InitialConditionFctPt> initial_value_fct)
112  {
113  // The time history stores the previous function values
114  unsigned n_time_value = ntstorage();
115 
116  // Find number of values stored
117  unsigned n_value = data_pt->nvalue();
118 
119  // Loop over current and stored timesteps
120  for (unsigned t = 0; t < n_time_value; t++)
121  {
122  // Get corresponding continous time
123  double time = Time_pt->time(t);
124 
125  // Loop over values
126  for (unsigned j = 0; j < n_value; j++)
127  {
128  data_pt->set_value(t, j, initial_value_fct[j](time));
129  }
130  }
131  }
132 
134  void shift_time_values(Data* const& data_pt)
135  {
136  throw OomphLibError(
137  "Cannot shift time values for PeriodicOrbitTimeDiscretisation",
140  }
141 
143  void shift_time_positions(Node* const& node_pt)
144  {
145  throw OomphLibError(
146  "Cannot shift time positions for PeriodicOrbitTimeDiscretisation",
149  }
150 
152  void set_weights() {}
153 
155  unsigned nprev_values() const
156  {
157  return ntstorage();
158  }
159 
161  unsigned ndt() const
162  {
163  return ntstorage();
164  }
165  };
166 
167 
168  // Special element for integrating the residuals over one period
169  class PeriodicOrbitEquations : public virtual FiniteElement
170  {
171  // Storage for the total number of time variables
172  unsigned Ntstorage;
173 
174  // Pointer to the global variable that represents the frequency
175  double* Omega_pt;
176 
179 
180  public:
181  // Constructor, do nothing
183 
186 
188  // Commented out broken assignment operator because this can lead to a
189  // conflict warning when used in the virtual inheritence hierarchy.
190  // Essentially the compiler doesn't realise that two separate
191  // implementations of the broken function are the same and so, quite
192  // rightly, it shouts.
193  /*void operator=(const PeriodicOrbitEquations&) = delete;*/
194 
196  double*& omega_pt()
197  {
198  return Omega_pt;
199  }
200 
202  double omega()
203  {
204  return *Omega_pt;
205  }
206 
208  void set_ntstorage(const unsigned& n_tstorage)
209  {
210  Ntstorage = n_tstorage;
211  }
212 
215  {
216  return Time_pt;
217  }
218 
220  Time* const& time_pt() const
221  {
222  return Time_pt;
223  }
224 
226  double time() const
227  {
228  // If no Time_pt, return 0.0
229  if (Time_pt == 0)
230  {
231  return 0.0;
232  }
233  else
234  {
235  return Time_pt->time();
236  }
237  }
238 
241  PeriodicOrbitAssemblyHandlerBase* const& assembly_handler_pt,
242  GeneralisedElement* const& elem_pt,
243  Vector<double>& residuals)
244  {
245  // Call the generic residuals function with flag set to 0
246  // using a dummy matrix argument
248  assembly_handler_pt,
249  elem_pt,
250  residuals,
252  0);
253  }
254 
258  PeriodicOrbitAssemblyHandlerBase* const& assembly_handler_pt,
259  GeneralisedElement* const& elem_pt,
260  Vector<double>& residuals,
261  DenseMatrix<double>& jacobian)
262  {
263  // Call the generic routine with the flag set to 1
265  assembly_handler_pt, elem_pt, residuals, jacobian, 1);
266  }
267 
268 
269  void orbit_output(GeneralisedElement* const& elem_pt,
270  std::ostream& outfile,
271  const unsigned& n_plot);
272 
273 
274  protected:
277  PeriodicOrbitAssemblyHandlerBase* const& assembly_handler_pt,
278  GeneralisedElement* const& elem_pt,
279  Vector<double>& residuals,
280  DenseMatrix<double>& jacobian,
281  const unsigned& flag);
282 
284  void set_timestepper_weights(const Shape& psi, const DShape& dpsidt)
285  {
286  PeriodicOrbitTimeDiscretisation* cast_time_stepper_pt =
288 
289 
290  // Zero the timestepper weights
291  unsigned n_time_dof = cast_time_stepper_pt->ntstorage();
292  for (unsigned i = 0; i < n_time_dof; i++)
293  {
294  cast_time_stepper_pt->Weight(0, i) = 0.0;
295  cast_time_stepper_pt->Weight(1, i) = 0.0;
296  }
297 
298  // Cache the frequency (timescale)
299  const double inverse_timescale = this->omega();
300  // Now set the weights
301  const unsigned n_node = this->nnode();
302 
303  // Global equation for the total number of time unknowns
304  // in the problem
305  int global_eqn;
306  for (unsigned l = 0; l < n_node; l++)
307  {
308  global_eqn = this->eqn_number(this->nodal_local_eqn(l, 0));
309  cast_time_stepper_pt->Weight(0, global_eqn) = psi(l);
310  cast_time_stepper_pt->Weight(1, global_eqn) =
311  dpsidt(l, 0) * inverse_timescale;
312  }
313  }
314 
318  Shape& psi,
319  DShape& dpsidt,
320  Shape& test,
321  DShape& dtestdt) const = 0;
322 
323 
327  const unsigned& ipt,
328  Shape& psi,
329  DShape& dpsidt,
330  Shape& test,
331  DShape& dtestdt) const = 0;
332 
335 
336  // Output function
337 
340  };
341 
342 
343  //======================================================================
346  //======================================================================
347  template<unsigned NNODE_1D>
349  : public virtual QSpectralElement<1, NNODE_1D>,
350  public virtual RefineableQSpectralElement<1>,
351  public virtual PeriodicOrbitEquations,
352  public virtual ElementWithZ2ErrorEstimator
353  {
354  public:
358  : QSpectralElement<1, NNODE_1D>(),
361  {
362  }
363 
366  const SpectralPeriodicOrbitElement<NNODE_1D>& dummy) = delete;
367 
369  /*void operator=(const SpectralPeriodicOrbitElement<NNODE_1D>&) = delete;*/
370 
371 
376  inline unsigned required_nvalue(const unsigned& n) const
377  {
378  return 1;
379  }
380 
382  inline unsigned ncont_interpolated_values() const
383  {
384  return 1;
385  }
386 
389  {
390  this->get_interpolated_values(0, s, value);
391  }
392 
394  void get_interpolated_values(const unsigned& t,
395  const Vector<double>& s,
397  {
398  value.resize(1);
399  value[0] = 0.0;
400 
401  const unsigned n_node = this->nnode();
402  Shape psi(n_node);
403  this->shape(s, psi);
404 
405  for (unsigned n = 0; n < n_node; n++)
406  {
407  value[0] += this->nodal_value(t, n, 0) * psi(n);
408  }
409  }
410 
411  // Order of recovery shape functions for Z2 error estimation:
412  unsigned nrecovery_order()
413  {
414  return NNODE_1D - 1;
415  }
416 
419  unsigned num_Z2_flux_terms()
420  {
421  return this->node_pt(0)->ntstorage();
422  }
423 
426  {
427  // Find out the number of nodes in the element
428  const unsigned n_node = this->nnode();
429 
430  // Get the shape functions
431  Shape psi(n_node);
432  DShape dpsidx(n_node, 1);
433 
434  // Get the derivatives
435  (void)this->dshape_eulerian(s, psi, dpsidx);
436 
437  // Now assemble all the derivatives
438  const unsigned n_tstorage = this->node_pt(0)->ntstorage();
439 
440  // Zero the flux vector
441  for (unsigned t = 0; t < n_tstorage; t++)
442  {
443  flux[t] = 0.0;
444  }
445 
446  // Loop over the nodes
447  for (unsigned n = 0; n < n_node; n++)
448  {
449  const double dpsidx_ = dpsidx(n, 0);
450  for (unsigned t = 0; t < n_tstorage; t++)
451  {
452  flux[t] += this->nodal_value(t, n, 0) * dpsidx_;
453  }
454  }
455  }
456 
457  // Number of vertex nodes in the element (always 2)
458  unsigned nvertex_node() const
459  {
460  return 2;
461  }
462 
464  Node* vertex_node_pt(const unsigned& j) const
465  {
467  }
468 
469 
470  //
472 
475  void output(std::ostream& outfile)
476  {
478  }
479 
480 
483  void output(std::ostream& outfile, const unsigned& n_plot)
484  {
485  PeriodicOrbitEquations::output(outfile, n_plot);
486  }
487 
488 
491  void output(FILE* file_pt)
492  {
494  }
495 
496 
499  void output(FILE* file_pt, const unsigned& n_plot)
500  {
501  PeriodicOrbitEquations::output(file_pt, n_plot);
502  }
503 
504 
505  protected:
508  inline double dshape_and_dtest_eulerian_orbit(const Vector<double>& s,
509  Shape& psi,
510  DShape& dpsidt,
511  Shape& test,
512  DShape& dtestdt) const;
513 
514 
518  const unsigned& ipt,
519  Shape& psi,
520  DShape& dpsidt,
521  Shape& test,
522  DShape& dtestdt) const;
523  };
524 
525 
526  // Inline functions:
527 
528 
529  //======================================================================
534  //======================================================================
535  template<unsigned NNODE_1D>
536  double SpectralPeriodicOrbitElement<
537  NNODE_1D>::dshape_and_dtest_eulerian_orbit(const Vector<double>& s,
538  Shape& psi,
539  DShape& dpsidt,
540  Shape& test,
541  DShape& dtestdt) const
542  {
543  // Call the geometrical shape functions and derivatives
544  const double J = this->dshape_eulerian(s, psi, dpsidt);
545 
546  // Set the test functions equal to the shape functions
547  test = psi;
548  dtestdt = dpsidt;
549 
550  // Return the jacobian
551  return J;
552  }
553 
554 
555  //======================================================================
560  //======================================================================
561  template<unsigned NNODE_1D>
563  NNODE_1D>::dshape_and_dtest_eulerian_at_knot_orbit(const unsigned& ipt,
564  Shape& psi,
565  DShape& dpsidt,
566  Shape& test,
567  DShape& dtestdt) const
568  {
569  // Call the geometrical shape functions and derivatives
570  const double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidt);
571 
572  // Set the pointers of the test functions
573  test = psi;
574  dtestdt = dpsidt;
575 
576  // Return the jacobian
577  return J;
578  }
579 
580 
581  template<unsigned NNODE_1D>
583 
584 
585  //======================================================================
587  //=====================================================================
588  template<class ELEMENT>
590  {
591  // Let's have the periodic handler as a friend
592  template<unsigned NNODE_1D>
594 
595  public:
597  PeriodicOrbitTemporalMesh(const unsigned& n_element)
598  : OneDMesh<ELEMENT>(n_element, 1.0),
599  RefineableOneDMesh<ELEMENT>(n_element, 1.0)
600  {
601  // Make the mesh periodic by setting the LAST node to have the same data
602  // as the FIRST node
603  // Not necessarily a smart move for when doing Floquet analysis
604  this->boundary_node_pt(1, 0)->make_periodic(this->boundary_node_pt(0, 0));
605  }
606 
607 
608  // Output the orbit for all elements in the mesh
609  void orbit_output(GeneralisedElement* const& elem_pt,
610  std::ostream& outfile,
611  const unsigned& n_plot)
612  {
613  // Loop over all elements in the mesh
614  const unsigned n_element = this->nelement();
615  for (unsigned e = 0; e < n_element; e++)
616  {
617  dynamic_cast<ELEMENT*>(this->element_pt(e))
618  ->orbit_output(elem_pt, outfile, n_plot);
619  }
620  }
621 
622  // Loop over all temporal elements and assemble their contributions
624  PeriodicOrbitAssemblyHandlerBase* const& assembly_handler_pt,
625  GeneralisedElement* const& elem_pt,
626  Vector<double>& residuals)
627  {
628  // Initialise the residuals to zero
629  residuals.initialise(0.0);
630  // Loop over all elements in the mesh
631  const unsigned n_element = this->nelement();
632  for (unsigned e = 0; e < n_element; e++)
633  {
634  dynamic_cast<ELEMENT*>(this->element_pt(e))
635  ->fill_in_contribution_to_integrated_residuals(
636  assembly_handler_pt, elem_pt, residuals);
637  }
638  }
639 
640 
641  // Loop over all temporal elements and assemble their contributions
642  // and the jaobian
644  PeriodicOrbitAssemblyHandlerBase* const& assembly_handler_pt,
645  GeneralisedElement* const& elem_pt,
646  Vector<double>& residuals,
647  DenseMatrix<double>& jacobian)
648  {
649  // Initialise the residuals to zero
650  residuals.initialise(0.0);
651  jacobian.initialise(0.0);
652  // Loop over all elements in the mesh
653  const unsigned n_element = this->nelement();
654  for (unsigned e = 0; e < n_element; e++)
655  {
656  dynamic_cast<ELEMENT*>(this->element_pt(e))
657  ->fill_in_contribution_to_integrated_jacobian(
658  assembly_handler_pt, elem_pt, residuals, jacobian);
659  }
660  }
661  };
662 
665  //===============================================================
667  {
668  public:
669  // Do nothing in constructor
671 
672  // Provide interface
673  virtual void get_dofs_for_element(GeneralisedElement* const elem_pt,
674  Vector<double>& dofs) = 0;
675 
676 
678  GeneralisedElement* const elem_pt, Vector<double>& dofs) = 0;
679 
680 
681  virtual void set_dofs_for_element(GeneralisedElement* const elem_pt,
682  Vector<double> const& dofs) = 0;
683  };
684 
685  //======================================================================
688  //========================================================================
689  template<unsigned NNODE_1D>
691  {
692  private:
695 
698 
702 
705 
708 
710  unsigned Ndof;
711 
714 
716  unsigned N_tstorage;
717 
719  double Omega;
720 
721  public:
724  Problem* const& problem_pt,
725  const unsigned& n_element_in_period,
726  const DenseMatrix<double>& initial_guess,
727  const double& omega)
728  : Problem_pt(problem_pt),
729  N_element_in_period(n_element_in_period),
730  Omega(omega / (2.0 * MathematicalConstants::Pi))
731  {
732  // Store the current number of degrees of freedom
733  Ndof = problem_pt->ndof();
734 
735  // Create the appropriate mesh of "1D" time elements depending on
736  // the specified spectral order
737  // The time domain runs from zero to one
738  Time_mesh_pt =
740  n_element_in_period);
741 
743 
744  // Set the error estimator
745  Time_mesh_pt->spatial_error_estimator_pt() = new Z2ErrorEstimator;
746  Time_mesh_pt->max_permitted_error() = 1.0e-2;
747  Time_mesh_pt->min_permitted_error() = 1.0e-5;
748  Time_mesh_pt->max_refinement_level() = 10;
749 
750  // Now we need to number the mesh
751  // Dummy dof pointer
752  Vector<double*> dummy_dof_pt;
753  Time_mesh_pt->assign_global_eqn_numbers(dummy_dof_pt);
754  // Assign the local equation numbers
755  Time_mesh_pt->assign_local_eqn_numbers(false);
756 
757  // Find the number of temporal degrees of freedom
758  N_tstorage = dummy_dof_pt.size();
759 
760  // Now we need to do something clever to setup the time storage schemes
761  // and the initial values (don't quite know what that is yet)
762 
763  // Create the "fake" timestepper
765  // Loop over the temporal elements and set the pointers
766  for (unsigned e = 0; e < n_element_in_period; e++)
767  {
770  Time_mesh_pt->element_pt(e));
771 
772  // Set the time and the timestepper
773  el_pt->time_pt() = problem_pt->time_pt();
774  el_pt->time_stepper_pt() = Time_stepper_pt;
775 
776  // Set the number of temporal degrees of freedom
777  el_pt->set_ntstorage(N_tstorage);
778  // Set the frequency
779  el_pt->omega_pt() = &Omega;
780  }
781 
782  // We now need to do something much more drastic which is to loop over all
783  // our the data in the problem and change the timestepper, which is going
784  // to be a real pain when I start to worry about halo nodes, etc.
785 
786  // Will need to use the appropriate mesh-level functions that have
787  // not been written yet ..
788 
789  // Let's just break if there are submeshes
790  if (problem_pt->nsub_mesh() > 0)
791  {
792  throw OomphLibError(
793  "PeriodicOrbitHandler can't cope with submeshes yet",
796  }
797 
798  // OK now we have only one mesh
799  unsigned n_node = problem_pt->mesh_pt()->nnode();
800  for (unsigned n = 0; n < n_node; n++)
801  {
802  Node* const nod_pt = problem_pt->mesh_pt()->node_pt(n);
803  nod_pt->set_time_stepper(Time_stepper_pt, false);
804  // If the unknowns are pinned then copy the value to all values
805  unsigned n_value = nod_pt->nvalue();
806  for (unsigned i = 0; i < n_value; i++)
807  {
808  if (nod_pt->is_pinned(i))
809  {
810  const unsigned n_tstorage = nod_pt->ntstorage();
811  const double value = nod_pt->value(i);
812  for (unsigned t = 1; t < n_tstorage; t++)
813  {
814  nod_pt->set_value(t, i, value);
815  }
816  }
817  }
818  }
819 
820  unsigned n_element = problem_pt->mesh_pt()->nelement();
821  for (unsigned e = 0; e < n_element; e++)
822  {
823  unsigned n_internal =
824  problem_pt->mesh_pt()->element_pt(e)->ninternal_data();
825  for (unsigned i = 0; i < n_internal; i++)
826  {
827  // Cache the internal data
828  Data* const data_pt =
829  problem_pt->mesh_pt()->element_pt(e)->internal_data_pt(i);
830  // and set the timestepper
831  data_pt->set_time_stepper(Time_stepper_pt, false);
832 
833  // If the unknowns are pinned then copy the value to all values
834  unsigned n_value = data_pt->nvalue();
835  for (unsigned j = 0; j < n_value; j++)
836  {
837  if (data_pt->is_pinned(j))
838  {
839  const unsigned n_tstorage = data_pt->ntstorage();
840  const double value = data_pt->value(j);
841  for (unsigned t = 1; t < n_tstorage; t++)
842  {
843  data_pt->set_value(t, j, value);
844  }
845  }
846  }
847  }
848  }
849 
850  // Need to reassign equation numbers so that the DOF pointer, points to
851  // the newly allocated storage
852  oomph_info << "Re-allocated " << problem_pt->assign_eqn_numbers()
853  << " equation numbers\n";
854 
855  // Now's let's add all the unknowns to the problem
856  problem_pt->Dof_pt.resize(Ndof * N_tstorage + 1);
857  // This is reasonably straight forward using pointer arithmetic
858  // but this does rely on knowing how the data is stored in the
859  // Nodes which is a little nasty
860  for (unsigned i = 0; i < N_tstorage; i++)
861  {
862  unsigned offset = Ndof * i;
863  for (unsigned n = 0; n < Ndof; n++)
864  {
865  problem_pt->Dof_pt[offset + n] = problem_pt->Dof_pt[n] + i;
866  }
867  }
868 
869  // Add the frequency of the orbit to the unknowns
870  problem_pt->Dof_pt[Ndof * N_tstorage] = &Omega;
871 
872  // Rebuild everything
873  problem_pt->Dof_distribution_pt->build(
874  problem_pt->communicator_pt(), Ndof * N_tstorage + 1, true);
875 
876 
877  // Set initial condition of constant-ness plus wobble
878  for (unsigned i = 0; i < N_tstorage; i++)
879  {
880  unsigned offset = Ndof * i;
881  for (unsigned n = 0; n < Ndof; n++)
882  {
883  problem_pt->dof(offset + n) =
884  initial_guess(i, n); // problem_pt->dof(n);
885  }
886  }
887 
888  // Set the initial unkowns to be the original problem
889  Previous_dofs.resize(Ndof * N_tstorage + 1, 0.0);
891 
892  // Now check everything is OK ... it seems to be
893  // std::cout << problem_pt->ndof() << "\n";
894  // Let's check it
895  // for(unsigned i=0;i<problem_pt->ndof();i++)
896  // {
897  // std::cout << i << " " << problem_pt->dof(i) << "\n";
898  //}
899  }
900 
903  {
904  for (unsigned n = 0; n < Ndof * N_tstorage + 1; n++)
905  {
907  }
908  }
909 
911  unsigned ndof(GeneralisedElement* const& elem_pt)
912  {
913  return ((elem_pt->ndof()) * N_tstorage + 1);
914  }
915 
918  unsigned long eqn_number(GeneralisedElement* const& elem_pt,
919  const unsigned& ieqn_local)
920  {
921  // Get unaugmented number of (spatial) dofs in element
922  unsigned raw_ndof = elem_pt->ndof();
923  // The final variable (the period) is stored at the end
924  if (ieqn_local == raw_ndof * N_tstorage)
925  {
926  return N_tstorage * Ndof;
927  }
928  // Otherwise we need to do a little more work
929  else
930  {
931  // Now find out the time level
932  unsigned t = ieqn_local / raw_ndof;
933  // and the remainder (original eqn number)
934  unsigned raw_ieqn = ieqn_local % raw_ndof;
935  // hence calculate the global value
936  return t * Ndof + elem_pt->eqn_number(raw_ieqn);
937  }
938  }
939 
941  void get_residuals(GeneralisedElement* const& elem_pt,
942  Vector<double>& residuals)
943  {
944  Time_mesh_pt->assemble_residuals(this, elem_pt, residuals);
945  }
946 
947 
948  // Provide interface
950  Vector<double>& dofs)
951  {
952  // Find the number of dofs in the element
953  const unsigned n_elem_dof = this->ndof(elem_pt);
954  dofs.resize(n_elem_dof);
955  // Now just get the dofs corresponding to the element's unknowns from the
956  // problem dof
957  for (unsigned i = 0; i < n_elem_dof; i++)
958  {
959  dofs[i] = Problem_pt->dof(this->eqn_number(elem_pt, i));
960  }
961  }
962 
964  Vector<double>& dofs)
965  {
966  // Find the number of dofs in the element
967  const unsigned n_elem_dof = this->ndof(elem_pt);
968  dofs.resize(n_elem_dof);
969  // Now just get the dofs corresponding to the element's unknowns from the
970  // problem dof
971  for (unsigned i = 0; i < n_elem_dof; i++)
972  {
973  dofs[i] = Previous_dofs[this->eqn_number(elem_pt, i)];
974  }
975  }
976 
977 
979  Vector<double> const& dofs)
980  {
981  // Find the number of dofs in the element
982  const unsigned n_elem_dof = this->ndof(elem_pt);
983  // Now just get the dofs corresponding to the element's unknowns from the
984  // problem dof
985  for (unsigned i = 0; i < n_elem_dof; i++)
986  {
987  Problem_pt->dof(this->eqn_number(elem_pt, i)) = dofs[i];
988  }
989  }
990 
991 
994  void get_jacobian(GeneralisedElement* const& elem_pt,
995  Vector<double>& residuals,
996  DenseMatrix<double>& jacobian)
997  {
998  Time_mesh_pt->assemble_residuals_and_jacobian(
999  this, elem_pt, residuals, jacobian);
1000  }
1001 
1004  // void get_all_vectors_and_matrices(
1005  // GeneralisedElement* const &elem_pt,
1006  // Vector<Vector<double> >&vec, Vector<DenseMatrix<double> > &matrix) {}
1007 
1011  // virtual int bifurcation_type() const {return 0;}
1012 
1015  // virtual double* bifurcation_parameter_pt() const;
1016 
1019  // virtual void get_eigenfunction(Vector<DoubleVector> &eigenfunction);
1020 
1022  void orbit_output(std::ostream& outfile, const unsigned& n_plot)
1023  {
1024  const unsigned n_element = Problem_pt->mesh_pt()->nelement();
1025  for (unsigned e = 0; e < n_element; e++)
1026  {
1027  Time_mesh_pt->orbit_output(
1028  Problem_pt->mesh_pt()->element_pt(e), outfile, n_plot);
1029  }
1030  }
1031 
1032 
1035  {
1036  const unsigned n_node = Time_mesh_pt->nnode();
1037  t.resize(n_node);
1038  for (unsigned n = 0; n < n_node; n++)
1039  {
1040  t[n] = Time_mesh_pt->node_pt(n)->x(0);
1041  }
1042  }
1043 
1046  {
1047  // First job is to compute some sort of error measure
1048  // Then we can decide how to refine this is probably best handled
1049  // separately for now
1050 
1051  // The current plan is to copy all (locally held in the case of
1052  // distributed problem) spatial degrees of freedom into the dummy
1053  // storage of the time mesh
1054 
1055  // Probably should kick this down to the mesh level...
1056 
1057  // OK, let's do it, count up all values
1058  unsigned total_n_value = 0;
1059 
1060  // Firstly the global data in the mesh
1061  unsigned n_global_data = Problem_pt->nglobal_data();
1062  for (unsigned i = 0; i < n_global_data; i++)
1063  {
1064  total_n_value += Problem_pt->global_data_pt(i)->nvalue();
1065  }
1066 
1067  // Now the nodal data
1068  unsigned n_node = Problem_pt->mesh_pt()->nnode();
1069  for (unsigned n = 0; n < n_node; n++)
1070  {
1071  total_n_value += Problem_pt->mesh_pt()->node_pt(n)->nvalue();
1072  SolidNode* solid_nod_pt =
1073  dynamic_cast<SolidNode*>(Problem_pt->mesh_pt()->node_pt(n));
1074  if (solid_nod_pt != 0)
1075  {
1076  total_n_value += solid_nod_pt->variable_position_pt()->nvalue();
1077  }
1078  }
1079 
1080  // Now just do the internal data
1081  unsigned n_space_element = Problem_pt->mesh_pt()->nelement();
1082  for (unsigned e = 0; e < n_space_element; e++)
1083  {
1084  const unsigned n_internal_data =
1086  for (unsigned i = 0; i < n_internal_data; i++)
1087  {
1088  total_n_value +=
1090  }
1091  }
1092 
1093  // Now in theory I know the total number of values in the problem
1094  // So I can create another Fake timestepper
1095  TimeStepper* fake_space_time_stepper_pt =
1096  new PeriodicOrbitTimeDiscretisation(total_n_value);
1097 
1098  // Now apply this time stepper to all time nodes
1099  unsigned n_time_node = Time_mesh_pt->nnode();
1100  for (unsigned t = 0; t < n_time_node; t++) // Do include the periodic one
1101  {
1102  Time_mesh_pt->node_pt(t)->set_time_stepper(fake_space_time_stepper_pt,
1103  false);
1104  }
1105 
1106  // Now I "just" copy the values into the new storage
1107  unsigned count = 0;
1108  for (unsigned i = 0; i < n_global_data; i++)
1109  {
1110  Data* const glob_data_pt = Problem_pt->global_data_pt(i);
1111  const unsigned n_value = glob_data_pt->nvalue();
1112  for (unsigned j = 0; j < n_value; j++)
1113  {
1114  for (unsigned t = 0; t < N_tstorage; t++)
1115  {
1116  // Some heavy assumptions here about the time mesh, but that's OK
1117  // because I know exactly how it's laid out
1118  Time_mesh_pt->node_pt(t)->set_value(
1119  count, 0, glob_data_pt->value(t, j));
1120  }
1121  ++count;
1122  }
1123  }
1124 
1125  // Now the nodal data
1126  for (unsigned n = 0; n < n_node; n++)
1127  {
1128  Node* const nod_pt = Problem_pt->mesh_pt()->node_pt(n);
1129  const unsigned n_value = nod_pt->nvalue();
1130  for (unsigned i = 0; i < n_value; i++)
1131  {
1132  for (unsigned t = 0; t < N_tstorage; t++)
1133  {
1134  Time_mesh_pt->node_pt(t)->set_value(count, 0, nod_pt->value(t, i));
1135  }
1136  ++count;
1137  }
1138 
1139  // Now deal with the solid node data
1140  SolidNode* solid_nod_pt = dynamic_cast<SolidNode*>(nod_pt);
1141  if (solid_nod_pt != 0)
1142  {
1143  const unsigned n_solid_value =
1144  solid_nod_pt->variable_position_pt()->nvalue();
1145  for (unsigned i = 0; i < n_solid_value; i++)
1146  {
1147  for (unsigned t = 0; t < N_tstorage; t++)
1148  {
1149  Time_mesh_pt->node_pt(t)->set_value(
1150  count, 0, solid_nod_pt->variable_position_pt()->value(t, i));
1151  }
1152  ++count;
1153  }
1154  }
1155  }
1156 
1157  // Now just do the internal data
1158  for (unsigned e = 0; e < n_space_element; e++)
1159  {
1160  const unsigned n_internal =
1162  for (unsigned i = 0; i < n_internal; i++)
1163  {
1164  Data* const internal_dat_pt =
1166 
1167  const unsigned n_value = internal_dat_pt->nvalue();
1168  for (unsigned j = 0; j < n_value; j++)
1169  {
1170  for (unsigned t = 0; t < N_tstorage; t++)
1171  {
1172  Time_mesh_pt->node_pt(t)->set_value(
1173  count, 0, internal_dat_pt->value(t, j));
1174  }
1175  ++count;
1176  }
1177  }
1178  }
1179 
1180 
1181  // Think it's done but let's check
1182  /*{
1183  std::ofstream munge("data_remunge.dat");
1184  const unsigned n_time_element = Time_mesh_pt->nelement();
1185  for(unsigned e=0;e<n_time_element;e++)
1186  {
1187  const unsigned n_node = Time_mesh_pt->nnode();
1188  for(unsigned n=0;n<n_node;n++)
1189  {
1190  Node* const nod_pt = Time_mesh_pt->node_pt(n);
1191  munge << nod_pt->x(0) << " ";
1192  const unsigned n_space_storage = nod_pt->ntstorage();
1193  for(unsigned t=0;t<n_space_storage;t++)
1194  {
1195  munge << nod_pt->value(t,0) << " ";
1196  }
1197  munge << std::endl;
1198  }
1199  }
1200  munge.close();
1201  }*/
1202 
1203  // Ok get the elemental errors
1204  const unsigned n_time_element = Time_mesh_pt->nelement();
1205  Vector<double> elemental_error(n_time_element);
1206  Time_mesh_pt->spatial_error_estimator_pt()->get_element_errors(
1207  Problem_pt->communicator_pt(), Basic_time_mesh_pt, elemental_error);
1208 
1209  // Let's dump it
1210  for (unsigned e = 0; e < n_time_element; e++)
1211  {
1212  oomph_info << e << " " << elemental_error[e] << "\n";
1213  }
1214 
1215  // Now adapt the mesh
1216  Time_mesh_pt->adapt(Problem_pt->communicator_pt(), elemental_error);
1217 
1218  // I seem to have remunged the data,
1219  // Now let's pretend that we have done the the error adaptation
1220  // Time_mesh_pt->refine_uniformly();
1221 
1222  // Let's just refine the central elements twice
1223  // Vector<unsigned> refine_elements;
1224  // refine_elements.push_back(0);
1225  // refine_elements.push_back(9);
1226  // Time_mesh_pt->refine_selected_elements(refine_elements);
1227  // refine_elements.clear();
1228  // refine_elements.push_back(0);
1229  // refine_elements.push_back(1);
1230  // refine_elements.push_back(10);
1231  // refine_elements.push_back(11);
1232  // Time_mesh_pt->refine_selected_elements(refine_elements);
1233 
1234  /* std::ofstream munge("data_refine.dat");
1235  const unsigned n_time_element = Time_mesh_pt->nelement();
1236  for(unsigned e=0;e<n_time_element;e++)
1237  {
1238  const unsigned n_node = Time_mesh_pt->nnode();
1239  for(unsigned n=0;n<n_node;n++)
1240  {
1241  Node* const nod_pt = Time_mesh_pt->node_pt(n);
1242  munge << nod_pt->x(0) << " ";
1243  const unsigned n_space_storage = nod_pt->ntstorage();
1244  for(unsigned t=0;t<n_space_storage;t++)
1245  {
1246  munge << nod_pt->value(t,0) << " ";
1247  }
1248  munge << std::endl;
1249  }
1250  }
1251  munge.close();*/
1252 
1253  // Now we need to put the refined data back into the problem
1254 
1255  // Now we need to number the mesh
1256  // Dummy dof pointer
1257  Vector<double*> dummy_dof_pt;
1258  Time_mesh_pt->assign_global_eqn_numbers(dummy_dof_pt);
1259  // Assign the local equation numbers
1260  Time_mesh_pt->assign_local_eqn_numbers(false);
1261 
1262  // Find the number of temporal degrees of freedom
1263  N_tstorage = dummy_dof_pt.size();
1264  // and new number of elements
1265  N_element_in_period = Time_mesh_pt->nelement();
1266 
1267  // Create the new "fake" timestepper
1268  PeriodicOrbitTimeDiscretisation* periodic_time_stepper_pt =
1270 
1271  // Loop over the temporal elements and set the pointers
1272  for (unsigned e = 0; e < N_element_in_period; e++)
1273  {
1276  Time_mesh_pt->element_pt(e));
1277 
1278  // Set the time and the timestepper
1279  el_pt->time_pt() = Problem_pt->time_pt();
1280  el_pt->time_stepper_pt() = periodic_time_stepper_pt;
1281 
1282  // Set the number of temporal degrees of freedom
1283  el_pt->set_ntstorage(N_tstorage);
1284  // Set the frequency
1285  el_pt->omega_pt() = &Omega;
1286  }
1287 
1288  // We now need to do something much more drastic which is to loop over all
1289  // our the data in the problem and change the timestepper, which is going
1290  // to be a real pain when I start to worry about halo nodes, etc.
1291 
1292  // Will need to use the appropriate mesh-level functions that have
1293  // not been written yet ..
1294 
1295  // Let's just break if there are submeshes
1296  if (Problem_pt->nsub_mesh() > 0)
1297  {
1298  throw OomphLibError(
1299  "PeriodicOrbitHandler can't cope with submeshes yet",
1302  }
1303 
1304  // OK now we have only one mesh
1305  for (unsigned n = 0; n < n_node; n++)
1306  {
1307  Node* const nod_pt = Problem_pt->mesh_pt()->node_pt(n);
1308  nod_pt->set_time_stepper(periodic_time_stepper_pt, false);
1309  }
1310 
1311  for (unsigned e = 0; e < n_space_element; e++)
1312  {
1313  unsigned n_internal =
1315  for (unsigned i = 0; i < n_internal; i++)
1316  {
1317  // Cache the internal data
1318  Data* const data_pt =
1320  // and set the timestepper
1321  data_pt->set_time_stepper(periodic_time_stepper_pt, false);
1322  }
1323  }
1324 
1325  // Now I can delete the old timestepper and switch
1326  delete Time_stepper_pt;
1327  Time_stepper_pt = periodic_time_stepper_pt;
1328 
1329  // Need to reassign equation numbers so that the DOF pointer, points to
1330  // the newly allocated storage
1331  oomph_info << "Re-allocated " << Problem_pt->assign_eqn_numbers()
1332  << " equation numbers\n";
1333 
1334  // Now's let's add all the unknowns to the problem
1335  Problem_pt->Dof_pt.resize(Ndof * N_tstorage + 1);
1336  // This is reasonably straight forward using pointer arithmetic
1337  // but this does rely on knowing how the data is stored in the
1338  // Nodes which is a little nasty
1339  for (unsigned i = 0; i < N_tstorage; i++)
1340  {
1341  unsigned offset = Ndof * i;
1342  for (unsigned n = 0; n < Ndof; n++)
1343  {
1344  Problem_pt->Dof_pt[offset + n] = Problem_pt->Dof_pt[n] + i;
1345  }
1346  }
1347 
1348  // Add the frequency of the orbit to the unknowns
1350 
1351  // Rebuild everything
1353  Problem_pt->communicator_pt(), Ndof * N_tstorage + 1, true);
1354 
1355 
1356  // Now finally transfer the solution accross
1357 
1358  // Now I "just" copy the values into the new storage
1359  count = 0;
1360  for (unsigned i = 0; i < n_global_data; i++)
1361  {
1362  Data* const glob_data_pt = Problem_pt->global_data_pt(i);
1363  const unsigned n_value = glob_data_pt->nvalue();
1364  for (unsigned j = 0; j < n_value; j++)
1365  {
1366  for (unsigned t = 0; t < N_tstorage; t++)
1367  {
1368  // Some heavy assumptions here about the time mesh, but that's OK
1369  // because I know exactly how it's laid out
1370  glob_data_pt->set_value(
1371  t, j, Time_mesh_pt->node_pt(t)->value(count, 0));
1372  }
1373  ++count;
1374  }
1375  }
1376 
1377  // Now the nodal data
1378  for (unsigned n = 0; n < n_node; n++)
1379  {
1380  Node* const nod_pt = Problem_pt->mesh_pt()->node_pt(n);
1381  const unsigned n_value = nod_pt->nvalue();
1382  for (unsigned i = 0; i < n_value; i++)
1383  {
1384  for (unsigned t = 0; t < N_tstorage; t++)
1385  {
1386  nod_pt->set_value(t, i, Time_mesh_pt->node_pt(t)->value(count, 0));
1387  }
1388  ++count;
1389  }
1390 
1391  // Now deal with the solid node data
1392  SolidNode* solid_nod_pt = dynamic_cast<SolidNode*>(nod_pt);
1393  if (solid_nod_pt != 0)
1394  {
1395  const unsigned n_solid_value =
1396  solid_nod_pt->variable_position_pt()->nvalue();
1397  for (unsigned i = 0; i < n_solid_value; i++)
1398  {
1399  for (unsigned t = 0; t < N_tstorage; t++)
1400  {
1401  solid_nod_pt->variable_position_pt()->set_value(
1402  t, i, Time_mesh_pt->node_pt(t)->value(count, 0));
1403  }
1404  ++count;
1405  }
1406  }
1407  }
1408 
1409  // Now just do the internal data
1410  for (unsigned e = 0; e < n_space_element; e++)
1411  {
1412  const unsigned n_internal =
1414  for (unsigned i = 0; i < n_internal; i++)
1415  {
1416  Data* const internal_dat_pt =
1418 
1419  const unsigned n_value = internal_dat_pt->nvalue();
1420  for (unsigned j = 0; j < n_value; j++)
1421  {
1422  for (unsigned t = 0; t < N_tstorage; t++)
1423  {
1424  internal_dat_pt->set_value(
1425  t, j, Time_mesh_pt->node_pt(t)->value(count, 0));
1426  }
1427  ++count;
1428  }
1429  }
1430  }
1431 
1432 
1433  // Now I should be able to delete the fake time timestepper
1434  n_time_node = Time_mesh_pt->nnode();
1435  for (unsigned t = 0; t < n_time_node; t++)
1436  {
1437  Time_mesh_pt->node_pt(t)->set_time_stepper(&Mesh::Default_TimeStepper,
1438  false);
1439  }
1440  // Delete the fake timestepper
1441  delete fake_space_time_stepper_pt;
1442 
1443  // Set the initial unkowns to be the original problem
1444  Previous_dofs.resize(Ndof * N_tstorage + 1, 0.0);
1446  }
1447 
1448 
1451  {
1452  delete Time_mesh_pt;
1453  }
1454  };
1455 
1456 
1458  {
1459  public:
1461 
1462 
1465 
1469 
1470 
1472  virtual void get_inner_product_matrix(DenseMatrix<double>& inner_product)
1473  {
1474  const unsigned n_dof = this->ndof();
1475  inner_product.initialise(0.0);
1476  for (unsigned i = 0; i < n_dof; i++)
1477  {
1478  inner_product(i, i) = 1.0;
1479  }
1480  }
1481 
1482  virtual void spacetime_output(std::ostream& outilfe,
1483  const unsigned& Nplot,
1484  const double& time = 0.0)
1485  {
1486  }
1487  };
1488 
1489 
1490 } // namespace oomph
1491 
1492 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
Definition: assembly_handler.h:63
Definition: shape.h:278
Definition: nodes.h:86
void set_value(const unsigned &i, const double &value_)
Definition: nodes.h:271
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
double value(const unsigned &i) const
Definition: nodes.h:293
unsigned ntstorage() const
Definition: nodes.cc:879
void set_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Definition: nodes.cc:406
bool is_pinned(const unsigned &i) const
Test whether the i-th variable is pinned (1: true; 0: false).
Definition: nodes.h:417
void initialise(const T &val)
Initialize all values in the matrix to val.
Definition: matrices.h:514
Definition: error_estimator.h:79
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void output(std::ostream &outfile)
Definition: elements.h:3050
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Definition: elements.cc:3298
Definition: elements.h:73
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
Definition: elements.h:704
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
unsigned ninternal_data() const
Return the number of internal data objects.
Definition: elements.h:823
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227
TimeStepper *& time_stepper_pt()
Definition: geom_objects.h:192
void build(const OomphCommunicator *const comm_pt, const unsigned &first_row, const unsigned &nrow_local, const unsigned &nrow=0)
Definition: linear_algebra_distribution.cc:35
Definition: mesh.h:67
static Steady< 0 > Default_TimeStepper
The Steady Timestepper.
Definition: mesh.h:75
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
Definition: nodes.h:906
virtual void make_periodic(Node *const &node_pt)
Definition: nodes.cc:2257
double value(const unsigned &i) const
Definition: nodes.cc:2408
Definition: one_d_mesh.template.h:52
Definition: oomph_definitions.h:222
Definition: periodic_orbit_handler.h:667
virtual void set_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > const &dofs)=0
virtual void get_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > &dofs)=0
virtual void get_previous_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > &dofs)=0
PeriodicOrbitAssemblyHandlerBase()
Definition: periodic_orbit_handler.h:670
Definition: periodic_orbit_handler.h:691
void adapt_temporal_mesh()
Adapt the time mesh.
Definition: periodic_orbit_handler.h:1045
void set_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > const &dofs)
Definition: periodic_orbit_handler.h:978
void orbit_output(std::ostream &outfile, const unsigned &n_plot)
Return the contribution to the residuals of the element elem_pt.
Definition: periodic_orbit_handler.h:1022
unsigned N_element_in_period
Storage for number of elements in the period.
Definition: periodic_orbit_handler.h:713
void discrete_times(Vector< double > &t)
Tell me the times at which you want the solution.
Definition: periodic_orbit_handler.h:1034
void get_previous_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > &dofs)
Definition: periodic_orbit_handler.h:963
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: periodic_orbit_handler.h:994
~PeriodicOrbitAssemblyHandler()
Destructor, destroy the time mesh.
Definition: periodic_orbit_handler.h:1450
void get_dofs_for_element(GeneralisedElement *const elem_pt, Vector< double > &dofs)
Definition: periodic_orbit_handler.h:949
unsigned Ndof
Store number of degrees of freedom in the original problem.
Definition: periodic_orbit_handler.h:710
PeriodicOrbitTemporalMesh< SpectralPeriodicOrbitElement< NNODE_1D > > * Time_mesh_pt
Storage for mesh of temporal elements.
Definition: periodic_orbit_handler.h:701
Vector< double > Previous_dofs
Storage for the previous solution.
Definition: periodic_orbit_handler.h:707
unsigned ndof(GeneralisedElement *const &elem_pt)
Return the number of degrees of freedom in the element elem_pt.
Definition: periodic_orbit_handler.h:911
void set_previous_dofs_to_current_dofs()
Update the previous dofs.
Definition: periodic_orbit_handler.h:902
Problem * Problem_pt
Pointer to the problem.
Definition: periodic_orbit_handler.h:697
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Definition: periodic_orbit_handler.h:918
unsigned N_tstorage
Storage for the number of unknown time values.
Definition: periodic_orbit_handler.h:716
PeriodicOrbitTimeDiscretisation * Time_stepper_pt
Pointer to the timestepper.
Definition: periodic_orbit_handler.h:694
Mesh * Basic_time_mesh_pt
Storage for the mesh of temporal elements with a simple mesh pointer.
Definition: periodic_orbit_handler.h:704
double Omega
Storage for the frequency of the orbit (scaled by 2pi)
Definition: periodic_orbit_handler.h:719
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Return the contribution to the residuals of the element elem_pt.
Definition: periodic_orbit_handler.h:941
Definition: periodic_orbit_handler.h:1458
virtual void get_non_external_ddofs_dt(Vector< double > &du_dt)
Definition: periodic_orbit_handler.h:1468
PeriodicOrbitBaseElement()
Definition: periodic_orbit_handler.h:1460
virtual void spacetime_output(std::ostream &outilfe, const unsigned &Nplot, const double &time=0.0)
Definition: periodic_orbit_handler.h:1482
virtual void get_non_external_dofs(Vector< double > &u)
Interface to get the current value of all (internal and shared) unknowns.
Definition: periodic_orbit_handler.h:1464
virtual void get_inner_product_matrix(DenseMatrix< double > &inner_product)
Get the inner product matrix.
Definition: periodic_orbit_handler.h:1472
Definition: periodic_orbit_handler.h:170
Time * Time_pt
Pointer to global time.
Definition: periodic_orbit_handler.h:178
double * Omega_pt
Definition: periodic_orbit_handler.h:175
void orbit_output(GeneralisedElement *const &elem_pt, std::ostream &outfile, const unsigned &n_plot)
Definition: periodic_orbit_handler.cc:30
unsigned Ntstorage
Definition: periodic_orbit_handler.h:172
void fill_in_contribution_to_integrated_jacobian(PeriodicOrbitAssemblyHandlerBase *const &assembly_handler_pt, GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: periodic_orbit_handler.h:257
void set_timestepper_weights(const Shape &psi, const DShape &dpsidt)
Set the timestepper weights.
Definition: periodic_orbit_handler.h:284
virtual double dshape_and_dtest_eulerian_at_knot_orbit(const unsigned &ipt, Shape &psi, DShape &dpsidt, Shape &test, DShape &dtestdt) const =0
void fill_in_contribution_to_integrated_residuals(PeriodicOrbitAssemblyHandlerBase *const &assembly_handler_pt, GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: periodic_orbit_handler.h:240
double *& omega_pt()
Broken assignment operator.
Definition: periodic_orbit_handler.h:196
Time *& time_pt()
Retun the pointer to the global time.
Definition: periodic_orbit_handler.h:214
virtual double dshape_and_dtest_eulerian_orbit(const Vector< double > &s, Shape &psi, DShape &dpsidt, Shape &test, DShape &dtestdt) const =0
double time() const
Return the global time, accessed via the time pointer.
Definition: periodic_orbit_handler.h:226
PeriodicOrbitEquations()
Definition: periodic_orbit_handler.h:182
void fill_in_generic_residual_contribution_orbit(PeriodicOrbitAssemblyHandlerBase *const &assembly_handler_pt, GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
The routine that actually does all the work!
Definition: periodic_orbit_handler.cc:77
Time *const & time_pt() const
Return the pointer to the global time (const version)
Definition: periodic_orbit_handler.h:220
void set_ntstorage(const unsigned &n_tstorage)
Set the total number of time storage values.
Definition: periodic_orbit_handler.h:208
double omega()
Return the frequency.
Definition: periodic_orbit_handler.h:202
PeriodicOrbitEquations(const PeriodicOrbitEquations &dummy)=delete
Broken copy constructor.
A special temporal mesh class.
Definition: periodic_orbit_handler.h:590
PeriodicOrbitTemporalMesh(const unsigned &n_element)
Constructor, create a 1D mesh from 0 to 1 that is periodic.
Definition: periodic_orbit_handler.h:597
void assemble_residuals_and_jacobian(PeriodicOrbitAssemblyHandlerBase *const &assembly_handler_pt, GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: periodic_orbit_handler.h:643
void orbit_output(GeneralisedElement *const &elem_pt, std::ostream &outfile, const unsigned &n_plot)
Definition: periodic_orbit_handler.h:609
void assemble_residuals(PeriodicOrbitAssemblyHandlerBase *const &assembly_handler_pt, GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Definition: periodic_orbit_handler.h:623
Definition: periodic_orbit_handler.h:57
double(* InitialConditionFctPt)(const double &t)
Definition: periodic_orbit_handler.h:105
void shift_time_positions(Node *const &node_pt)
Broken shifting of time positions.
Definition: periodic_orbit_handler.h:143
void set_weights()
Set the weights.
Definition: periodic_orbit_handler.h:152
unsigned order() const
Return the actual order of the scheme.
Definition: periodic_orbit_handler.h:77
void assign_initial_values_impulsive(Data *const &data_pt)
Definition: periodic_orbit_handler.h:84
void shift_time_values(Data *const &data_pt)
Broken shifting of time values.
Definition: periodic_orbit_handler.h:134
PeriodicOrbitTimeDiscretisation(const unsigned &n_tstorage)
Constructor for the case when we allow adaptive timestepping.
Definition: periodic_orbit_handler.h:62
void assign_initial_positions_impulsive(Node *const &node_pt)
Definition: periodic_orbit_handler.h:94
void assign_initial_data_values(Data *const &data_pt, Vector< InitialConditionFctPt > initial_value_fct)
Definition: periodic_orbit_handler.h:110
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
Definition: periodic_orbit_handler.h:161
PeriodicOrbitTimeDiscretisation(const PeriodicOrbitTimeDiscretisation &)=delete
Broken copy constructor.
void operator=(const PeriodicOrbitTimeDiscretisation &)=delete
Broken assignment operator.
unsigned nprev_values() const
Number of previous values available.
Definition: periodic_orbit_handler.h:155
Definition: problem.h:151
unsigned long ndof() const
Return the number of dofs.
Definition: problem.h:1674
Time *& time_pt()
Return a pointer to the global time object.
Definition: problem.h:1504
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
Definition: problem.h:1246
unsigned nglobal_data() const
Return the number of global data values.
Definition: problem.h:1686
double & dof(const unsigned &i)
i-th dof in the problem
Definition: problem.h:1813
Vector< double * > Dof_pt
Vector of pointers to dofs.
Definition: problem.h:554
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Definition: problem.h:1280
unsigned nsub_mesh() const
Return number of submeshes.
Definition: problem.h:1323
unsigned long assign_eqn_numbers(const bool &assign_local_eqn_numbers=true)
Definition: problem.cc:1989
LinearAlgebraDistribution * Dof_distribution_pt
Definition: problem.h:460
Data *& global_data_pt(const unsigned &i)
Return a pointer to the the i-th global data object.
Definition: problem.h:1647
void shape(const Vector< double > &s, Shape &psi) const
Calculate the geometric shape functions at local coordinate s.
Definition: Qspectral_elements.h:576
Definition: Qspectral_elements.h:363
Refineable version of the OneDMesh.
Definition: one_d_mesh.template.h:123
Definition: Qspectral_elements.h:1323
Definition: shape.h:76
Definition: nodes.h:1686
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
Definition: nodes.h:1765
Definition: periodic_orbit_handler.h:353
double dshape_and_dtest_eulerian_at_knot_orbit(const unsigned &ipt, Shape &psi, DShape &dpsidt, Shape &test, DShape &dtestdt) const
Definition: periodic_orbit_handler.h:563
double dshape_and_dtest_eulerian_orbit(const Vector< double > &s, Shape &psi, DShape &dpsidt, Shape &test, DShape &dtestdt) const
Definition: periodic_orbit_handler.h:537
void get_interpolated_values(const Vector< double > &s, Vector< double > &value)
Return the dummy values.
Definition: periodic_orbit_handler.h:388
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Definition: periodic_orbit_handler.h:464
void output(FILE *file_pt)
Definition: periodic_orbit_handler.h:491
unsigned nrecovery_order()
Order of recovery shape functions.
Definition: periodic_orbit_handler.h:412
unsigned nvertex_node() const
Number of vertex nodes in the element.
Definition: periodic_orbit_handler.h:458
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &value)
Return the temporal dummy values.
Definition: periodic_orbit_handler.h:394
unsigned num_Z2_flux_terms()
Definition: periodic_orbit_handler.h:419
unsigned ncont_interpolated_values() const
Number of continuously interpolated values (1)
Definition: periodic_orbit_handler.h:382
unsigned required_nvalue(const unsigned &n) const
Broken assignment operator.
Definition: periodic_orbit_handler.h:376
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: periodic_orbit_handler.h:483
void output(std::ostream &outfile)
Function to return the number of values.
Definition: periodic_orbit_handler.h:475
SpectralPeriodicOrbitElement(const SpectralPeriodicOrbitElement< NNODE_1D > &dummy)=delete
Broken copy constructor.
SpectralPeriodicOrbitElement()
Definition: periodic_orbit_handler.h:357
void output(FILE *file_pt, const unsigned &n_plot)
Definition: periodic_orbit_handler.h:499
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Get the fluxes for the recovert.
Definition: periodic_orbit_handler.h:425
Definition: timesteppers.h:231
DenseMatrix< double > Weight
Storage for the weights associated with the timestepper.
Definition: timesteppers.h:237
Time * Time_pt
Pointer to discrete time storage scheme.
Definition: timesteppers.h:234
unsigned ntstorage() const
Definition: timesteppers.h:601
std::string Type
Definition: timesteppers.h:241
double & time()
Return current value of continous time.
Definition: timesteppers.h:332
Definition: timesteppers.h:63
double & time()
Return the current value of the continuous time.
Definition: timesteppers.h:123
Definition: oomph-lib/src/generic/Vector.h:58
void initialise(const _Tp &__value)
Iterate over all values and set to the desired value.
Definition: oomph-lib/src/generic/Vector.h:167
Definition: error_estimator.h:266
RealScalar s
Definition: level1_cplx_impl.h:130
double Pi
Definition: two_d_biharmonic.cc:235
Vector::Scalar omega(const Vector &t, const Vector &s, RealScalar angle)
Definition: IDRS.h:36
squared absolute value
Definition: GlobalFunctions.h:87
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
t
Definition: plotPSD.py:36
Definition: indexed_view.cpp:20
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2