deal.II version GIT relicensing-2173-gae8fc9d14b 2024-11-24 06:40:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
Swift-Hohenberg-Solver.h
Go to the documentation of this file.
1
377 *  
378 *  
379 *   #include <deal.II/base/utilities.h>
380 *   #include <deal.II/base/quadrature_lib.h>
381 *   #include <deal.II/base/function.h>
382 *   #include <deal.II/base/logstream.h>
383 *   #include <deal.II/lac/vector.h>
384 *   #include <deal.II/lac/full_matrix.h>
385 *   #include <deal.II/lac/dynamic_sparsity_pattern.h>
386 *   #include <deal.II/lac/sparse_matrix.h>
387 *   #include <deal.II/lac/solver_cg.h>
388 *   #include <deal.II/lac/precondition.h>
389 *   #include <deal.II/lac/affine_constraints.h>
390 *   #include <deal.II/grid/tria.h>
391 *   #include <deal.II/grid/grid_generator.h>
392 *   #include <deal.II/grid/grid_refinement.h>
393 *   #include <deal.II/grid/grid_out.h>
394 *   #include <deal.II/dofs/dof_handler.h>
395 *   #include <deal.II/dofs/dof_tools.h>
396 *   #include <deal.II/fe/fe_q.h>
397 *   #include <deal.II/fe/fe_system.h>
398 *   #include <deal.II/fe/fe_values.h>
399 *   #include <deal.II/numerics/data_out.h>
400 *   #include <deal.II/numerics/vector_tools.h>
401 *   #include <deal.II/numerics/error_estimator.h>
402 *   #include <deal.II/numerics/solution_transfer.h>
403 *   #include <deal.II/numerics/matrix_tools.h>
404 *   #include <deal.II/lac/sparse_direct.h>
405 *   #include <deal.II/base/timer.h>
406 *  
407 *   #include <deal.II/grid/manifold_lib.h>
408 *   #include <deal.II/grid/grid_tools.h>
409 *  
410 *   #include <boost/math/special_functions/ellint_1.hpp>
411 *  
412 *   #include <fstream>
413 *   #include <iostream>
414 *   #include <random>
415 *  
416 *   namespace SwiftHohenbergSolver
417 *   {
418 *   using namespace dealii;
419 *  
420 *  
421 *  
422 *  
427 *   enum MeshType {HYPERCUBE, CYLINDER, SPHERE, TORUS, SINUSOID};
428 *  
429 *  
430 *  
436 *   enum InitialConditionType {HOTSPOT, PSUEDORANDOM, RANDOM};
437 *  
438 *  
439 *  
440 *  
441 *  
448 *   template<int spacedim>
449 *   Point<spacedim> transform_function(const Point<spacedim>&p)
450 *   {
451 * @endcode
452 *
453 * Currently this only works for a 3-dimensional embedding space
454 * because we are explicitly referencing the x, y, and z coordinates
455 *
456 * @code
457 *   Assert(spacedim == 3, ExcNotImplemented());
458 *  
459 * @endcode
460 *
461 * Returns a point where the x-coordinate is unchanged but the y and z coordinates are adjusted
462 * by a cos wave of period 20, amplitude .5, and vertical shift 1
463 *
464 * @code
465 *   return Point<spacedim>(p(0), p(1)*(1 + .5*std::cos((3.14159/10)*p(0))), p(2)*(1 + .5*std::cos((3.14159/10)*p(0))));
466 *   }
467 *  
468 *  
469 *  
470 *  
471 *  
479 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
480 *   class SHEquation
481 *   {
482 *   public:
483 * @endcode
484 *
485 * / @brief Default constructor, initializes all variables and objects with default values
486 *
487 * @code
488 *   SHEquation();
489 *  
490 *  
491 *  
500 *   SHEquation(const unsigned int degree
501 *   , double time_step_denominator
502 *   , unsigned int ref_num
503 *   , double r_constant = 0.5
504 *   , double g1_constant = 0.5
505 *   , std::string output_file_name = "solution-"
506 *   , double end_time = 0.5);
507 *   void run();
508 *  
509 *   private:
510 *   void setup_system();
511 *   void solve_time_step();
512 *   void output_results() const;
513 *  
516 *   void make_grid();
517 *  
518 *  
521 *   void make_cylinder();
522 * @endcode
523 *
524 * / @brief Uses the same process as creating a cylinder, but then also warps the boundary of the cylinder by the function (1 + 0.5*cos(pi*x/10))
525 *
526 * @code
527 *   void make_sinusoid();
528 * @endcode
529 *
530 * / @brief Generates a spherical mesh of radius 6*pi using GridGenerator and refines it refinement_number times.
531 *
532 * @code
533 *   void make_sphere();
534 * @endcode
535 *
536 * / @brief Generates a torus mesh with inner radius 4 and outer radius 9 using GridGenerator and refines it refinement_number times.
537 *
538 * @code
539 *   void make_torus();
540 * @endcode
541 *
542 * / @brief Generates a hypercube mesh with sidelenth 12*pi using GridGenerator and refines it refinement_number times.
543 *
544 * @code
545 *   void make_hypercube();
546 *  
547 *  
548 * @endcode
549 *
550 * / @brief The degree of finite element to be used, default 1
551 *
552 * @code
553 *   const unsigned int degree;
554 *  
555 * @endcode
556 *
557 * / @brief Object holding the mesh
558 *
559 * @code
561 *  
565 * @endcode
566 *
567 * / @brief Object which understands which finite elements are at each node
568 *
569 * @code
570 *   DoFHandler<dim, spacedim> dof_handler;
571 *  
572 * @endcode
573 *
574 * / @brief Describes the sparsity of the system matrix, allows for more efficient storage
575 *
576 * @code
577 *   SparsityPattern sparsity_pattern;
578 *  
579 * @endcode
580 *
581 * / @brief Object holding the system matrix, stored as a sparse matrix
582 *
583 * @code
584 *   SparseMatrix<double> system_matrix;
585 *  
586 *  
589 *   Vector<double> solution;
590 * @endcode
591 *
592 * / @brief Stores the solution from the previous timestep. Used to compute non-linear terms
593 *
594 * @code
595 *   Vector<double> old_solution;
596 *  
599 *   Vector<double> system_rhs;
600 *  
601 * @endcode
602 *
603 * / @brief Stores the current time, in the units of the problem
604 *
605 * @code
606 *   double time;
607 * @endcode
608 *
609 * / @brief The amount time is increased each iteration/ the denominator of the discretized time derivative
610 *
611 * @code
612 *   double time_step;
613 * @endcode
614 *
615 * / @brief Counts the number of iterations that have elapsed
616 *
617 * @code
618 *   unsigned int timestep_number;
619 * @endcode
620 *
621 * / @brief Used to compute the time_step: time_step = 1/timestep_denominator
622 *
623 * @code
624 *   unsigned int timestep_denominator;
625 * @endcode
626 *
627 * / @brief Determines how much to globally refine each mesh
628 *
629 * @code
630 *   unsigned int refinement_number;
631 *  
632 * @endcode
633 *
634 * / @brief Coefficient of the linear term in the SH equation. This is often taken to be constant and g_1 allowed to vary
635 *
636 * @code
637 *   const double r;
638 * @endcode
639 *
640 * / @brief Coefficient of the quadratic term in the SH equation. Determines whether hexagonal lattices can form
641 *
642 * @code
643 *   const double g1;
644 * @endcode
645 *
646 * / @brief A control parameter for the cubic term. Can be useful for testing, in this code we let k=1 in all cases
647 *
648 * @code
649 *   const double k;
650 *  
651 * @endcode
652 *
653 * / @brief Name used to create output file. Should not include extension
654 *
655 * @code
656 *   const std::string output_file_name;
657 *  
658 * @endcode
659 *
660 * / @brief Determines when the solver terminates, endtime of ~100 are useful to see equilibrium results
661 *
662 * @code
663 *   const double end_time;
664 *   };
665 *  
666 *  
667 *  
672 *   template <int spacedim>
673 *   class BoundaryValues : public Function<spacedim>
674 *   {
675 *   public:
676 *   BoundaryValues()
677 *   : Function<spacedim>(2)
678 *   {}
679 *  
680 *   virtual double value(const Point<spacedim> & p,
681 *   const unsigned int component = 0) const override;
682 *   };
683 *  
684 *  
685 *  
686 *  
693 *   template <int spacedim>
694 *   double BoundaryValues<spacedim>::value(const Point<spacedim> & p,
695 *   const unsigned int component) const
696 *   {
697 *   (void)component;
698 *   AssertIndexRange(component, 2);
699 *  
700 *   return 0.;
701 *   }
702 *  
703 *  
716 *   template<int spacedim, MeshType MESH, InitialConditionType ICTYPE>
717 *   class InitialCondition : public Function<spacedim>
718 *   {
719 *   private:
720 * @endcode
721 *
722 * / @brief The value of the parameter r, used to determine a bound for the magnitude of the initial conditions
723 *
724 * @code
725 *   const double r;
726 * @endcode
727 *
728 * / @brief A center point, used to determine the location of the hot spot for the HotSpot initial condition
729 *
730 * @code
731 *   Point<spacedim> center;
732 * @endcode
733 *
734 * / @brief Radius of the hot spot
735 *
736 * @code
737 *   double radius;
738 * @endcode
739 *
740 * / @brief Stores the randomly generated coefficients for planar sine waves along the x-axis, used for psuedorandom initial conditions
741 *
742 * @code
743 *   double x_sin_coefficients[10];
744 * @endcode
745 *
746 * / @brief Stores the randomly generated coefficients for planar sine waves along the y-axis, used for psuedorandom initial conditions
747 *
748 * @code
749 *   double y_sin_coefficients[10];
750 *  
751 *   public:
752 *  
755 *   InitialCondition()
756 *   : Function<spacedim>(2),
757 *   r(0.5),
758 *   radius(.5)
759 *   {
760 *   for(int i = 0; i < 10; ++i){
761 *   x_sin_coefficients[i] = 2*std::sqrt(r)*(std::rand()%1001)/1000 - std::sqrt(r);
762 *   y_sin_coefficients[i] = 2*std::sqrt(r)*(std::rand()%1001)/1000 - std::sqrt(r);
763 *   }
764 *   }
765 *  
766 *  
771 *   InitialCondition(const double r,
772 *   const double radius)
773 *   : Function<spacedim>(2),
774 *   r(r),
775 *   radius(radius)
776 *   {
777 *   for(int i = 0; i < 10; ++i){
778 *   x_sin_coefficients[i] = 2*std::sqrt(r)*(std::rand()%1001)/1000 - std::sqrt(r);
779 *   y_sin_coefficients[i] = 2*std::sqrt(r)*(std::rand()%1001)/1000 - std::sqrt(r);
780 *   }
781 *   }
782 *  
783 *  
803 *   virtual double value(const Point<spacedim> &p, const unsigned int component) const override;
804 *   };
805 *  
806 *  
811 *   template <>
812 *   double InitialCondition<2, HYPERCUBE, HOTSPOT>::value(
813 *   const Point<2> &p,
814 *   const unsigned int component) const
815 *   {
816 *   if(component == 0){
817 *   if(p.square() <= radius){
818 *   return std::sqrt(r);
819 *   }
820 *   else{
821 *   return -std::sqrt(r);
822 *   }
823 *   }
824 *   else{
825 *   return 1e18;
826 *   }
827 *   }
828 *  
829 *  
834 *   template <>
835 *   double InitialCondition<3, CYLINDER, HOTSPOT>::value(
836 *   const Point<3> &p,
837 *   const unsigned int component) const
838 *   {
839 *   if(component == 0){
840 *   const Point<3> center(0, 0, 6);
841 *   const Point<3> compare(p - center);
842 *   if(compare.square() <= radius){
843 *   return std::sqrt(r);
844 *   }
845 *   else{
846 *   return -std::sqrt(r);
847 *   }
848 *   }
849 *   else{
850 *   return 1e18;
851 *   }
852 *   }
853 *  
854 *  
859 *   template <>
860 *   double InitialCondition<3, SPHERE, HOTSPOT>::value(
861 *   const Point<3> &p,
862 *   const unsigned int component) const
863 *   {
864 *   if(component == 0){
865 *   const Point<3> center(18.41988074, 0, 0);
866 *   const Point<3> compare(p - center);
867 *   if(compare.square() <= radius){
868 *   return std::sqrt(r);
869 *   }
870 *   else{
871 *   return -std::sqrt(r);
872 *   }
873 *   }
874 *   else{
875 *   return 1e18;
876 *   }
877 *   }
878 *  
879 *  
884 *   template <>
885 *   double InitialCondition<3, TORUS, HOTSPOT>::value(
886 *   const Point<3> &p,
887 *   const unsigned int component) const
888 *   {
889 *   if(component == 0){
890 *   const Point<3> center(13., 0, 0);
891 *   const Point<3> compare(p - center);
892 *   if(compare.square() <= radius){
893 *   return std::sqrt(r);
894 *   }
895 *   else{
896 *   return -std::sqrt(r);
897 *   }
898 *   }
899 *   else{
900 *   return 1e18;
901 *   }
902 *   }
903 *  
904 *  
909 *   template <>
910 *   double InitialCondition<3, SINUSOID, HOTSPOT>::value(
911 *   const Point<3> &p,
912 *   const unsigned int component) const
913 *   {
914 *   if(component == 0){
915 *   const Point<3> center(0, 0, 9.);
916 *   const Point<3> compare(p - center);
917 *   if(compare.square() <= radius){
918 *   return std::sqrt(r);
919 *   }
920 *   else{
921 *   return -std::sqrt(r);
922 *   }
923 *   }
924 *   else{
925 *   return 1e18;
926 *   }
927 *   }
928 *  
929 *  
934 *   template <>
935 *   double InitialCondition<2, HYPERCUBE, PSUEDORANDOM>::value(
936 *   const Point<2> &p,
937 *   const unsigned int component) const
938 *   {
939 *   if(component == 0){
940 *   double x_val = 0;
941 *   double y_val = 0;
942 *   for(int i=0; i < 10; ++i){
943 *   x_val += x_sin_coefficients[i]*std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
944 *   y_val += y_sin_coefficients[i]*std::sin(2*3.141592653*p(1)/((i+1)*1.178097245));
945 *   }
946 *  
947 *   return x_val*y_val;
948 *   }
949 *   else{
950 *   return 1e18;
951 *   }
952 *   }
953 *  
954 *  
959 *   template <>
960 *   double InitialCondition<3, CYLINDER, PSUEDORANDOM>::value(
961 *   const Point<3> &p,
962 *   const unsigned int component) const
963 *   {
964 *   if(component == 0){
965 *   double x_val = 0;
966 *   double w_val = 0;
967 *   double width = ((std::atan2(p(1),p(2)) - 3.1415926)/3.1415926)*18.84955592;
968 *   for(int i=0; i < 10; ++i){
969 *   x_val += x_sin_coefficients[i]*std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
970 *   w_val += y_sin_coefficients[i]*std::sin(2*3.141592653*width/((i+1)*1.178097245));
971 *   }
972 *  
973 *   return x_val*w_val;
974 *   }
975 *   else{
976 *   return 1e18;
977 *   }
978 *   }
979 *  
980 *  
985 *   template <>
986 *   double InitialCondition<3, SPHERE, PSUEDORANDOM>::value(
987 *   const Point<3> &p,
988 *   const unsigned int component) const
989 *   {
990 *   if(component == 0){
991 *   double x_val = 0;
992 *   double y_val = 0;
993 *   for(int i=0; i < 10; ++i){
994 *   x_val += x_sin_coefficients[i]*std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
995 *   y_val += y_sin_coefficients[i]*std::sin(2*3.141592653*p(1)/((i+1)*1.178097245));
996 *   }
997 *  
998 *   return x_val*y_val;
999 *   }
1000 *   else{
1001 *   return 1e18;
1002 *   }
1003 *   }
1004 *  
1005 *  
1010 *   template <>
1011 *   double InitialCondition<3, TORUS, PSUEDORANDOM>::value(
1012 *   const Point<3> &p,
1013 *   const unsigned int component) const
1014 *   {
1015 *   if(component == 0){
1016 *   double x_val = 0;
1017 *   double z_val = 0;
1018 *   for(int i=0; i < 10; ++i){
1019 *   x_val += x_sin_coefficients[i]*std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
1020 *   z_val += y_sin_coefficients[i]*std::sin(2*3.141592653*p(2)/((i+1)*1.178097245));
1021 *   }
1022 *  
1023 *   return x_val*z_val;
1024 *   }
1025 *   else{
1026 *   return 1e18;
1027 *   }
1028 *   }
1029 *  
1030 *  
1035 *   template <>
1036 *   double InitialCondition<3, SINUSOID, PSUEDORANDOM>::value(
1037 *   const Point<3> &p,
1038 *   const unsigned int component) const
1039 *   {
1040 *   if(component == 0){
1041 *   double x_val = 0;
1042 *   double w_val = 0;
1043 *   double width = ((std::atan2(p(1),p(2)) - 3.1415926)/3.1415926)*18.84955592;
1044 *   for(int i=0; i < 10; ++i){
1045 *   x_val += x_sin_coefficients[i]*std::sin(2*3.141592653*p(0)/((i+1)*1.178097245));
1046 *   w_val += y_sin_coefficients[i]*std::sin(2*3.141592653*width/((i+1)*1.178097245));
1047 *   }
1048 *  
1049 *   return x_val*w_val;
1050 *   }
1051 *   else{
1052 *   return 1e18;
1053 *   }
1054 *   }
1055 *  
1056 *  
1061 *   template <>
1062 *   double InitialCondition<2, HYPERCUBE, RANDOM>::value(
1063 *   const Point<2> &/*p*/,
1064 *   const unsigned int component) const
1065 *   {
1066 *   if(component == 0){
1067 *   return 2*std::sqrt(r)*(std::rand()%10001)/10000 - std::sqrt(r);
1068 *   }
1069 *   else{
1070 *   return 1e18;
1071 *   }
1072 *   }
1073 *  
1074 *  
1079 *   template <>
1080 *   double InitialCondition<3, CYLINDER, RANDOM>::value(
1081 *   const Point<3> &/*p*/,
1082 *   const unsigned int component) const
1083 *   {
1084 *   if(component == 0){
1085 *   return 2*std::sqrt(r)*(std::rand()%10001)/10000 - std::sqrt(r);
1086 *   }
1087 *   else{
1088 *   return 1e18;
1089 *   }
1090 *   }
1091 *  
1092 *  
1097 *   template <>
1098 *   double InitialCondition<3, SPHERE, RANDOM>::value(
1099 *   const Point<3> &/*p*/,
1100 *   const unsigned int component) const
1101 *   {
1102 *   if(component == 0){
1103 *   return 2*std::sqrt(r)*(std::rand()%10001)/10000 - std::sqrt(r);
1104 *   }
1105 *   else{
1106 *   return 1e18;
1107 *   }
1108 *   }
1109 *  
1110 *  
1115 *   template <>
1116 *   double InitialCondition<3, TORUS, RANDOM>::value(
1117 *   const Point<3> &/*p*/,
1118 *   const unsigned int component) const
1119 *   {
1120 *   if(component == 0){
1121 *   return 2*std::sqrt(r)*(std::rand()%10001)/10000 - std::sqrt(r);
1122 *   }
1123 *   else{
1124 *   return 1e18;
1125 *   }
1126 *   }
1127 *  
1128 *  
1133 *   template <>
1134 *   double InitialCondition<3, SINUSOID, RANDOM>::value(
1135 *   const Point<3> &/*p*/,
1136 *   const unsigned int component) const
1137 *   {
1138 *   if(component == 0){
1139 *   return 2*std::sqrt(r)*(std::rand()%10001)/10000 - std::sqrt(r);
1140 *   }
1141 *   else{
1142 *   return 1e18;
1143 *   }
1144 *   }
1145 *  
1146 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1147 *   SHEquation<dim, spacedim, MESH, ICTYPE>::SHEquation()
1148 *   : degree(1)
1149 *   , fe(FE_Q<dim, spacedim>(degree), 2)
1150 *   , dof_handler(triangulation)
1151 *   , time_step(1. / 1500)
1152 *   , timestep_denominator(1500)
1153 *   , refinement_number(4)
1154 *   , r(0.5)
1155 *   , g1(0.5)
1156 *   , k(1.)
1157 *   , output_file_name("solution-")
1158 *   , end_time(0.5)
1159 *   {}
1160 *  
1161 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1162 *   SHEquation<dim, spacedim, MESH, ICTYPE>::SHEquation(const unsigned int degree,
1163 *   double time_step_denominator,
1164 *   unsigned int ref_num,
1165 *   double r_constant,
1166 *   double g1_constant,
1167 *   std::string output_file_name,
1168 *   double end_time)
1169 *   : degree(degree)
1170 *   , fe(FE_Q<dim, spacedim>(degree), 2)
1171 *   , dof_handler(triangulation)
1172 *   , time_step(1. / time_step_denominator)
1173 *   , timestep_denominator(time_step_denominator)
1174 *   , refinement_number(ref_num)
1175 *   , r(r_constant)
1176 *   , g1(g1_constant)
1177 *   , k(1.)
1178 *   , output_file_name(output_file_name)
1179 *   , end_time(end_time)
1180 *   {}
1181 *  
1182 *  
1189 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1190 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::setup_system()
1191 *   {
1192 *   dof_handler.distribute_dofs(fe);
1193 *  
1194 * @endcode
1195 *
1196 * Counts the DoF's for outputting to consolse
1197 *
1198 * @code
1199 *   const std::vector<types::global_dof_index> dofs_per_component =
1200 *   DoFTools::count_dofs_per_fe_component(dof_handler);
1201 *   const unsigned int n_u = dofs_per_component[0],
1202 *   n_v = dofs_per_component[1];
1203 *  
1204 *   std::cout << "Number of active cells: " << triangulation.n_active_cells()
1205 *   << std::endl
1206 *   << "Total number of cells: " << triangulation.n_cells()
1207 *   << std::endl
1208 *   << "Number of degrees of freedom: " << dof_handler.n_dofs()
1209 *   << " (" << n_u << '+' << n_v << ')' << std::endl;
1210 *  
1211 *   DynamicSparsityPattern dsp(dof_handler.n_dofs());
1212 *  
1213 *   DoFTools::make_sparsity_pattern(dof_handler,
1214 *   dsp);
1215 *   sparsity_pattern.copy_from(dsp);
1216 *  
1217 *   system_matrix.reinit(sparsity_pattern);
1218 *  
1219 *   solution.reinit(dof_handler.n_dofs());
1220 *   old_solution.reinit(dof_handler.n_dofs());
1221 *   system_rhs.reinit(dof_handler.n_dofs());
1222 *   }
1223 *  
1224 *  
1225 *   /** @brief Uses a direct solver to invert the system matrix, then multiplies the RHS vector by the inverted matrix to get the solution.
1226 *   * Also includes a timer feature, which is currently commented out, but can be helpful to compute how long a run will take
1227 *   * @tparam dim The dimension of the manifold
1228 *   * @tparam spacedim The dimension of the ambient space
1229 *   * @tparam MESH The type of mesh being used, doesn't change how this function works
1230 *   * @tparam ICTYPE The type of initial condition used, doesn't change how this function works
1231 *   */
1232 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1233 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::solve_time_step()
1234 *   {
1235 * @endcode
1236 *
1237 * std::cout << "Solving linear system" << std::endl;
1238 * Timer timer;
1239 *
1240
1241 *
1242 *
1243 * @code
1244 *   SparseDirectUMFPACK direct_solver;
1245 *  
1246 *   direct_solver.initialize(system_matrix);
1247 *  
1248 *   direct_solver.vmult(solution, system_rhs);
1249 *  
1250 * @endcode
1251 *
1252 * timer.stop();
1253 * std::cout << "done (" << timer.cpu_time() << " s)" << std::endl;
1254 *
1255 * @code
1256 *   }
1257 *  
1258 *  
1259 *  
1260 *   /** @brief Converts the solution vector into a .vtu file and labels the outputs as u and v
1261 *   * @tparam dim The dimension of the manifold
1262 *   * @tparam spacedim The dimension of the ambient space
1263 *   * @tparam MESH The type of mesh being used, doesn't change how this function works
1264 *   * @tparam ICTYPE The type of initial condition used, doesn't change how this function works
1265 *   */
1266 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1267 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::output_results() const
1268 *   {
1269 *   std::vector<std::string> solution_names(1, "u");
1270 *   solution_names.emplace_back("v");
1271 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
1272 *   interpretation(1,
1273 *   DataComponentInterpretation::component_is_scalar);
1274 *   interpretation.push_back(DataComponentInterpretation::component_is_scalar);
1275 *  
1276 *   DataOut<dim, spacedim> data_out;
1277 *   data_out.add_data_vector(dof_handler,
1278 *   solution,
1279 *   solution_names,
1280 *   interpretation /*,
1281 *   DataOut<dim, spacedim>::type_dof_data*/);
1282 *  
1283 *   data_out.build_patches(degree + 1);
1284 *  
1285 * @endcode
1286 *
1287 * Takes the output_file_name string and appends timestep_number with up to three leading 0's
1288 *
1289 * @code
1290 *   const std::string filename =
1291 *   output_file_name + Utilities::int_to_string(timestep_number, 3) + ".vtu";
1292 *  
1293 *   std::ofstream output(filename);
1294 *   data_out.write_vtu(output);
1295 *   }
1296 *  
1297 * @endcode
1298 *
1299 * Below are all the different template cases for the make_grid() function
1300 *
1301 * @code
1302 *   template <>
1303 *   void SHEquation<2, 2, HYPERCUBE, HOTSPOT>::make_grid()
1304 *   {
1305 *   make_hypercube();
1306 *   }
1307 *  
1308 *   template <>
1309 *   void SHEquation<2, 3, CYLINDER, HOTSPOT>::make_grid()
1310 *   {
1311 *   make_cylinder();
1312 *   }
1313 *  
1314 *   template <>
1315 *   void SHEquation<2, 3, SPHERE, HOTSPOT>::make_grid()
1316 *   {
1317 *   make_sphere();
1318 *   }
1319 *  
1320 *   template <>
1321 *   void SHEquation<2, 3, TORUS, HOTSPOT>::make_grid()
1322 *   {
1323 *   make_torus();
1324 *   }
1325 *  
1326 *   template <>
1327 *   void SHEquation<2, 3, SINUSOID, HOTSPOT>::make_grid()
1328 *   {
1329 *   make_sinusoid();
1330 *   }
1331 *  
1332 *   template <>
1333 *   void SHEquation<2, 2, HYPERCUBE, PSUEDORANDOM>::make_grid()
1334 *   {
1335 *   make_hypercube();
1336 *   }
1337 *  
1338 *   template <>
1339 *   void SHEquation<2, 3, CYLINDER, PSUEDORANDOM>::make_grid()
1340 *   {
1341 *   make_cylinder();
1342 *   }
1343 *  
1344 *   template <>
1345 *   void SHEquation<2, 3, SPHERE, PSUEDORANDOM>::make_grid()
1346 *   {
1347 *   make_sphere();
1348 *   }
1349 *  
1350 *   template <>
1351 *   void SHEquation<2, 3, TORUS, PSUEDORANDOM>::make_grid()
1352 *   {
1353 *   make_torus();
1354 *   }
1355 *  
1356 *   template <>
1357 *   void SHEquation<2, 3, SINUSOID, PSUEDORANDOM>::make_grid()
1358 *   {
1359 *   make_sinusoid();
1360 *   }
1361 *  
1362 *   template <>
1363 *   void SHEquation<2, 2, HYPERCUBE, RANDOM>::make_grid()
1364 *   {
1365 *   make_hypercube();
1366 *   }
1367 *  
1368 *   template <>
1369 *   void SHEquation<2, 3, CYLINDER, RANDOM>::make_grid()
1370 *   {
1371 *   make_cylinder();
1372 *   }
1373 *  
1374 *   template <>
1375 *   void SHEquation<2, 3, SPHERE, RANDOM>::make_grid()
1376 *   {
1377 *   make_sphere();
1378 *   }
1379 *  
1380 *   template <>
1381 *   void SHEquation<2, 3, TORUS, RANDOM>::make_grid()
1382 *   {
1383 *   make_torus();
1384 *   }
1385 *  
1386 *   template <>
1387 *   void SHEquation<2, 3, SINUSOID, RANDOM>::make_grid()
1388 *   {
1389 *   make_sinusoid();
1390 *   }
1391 *  
1392 *  
1393 *  
1400 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1401 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::run()
1402 *   {
1403 *   make_grid();
1404 *  
1405 *   setup_system();
1406 *  
1407 * @endcode
1408 *
1409 * Counts total time elapsed
1410 *
1411 * @code
1412 *   time = 0.0;
1413 * @endcode
1414 *
1415 * Counts number of iterations
1416 *
1417 * @code
1418 *   timestep_number = 0;
1419 *  
1420 * @endcode
1421 *
1422 * Sets the random seed so runs are repeatable, remove for varying random initial conditions
1423 *
1424 * @code
1425 *   std::srand(314);
1426 *  
1427 *   InitialCondition<spacedim, MESH, ICTYPE> initial_conditions(r, 0.5);
1428 *  
1429 * @endcode
1430 *
1431 * Applies the initial conditions to the old_solution
1432 *
1433 * @code
1434 *   VectorTools::interpolate(dof_handler,
1435 *   initial_conditions,
1436 *   old_solution);
1437 *   solution = old_solution;
1438 *  
1439 * @endcode
1440 *
1441 * Outputs initial solution
1442 *
1443 * @code
1444 *   output_results();
1445 *  
1446 * @endcode
1447 *
1448 * Sets up the quadrature formula and FEValues object
1449 *
1450 * @code
1451 *   const QGauss<dim> quadrature_formula(degree + 2);
1452 *  
1453 *   FEValues<dim, spacedim> fe_values(fe, quadrature_formula,
1456 *  
1457 *   const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
1458 *  
1459 *   FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
1460 *   Vector<double> cell_rhs(dofs_per_cell);
1461 *  
1462 * @endcode
1463 *
1464 * The vector which stores the global indices that each local index connects to
1465 *
1466 * @code
1467 *   std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1468 *  
1469 * @endcode
1470 *
1471 * Extracts the finite elements associated to u and v
1472 *
1473 * @code
1474 *   const FEValuesExtractors::Scalar u(0);
1475 *   const FEValuesExtractors::Scalar v(1);
1476 *  
1477 * @endcode
1478 *
1479 * Loops over the cells to create the system matrix. We do this only once because the timestep is constant
1480 *
1481 * @code
1482 *   for(const auto &cell : dof_handler.active_cell_iterators()){
1483 *   cell_matrix = 0;
1484 *   cell_rhs = 0;
1485 *  
1486 *   fe_values.reinit(cell);
1487 *  
1488 *   cell->get_dof_indices(local_dof_indices);
1489 *  
1490 *   for(const unsigned int q_index : fe_values.quadrature_point_indices()){
1491 *  
1492 *   for(const unsigned int i : fe_values.dof_indices()){
1493 * @endcode
1494 *
1495 * These are the ith finite elements associated to u and v
1496 *
1497 * @code
1498 *   const double phi_i_u = fe_values[u].value(i, q_index);
1499 *   const Tensor<1, spacedim> grad_phi_i_u = fe_values[u].gradient(i, q_index);
1500 *   const double phi_i_v = fe_values[v].value(i, q_index);
1501 *   const Tensor<1, spacedim> grad_phi_i_v = fe_values[v].gradient(i, q_index);
1502 *  
1503 *   for(const unsigned int j : fe_values.dof_indices())
1504 *   {
1505 * @endcode
1506 *
1507 * These are the jth finite elements associated to u and v
1508 *
1509 * @code
1510 *   const double phi_j_u = fe_values[u].value(j, q_index);
1511 *   const Tensor<1, spacedim> grad_phi_j_u = fe_values[u].gradient(j, q_index);
1512 *   const double phi_j_v = fe_values[v].value(j, q_index);
1513 *   const Tensor<1, spacedim> grad_phi_j_v = fe_values[v].gradient(j, q_index);
1514 *  
1515 * @endcode
1516 *
1517 * This formula comes from expanding the PDE system
1518 *
1519 * @code
1520 *   cell_matrix(i, j) += (phi_i_u*phi_j_u - time_step*r*phi_i_u*phi_j_u
1521 *   + time_step*phi_i_u*phi_j_v - time_step*grad_phi_i_u*grad_phi_j_v
1522 *   + phi_i_v*phi_j_u - grad_phi_i_v*grad_phi_j_u
1523 *   - phi_i_v*phi_j_v)*fe_values.JxW(q_index);
1524 *   }
1525 *   }
1526 *   }
1527 *  
1528 * @endcode
1529 *
1530 * Loops over the dof indices to fill the entries of the system_matrix with the local data
1531 *
1532 * @code
1533 *   for(unsigned int i : fe_values.dof_indices()){
1534 *   for(unsigned int j : fe_values.dof_indices()){
1535 *   system_matrix.add(local_dof_indices[i],
1536 *   local_dof_indices[j],
1537 *   cell_matrix(i, j));
1538 *   }
1539 *   }
1540 *   }
1541 *  
1542 * @endcode
1543 *
1544 * Loops over time, incrementing by timestep, to create the RHS, solve the linear system, then output the result
1545 *
1546 * @code
1547 *   while (time <= end_time)
1548 *   {
1549 * @endcode
1550 *
1551 * Increments time and timestep_number
1552 *
1553 * @code
1554 *   time += time_step;
1555 *   ++timestep_number;
1556 *  
1557 * @endcode
1558 *
1559 * Outputs to console the number of iterations and current time. Currently outputs once every "second"
1560 *
1561 * @code
1562 *   if(timestep_number%timestep_denominator == 0){
1563 *   std::cout << "Time step " << timestep_number << " at t=" << time
1564 *   << std::endl;
1565 *   }
1566 *  
1567 * @endcode
1568 *
1569 * Resets the system_rhs vector. THIS IS VERY IMPORTANT TO ENSURE THE SYSTEM IS SOLVED CORRECTLY AT EACH TIMESTEP
1570 *
1571 * @code
1572 *   system_rhs = 0;
1573 *  
1574 * @endcode
1575 *
1576 * Loops over cells, then quadrature points, then dof indices to construct the RHS
1577 *
1578 * @code
1579 *   for(const auto &cell : dof_handler.active_cell_iterators()){
1580 * @endcode
1581 *
1582 * Resets the cell_rhs. THIS IS ALSO VERY IMPORTANT TO ENSURE THE SYSTEM IS SOLVED CORRECTLY
1583 *
1584 * @code
1585 *   cell_rhs = 0;
1586 *  
1587 * @endcode
1588 *
1589 * Resets the FEValues object to only the current cell
1590 *
1591 * @code
1592 *   fe_values.reinit(cell);
1593 *  
1594 *   cell->get_dof_indices(local_dof_indices);
1595 *  
1596 * @endcode
1597 *
1598 * Loop over the quadrature points
1599 *
1600 * @code
1601 *   for(const unsigned int q_index : fe_values.quadrature_point_indices()){
1602 * @endcode
1603 *
1604 * Stores the value of the previous solution at the quadrature point
1605 *
1606 * @code
1607 *   double Un1 = 0;
1608 *  
1609 * @endcode
1610 *
1611 * Loops over the dof indices to get the value of Un1
1612 *
1613 * @code
1614 *   for(const unsigned int i : fe_values.dof_indices()){
1615 *   Un1 += old_solution(local_dof_indices[i])*fe_values[u].value(i, q_index);
1616 *   }
1617 *  
1618 * @endcode
1619 *
1620 * Loops over the dof indices, using Un1 to construct the RHS for the current timestep. Un1 is used to account for the nonlinear terms in the SH equation
1621 *
1622 * @code
1623 *   for(const unsigned int i : fe_values.dof_indices()){
1624 *   cell_rhs(i) += (Un1 + time_step*g1*std::pow(Un1, 2) - time_step*k*std::pow(Un1, 3))
1625 *   *fe_values[u].value(i, q_index)*fe_values.JxW(q_index);
1626 *   }
1627 *   }
1628 *  
1629 * @endcode
1630 *
1631 * Loops over the dof indices to store the local data in the global RHS vector
1632 *
1633 * @code
1634 *   for(unsigned int i : fe_values.dof_indices()){
1635 *   system_rhs(local_dof_indices[i]) += cell_rhs(i);
1636 *   }
1637 *  
1638 *  
1639 *   }
1640 * @endcode
1641 *
1642 * This is where Dirichlet conditions are applied, or Neumann conditions if the code is commented out
1643 *
1644 * @code
1645 *   /* {
1646 *   BoundaryValues<spacedim> boundary_values_function;
1647 *   boundary_values_function.set_time(time);
1648 *  
1649 *   std::map<types::global_dof_index, double> boundary_values;
1650 *   VectorTools::interpolate_boundary_values(dof_handler,
1651 *   0,
1652 *   boundary_values_function,
1653 *   boundary_values);
1654 *  
1655 *   MatrixTools::apply_boundary_values(boundary_values,
1656 *   system_matrix,
1657 *   solution,
1658 *   system_rhs);
1659 *   } */
1660 *  
1661 *   solve_time_step();
1662 *  
1663 * @endcode
1664 *
1665 * Outputs the solution at regular intervals, currently once every "second" The SH equation evolves slowly in time, so this saves disk space
1666 *
1667 * @code
1668 *   if(timestep_number%timestep_denominator == 0){
1669 *   output_results();
1670 *   }
1671 *  
1672 *   old_solution = solution;
1673 *   }
1674 *   }
1675 *  
1676 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1677 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::make_cylinder()
1678 *   {
1679 * @endcode
1680 *
1681 * Creates a volumetric cylinder
1682 *
1683 * @code
1685 *   GridGenerator::cylinder(cylinder, 6, 18.84955592);
1686 *  
1687 * @endcode
1688 *
1689 * Extracts the boundary mesh with ID 0, which happens to be the tube part of the cylinder
1690 *
1691 * @code
1693 *  
1694 * @endcode
1695 *
1696 * The manifold information is lost upon boundary extraction. This sets the mesh boundary type to be a cylinder again
1697 *
1698 * @code
1699 *   const CylindricalManifold<dim, spacedim> boundary;
1700 *   triangulation.set_all_manifold_ids(0);
1701 *   triangulation.set_manifold(0, boundary);
1702 *  
1703 *   triangulation.refine_global(refinement_number);
1704 *   }
1705 *  
1706 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1707 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::make_sinusoid()
1708 *   {
1709 * @endcode
1710 *
1711 * Same process as above
1712 *
1713 * @code
1715 *   GridGenerator::cylinder(cylinder, 6, 18.84955592);
1716 *  
1718 *  
1719 *   const CylindricalManifold<dim, spacedim> boundary;
1720 *   triangulation.set_all_manifold_ids(0);
1721 *   triangulation.set_manifold(0, boundary);
1722 *  
1723 *   triangulation.refine_global(refinement_number);
1724 *  
1725 * @endcode
1726 *
1727 * We warp the mesh after refinement to avoid a jagged mesh. We can't tell the code that the boundary should be a perfect sine wave, so we only warp after the
1728 * mesh is fine enough to resolve this
1729 *
1730 * @code
1731 *   GridTools::transform(transform_function<spacedim>, triangulation);
1732 *   }
1733 *  
1734 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1735 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::make_sphere()
1736 *   {
1737 *   GridGenerator::hyper_sphere(triangulation, Point<3>(0, 0, 0), 18.41988074);
1738 *   triangulation.refine_global(refinement_number);
1739 *   }
1740 *  
1741 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1742 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::make_torus()
1743 *   {
1744 *   GridGenerator::torus(triangulation, 9., 4.);
1745 *   triangulation.refine_global(refinement_number);
1746 *   }
1747 *   template <int dim, int spacedim, MeshType MESH, InitialConditionType ICTYPE>
1748 *   void SHEquation<dim, spacedim, MESH, ICTYPE>::make_hypercube()
1749 *   {
1750 *   GridGenerator::hyper_cube(triangulation, -18.84955592, 18.84955592);
1751 *   triangulation.refine_global(refinement_number);
1752 *   }
1753 *   } // namespace SwiftHohenbergSolver
1754 *  
1755 *  
1756 *  
1757 *   int main()
1758 *   {
1759 *   using namespace SwiftHohenbergSolver;
1760 *  
1761 * @endcode
1762 *
1763 * An array of mesh types. We iterate over this to allow for longer runs without having to stop the code
1764 *
1765 * @code
1766 *   MeshType mesh_types[5] = {HYPERCUBE, CYLINDER, SPHERE, TORUS, SINUSOID};
1767 * @endcode
1768 *
1769 * An array of initial condition types. We iterate this as well, for the same reason
1770 *
1771 * @code
1772 *   InitialConditionType ic_types[3] = {HOTSPOT, PSUEDORANDOM, RANDOM};
1773 *  
1774 * @endcode
1775 *
1776 * Controls how long the code runs
1777 *
1778 * @code
1779 *   const double end_time = 100.;
1780 *  
1781 * @endcode
1782 *
1783 * The number of times we refine the hypercube mesh
1784 *
1785 * @code
1786 *   const unsigned int ref_num = 6;
1787 *  
1788 * @endcode
1789 *
1790 * The timestep will be 1/timestep_denominator
1791 *
1792 * @code
1793 *   const unsigned int timestep_denominator = 25;
1794 *  
1795 * @endcode
1796 *
1797 * Loops over mesh types, then initial condition types, then loops over values of g_1
1798 *
1799 * @code
1800 *   for(const auto MESH : mesh_types){
1801 *   for(const auto ICTYPE: ic_types){
1802 *   for(int i = 0; i < 8; ++i){
1803 * @endcode
1804 *
1805 * The value of g_1 passed to the solver object
1806 *
1807 * @code
1808 *   const double g_constant = 0.2*i;
1809 *  
1810 * @endcode
1811 *
1812 * Used to distinguish the start of each run
1813 *
1814 * @code
1815 *   std::cout<< std::endl << std::endl;
1816 *  
1817 *   try{
1818 * @endcode
1819 *
1820 * Switch statement that determines what template parameters are used by the solver object. Template parameters must be known at compile time, so we cannot
1821 * pass this as a variable unfortunately. In each case, we create a filename string (named appropriately for the particular case), output to the console what
1822 * we are running, create the solver object, and call run(). Note that for the cylinder, sphere, and sinusoid we decrease the refinement number by 1. This keeps
1823 * the number of dofs used in these cases comparable to the number of dofs on the 2D hypercube (otherwise the number of dofs is much larger). For the torus, we
1824 * decrease the refinement number by 2.
1825 *
1826 * @code
1827 *   switch (MESH)
1828 *   {
1829 *   case HYPERCUBE:
1830 *   switch (ICTYPE){
1831 *   case HOTSPOT:
1832 *   {
1833 *   std::string filename = "HYPERCUBE-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1834 *   std::cout << "Running: " << filename << std::endl << std::endl;
1835 *  
1836 *   SHEquation<2, 2, HYPERCUBE, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1837 *   ref_num, 0.3, g_constant,
1838 *   filename, end_time);
1839 *   heat_equation_solver.run();
1840 *   }
1841 *   break;
1842 *  
1843 *   case PSUEDORANDOM:
1844 *   {
1845 *   std::string filename = "HYPERCUBE-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1846 *   std::cout << "Running: " << filename << std::endl << std::endl;
1847 *  
1848 *   SHEquation<2, 2, HYPERCUBE, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1849 *   ref_num, 0.3, g_constant,
1850 *   filename, end_time);
1851 *   heat_equation_solver.run();
1852 *   }
1853 *   break;
1854 *  
1855 *   case RANDOM:
1856 *   {
1857 *   std::string filename = "HYPERCUBE-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1858 *   std::cout << "Running: " << filename << std::endl << std::endl;
1859 *  
1860 *   SHEquation<2, 2, HYPERCUBE, RANDOM> heat_equation_solver(1, timestep_denominator,
1861 *   ref_num, 0.3, g_constant,
1862 *   filename, end_time);
1863 *   heat_equation_solver.run();
1864 *   }
1865 *   break;
1866 *   }
1867 *   break;
1868 *   case CYLINDER:
1869 *   switch (ICTYPE){
1870 *   case HOTSPOT:
1871 *   {
1872 *   std::string filename = "CYLINDER-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1873 *   std::cout << "Running: " << filename << std::endl << std::endl;
1874 *  
1875 *   SHEquation<2, 3, CYLINDER, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1876 *   ref_num-1, 0.3, g_constant,
1877 *   filename, end_time);
1878 *   heat_equation_solver.run();
1879 *   }
1880 *   break;
1881 *  
1882 *   case PSUEDORANDOM:
1883 *   {
1884 *   std::string filename = "CYLINDER-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1885 *   std::cout << "Running: " << filename << std::endl << std::endl;
1886 *  
1887 *   SHEquation<2, 3, CYLINDER, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1888 *   ref_num-1, 0.3, g_constant,
1889 *   filename, end_time);
1890 *   heat_equation_solver.run();
1891 *   }
1892 *   break;
1893 *  
1894 *   case RANDOM:
1895 *   {
1896 *   std::string filename = "CYLINDER-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1897 *   std::cout << "Running: " << filename << std::endl << std::endl;
1898 *  
1899 *   SHEquation<2, 3, CYLINDER, RANDOM> heat_equation_solver(1, timestep_denominator,
1900 *   ref_num-1, 0.3, g_constant,
1901 *   filename, end_time);
1902 *   heat_equation_solver.run();
1903 *   }
1904 *   break;
1905 *   }
1906 *   break;
1907 *   case SPHERE:
1908 *   switch (ICTYPE){
1909 *   case HOTSPOT:
1910 *   {
1911 *   std::string filename = "SPHERE-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1912 *   std::cout << "Running: " << filename << std::endl << std::endl;
1913 *  
1914 *   SHEquation<2, 3, SPHERE, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1915 *   ref_num-1, 0.3, g_constant,
1916 *   filename, end_time);
1917 *   heat_equation_solver.run();
1918 *   }
1919 *   break;
1920 *  
1921 *   case PSUEDORANDOM:
1922 *   {
1923 *   std::string filename = "SPHERE-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1924 *   std::cout << "Running: " << filename << std::endl << std::endl;
1925 *  
1926 *   SHEquation<2, 3, SPHERE, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1927 *   ref_num-1, 0.3, g_constant,
1928 *   filename, end_time);
1929 *   heat_equation_solver.run();
1930 *   }
1931 *   break;
1932 *  
1933 *   case RANDOM:
1934 *   {
1935 *   std::string filename = "SPHERE-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1936 *   std::cout << "Running: " << filename << std::endl << std::endl;
1937 *  
1938 *   SHEquation<2, 3, SPHERE, RANDOM> heat_equation_solver(1, timestep_denominator,
1939 *   ref_num-1, 0.3, g_constant,
1940 *   filename, end_time);
1941 *   heat_equation_solver.run();
1942 *   }
1943 *   break;
1944 *   }
1945 *   break;
1946 *   case TORUS:
1947 *   switch (ICTYPE){
1948 *   case HOTSPOT:
1949 *   {
1950 *   std::string filename = "TORUS-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1951 *   std::cout << "Running: " << filename << std::endl << std::endl;
1952 *  
1953 *   SHEquation<2, 3, TORUS, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1954 *   ref_num-2, 0.3, g_constant,
1955 *   filename, end_time);
1956 *   heat_equation_solver.run();
1957 *   }
1958 *   break;
1959 *  
1960 *   case PSUEDORANDOM:
1961 *   {
1962 *   std::string filename = "TORUS-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1963 *   std::cout << "Running: " << filename << std::endl << std::endl;
1964 *  
1965 *   SHEquation<2, 3, TORUS, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
1966 *   ref_num-2, 0.3, g_constant,
1967 *   filename, end_time);
1968 *   heat_equation_solver.run();
1969 *   }
1970 *   break;
1971 *  
1972 *   case RANDOM:
1973 *   {
1974 *   std::string filename = "TORUS-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1975 *   std::cout << "Running: " << filename << std::endl << std::endl;
1976 *  
1977 *   SHEquation<2, 3, TORUS, RANDOM> heat_equation_solver(1, timestep_denominator,
1978 *   ref_num-2, 0.3, g_constant,
1979 *   filename, end_time);
1980 *   heat_equation_solver.run();
1981 *   }
1982 *   break;
1983 *   }
1984 *   break;
1985 *   case SINUSOID:
1986 *   switch (ICTYPE){
1987 *   case HOTSPOT:
1988 *   {
1989 *   std::string filename = "SINUSOID-HOTSPOT-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
1990 *   std::cout << "Running: " << filename << std::endl << std::endl;
1991 *  
1992 *   SHEquation<2, 3, SINUSOID, HOTSPOT> heat_equation_solver(1, timestep_denominator,
1993 *   ref_num-1, 0.3, g_constant,
1994 *   filename, end_time);
1995 *   heat_equation_solver.run();
1996 *   }
1997 *   break;
1998 *  
1999 *   case PSUEDORANDOM:
2000 *   {
2001 *   std::string filename = "SINUSOID-PSUEDORANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
2002 *   std::cout << "Running: " << filename << std::endl << std::endl;
2003 *  
2004 *   SHEquation<2, 3, SINUSOID, PSUEDORANDOM> heat_equation_solver(1, timestep_denominator,
2005 *   ref_num-1, 0.3, g_constant,
2006 *   filename, end_time);
2007 *   heat_equation_solver.run();
2008 *   }
2009 *   break;
2010 *  
2011 *   case RANDOM:
2012 *   {
2013 *   std::string filename = "SINUSOID-RANDOM-G1-0.2x" + Utilities::int_to_string(i, 1) + "-";
2014 *   std::cout << "Running: " << filename << std::endl << std::endl;
2015 *  
2016 *   SHEquation<2, 3, SINUSOID, RANDOM> heat_equation_solver(1, timestep_denominator,
2017 *   ref_num-1, 0.3, g_constant,
2018 *   filename, end_time);
2019 *   heat_equation_solver.run();
2020 *   }
2021 *   break;
2022 *   }
2023 *   break;
2024 *   default:
2025 *   break;
2026 *   }
2027 *   }
2028 *   catch (std::exception &exc)
2029 *   {
2030 *   std::cout << "An error occurred" << std::endl;
2031 *   std::cerr << std::endl
2032 *   << std::endl
2033 *   << "----------------------------------------------------"
2034 *   << std::endl;
2035 *   std::cerr << "Exception on processing: " << std::endl
2036 *   << exc.what() << std::endl
2037 *   << "Aborting!" << std::endl
2038 *   << "----------------------------------------------------"
2039 *   << std::endl;
2040 *  
2041 *   return 1;
2042 *   }
2043 *   catch (...)
2044 *   {
2045 *   std::cout << "Error occurred, made it past first catch" << std::endl;
2046 *   std::cerr << std::endl
2047 *   << std::endl
2048 *   << "----------------------------------------------------"
2049 *   << std::endl;
2050 *   std::cerr << "Unknown exception!" << std::endl
2051 *   << "Aborting!" << std::endl
2052 *   << "----------------------------------------------------"
2053 *   << std::endl;
2054 *   return 1;
2055 *   }
2056 *   }
2057 *   }
2058 *   }
2059 *   return 0;
2060 *   }
2061 * @endcode
2062
2063
2064*/
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
Definition fe_q.h:554
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
Definition point.h:111
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
std::vector< index_type > data
Definition mpi.cc:735
const Event initial
Definition event.cc:64
void random(DoFHandler< dim, spacedim > &dof_handler)
void cylinder(Triangulation< dim > &tria, const double radius=1., const double half_length=1.)
return_type extract_boundary_mesh(const MeshType< dim, spacedim > &volume_mesh, MeshType< dim - 1, spacedim > &surface_mesh, const std::set< types::boundary_id > &boundary_ids=std::set< types::boundary_id >())
void torus(Triangulation< dim, spacedim > &tria, const double centerline_radius, const double inner_radius, const unsigned int n_cells_toroidal=6, const double phi=2.0 *numbers::PI)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void shift(const Tensor< 1, spacedim > &shift_vector, Triangulation< dim, spacedim > &triangulation)
@ matrix
Contents is actually a matrix.
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
Definition advection.h:74
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition utilities.cc:191
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition utilities.cc:470
void interpolate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Function< spacedim, typename VectorType::value_type > &function, VectorType &vec, const ComponentMask &component_mask={}, const unsigned int level=numbers::invalid_unsigned_int)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation