deal.II version GIT relicensing-6750-g1dc21bc838 2026-09-15 17:20:01+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
L-BFGS-phasefield-solver.h
Go to the documentation of this file.
1
778 *  
779 *   /* A monolithic scheme based on the L-BFGS method to solve the phase-field crack problem
780 *   * 1. The phase-field formulation itself is based on "A phase field model for rate-independent
781 *   * crack propagation - Robust algorithmic implementation based on operator splits"
782 *   * by Christian Miehe , Martina Hofacker, Fabian Welschinger
783 *   * 2. This code implements a monolithic approach. The phase-field irreversibility
784 *   * is enforced through the history field Phi_0^+ and the viscosity parameter.
785 *   * 3. Using TBB for stiffness assembly and Gauss point calculation.
786 *   * 4. Using adaptive mesh refinement.
787 *   */
788 *  
789 *   #include <deal.II/grid/tria.h>
790 *   #include <deal.II/grid/grid_generator.h>
791 *   #include <deal.II/grid/grid_refinement.h>
792 *   #include <deal.II/grid/grid_out.h>
793 *   #include <deal.II/grid/grid_in.h>
794 *   #include <deal.II/grid/manifold_lib.h>
795 *  
796 *   #include <deal.II/dofs/dof_handler.h>
797 *   #include <deal.II/dofs/dof_tools.h>
798 *   #include <deal.II/dofs/dof_renumbering.h>
799 *  
800 *   #include <deal.II/fe/fe_values.h>
801 *   #include <deal.II/fe/fe_system.h>
802 *   #include <deal.II/fe/fe_q.h>
803 *   #include <deal.II/fe/fe_dgp_monomial.h>
804 *   #include <deal.II/fe/mapping_q_eulerian.h>
805 *  
806 *   #include <deal.II/base/timer.h>
807 *   #include <deal.II/base/quadrature_point_data.h>
808 *   #include <deal.II/base/parameter_handler.h>
809 *  
810 *   #include <deal.II/lac/affine_constraints.h>
811 *   #include <deal.II/lac/vector.h>
812 *   #include <deal.II/lac/full_matrix.h>
813 *   #include <deal.II/lac/sparse_matrix.h>
814 *   #include <deal.II/lac/dynamic_sparsity_pattern.h>
815 *   #include <deal.II/lac/block_sparse_matrix.h>
816 *   #include <deal.II/lac/block_vector.h>
817 *  
818 *  
819 *   #include <deal.II/numerics/vector_tools.h>
820 *   #include <deal.II/numerics/matrix_tools.h>
821 *   #include <deal.II/numerics/data_out.h>
822 *  
823 *   #include <deal.II/lac/solver_cg.h>
824 *   #include <deal.II/lac/precondition.h>
825 *   #include <deal.II/lac/linear_operator.h>
826 *   #include <deal.II/lac/packaged_operation.h>
827 *   #include <deal.II/lac/precondition_selector.h>
828 *   #include <deal.II/lac/solver_selector.h>
829 *   #include <deal.II/lac/sparse_direct.h>
830 *  
831 *   #include <deal.II/numerics/error_estimator.h>
832 *  
833 *   #include <deal.II/physics/elasticity/standard_tensors.h>
834 *  
835 *   #include <deal.II/base/quadrature_point_data.h>
836 *  
837 *   #include <deal.II/grid/grid_tools.h>
838 *  
839 *   #include <deal.II/base/work_stream.h>
840 *  
841 *   #include <deal.II/numerics/solution_transfer.h>
842 *  
843 *   #include <fstream>
844 *   #include <iostream>
845 *   #include <deal.II/base/logstream.h>
846 *  
847 *   #include "SpectrumDecomposition.h"
848 *   #include "Utilities.h"
849 *  
850 *   namespace PhaseField
851 *   {
852 *   using namespace dealii;
853 *  
854 * @endcode
855 *
856 * body force
857 *
858 * @code
859 *   template <int dim>
860 *   void right_hand_side(const std::vector<Point<dim>> &points,
861 *   std::vector<Tensor<1, dim>> & values,
862 *   const double fx,
863 *   const double fy,
864 *   const double fz)
865 *   {
866 *   Assert(values.size() == points.size(),
867 *   ExcDimensionMismatch(values.size(), points.size()));
868 *   Assert(dim >= 2, ExcNotImplemented());
869 *  
870 *   for (unsigned int point_n = 0; point_n < points.size(); ++point_n)
871 *   {
872 *   if (dim == 2)
873 *   {
874 *   values[point_n][0] = fx;
875 *   values[point_n][1] = fy;
876 *   }
877 *   else
878 *   {
879 *   values[point_n][0] = fx;
880 *   values[point_n][1] = fy;
881 *   values[point_n][2] = fz;
882 *   }
883 *   }
884 *   }
885 *  
886 *   double degradation_function(const double d)
887 *   {
888 *   return (1.0 - d) * (1.0 - d);
889 *   }
890 *  
891 *   double degradation_function_derivative(const double d)
892 *   {
893 *   return 2.0 * (d - 1.0);
894 *   }
895 *  
896 *   double degradation_function_2nd_order_derivative(const double d)
897 *   {
898 *   (void) d;
899 *   return 2.0;
900 *   }
901 *  
902 *   namespace Parameters
903 *   {
904 *   struct Scenario
905 *   {
906 *   unsigned int m_scenario;
907 *   std::string m_logfile_name;
908 *   bool m_output_iteration_history;
909 *   std::string m_type_nonlinear_solver;
910 *   std::string m_type_line_search;
911 *   std::string m_type_linear_solver;
912 *   std::string m_refinement_strategy;
913 *   unsigned int m_LBFGS_m;
914 *   unsigned int m_global_refine_times;
915 *   unsigned int m_local_prerefine_times;
916 *   unsigned int m_max_adaptive_refine_times;
917 *   int m_max_allowed_refinement_level;
918 *   double m_phasefield_refine_threshold;
919 *   double m_allowed_max_h_l_ratio;
920 *   unsigned int m_total_material_regions;
921 *   std::string m_material_file_name;
922 *   int m_reaction_force_face_id;
923 *  
924 *   static void declare_parameters(ParameterHandler &prm);
925 *   void parse_parameters(ParameterHandler &prm);
926 *   };
927 *  
928 *   void Scenario::declare_parameters(ParameterHandler &prm)
929 *   {
930 *   prm.enter_subsection("Scenario");
931 *   {
932 *   prm.declare_entry("Scenario number",
933 *   "1",
935 *   "Geometry, loading and boundary conditions scenario");
936 *  
937 *   prm.declare_entry("Log file name",
938 *   "Output.log",
940 *   "Name of the file for log");
941 *  
942 *   prm.declare_entry("Output iteration history",
943 *   "yes",
944 *   Patterns::Selection("yes|no"),
945 *   "Shall we write iteration history to the log file?");
946 *  
947 *   prm.declare_entry("Nonlinear solver type",
948 *   "Newton",
949 *   Patterns::Selection("Newton|BFGS|LBFGS"),
950 *   "Type of solver used to solve the nonlinear system");
951 *  
952 *   prm.declare_entry("Line search type",
953 *   "GradientBased",
954 *   Patterns::Selection("GradientBased|StrongWolfe"),
955 *   "Type of line search method, the gradient-based method "
956 *   "should be preferred since it is generally faster");
957 *  
958 *   prm.declare_entry("Linear solver type",
959 *   "Direct",
960 *   Patterns::Selection("Direct|CG"),
961 *   "Type of solver used to solve the linear system B0");
962 *  
963 *   prm.declare_entry("Mesh refinement strategy",
964 *   "adaptive-refine",
965 *   Patterns::Selection("pre-refine|adaptive-refine"),
966 *   "Mesh refinement strategy: pre-refine or adaptive-refine");
967 *  
968 *   prm.declare_entry("LBFGS m",
969 *   "40",
971 *   "Number of vectors used for LBFGS");
972 *  
973 *   prm.declare_entry("Global refinement times",
974 *   "0",
976 *   "Global refinement times (across the entire domain)");
977 *  
978 *   prm.declare_entry("Local prerefinement times",
979 *   "0",
981 *   "Local pre-refinement times (assume crack path is known a priori), "
982 *   "only refine along the crack path.");
983 *  
984 *   prm.declare_entry("Max adaptive refinement times",
985 *   "100",
987 *   "Maximum number of adaptive refinement times allowed in each step");
988 *  
989 *   prm.declare_entry("Max allowed refinement level",
990 *   "100",
992 *   "Maximum allowed cell refinement level");
993 *  
994 *   prm.declare_entry("Phasefield refine threshold",
995 *   "0.8",
997 *   "Phasefield-based refinement threshold value");
998 *  
999 *   prm.declare_entry("Allowed max hl ratio",
1000 *   "0.25",
1001 *   Patterns::Double(),
1002 *   "Allowed maximum ratio between mesh size h and length scale l");
1003 *  
1004 *   prm.declare_entry("Material regions",
1005 *   "1",
1006 *   Patterns::Integer(0),
1007 *   "Number of material regions");
1008 *  
1009 *   prm.declare_entry("Material data file",
1010 *   "1",
1012 *   "Material data file");
1013 *  
1014 *   prm.declare_entry("Reaction force face ID",
1015 *   "1",
1017 *   "Face id where reaction forces should be calculated "
1018 *   "(negative integer means not to calculate reaction force)");
1019 *   }
1020 *   prm.leave_subsection();
1021 *   }
1022 *  
1023 *   void Scenario::parse_parameters(ParameterHandler &prm)
1024 *   {
1025 *   prm.enter_subsection("Scenario");
1026 *   {
1027 *   m_scenario = prm.get_integer("Scenario number");
1028 *   m_logfile_name = prm.get("Log file name");
1029 *   m_output_iteration_history = prm.get_bool("Output iteration history");
1030 *   m_type_nonlinear_solver = prm.get("Nonlinear solver type");
1031 *   m_type_line_search = prm.get("Line search type");
1032 *   m_type_linear_solver = prm.get("Linear solver type");
1033 *   m_refinement_strategy = prm.get("Mesh refinement strategy");
1034 *   m_LBFGS_m = prm.get_integer("LBFGS m");
1035 *   m_global_refine_times = prm.get_integer("Global refinement times");
1036 *   m_local_prerefine_times = prm.get_integer("Local prerefinement times");
1037 *   m_max_adaptive_refine_times = prm.get_integer("Max adaptive refinement times");
1038 *   m_max_allowed_refinement_level = prm.get_integer("Max allowed refinement level");
1039 *   m_phasefield_refine_threshold = prm.get_double("Phasefield refine threshold");
1040 *   m_allowed_max_h_l_ratio = prm.get_double("Allowed max hl ratio");
1041 *   m_total_material_regions = prm.get_integer("Material regions");
1042 *   m_material_file_name = prm.get("Material data file");
1043 *   m_reaction_force_face_id = prm.get_integer("Reaction force face ID");
1044 *   }
1045 *   prm.leave_subsection();
1046 *   }
1047 *  
1048 *   struct FESystem
1049 *   {
1050 *   unsigned int m_poly_degree;
1051 *   unsigned int m_quad_order;
1052 *  
1053 *   static void declare_parameters(ParameterHandler &prm);
1054 *  
1055 *   void parse_parameters(ParameterHandler &prm);
1056 *   };
1057 *  
1058 *  
1059 *   void FESystem::declare_parameters(ParameterHandler &prm)
1060 *   {
1061 *   prm.enter_subsection("Finite element system");
1062 *   {
1063 *   prm.declare_entry("Polynomial degree",
1064 *   "1",
1065 *   Patterns::Integer(0),
1066 *   "Phase field polynomial order");
1067 *  
1068 *   prm.declare_entry("Quadrature order",
1069 *   "2",
1070 *   Patterns::Integer(0),
1071 *   "Gauss quadrature order");
1072 *   }
1073 *   prm.leave_subsection();
1074 *   }
1075 *  
1076 *   void FESystem::parse_parameters(ParameterHandler &prm)
1077 *   {
1078 *   prm.enter_subsection("Finite element system");
1079 *   {
1080 *   m_poly_degree = prm.get_integer("Polynomial degree");
1081 *   m_quad_order = prm.get_integer("Quadrature order");
1082 *   }
1083 *   prm.leave_subsection();
1084 *   }
1085 *  
1086 * @endcode
1087 *
1088 * body force (N/m^3)
1089 *
1090 * @code
1091 *   struct BodyForce
1092 *   {
1093 *   double m_x_component;
1094 *   double m_y_component;
1095 *   double m_z_component;
1096 *  
1097 *   static void declare_parameters(ParameterHandler &prm);
1098 *  
1099 *   void parse_parameters(ParameterHandler &prm);
1100 *   };
1101 *  
1102 *   void BodyForce::declare_parameters(ParameterHandler &prm)
1103 *   {
1104 *   prm.enter_subsection("Body force");
1105 *   {
1106 *   prm.declare_entry("Body force x component",
1107 *   "0.0",
1108 *   Patterns::Double(),
1109 *   "Body force x-component (N/m^3)");
1110 *  
1111 *   prm.declare_entry("Body force y component",
1112 *   "0.0",
1113 *   Patterns::Double(),
1114 *   "Body force y-component (N/m^3)");
1115 *  
1116 *   prm.declare_entry("Body force z component",
1117 *   "0.0",
1118 *   Patterns::Double(),
1119 *   "Body force z-component (N/m^3)");
1120 *   }
1121 *   prm.leave_subsection();
1122 *   }
1123 *  
1124 *   void BodyForce::parse_parameters(ParameterHandler &prm)
1125 *   {
1126 *   prm.enter_subsection("Body force");
1127 *   {
1128 *   m_x_component = prm.get_double("Body force x component");
1129 *   m_y_component = prm.get_double("Body force y component");
1130 *   m_z_component = prm.get_double("Body force z component");
1131 *   }
1132 *   prm.leave_subsection();
1133 *   }
1134 *  
1135 *   struct NonlinearSolver
1136 *   {
1137 *   unsigned int m_max_iterations_NR;
1138 *   unsigned int m_max_iterations_BFGS;
1139 *   bool m_relative_residual;
1140 *  
1141 *   double m_tol_u_residual;
1142 *   double m_tol_d_residual;
1143 *   double m_tol_u_incr;
1144 *   double m_tol_d_incr;
1145 *  
1146 *   static void declare_parameters(ParameterHandler &prm);
1147 *  
1148 *   void parse_parameters(ParameterHandler &prm);
1149 *   };
1150 *  
1151 *   void NonlinearSolver::declare_parameters(ParameterHandler &prm)
1152 *   {
1153 *   prm.enter_subsection("Nonlinear solver");
1154 *   {
1155 *   prm.declare_entry("Max iterations Newton-Raphson",
1156 *   "10",
1157 *   Patterns::Integer(0),
1158 *   "Number of Newton-Raphson iterations allowed");
1159 *  
1160 *   prm.declare_entry("Max iterations BFGS",
1161 *   "20",
1162 *   Patterns::Integer(0),
1163 *   "Number of BFGS iterations allowed");
1164 *  
1165 *   prm.declare_entry("Relative residual",
1166 *   "yes",
1167 *   Patterns::Selection("yes|no"),
1168 *   "Shall we use relative residual for convergence?");
1169 *  
1170 *   prm.declare_entry("Tolerance displacement residual",
1171 *   "1.0e-9",
1172 *   Patterns::Double(0.0),
1173 *   "Displacement residual tolerance");
1174 *  
1175 *   prm.declare_entry("Tolerance phasefield residual",
1176 *   "1.0e-9",
1177 *   Patterns::Double(0.0),
1178 *   "Phasefield residual tolerance");
1179 *  
1180 *   prm.declare_entry("Tolerance displacement increment",
1181 *   "1.0e-9",
1182 *   Patterns::Double(0.0),
1183 *   "Displacement increment tolerance");
1184 *  
1185 *   prm.declare_entry("Tolerance phasefield increment",
1186 *   "1.0e-9",
1187 *   Patterns::Double(0.0),
1188 *   "Phasefield increment tolerance");
1189 *   }
1190 *   prm.leave_subsection();
1191 *   }
1192 *  
1193 *   void NonlinearSolver::parse_parameters(ParameterHandler &prm)
1194 *   {
1195 *   prm.enter_subsection("Nonlinear solver");
1196 *   {
1197 *   m_max_iterations_NR = prm.get_integer("Max iterations Newton-Raphson");
1198 *   m_max_iterations_BFGS = prm.get_integer("Max iterations BFGS");
1199 *   m_relative_residual = prm.get_bool("Relative residual");
1200 *  
1201 *   m_tol_u_residual = prm.get_double("Tolerance displacement residual");
1202 *   m_tol_d_residual = prm.get_double("Tolerance phasefield residual");
1203 *   m_tol_u_incr = prm.get_double("Tolerance displacement increment");
1204 *   m_tol_d_incr = prm.get_double("Tolerance phasefield increment");
1205 *   }
1206 *   prm.leave_subsection();
1207 *   }
1208 *  
1209 *   struct TimeInfo
1210 *   {
1211 *   double m_end_time;
1212 *   std::string m_time_file_name;
1213 *  
1214 *   static void declare_parameters(ParameterHandler &prm);
1215 *  
1216 *   void parse_parameters(ParameterHandler &prm);
1217 *   };
1218 *  
1219 *   void TimeInfo::declare_parameters(ParameterHandler &prm)
1220 *   {
1221 *   prm.enter_subsection("Time");
1222 *   {
1223 *   prm.declare_entry("End time", "1", Patterns::Double(), "End time");
1224 *  
1225 *   prm.declare_entry("Time data file",
1226 *   "1",
1228 *   "Time data file");
1229 *   }
1230 *   prm.leave_subsection();
1231 *   }
1232 *  
1233 *   void TimeInfo::parse_parameters(ParameterHandler &prm)
1234 *   {
1235 *   prm.enter_subsection("Time");
1236 *   {
1237 *   m_end_time = prm.get_double("End time");
1238 *   m_time_file_name = prm.get("Time data file");
1239 *   }
1240 *   prm.leave_subsection();
1241 *   }
1242 *  
1243 *   struct AllParameters : public Scenario,
1244 *   public FESystem,
1245 *   public BodyForce,
1246 *   public NonlinearSolver,
1247 *   public TimeInfo
1248 *   {
1249 *   AllParameters(const std::string &input_file);
1250 *  
1251 *   static void declare_parameters(ParameterHandler &prm);
1252 *  
1253 *   void parse_parameters(ParameterHandler &prm);
1254 *   };
1255 *  
1256 *   AllParameters::AllParameters(const std::string &input_file)
1257 *   {
1258 *   ParameterHandler prm;
1259 *   declare_parameters(prm);
1260 *   prm.parse_input(input_file);
1261 *   parse_parameters(prm);
1262 *   }
1263 *  
1264 *   void AllParameters::declare_parameters(ParameterHandler &prm)
1265 *   {
1266 *   Scenario::declare_parameters(prm);
1267 *   FESystem::declare_parameters(prm);
1268 *   BodyForce::declare_parameters(prm);
1269 *   NonlinearSolver::declare_parameters(prm);
1270 *   TimeInfo::declare_parameters(prm);
1271 *   }
1272 *  
1273 *   void AllParameters::parse_parameters(ParameterHandler &prm)
1274 *   {
1275 *   Scenario::parse_parameters(prm);
1276 *   FESystem::parse_parameters(prm);
1277 *   BodyForce::parse_parameters(prm);
1278 *   NonlinearSolver::parse_parameters(prm);
1279 *   TimeInfo::parse_parameters(prm);
1280 *   }
1281 *   } // namespace Parameters
1282 *  
1283 *   class Time
1284 *   {
1285 *   public:
1286 *   Time(const double time_end)
1287 *   : m_timestep(0)
1288 *   , m_time_current(0.0)
1289 *   , m_time_end(time_end)
1290 *   , m_delta_t(0.0)
1291 *   , m_magnitude(1.0)
1292 *   {}
1293 *  
1294 *   virtual ~Time() = default;
1295 *  
1296 *   double current() const
1297 *   {
1298 *   return m_time_current;
1299 *   }
1300 *   double end() const
1301 *   {
1302 *   return m_time_end;
1303 *   }
1304 *   double get_delta_t() const
1305 *   {
1306 *   return m_delta_t;
1307 *   }
1308 *   double get_magnitude() const
1309 *   {
1310 *   return m_magnitude;
1311 *   }
1312 *   unsigned int get_timestep() const
1313 *   {
1314 *   return m_timestep;
1315 *   }
1316 *   void increment(std::vector<std::array<double, 4>> time_table)
1317 *   {
1318 *   double t_1, t_delta, t_magnitude;
1319 *   for (auto & time_group : time_table)
1320 *   {
1321 *   t_1 = time_group[1];
1322 *   t_delta = time_group[2];
1323 *   t_magnitude = time_group[3];
1324 *  
1325 *   if (m_time_current < t_1 - 1.0e-6*t_delta)
1326 *   {
1327 *   m_delta_t = t_delta;
1328 *   m_magnitude = t_magnitude;
1329 *   break;
1330 *   }
1331 *   }
1332 *  
1333 *   m_time_current += m_delta_t;
1334 *   ++m_timestep;
1335 *   }
1336 *  
1337 *   private:
1338 *   unsigned int m_timestep;
1339 *   double m_time_current;
1340 *   const double m_time_end;
1341 *   double m_delta_t;
1342 *   double m_magnitude;
1343 *   };
1344 *  
1345 *   template <int dim>
1346 *   class LinearIsotropicElasticityAdditiveSplit
1347 *   {
1348 *   public:
1349 *   LinearIsotropicElasticityAdditiveSplit(const double lame_lambda,
1350 *   const double lame_mu,
1351 *   const double residual_k,
1352 *   const double length_scale,
1353 *   const double viscosity,
1354 *   const double gc)
1355 *   : m_lame_lambda(lame_lambda)
1356 *   , m_lame_mu(lame_mu)
1357 *   , m_residual_k(residual_k)
1358 *   , m_length_scale(length_scale)
1359 *   , m_eta(viscosity)
1360 *   , m_gc(gc)
1361 *   , m_phase_field_value(0.0)
1362 *   , m_grad_phasefield(Tensor<1, dim>())
1363 *   , m_strain(SymmetricTensor<2, dim>())
1364 *   , m_stress(SymmetricTensor<2, dim>())
1365 *   , m_stress_positive(SymmetricTensor<2, dim>())
1366 *   , m_mechanical_C(SymmetricTensor<4, dim>())
1367 *   , m_strain_energy_positive(0.0)
1368 *   , m_strain_energy_negative(0.0)
1369 *   , m_strain_energy_total(0.0)
1370 *   , m_crack_energy_dissipation(0.0)
1371 *   {
1372 *   Assert( ( lame_lambda / (2*(lame_lambda + lame_mu)) <= 0.5)
1373 *   & ( lame_lambda / (2*(lame_lambda + lame_mu)) >=-1.0),
1374 *   ExcInternalError() );
1375 *   }
1376 *  
1377 *   const SymmetricTensor<4, dim> & get_mechanical_C() const
1378 *   {
1379 *   return m_mechanical_C;
1380 *   }
1381 *  
1382 *   const SymmetricTensor<2, dim> & get_cauchy_stress() const
1383 *   {
1384 *   return m_stress;
1385 *   }
1386 *  
1387 *   const SymmetricTensor<2, dim> & get_cauchy_stress_positive() const
1388 *   {
1389 *   return m_stress_positive;
1390 *   }
1391 *  
1392 *   double get_positive_strain_energy() const
1393 *   {
1394 *   return m_strain_energy_positive;
1395 *   }
1396 *  
1397 *   double get_negative_strain_energy() const
1398 *   {
1399 *   return m_strain_energy_negative;
1400 *   }
1401 *  
1402 *   double get_total_strain_energy() const
1403 *   {
1404 *   return m_strain_energy_total;
1405 *   }
1406 *  
1407 *   double get_crack_energy_dissipation() const
1408 *   {
1409 *   return m_crack_energy_dissipation;
1410 *   }
1411 *  
1412 *   double get_phase_field_value() const
1413 *   {
1414 *   return m_phase_field_value;
1415 *   }
1416 *  
1417 *   const Tensor<1, dim> get_phase_field_gradient() const
1418 *   {
1419 *   return m_grad_phasefield;
1420 *   }
1421 *  
1422 *   void update_material_data(const SymmetricTensor<2, dim> & strain,
1423 *   const double phase_field_value,
1424 *   const Tensor<1, dim> & grad_phasefield,
1425 *   const double phase_field_value_previous_step,
1426 *   const double delta_time)
1427 *   {
1428 *   m_strain = strain;
1429 *   m_phase_field_value = phase_field_value;
1430 *   m_grad_phasefield = grad_phasefield;
1432 *   std::vector<Tensor<1, dim>> eigenvectors(dim);
1433 *   usr_spectrum_decomposition::spectrum_decomposition<dim>(m_strain,
1434 *   eigenvalues,
1435 *   eigenvectors);
1436 *  
1437 *   SymmetricTensor<2, dim> strain_positive, strain_negative;
1438 *   strain_positive = usr_spectrum_decomposition::positive_tensor(eigenvalues, eigenvectors);
1439 *   strain_negative = usr_spectrum_decomposition::negative_tensor(eigenvalues, eigenvectors);
1440 *  
1441 *   SymmetricTensor<4, dim> projector_positive, projector_negative;
1442 *   usr_spectrum_decomposition::positive_negative_projectors(eigenvalues,
1443 *   eigenvectors,
1444 *   projector_positive,
1445 *   projector_negative);
1446 *  
1447 *   SymmetricTensor<2, dim> stress_positive, stress_negative;
1448 *   const double degradation = degradation_function(m_phase_field_value) + m_residual_k;
1449 *   const double I_1 = trace(m_strain);
1450 *   stress_positive = m_lame_lambda * usr_spectrum_decomposition::positive_ramp_function(I_1)
1452 *   + 2 * m_lame_mu * strain_positive;
1453 *   stress_negative = m_lame_lambda * usr_spectrum_decomposition::negative_ramp_function(I_1)
1455 *   + 2 * m_lame_mu * strain_negative;
1456 *  
1457 *   m_stress = degradation * stress_positive + stress_negative;
1458 *   m_stress_positive = stress_positive;
1459 *  
1460 *   SymmetricTensor<4, dim> C_positive, C_negative;
1461 *   C_positive = m_lame_lambda * usr_spectrum_decomposition::heaviside_function(I_1)
1463 *   + 2 * m_lame_mu * projector_positive;
1464 *   C_negative = m_lame_lambda * usr_spectrum_decomposition::heaviside_function(-I_1)
1466 *   + 2 * m_lame_mu * projector_negative;
1467 *   m_mechanical_C = degradation * C_positive + C_negative;
1468 *  
1469 *   m_strain_energy_positive = 0.5 * m_lame_lambda * usr_spectrum_decomposition::positive_ramp_function(I_1)
1470 *   * usr_spectrum_decomposition::positive_ramp_function(I_1)
1471 *   + m_lame_mu * strain_positive * strain_positive;
1472 *  
1473 *   m_strain_energy_negative = 0.5 * m_lame_lambda * usr_spectrum_decomposition::negative_ramp_function(I_1)
1474 *   * usr_spectrum_decomposition::negative_ramp_function(I_1)
1475 *   + m_lame_mu * strain_negative * strain_negative;
1476 *  
1477 *   m_strain_energy_total = degradation * m_strain_energy_positive + m_strain_energy_negative;
1478 *  
1479 *   m_crack_energy_dissipation = m_gc * ( 0.5 / m_length_scale * m_phase_field_value * m_phase_field_value
1480 *   + 0.5 * m_length_scale * m_grad_phasefield * m_grad_phasefield)
1481 * @endcode
1482 *
1483 * the term due to viscosity regularization
1484 *
1485 * @code
1486 *   + (m_phase_field_value - phase_field_value_previous_step)
1487 *   * (m_phase_field_value - phase_field_value_previous_step)
1488 *   * 0.5 * m_eta / delta_time;
1489 * @endcode
1490 *
1491 * (void)delta_time;
1492 * (void)phase_field_value_previous_step;
1493 *
1494 * @code
1495 *   }
1496 *  
1497 *   private:
1498 *   const double m_lame_lambda;
1499 *   const double m_lame_mu;
1500 *   const double m_residual_k;
1501 *   const double m_length_scale;
1502 *   const double m_eta;
1503 *   const double m_gc;
1504 *   double m_phase_field_value;
1505 *   Tensor<1, dim> m_grad_phasefield;
1506 *   SymmetricTensor<2, dim> m_strain;
1507 *   SymmetricTensor<2, dim> m_stress;
1508 *   SymmetricTensor<2, dim> m_stress_positive;
1509 *   SymmetricTensor<4, dim> m_mechanical_C;
1510 *   double m_strain_energy_positive;
1511 *   double m_strain_energy_negative;
1512 *   double m_strain_energy_total;
1513 *   double m_crack_energy_dissipation;
1514 *   };
1515 *  
1516 *  
1517 *   template <int dim>
1518 *   class PointHistory
1519 *   {
1520 *   public:
1521 *   PointHistory()
1522 *   : m_length_scale(0.0)
1523 *   , m_gc(0.0)
1524 *   , m_viscosity(0.0)
1525 *   , m_history_max_positive_strain_energy(0.0)
1526 *   {}
1527 *  
1528 *   virtual ~PointHistory() = default;
1529 *  
1530 *   void setup_lqp(const double lame_lambda,
1531 *   const double lame_mu,
1532 *   const double length_scale,
1533 *   const double gc,
1534 *   const double viscosity,
1535 *   const double residual_k)
1536 *   {
1537 *   m_material =
1538 *   std::make_shared<LinearIsotropicElasticityAdditiveSplit<dim>>(lame_lambda,
1539 *   lame_mu,
1540 *   residual_k,
1541 *   length_scale,
1542 *   viscosity,
1543 *   gc);
1544 *   m_history_max_positive_strain_energy = 0.0;
1545 *   m_length_scale = length_scale;
1546 *   m_gc = gc;
1547 *   m_viscosity = viscosity;
1548 *  
1549 *   update_field_values(SymmetricTensor<2, dim>(), 0.0, Tensor<1, dim>(), 0.0, 1.0);
1550 *   }
1551 *  
1552 *   void update_field_values(const SymmetricTensor<2, dim> & strain,
1553 *   const double phase_field_value,
1554 *   const Tensor<1, dim> & grad_phasefield,
1555 *   const double phase_field_value_previous_step,
1556 *   const double delta_time)
1557 *   {
1558 *   m_material->update_material_data(strain, phase_field_value, grad_phasefield,
1559 *   phase_field_value_previous_step, delta_time);
1560 *   }
1561 *  
1562 *   void update_history_variable()
1563 *   {
1564 *   double current_positive_strain_energy = m_material->get_positive_strain_energy();
1565 *   m_history_max_positive_strain_energy = std::fmax(m_history_max_positive_strain_energy,
1566 *   current_positive_strain_energy);
1567 *   }
1568 *  
1569 *   double get_current_positive_strain_energy() const
1570 *   {
1571 *   return m_material->get_positive_strain_energy();
1572 *   }
1573 *  
1574 *   const SymmetricTensor<4, dim> & get_mechanical_C() const
1575 *   {
1576 *   return m_material->get_mechanical_C();
1577 *   }
1578 *  
1579 *   const SymmetricTensor<2, dim> & get_cauchy_stress() const
1580 *   {
1581 *   return m_material->get_cauchy_stress();
1582 *   }
1583 *  
1584 *   const SymmetricTensor<2, dim> & get_cauchy_stress_positive() const
1585 *   {
1586 *   return m_material->get_cauchy_stress_positive();
1587 *   }
1588 *  
1589 *   double get_total_strain_energy() const
1590 *   {
1591 *   return m_material->get_total_strain_energy();
1592 *   }
1593 *  
1594 *   double get_crack_energy_dissipation() const
1595 *   {
1596 *   return m_material->get_crack_energy_dissipation();
1597 *   }
1598 *  
1599 *   double get_phase_field_value() const
1600 *   {
1601 *   return m_material->get_phase_field_value();
1602 *   }
1603 *  
1604 *   const Tensor<1, dim> get_phase_field_gradient() const
1605 *   {
1606 *   return m_material->get_phase_field_gradient();
1607 *   }
1608 *  
1609 *   double get_history_max_positive_strain_energy() const
1610 *   {
1611 *   return m_history_max_positive_strain_energy;
1612 *   }
1613 *  
1614 *   double get_length_scale() const
1615 *   {
1616 *   return m_length_scale;
1617 *   }
1618 *  
1619 *   double get_critical_energy_release_rate() const
1620 *   {
1621 *   return m_gc;
1622 *   }
1623 *  
1624 *   double get_viscosity() const
1625 *   {
1626 *   return m_viscosity;
1627 *   }
1628 *   private:
1629 *   std::shared_ptr<LinearIsotropicElasticityAdditiveSplit<dim>> m_material;
1630 *   double m_length_scale;
1631 *   double m_gc;
1632 *   double m_viscosity;
1633 *   double m_history_max_positive_strain_energy;
1634 *   };
1635 *  
1636 *   template <int dim>
1637 *   class PhaseFieldMonolithicSolve
1638 *   {
1639 *   public:
1640 *   PhaseFieldMonolithicSolve(const std::string &input_file);
1641 *  
1642 *   virtual ~PhaseFieldMonolithicSolve() = default;
1643 *   void run();
1644 *  
1645 *   private:
1646 *   struct PerTaskData_ASM;
1647 *   struct ScratchData_ASM;
1648 *  
1649 *   struct PerTaskData_ASM_RHS_BFGS;
1650 *   struct ScratchData_ASM_RHS_BFGS;
1651 *  
1652 *   struct PerTaskData_UQPH;
1653 *   struct ScratchData_UQPH;
1654 *  
1655 *   Parameters::AllParameters m_parameters;
1656 *   Triangulation<dim> m_triangulation;
1657 *  
1659 *   PointHistory<dim>>
1660 *   m_quadrature_point_history;
1661 *  
1662 *   Time m_time;
1663 *   std::ofstream m_logfile;
1664 *   mutable TimerOutput m_timer;
1665 *  
1666 *   DoFHandler<dim> m_dof_handler;
1667 *   FESystem<dim> m_fe;
1668 *   const unsigned int m_dofs_per_cell;
1669 *   const FEValuesExtractors::Vector m_u_fe;
1670 *   const FEValuesExtractors::Scalar m_d_fe;
1671 *  
1672 *   static const unsigned int m_n_blocks = 2;
1673 *   static const unsigned int m_n_components = dim + 1;
1674 *   static const unsigned int m_first_u_component = 0;
1675 *   static const unsigned int m_d_component = dim;
1676 *  
1677 *   enum
1678 *   {
1679 *   m_u_dof = 0,
1680 *   m_d_dof = 1
1681 *   };
1682 *  
1683 *   std::vector<types::global_dof_index> m_dofs_per_block;
1684 *  
1685 *   const QGauss<dim> m_qf_cell;
1686 *   const QGauss<dim - 1> m_qf_face;
1687 *   const unsigned int m_n_q_points;
1688 *  
1689 *   double m_vol_reference;
1690 *  
1691 *   AffineConstraints<double> m_constraints;
1692 *   BlockSparsityPattern m_sparsity_pattern;
1693 *   BlockSparseMatrix<double> m_tangent_matrix;
1694 *   BlockVector<double> m_system_rhs;
1695 *   BlockVector<double> m_solution;
1696 *   SparseDirectUMFPACK m_A_direct;
1697 *  
1698 *  
1699 *   std::map<unsigned int, std::vector<double>> m_material_data;
1700 *  
1701 *   std::vector<std::pair<double, std::vector<double>>> m_history_reaction_force;
1702 *   std::vector<std::pair<double, std::array<double, 3>>> m_history_energy;
1703 *  
1704 *  
1705 *   struct Errors
1706 *   {
1707 *   Errors()
1708 *   : m_norm(1.0)
1709 *   , m_u(1.0)
1710 *   , m_d(1.0)
1711 *   {}
1712 *  
1713 *   void reset()
1714 *   {
1715 *   m_norm = 1.0;
1716 *   m_u = 1.0;
1717 *   m_d = 1.0;
1718 *   }
1719 *  
1720 *   void normalize(const Errors &rhs)
1721 *   {
1722 *   if (rhs.m_norm != 0.0)
1723 *   m_norm /= rhs.m_norm;
1724 *   if (rhs.m_u != 0.0)
1725 *   m_u /= rhs.m_u;
1726 *   if (rhs.m_d != 0.0)
1727 *   m_d /= rhs.m_d;
1728 *   }
1729 *  
1730 *   double m_norm, m_u, m_d;
1731 *   };
1732 *  
1733 *   Errors m_error_residual, m_error_residual_0, m_error_residual_norm, m_error_update,
1734 *   m_error_update_0, m_error_update_norm;
1735 *  
1736 *   void get_error_residual(Errors &error_residual);
1737 *   void get_error_update(const BlockVector<double> &newton_update,
1738 *   Errors & error_update);
1739 *  
1740 *   void make_grid();
1741 *   void make_grid_case_1();
1742 *   void make_grid_case_2();
1743 *   void make_grid_case_3();
1744 *   void make_grid_case_4();
1745 *   void make_grid_case_5();
1746 *   void make_grid_case_6();
1747 *   void make_grid_case_7();
1748 *   void make_grid_case_8();
1749 *   void make_grid_case_9();
1750 *   void make_grid_case_11();
1751 *  
1752 *   void setup_system();
1753 *  
1754 *   void determine_component_extractors();
1755 *  
1756 *   void make_constraints(const unsigned int it_nr);
1757 *  
1758 *   void assemble_system_newton(const BlockVector<double> & solution_old);
1759 *  
1760 *   void assemble_system_B0(const BlockVector<double> & solution_old);
1761 *  
1762 *   void assemble_system_newton_one_cell(
1763 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
1764 *   ScratchData_ASM & scratch,
1765 *   PerTaskData_ASM & data) const;
1766 *  
1767 *   void assemble_system_B0_one_cell(
1768 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
1769 *   ScratchData_ASM & scratch,
1770 *   PerTaskData_ASM & data) const;
1771 *  
1772 *   void assemble_system_rhs_BFGS_one_cell(
1773 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
1774 *   ScratchData_ASM_RHS_BFGS & scratch,
1775 *   PerTaskData_ASM_RHS_BFGS & data) const;
1776 *  
1777 *   void assemble_system_rhs_BFGS(const BlockVector<double> & solution_old,
1778 *   BlockVector<double> & system_rhs);
1779 *  
1780 *   void assemble_system_rhs_BFGS_parallel(const BlockVector<double> & solution_old,
1781 *   BlockVector<double> & system_rhs);
1782 *  
1783 *   bool solve_nonlinear_timestep_newton(BlockVector<double> &solution_delta);
1784 *  
1785 *   void solve_nonlinear_timestep_BFGS(BlockVector<double> &solution_delta);
1786 *  
1787 *   void solve_nonlinear_timestep_LBFGS(BlockVector<double> &solution_delta,
1788 *   BlockVector<double> & LBFGS_update_refine);
1789 *  
1790 *   double line_search_stepsize_strong_wolfe(const double phi_0,
1791 *   const double phi_0_prime,
1792 *   const BlockVector<double> & BFGS_p_vector,
1793 *   const BlockVector<double> & solution_delta);
1794 *  
1795 *   double line_search_stepsize_gradient_based(const BlockVector<double> & BFGS_p_vector,
1796 *   const BlockVector<double> & solution_delta);
1797 *  
1798 *   double line_search_zoom_strong_wolfe(double phi_low, double phi_low_prime, double alpha_low,
1799 *   double phi_high, double phi_high_prime, double alpha_high,
1800 *   double phi_0, double phi_0_prime, const BlockVector<double> & BFGS_p_vector,
1801 *   double c1, double c2, unsigned int max_iter,
1802 *   const BlockVector<double> & solution_delta);
1803 *  
1804 *   double line_search_interpolation_cubic(const double alpha_0, const double phi_0, const double phi_0_prime,
1805 *   const double alpha_1, const double phi_1, const double phi_1_prime);
1806 *  
1807 *   std::pair<double, double> calculate_phi_and_phi_prime(const double alpha,
1808 *   const BlockVector<double> & BFGS_p_vector,
1809 *   const BlockVector<double> & solution_delta);
1810 *  
1811 *   std::vector<double> solve_linear_system(BlockVector<double> &newton_update);
1812 *  
1813 *   void LBFGS_B0(BlockVector<double> & LBFGS_r_vector,
1814 *   BlockVector<double> & LBFGS_q_vector);
1815 *  
1816 *   void update_history_field_step();
1817 *  
1818 *   void output_results() const;
1819 *  
1820 *   void setup_qph();
1821 *  
1822 *   void update_qph_incremental(const BlockVector<double> &solution_delta,
1823 *   const BlockVector<double> &solution_old,
1824 *   const bool is_print);
1825 *  
1826 *   void update_qph_incremental_one_cell(
1827 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
1828 *   ScratchData_UQPH & scratch,
1829 *   PerTaskData_UQPH & data);
1830 *  
1831 *   void copy_local_to_global_UQPH(const PerTaskData_UQPH & /*data*/)
1832 *   {}
1833 *  
1835 *   get_total_solution(const BlockVector<double> &solution_delta) const;
1836 *  
1837 * @endcode
1838 *
1839 * Should not make this function const
1840 *
1841 * @code
1842 *   void read_material_data(const std::string &data_file,
1843 *   const unsigned int total_material_regions);
1844 *  
1845 *   void read_time_data(const std::string &data_file,
1846 *   std::vector<std::array<double, 4>> & time_table);
1847 *  
1848 *   void print_conv_header_newton();
1849 *  
1850 *   void print_conv_header_BFGS();
1851 *  
1852 *   void print_conv_header_LBFGS();
1853 *  
1854 *   void print_parameter_information();
1855 *  
1856 *   void calculate_reaction_force(unsigned int face_ID);
1857 *  
1858 *   void write_history_data();
1859 *  
1860 *   double calculate_energy_functional() const;
1861 *  
1862 *   std::pair<double, double> calculate_total_strain_energy_and_crack_energy_dissipation() const;
1863 *  
1864 *   bool local_refine_and_solution_transfer(BlockVector<double> & solution_delta,
1865 *   BlockVector<double> & LBFGS_update_refine);
1866 *   }; // class PhaseFieldSplitSolve
1867 *  
1868 *  
1869 *   template <int dim>
1870 *   void PhaseFieldMonolithicSolve<dim>::get_error_residual(Errors &error_residual)
1871 *   {
1872 *   BlockVector<double> error_res(m_dofs_per_block);
1873 *  
1874 *   for (unsigned int i = 0; i < m_dof_handler.n_dofs(); ++i)
1875 *   if (!m_constraints.is_constrained(i))
1876 *   error_res(i) = m_system_rhs(i);
1877 *  
1878 *   error_residual.m_norm = error_res.l2_norm();
1879 *   error_residual.m_u = error_res.block(m_u_dof).l2_norm();
1880 *   error_residual.m_d = error_res.block(m_d_dof).l2_norm();
1881 *   }
1882 *  
1883 *   template <int dim>
1884 *   void PhaseFieldMonolithicSolve<dim>::get_error_update(const BlockVector<double> &newton_update,
1885 *   Errors & error_update)
1886 *   {
1887 *   BlockVector<double> error_ud(m_dofs_per_block);
1888 *   for (unsigned int i = 0; i < m_dof_handler.n_dofs(); ++i)
1889 *   if (!m_constraints.is_constrained(i))
1890 *   error_ud(i) = newton_update(i);
1891 *  
1892 *   error_update.m_norm = error_ud.l2_norm();
1893 *   error_update.m_u = error_ud.block(m_u_dof).l2_norm();
1894 *   error_update.m_d = error_ud.block(m_d_dof).l2_norm();
1895 *   }
1896 *  
1897 *   template <int dim>
1898 *   void PhaseFieldMonolithicSolve<dim>::read_material_data(const std::string &data_file,
1899 *   const unsigned int total_material_regions)
1900 *   {
1901 *   std::ifstream myfile (data_file);
1902 *  
1903 *   double lame_lambda, lame_mu, length_scale, gc, viscosity, residual_k;
1904 *   int material_region;
1905 *   double poisson_ratio;
1906 *   if (myfile.is_open())
1907 *   {
1908 *   m_logfile << "Reading material data file ..." << std::endl;
1909 *  
1910 *   while ( myfile >> material_region
1911 *   >> lame_lambda
1912 *   >> lame_mu
1913 *   >> length_scale
1914 *   >> gc
1915 *   >> viscosity
1916 *   >> residual_k)
1917 *   {
1918 *   m_material_data[material_region] = {lame_lambda,
1919 *   lame_mu,
1920 *   length_scale,
1921 *   gc,
1922 *   viscosity,
1923 *   residual_k};
1924 *   poisson_ratio = lame_lambda / (2*(lame_lambda + lame_mu));
1925 *   Assert( (poisson_ratio <= 0.5)&(poisson_ratio >=-1.0) , ExcInternalError());
1926 *  
1927 *   m_logfile << "\tRegion " << material_region << " : " << std::endl;
1928 *   m_logfile << "\t\tLame lambda = " << lame_lambda << std::endl;
1929 *   m_logfile << "\t\tLame mu = " << lame_mu << std::endl;
1930 *   m_logfile << "\t\tPoisson ratio = " << poisson_ratio << std::endl;
1931 *   m_logfile << "\t\tPhase field length scale (l) = " << length_scale << std::endl;
1932 *   m_logfile << "\t\tCritical energy release rate (gc) = " << gc << std::endl;
1933 *   m_logfile << "\t\tViscosity for regularization (eta) = " << viscosity << std::endl;
1934 *   m_logfile << "\t\tResidual_k (k) = " << residual_k << std::endl;
1935 *   }
1936 *  
1937 *   if (m_material_data.size() != total_material_regions)
1938 *   {
1939 *   m_logfile << "Material data file has " << m_material_data.size() << " rows. However, "
1940 *   << "the mesh has " << total_material_regions << " material regions."
1941 *   << std::endl;
1942 *   Assert(m_material_data.size() == total_material_regions,
1943 *   ExcDimensionMismatch(m_material_data.size(), total_material_regions));
1944 *   }
1945 *   myfile.close();
1946 *   }
1947 *   else
1948 *   {
1949 *   m_logfile << "Material data file : " << data_file << " not exist!" << std::endl;
1950 *   Assert(false, ExcMessage("Failed to read material data file"));
1951 *   }
1952 *   }
1953 *  
1954 *   template <int dim>
1955 *   void PhaseFieldMonolithicSolve<dim>::read_time_data(const std::string &data_file,
1956 *   std::vector<std::array<double, 4>> & time_table)
1957 *   {
1958 *   std::ifstream myfile (data_file);
1959 *  
1960 *   double t_0, t_1, delta_t, t_magnitude;
1961 *  
1962 *   if (myfile.is_open())
1963 *   {
1964 *   m_logfile << "Reading time data file ..." << std::endl;
1965 *  
1966 *   while ( myfile >> t_0
1967 *   >> t_1
1968 *   >> delta_t
1969 *   >> t_magnitude)
1970 *   {
1971 *   Assert( t_0 < t_1,
1972 *   ExcMessage("For each time pair, "
1973 *   "the start time should be smaller than the end time"));
1974 *   time_table.push_back({{t_0, t_1, delta_t, t_magnitude}});
1975 *   }
1976 *  
1977 *   Assert(std::fabs(t_1 - m_parameters.m_end_time) < 1.0e-9,
1978 *   ExcMessage("End time in time table is inconsistent with input data in parameters.prm"));
1979 *  
1980 *   Assert(time_table.size() > 0,
1981 *   ExcMessage("Time data file is empty."));
1982 *   myfile.close();
1983 *   }
1984 *   else
1985 *   {
1986 *   m_logfile << "Time data file : " << data_file << " not exist!" << std::endl;
1987 *   Assert(false, ExcMessage("Failed to read time data file"));
1988 *   }
1989 *  
1990 *   for (auto & time_group : time_table)
1991 *   {
1992 *   m_logfile << "\t\t"
1993 *   << time_group[0] << ",\t"
1994 *   << time_group[1] << ",\t"
1995 *   << time_group[2] << ",\t"
1996 *   << time_group[3] << std::endl;
1997 *   }
1998 *   }
1999 *  
2000 *   template <int dim>
2001 *   void PhaseFieldMonolithicSolve<dim>::setup_qph()
2002 *   {
2003 *   m_logfile << "\t\tSetting up quadrature point data ("
2004 *   << m_n_q_points
2005 *   << " points per cell)" << std::endl;
2006 *  
2007 *   m_quadrature_point_history.clear();
2008 *   for (auto const & cell : m_triangulation.active_cell_iterators())
2009 *   {
2010 *   m_quadrature_point_history.initialize(cell, m_n_q_points);
2011 *   }
2012 *  
2013 *   unsigned int material_id;
2014 *   double lame_lambda = 0.0;
2015 *   double lame_mu = 0.0;
2016 *   double length_scale = 0.0;
2017 *   double gc = 0.0;
2018 *   double viscosity = 0.0;
2019 *   double residual_k = 0.0;
2020 *  
2021 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2022 *   {
2023 *   material_id = cell->material_id();
2024 *   if (m_material_data.find(material_id) != m_material_data.end())
2025 *   {
2026 *   lame_lambda = m_material_data[material_id][0];
2027 *   lame_mu = m_material_data[material_id][1];
2028 *   length_scale = m_material_data[material_id][2];
2029 *   gc = m_material_data[material_id][3];
2030 *   viscosity = m_material_data[material_id][4];
2031 *   residual_k = m_material_data[material_id][5];
2032 *   }
2033 *   else
2034 *   {
2035 *   m_logfile << "Could not find material data for material id: " << material_id << std::endl;
2036 *   AssertThrow(false, ExcMessage("Could not find material data for material id."));
2037 *   }
2038 *  
2039 *   const std::vector<std::shared_ptr<PointHistory<dim>>> lqph =
2040 *   m_quadrature_point_history.get_data(cell);
2041 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
2042 *  
2043 *   for (unsigned int q_point = 0; q_point < m_n_q_points; ++q_point)
2044 *   lqph[q_point]->setup_lqp(lame_lambda, lame_mu, length_scale,
2045 *   gc, viscosity, residual_k);
2046 *   }
2047 *   }
2048 *  
2049 *   template <int dim>
2050 *   BlockVector<double> PhaseFieldMonolithicSolve<dim>::get_total_solution(
2051 *   const BlockVector<double> &solution_delta) const
2052 *   {
2053 *   BlockVector<double> solution_total(m_solution);
2054 *   solution_total += solution_delta;
2055 *   return solution_total;
2056 *   }
2057 *  
2058 *   template <int dim>
2059 *   void
2060 *   PhaseFieldMonolithicSolve<dim>::update_qph_incremental(const BlockVector<double> &solution_delta,
2061 *   const BlockVector<double> &solution_old,
2062 *   const bool is_print)
2063 *   {
2064 *   m_timer.enter_subsection("Update QPH data");
2065 *   if (is_print && m_parameters.m_output_iteration_history)
2066 *   m_logfile << " UQPH " << std::flush;
2067 *  
2068 *   const BlockVector<double> solution_total(get_total_solution(solution_delta));
2069 *  
2070 *   const UpdateFlags uf_UQPH(update_values | update_gradients);
2071 *   PerTaskData_UQPH per_task_data_UQPH;
2072 *   ScratchData_UQPH scratch_data_UQPH(m_fe,
2073 *   m_qf_cell,
2074 *   uf_UQPH,
2075 *   solution_total,
2076 *   solution_old,
2077 *   m_time.get_delta_t());
2078 *  
2079 *   auto worker = [this](const typename DoFHandler<dim>::active_cell_iterator &cell,
2080 *   ScratchData_UQPH & scratch,
2081 *   PerTaskData_UQPH & data)
2082 *   {
2083 *   this->update_qph_incremental_one_cell(cell, scratch, data);
2084 *   };
2085 *  
2086 *   auto copier = [this](const PerTaskData_UQPH &data)
2087 *   {
2088 *   this->copy_local_to_global_UQPH(data);
2089 *   };
2090 *  
2092 *   m_dof_handler.begin_active(),
2093 *   m_dof_handler.end(),
2094 *   worker,
2095 *   copier,
2096 *   scratch_data_UQPH,
2097 *   per_task_data_UQPH);
2098 *  
2099 *   m_timer.leave_subsection();
2100 *   }
2101 *  
2102 *   template <int dim>
2103 *   struct PhaseFieldMonolithicSolve<dim>::PerTaskData_UQPH
2104 *   {
2105 *   void reset()
2106 *   {}
2107 *   };
2108 *  
2109 *   template <int dim>
2110 *   struct PhaseFieldMonolithicSolve<dim>::ScratchData_UQPH
2111 *   {
2112 *   const BlockVector<double> & m_solution_UQPH;
2113 *  
2114 *   std::vector<SymmetricTensor<2, dim>> m_solution_symm_grads_u_cell;
2115 *   std::vector<double> m_solution_values_phasefield_cell;
2116 *   std::vector<Tensor<1, dim>> m_solution_grad_phasefield_cell;
2117 *  
2118 *   FEValues<dim> m_fe_values;
2119 *  
2120 *   const BlockVector<double>& m_solution_previous_step;
2121 *   std::vector<double> m_phasefield_previous_step_cell;
2122 *  
2123 *   const double m_delta_time;
2124 *  
2125 *   ScratchData_UQPH(const FiniteElement<dim> & fe_cell,
2126 *   const QGauss<dim> & qf_cell,
2127 *   const UpdateFlags uf_cell,
2128 *   const BlockVector<double> &solution_total,
2129 *   const BlockVector<double> &solution_old,
2130 *   const double delta_time)
2131 *   : m_solution_UQPH(solution_total)
2132 *   , m_solution_symm_grads_u_cell(qf_cell.size())
2133 *   , m_solution_values_phasefield_cell(qf_cell.size())
2134 *   , m_solution_grad_phasefield_cell(qf_cell.size())
2135 *   , m_fe_values(fe_cell, qf_cell, uf_cell)
2136 *   , m_solution_previous_step(solution_old)
2137 *   , m_phasefield_previous_step_cell(qf_cell.size())
2138 *   , m_delta_time(delta_time)
2139 *   {}
2140 *  
2141 *   ScratchData_UQPH(const ScratchData_UQPH &rhs)
2142 *   : m_solution_UQPH(rhs.m_solution_UQPH)
2143 *   , m_solution_symm_grads_u_cell(rhs.m_solution_symm_grads_u_cell)
2144 *   , m_solution_values_phasefield_cell(rhs.m_solution_values_phasefield_cell)
2145 *   , m_solution_grad_phasefield_cell(rhs.m_solution_grad_phasefield_cell)
2146 *   , m_fe_values(rhs.m_fe_values.get_fe(),
2147 *   rhs.m_fe_values.get_quadrature(),
2148 *   rhs.m_fe_values.get_update_flags())
2149 *   , m_solution_previous_step(rhs.m_solution_previous_step)
2150 *   , m_phasefield_previous_step_cell(rhs.m_phasefield_previous_step_cell)
2151 *   , m_delta_time(rhs.m_delta_time)
2152 *   {}
2153 *  
2154 *   void reset()
2155 *   {
2156 *   const unsigned int n_q_points = m_solution_symm_grads_u_cell.size();
2157 *   for (unsigned int q = 0; q < n_q_points; ++q)
2158 *   {
2159 *   m_solution_symm_grads_u_cell[q] = 0.0;
2160 *   m_solution_values_phasefield_cell[q] = 0.0;
2161 *   m_solution_grad_phasefield_cell[q] = 0.0;
2162 *   m_phasefield_previous_step_cell[q] = 0.0;
2163 *   }
2164 *   }
2165 *   };
2166 *  
2167 *   template <int dim>
2168 *   void PhaseFieldMonolithicSolve<dim>::update_qph_incremental_one_cell(
2169 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
2170 *   ScratchData_UQPH & scratch,
2171 *   PerTaskData_UQPH & /*data*/)
2172 *   {
2173 *   scratch.reset();
2174 *  
2175 *   scratch.m_fe_values.reinit(cell);
2176 *  
2177 *   const std::vector<std::shared_ptr<PointHistory<dim>>> lqph =
2178 *   m_quadrature_point_history.get_data(cell);
2179 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
2180 *  
2181 *   const FEValuesExtractors::Vector displacement(0);
2182 *  
2183 *   scratch.m_fe_values[m_u_fe].get_function_symmetric_gradients(
2184 *   scratch.m_solution_UQPH, scratch.m_solution_symm_grads_u_cell);
2185 *   scratch.m_fe_values[m_d_fe].get_function_values(
2186 *   scratch.m_solution_UQPH, scratch.m_solution_values_phasefield_cell);
2187 *   scratch.m_fe_values[m_d_fe].get_function_gradients(
2188 *   scratch.m_solution_UQPH, scratch.m_solution_grad_phasefield_cell);
2189 *  
2190 *   scratch.m_fe_values[m_d_fe].get_function_values(
2191 *   scratch.m_solution_previous_step, scratch.m_phasefield_previous_step_cell);
2192 *  
2193 *   for (const unsigned int q_point :
2194 *   scratch.m_fe_values.quadrature_point_indices())
2195 *   lqph[q_point]->update_field_values(scratch.m_solution_symm_grads_u_cell[q_point],
2196 *   scratch.m_solution_values_phasefield_cell[q_point],
2197 *   scratch.m_solution_grad_phasefield_cell[q_point],
2198 *   scratch.m_phasefield_previous_step_cell[q_point],
2199 *   scratch.m_delta_time);
2200 *   }
2201 *  
2202 *   template <int dim>
2203 *   struct PhaseFieldMonolithicSolve<dim>::PerTaskData_ASM
2204 *   {
2205 *   FullMatrix<double> m_cell_matrix;
2206 *   Vector<double> m_cell_rhs;
2207 *   std::vector<types::global_dof_index> m_local_dof_indices;
2208 *  
2209 *   PerTaskData_ASM(const unsigned int dofs_per_cell)
2210 *   : m_cell_matrix(dofs_per_cell, dofs_per_cell)
2211 *   , m_cell_rhs(dofs_per_cell)
2212 *   , m_local_dof_indices(dofs_per_cell)
2213 *   {}
2214 *  
2215 *   void reset()
2216 *   {
2217 *   m_cell_matrix = 0.0;
2218 *   m_cell_rhs = 0.0;
2219 *   }
2220 *   };
2221 *  
2222 *   template <int dim>
2223 *   struct PhaseFieldMonolithicSolve<dim>::PerTaskData_ASM_RHS_BFGS
2224 *   {
2225 *   Vector<double> m_cell_rhs;
2226 *   std::vector<types::global_dof_index> m_local_dof_indices;
2227 *  
2228 *   PerTaskData_ASM_RHS_BFGS(const unsigned int dofs_per_cell)
2229 *   : m_cell_rhs(dofs_per_cell)
2230 *   , m_local_dof_indices(dofs_per_cell)
2231 *   {}
2232 *  
2233 *   void reset()
2234 *   {
2235 *   m_cell_rhs = 0.0;
2236 *   }
2237 *   };
2238 *  
2239 *   template <int dim>
2240 *   struct PhaseFieldMonolithicSolve<dim>::ScratchData_ASM
2241 *   {
2242 *   FEValues<dim> m_fe_values;
2243 *   FEFaceValues<dim> m_fe_face_values;
2244 *  
2245 *   std::vector<std::vector<double>> m_Nx_phasefield; // shape function values for phase-field
2246 *   std::vector<std::vector<Tensor<1, dim>>> m_grad_Nx_phasefield; // gradient of shape function values for phase field
2247 *  
2248 *   std::vector<std::vector<Tensor<1, dim>>> m_Nx_disp; // shape function values for displacement
2249 *   std::vector<std::vector<Tensor<2, dim>>> m_grad_Nx_disp; // gradient of shape function values for displacement
2250 *   std::vector<std::vector<SymmetricTensor<2, dim>>> m_symm_grad_Nx_disp; // symmetric gradient of shape function values for displacement
2251 *  
2252 *   const BlockVector<double>& m_solution_previous_step;
2253 *   std::vector<double> m_phasefield_previous_step_cell;
2254 *  
2255 *   ScratchData_ASM(const FiniteElement<dim> & fe_cell,
2256 *   const QGauss<dim> & qf_cell,
2257 *   const UpdateFlags uf_cell,
2258 *   const QGauss<dim - 1> & qf_face,
2259 *   const UpdateFlags uf_face,
2260 *   const BlockVector<double>& solution_old)
2261 *   : m_fe_values(fe_cell, qf_cell, uf_cell)
2262 *   , m_fe_face_values(fe_cell, qf_face, uf_face)
2263 *   , m_Nx_phasefield(qf_cell.size(),
2264 *   std::vector<double>(fe_cell.n_dofs_per_cell()))
2265 *   , m_grad_Nx_phasefield(qf_cell.size(),
2266 *   std::vector<Tensor<1, dim>>(fe_cell.n_dofs_per_cell()))
2267 *   , m_Nx_disp(qf_cell.size(),
2268 *   std::vector<Tensor<1, dim>>(fe_cell.n_dofs_per_cell()))
2269 *   , m_grad_Nx_disp(qf_cell.size(),
2270 *   std::vector<Tensor<2, dim>>(fe_cell.n_dofs_per_cell()))
2271 *   , m_symm_grad_Nx_disp(qf_cell.size(),
2272 *   std::vector<SymmetricTensor<2, dim>>(fe_cell.n_dofs_per_cell()))
2273 *   , m_solution_previous_step(solution_old)
2274 *   , m_phasefield_previous_step_cell(qf_cell.size())
2275 *   {}
2276 *  
2277 *   ScratchData_ASM(const ScratchData_ASM &rhs)
2278 *   : m_fe_values(rhs.m_fe_values.get_fe(),
2279 *   rhs.m_fe_values.get_quadrature(),
2280 *   rhs.m_fe_values.get_update_flags())
2281 *   , m_fe_face_values(rhs.m_fe_face_values.get_fe(),
2282 *   rhs.m_fe_face_values.get_quadrature(),
2283 *   rhs.m_fe_face_values.get_update_flags())
2284 *   , m_Nx_phasefield(rhs.m_Nx_phasefield)
2285 *   , m_grad_Nx_phasefield(rhs.m_grad_Nx_phasefield)
2286 *   , m_Nx_disp(rhs.m_Nx_disp)
2287 *   , m_grad_Nx_disp(rhs.m_grad_Nx_disp)
2288 *   , m_symm_grad_Nx_disp(rhs.m_symm_grad_Nx_disp)
2289 *   , m_solution_previous_step(rhs.m_solution_previous_step)
2290 *   , m_phasefield_previous_step_cell(rhs.m_phasefield_previous_step_cell)
2291 *   {}
2292 *  
2293 *   void reset()
2294 *   {
2295 *   const unsigned int n_q_points = m_Nx_phasefield.size();
2296 *   const unsigned int n_dofs_per_cell = m_Nx_phasefield[0].size();
2297 *   for (unsigned int q_point = 0; q_point < n_q_points; ++q_point)
2298 *   {
2299 *   Assert(m_Nx_phasefield[q_point].size() == n_dofs_per_cell,
2300 *   ExcInternalError());
2301 *  
2302 *   Assert(m_grad_Nx_phasefield[q_point].size() == n_dofs_per_cell,
2303 *   ExcInternalError());
2304 *  
2305 *   Assert(m_Nx_disp[q_point].size() == n_dofs_per_cell,
2306 *   ExcInternalError());
2307 *  
2308 *   Assert(m_grad_Nx_disp[q_point].size() == n_dofs_per_cell,
2309 *   ExcInternalError());
2310 *  
2311 *   Assert(m_symm_grad_Nx_disp[q_point].size() == n_dofs_per_cell,
2312 *   ExcInternalError());
2313 *  
2314 *   m_phasefield_previous_step_cell[q_point] = 0.0;
2315 *   for (unsigned int k = 0; k < n_dofs_per_cell; ++k)
2316 *   {
2317 *   m_Nx_phasefield[q_point][k] = 0.0;
2318 *   m_grad_Nx_phasefield[q_point][k] = 0.0;
2319 *   m_Nx_disp[q_point][k] = 0.0;
2320 *   m_grad_Nx_disp[q_point][k] = 0.0;
2321 *   m_symm_grad_Nx_disp[q_point][k] = 0.0;
2322 *   }
2323 *   }
2324 *   }
2325 *   };
2326 *  
2327 *  
2328 *   template <int dim>
2329 *   struct PhaseFieldMonolithicSolve<dim>::ScratchData_ASM_RHS_BFGS
2330 *   {
2331 *   FEValues<dim> m_fe_values;
2332 *   FEFaceValues<dim> m_fe_face_values;
2333 *  
2334 *   std::vector<std::vector<double>> m_Nx_phasefield; // shape function values for phase-field
2335 *   std::vector<std::vector<Tensor<1, dim>>> m_grad_Nx_phasefield; // gradient of shape function values for phase field
2336 *  
2337 *   std::vector<std::vector<Tensor<1, dim>>> m_Nx_disp; // shape function values for displacement
2338 *   std::vector<std::vector<Tensor<2, dim>>> m_grad_Nx_disp; // gradient of shape function values for displacement
2339 *   std::vector<std::vector<SymmetricTensor<2, dim>>> m_symm_grad_Nx_disp; // symmetric gradient of shape function values for displacement
2340 *  
2341 *   const BlockVector<double>& m_solution_previous_step;
2342 *   std::vector<double> m_phasefield_previous_step_cell;
2343 *  
2344 *   ScratchData_ASM_RHS_BFGS(const FiniteElement<dim> & fe_cell,
2345 *   const QGauss<dim> & qf_cell,
2346 *   const UpdateFlags uf_cell,
2347 *   const QGauss<dim - 1> & qf_face,
2348 *   const UpdateFlags uf_face,
2349 *   const BlockVector<double>& solution_old)
2350 *   : m_fe_values(fe_cell, qf_cell, uf_cell)
2351 *   , m_fe_face_values(fe_cell, qf_face, uf_face)
2352 *   , m_Nx_phasefield(qf_cell.size(),
2353 *   std::vector<double>(fe_cell.n_dofs_per_cell()))
2354 *   , m_grad_Nx_phasefield(qf_cell.size(),
2355 *   std::vector<Tensor<1, dim>>(fe_cell.n_dofs_per_cell()))
2356 *   , m_Nx_disp(qf_cell.size(),
2357 *   std::vector<Tensor<1, dim>>(fe_cell.n_dofs_per_cell()))
2358 *   , m_grad_Nx_disp(qf_cell.size(),
2359 *   std::vector<Tensor<2, dim>>(fe_cell.n_dofs_per_cell()))
2360 *   , m_symm_grad_Nx_disp(qf_cell.size(),
2361 *   std::vector<SymmetricTensor<2, dim>>(fe_cell.n_dofs_per_cell()))
2362 *   , m_solution_previous_step(solution_old)
2363 *   , m_phasefield_previous_step_cell(qf_cell.size())
2364 *   {}
2365 *  
2366 *   ScratchData_ASM_RHS_BFGS(const ScratchData_ASM_RHS_BFGS &rhs)
2367 *   : m_fe_values(rhs.m_fe_values.get_fe(),
2368 *   rhs.m_fe_values.get_quadrature(),
2369 *   rhs.m_fe_values.get_update_flags())
2370 *   , m_fe_face_values(rhs.m_fe_face_values.get_fe(),
2371 *   rhs.m_fe_face_values.get_quadrature(),
2372 *   rhs.m_fe_face_values.get_update_flags())
2373 *   , m_Nx_phasefield(rhs.m_Nx_phasefield)
2374 *   , m_grad_Nx_phasefield(rhs.m_grad_Nx_phasefield)
2375 *   , m_Nx_disp(rhs.m_Nx_disp)
2376 *   , m_grad_Nx_disp(rhs.m_grad_Nx_disp)
2377 *   , m_symm_grad_Nx_disp(rhs.m_symm_grad_Nx_disp)
2378 *   , m_solution_previous_step(rhs.m_solution_previous_step)
2379 *   , m_phasefield_previous_step_cell(rhs.m_phasefield_previous_step_cell)
2380 *   {}
2381 *  
2382 *   void reset()
2383 *   {
2384 *   const unsigned int n_q_points = m_Nx_phasefield.size();
2385 *   const unsigned int n_dofs_per_cell = m_Nx_phasefield[0].size();
2386 *   for (unsigned int q_point = 0; q_point < n_q_points; ++q_point)
2387 *   {
2388 *   Assert(m_Nx_phasefield[q_point].size() == n_dofs_per_cell,
2389 *   ExcInternalError());
2390 *  
2391 *   Assert(m_grad_Nx_phasefield[q_point].size() == n_dofs_per_cell,
2392 *   ExcInternalError());
2393 *  
2394 *   Assert(m_Nx_disp[q_point].size() == n_dofs_per_cell,
2395 *   ExcInternalError());
2396 *  
2397 *   Assert(m_grad_Nx_disp[q_point].size() == n_dofs_per_cell,
2398 *   ExcInternalError());
2399 *  
2400 *   Assert(m_symm_grad_Nx_disp[q_point].size() == n_dofs_per_cell,
2401 *   ExcInternalError());
2402 *  
2403 *   m_phasefield_previous_step_cell[q_point] = 0.0;
2404 *   for (unsigned int k = 0; k < n_dofs_per_cell; ++k)
2405 *   {
2406 *   m_Nx_phasefield[q_point][k] = 0.0;
2407 *   m_grad_Nx_phasefield[q_point][k] = 0.0;
2408 *   m_Nx_disp[q_point][k] = 0.0;
2409 *   m_grad_Nx_disp[q_point][k] = 0.0;
2410 *   m_symm_grad_Nx_disp[q_point][k] = 0.0;
2411 *   }
2412 *   }
2413 *   }
2414 *   };
2415 *  
2416 * @endcode
2417 *
2418 * constructor has no return type
2419 *
2420 * @code
2421 *   template <int dim>
2422 *   PhaseFieldMonolithicSolve<dim>::PhaseFieldMonolithicSolve(const std::string &input_file)
2423 *   : m_parameters(input_file)
2424 *   , m_triangulation(Triangulation<dim>::maximum_smoothing)
2425 *   , m_time(m_parameters.m_end_time)
2426 *   , m_logfile(m_parameters.m_logfile_name)
2427 *   , m_timer(m_logfile, TimerOutput::summary, TimerOutput::wall_times)
2428 *   , m_dof_handler(m_triangulation)
2429 *   , m_fe(FE_Q<dim>(m_parameters.m_poly_degree),
2430 *   dim, // displacement
2431 *   FE_Q<dim>(m_parameters.m_poly_degree),
2432 *   1) // phasefield
2433 *   , m_dofs_per_cell(m_fe.n_dofs_per_cell())
2434 *   , m_u_fe(m_first_u_component)
2435 *   , m_d_fe(m_d_component)
2436 *   , m_dofs_per_block(m_n_blocks)
2437 *   , m_qf_cell(m_parameters.m_quad_order)
2438 *   , m_qf_face(m_parameters.m_quad_order)
2439 *   , m_n_q_points(m_qf_cell.size())
2440 *   , m_vol_reference(0.0)
2441 *   {}
2442 *  
2443 *   template <int dim>
2444 *   void PhaseFieldMonolithicSolve<dim>::make_grid()
2445 *   {
2446 *   if (m_parameters.m_scenario == 1)
2447 *   make_grid_case_1();
2448 *   else if (m_parameters.m_scenario == 2)
2449 *   make_grid_case_2();
2450 *   else if (m_parameters.m_scenario == 3)
2451 *   make_grid_case_3();
2452 *   else if (m_parameters.m_scenario == 4)
2453 *   make_grid_case_4();
2454 *   else if (m_parameters.m_scenario == 5)
2455 *   make_grid_case_5();
2456 *   else if (m_parameters.m_scenario == 6)
2457 *   make_grid_case_6();
2458 *   else if (m_parameters.m_scenario == 7)
2459 *   make_grid_case_7();
2460 *   else if (m_parameters.m_scenario == 8)
2461 *   make_grid_case_8();
2462 *   else if (m_parameters.m_scenario == 9)
2463 *   make_grid_case_9();
2464 *   else if (m_parameters.m_scenario == 11)
2465 *   make_grid_case_11();
2466 *   else
2467 *   Assert(false, ExcMessage("The scenario has not been implemented!"));
2468 *  
2469 *   m_logfile << "\t\tTriangulation:"
2470 *   << "\n\t\t\tNumber of active cells: "
2471 *   << m_triangulation.n_active_cells()
2472 *   << "\n\t\t\tNumber of used vertices: "
2473 *   << m_triangulation.n_used_vertices()
2474 *   << std::endl;
2475 *  
2476 *   std::ofstream out("original_mesh.vtu");
2477 *   GridOut grid_out;
2478 *   grid_out.write_vtu(m_triangulation, out);
2479 *  
2480 *   m_vol_reference = GridTools::volume(m_triangulation);
2481 *   m_logfile << "\t\tGrid:\n\t\t\tReference volume: " << m_vol_reference << std::endl;
2482 *   }
2483 *  
2484 *   template <int dim>
2485 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_1()
2486 *   {
2487 *   for (unsigned int i = 0; i < 80; ++i)
2488 *   m_logfile << "*";
2489 *   m_logfile << std::endl;
2490 *   m_logfile << "\t\t\tSquare tension (unstructured)" << std::endl;
2491 *   for (unsigned int i = 0; i < 80; ++i)
2492 *   m_logfile << "*";
2493 *   m_logfile << std::endl;
2494 *  
2495 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
2496 *  
2497 *   GridIn<dim> gridin;
2498 *   gridin.attach_triangulation(m_triangulation);
2499 *   std::ifstream f("square_tension_unstructured.msh");
2500 *   gridin.read_msh(f);
2501 *  
2502 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2503 *   for (const auto &face : cell->face_iterators())
2504 *   {
2505 *   if (face->at_boundary() == true)
2506 *   {
2507 *   if (std::fabs(face->center()[1] + 0.5 ) < 1.0e-9 )
2508 *   face->set_boundary_id(0);
2509 *   else if (std::fabs(face->center()[1] - 0.5 ) < 1.0e-9)
2510 *   face->set_boundary_id(1);
2511 *   else
2512 *   face->set_boundary_id(2);
2513 *   }
2514 *   }
2515 *  
2516 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
2517 *  
2518 *   if (m_parameters.m_refinement_strategy == "pre-refine")
2519 *   {
2520 *   unsigned int material_id;
2521 *   double length_scale;
2522 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
2523 *   {
2524 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2525 *   {
2526 *   if ( std::fabs(cell->center()[1]) < 0.01
2527 *   && cell->center()[0] > 0.495)
2528 *   {
2529 *   material_id = cell->material_id();
2530 *   length_scale = m_material_data[material_id][2];
2531 *   if ( std::sqrt(cell->measure())
2532 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2533 *   cell->set_refine_flag();
2534 *   }
2535 *   }
2536 *   m_triangulation.execute_coarsening_and_refinement();
2537 *   }
2538 *   }
2539 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
2540 *   {
2541 *   unsigned int material_id;
2542 *   double length_scale;
2543 *   bool initiation_point_refine_unfinished = true;
2544 *   while (initiation_point_refine_unfinished)
2545 *   {
2546 *   initiation_point_refine_unfinished = false;
2547 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2548 *   {
2549 *   if ( std::fabs(cell->center()[1] - 0.0) < 0.05
2550 *   && std::fabs(cell->center()[0] - 0.5) < 0.05)
2551 *   {
2552 *   material_id = cell->material_id();
2553 *   length_scale = m_material_data[material_id][2];
2554 *   if ( std::sqrt(cell->measure())
2555 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2556 *   {
2557 *   cell->set_refine_flag();
2558 *   initiation_point_refine_unfinished = true;
2559 *   }
2560 *   }
2561 *   }
2562 *   m_triangulation.execute_coarsening_and_refinement();
2563 *   }
2564 *   }
2565 *   else
2566 *   {
2567 *   AssertThrow(false,
2568 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
2569 *   }
2570 *   }
2571 *  
2572 *  
2573 *   template <int dim>
2574 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_2()
2575 *   {
2576 *   for (unsigned int i = 0; i < 80; ++i)
2577 *   m_logfile << "*";
2578 *   m_logfile << std::endl;
2579 *   m_logfile << "\t\t\t\tSquare shear (unstructured)" << std::endl;
2580 *   for (unsigned int i = 0; i < 80; ++i)
2581 *   m_logfile << "*";
2582 *   m_logfile << std::endl;
2583 *  
2584 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
2585 *  
2586 *   GridIn<dim> gridin;
2587 *   gridin.attach_triangulation(m_triangulation);
2588 *   std::ifstream f("square_shear_unstructured.msh");
2589 *   gridin.read_msh(f);
2590 *  
2591 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2592 *   for (const auto &face : cell->face_iterators())
2593 *   {
2594 *   if (face->at_boundary() == true)
2595 *   {
2596 *   if (std::fabs(face->center()[1] + 0.5 ) < 1.0e-9 )
2597 *   face->set_boundary_id(0);
2598 *   else if (std::fabs(face->center()[1] - 0.5 ) < 1.0e-9)
2599 *   face->set_boundary_id(1);
2600 *   else if ( (std::fabs(face->center()[0] - 0.0 ) < 1.0e-9)
2601 *   || (std::fabs(face->center()[0] - 1.0 ) < 1.0e-9))
2602 *   face->set_boundary_id(2);
2603 *   else
2604 *   face->set_boundary_id(3);
2605 *   }
2606 *   }
2607 *  
2608 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
2609 *  
2610 *   if (m_parameters.m_refinement_strategy == "pre-refine")
2611 *   {
2612 *   unsigned int material_id;
2613 *   double length_scale;
2614 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
2615 *   {
2616 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2617 *   {
2618 *   if ( (cell->center()[0] > 0.45)
2619 *   && (cell->center()[1] < 0.05) )
2620 *   {
2621 *   material_id = cell->material_id();
2622 *   length_scale = m_material_data[material_id][2];
2623 *   if ( std::sqrt(cell->measure())
2624 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2625 *   cell->set_refine_flag();
2626 *   }
2627 *   }
2628 *   m_triangulation.execute_coarsening_and_refinement();
2629 *   }
2630 *   }
2631 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
2632 *   {
2633 *   unsigned int material_id;
2634 *   double length_scale;
2635 *   bool initiation_point_refine_unfinished = true;
2636 *   while (initiation_point_refine_unfinished)
2637 *   {
2638 *   initiation_point_refine_unfinished = false;
2639 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2640 *   {
2641 *   if ( std::fabs(cell->center()[0] - 0.5) < 0.025
2642 *   && cell->center()[1] < 0.0 && cell->center()[1] > -0.025)
2643 *   {
2644 *   material_id = cell->material_id();
2645 *   length_scale = m_material_data[material_id][2];
2646 *   if ( std::sqrt(cell->measure())
2647 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2648 *   {
2649 *   cell->set_refine_flag();
2650 *   initiation_point_refine_unfinished = true;
2651 *   }
2652 *   }
2653 *   }
2654 *   m_triangulation.execute_coarsening_and_refinement();
2655 *   }
2656 *   }
2657 *   else
2658 *   {
2659 *   AssertThrow(false,
2660 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
2661 *   }
2662 *   }
2663 *  
2664 *   template <int dim>
2665 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_3()
2666 *   {
2667 *   for (unsigned int i = 0; i < 80; ++i)
2668 *   m_logfile << "*";
2669 *   m_logfile << std::endl;
2670 *   m_logfile << "\t\t\tSquare tension (structured)" << std::endl;
2671 *   for (unsigned int i = 0; i < 80; ++i)
2672 *   m_logfile << "*";
2673 *   m_logfile << std::endl;
2674 *  
2675 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
2676 *  
2677 *   GridIn<dim> gridin;
2678 *   gridin.attach_triangulation(m_triangulation);
2679 *   std::ifstream f("square_tension_structured.msh");
2680 *   gridin.read_msh(f);
2681 *  
2682 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2683 *   for (const auto &face : cell->face_iterators())
2684 *   {
2685 *   if (face->at_boundary() == true)
2686 *   {
2687 *   if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9 )
2688 *   face->set_boundary_id(0);
2689 *   else if (std::fabs(face->center()[1] - 1.0 ) < 1.0e-9)
2690 *   face->set_boundary_id(1);
2691 *   else
2692 *   face->set_boundary_id(2);
2693 *   }
2694 *   }
2695 *  
2696 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
2697 *  
2698 *   if (m_parameters.m_refinement_strategy == "pre-refine")
2699 *   {
2700 *   unsigned int material_id;
2701 *   double length_scale;
2702 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
2703 *   {
2704 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2705 *   {
2706 *   if ( (std::fabs(cell->center()[1] - 0.5) < 0.025)
2707 *   && (cell->center()[0] > 0.475) )
2708 *   {
2709 *   material_id = cell->material_id();
2710 *   length_scale = m_material_data[material_id][2];
2711 *   if ( std::sqrt(cell->measure())
2712 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2713 *   cell->set_refine_flag();
2714 *   }
2715 *   }
2716 *   m_triangulation.execute_coarsening_and_refinement();
2717 *   }
2718 *   }
2719 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
2720 *   {
2721 *   unsigned int material_id;
2722 *   double length_scale;
2723 *   bool initiation_point_refine_unfinished = true;
2724 *   while (initiation_point_refine_unfinished)
2725 *   {
2726 *   initiation_point_refine_unfinished = false;
2727 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2728 *   {
2729 *   if ( std::fabs(cell->center()[0] - 0.5) < 0.025
2730 *   && std::fabs(cell->center()[1] - 0.5) < 0.025 )
2731 *   {
2732 *   material_id = cell->material_id();
2733 *   length_scale = m_material_data[material_id][2];
2734 *   if ( std::sqrt(cell->measure())
2735 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2736 *   {
2737 *   cell->set_refine_flag();
2738 *   initiation_point_refine_unfinished = true;
2739 *   }
2740 *   }
2741 *   }
2742 *   m_triangulation.execute_coarsening_and_refinement();
2743 *   }
2744 *   }
2745 *   else
2746 *   {
2747 *   AssertThrow(false,
2748 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
2749 *   }
2750 *   }
2751 *  
2752 *   template <int dim>
2753 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_4()
2754 *   {
2755 *   for (unsigned int i = 0; i < 80; ++i)
2756 *   m_logfile << "*";
2757 *   m_logfile << std::endl;
2758 *   m_logfile << "\t\t\t\tSquare shear (structured)" << std::endl;
2759 *   for (unsigned int i = 0; i < 80; ++i)
2760 *   m_logfile << "*";
2761 *   m_logfile << std::endl;
2762 *  
2763 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
2764 *  
2765 *   GridIn<dim> gridin;
2766 *   gridin.attach_triangulation(m_triangulation);
2767 *   std::ifstream f("square_shear_structured.msh");
2768 *   gridin.read_msh(f);
2769 *  
2770 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2771 *   for (const auto &face : cell->face_iterators())
2772 *   {
2773 *   if (face->at_boundary() == true)
2774 *   {
2775 *   if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9 )
2776 *   face->set_boundary_id(0);
2777 *   else if (std::fabs(face->center()[1] - 1.0 ) < 1.0e-9)
2778 *   face->set_boundary_id(1);
2779 *   else if ( (std::fabs(face->center()[0] - 0.0 ) < 1.0e-9)
2780 *   || (std::fabs(face->center()[0] - 1.0 ) < 1.0e-9))
2781 *   face->set_boundary_id(2);
2782 *   else
2783 *   face->set_boundary_id(3);
2784 *   }
2785 *   }
2786 *  
2787 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
2788 *  
2789 *   if (m_parameters.m_refinement_strategy == "pre-refine")
2790 *   {
2791 *   unsigned int material_id;
2792 *   double length_scale;
2793 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
2794 *   {
2795 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2796 *   {
2797 *   if ( (cell->center()[0] > 0.475)
2798 *   && (cell->center()[1] < 0.525) )
2799 *   {
2800 *   material_id = cell->material_id();
2801 *   length_scale = m_material_data[material_id][2];
2802 *   if ( std::sqrt(cell->measure())
2803 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2804 *   cell->set_refine_flag();
2805 *   }
2806 *   }
2807 *   m_triangulation.execute_coarsening_and_refinement();
2808 *   }
2809 *   }
2810 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
2811 *   {
2812 *   unsigned int material_id;
2813 *   double length_scale;
2814 *   bool initiation_point_refine_unfinished = true;
2815 *   while (initiation_point_refine_unfinished)
2816 *   {
2817 *   initiation_point_refine_unfinished = false;
2818 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2819 *   {
2820 *   if ( std::fabs(cell->center()[0] - 0.5) < 0.025
2821 *   && cell->center()[1] < 0.5 && cell->center()[1] > 0.475 )
2822 *   {
2823 *   material_id = cell->material_id();
2824 *   length_scale = m_material_data[material_id][2];
2825 *   if ( std::sqrt(cell->measure())
2826 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2827 *   {
2828 *   cell->set_refine_flag();
2829 *   initiation_point_refine_unfinished = true;
2830 *   }
2831 *   }
2832 *   }
2833 *   m_triangulation.execute_coarsening_and_refinement();
2834 *   }
2835 *   }
2836 *   else
2837 *   {
2838 *   AssertThrow(false,
2839 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
2840 *   }
2841 *   }
2842 *  
2843 *   template <int dim>
2844 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_5()
2845 *   {
2846 *   for (unsigned int i = 0; i < 80; ++i)
2847 *   m_logfile << "*";
2848 *   m_logfile << std::endl;
2849 *   m_logfile << "\t\t\t\tThree-point bending (structured)" << std::endl;
2850 *   for (unsigned int i = 0; i < 80; ++i)
2851 *   m_logfile << "*";
2852 *   m_logfile << std::endl;
2853 *  
2854 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
2855 *  
2856 *   GridIn<dim> gridin;
2857 *   gridin.attach_triangulation(m_triangulation);
2858 *   std::ifstream f("three_point_bending_structured.msh");
2859 *   gridin.read_msh(f);
2860 *  
2861 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2862 *   for (const auto &face : cell->face_iterators())
2863 *   {
2864 *   if (face->at_boundary() == true)
2865 *   {
2866 *   if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9 )
2867 *   face->set_boundary_id(0);
2868 *   else if (std::fabs(face->center()[1] - 2.0 ) < 1.0e-9)
2869 *   face->set_boundary_id(1);
2870 *   else
2871 *   face->set_boundary_id(2);
2872 *   }
2873 *   }
2874 *  
2875 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
2876 *  
2877 *   if (m_parameters.m_refinement_strategy == "pre-refine")
2878 *   {
2879 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2880 *   {
2881 *   if ( std::fabs(cell->center()[0] - 4.0) < 0.075
2882 *   && cell->center()[1] < 1.6)
2883 *   {
2884 *   cell->set_refine_flag();
2885 *   }
2886 *   }
2887 *   m_triangulation.execute_coarsening_and_refinement();
2888 *  
2889 *   unsigned int material_id;
2890 *   double length_scale;
2891 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
2892 *   {
2893 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2894 *   {
2895 *   if ( std::fabs(cell->center()[0] - 4.0) < 0.05
2896 *   && cell->center()[1] < 1.6)
2897 *   {
2898 *   material_id = cell->material_id();
2899 *   length_scale = m_material_data[material_id][2];
2900 *   if ( std::sqrt(cell->measure())
2901 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2902 *   cell->set_refine_flag();
2903 *   }
2904 *   }
2905 *   m_triangulation.execute_coarsening_and_refinement();
2906 *   }
2907 *   }
2908 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
2909 *   {
2910 *   unsigned int material_id;
2911 *   double length_scale;
2912 *   bool initiation_point_refine_unfinished = true;
2913 *   while (initiation_point_refine_unfinished)
2914 *   {
2915 *   initiation_point_refine_unfinished = false;
2916 *   for (const auto &cell : m_triangulation.active_cell_iterators())
2917 *   {
2918 *   if ( std::fabs(cell->center()[0] - 4.0) < 0.075
2919 *   && std::fabs(cell->center()[1] - 0.4) < 0.075 )
2920 *   {
2921 *   material_id = cell->material_id();
2922 *   length_scale = m_material_data[material_id][2];
2923 *   if ( std::sqrt(cell->measure())
2924 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
2925 *   {
2926 *   cell->set_refine_flag();
2927 *   initiation_point_refine_unfinished = true;
2928 *   }
2929 *   }
2930 *   }
2931 *   m_triangulation.execute_coarsening_and_refinement();
2932 *   }
2933 *   }
2934 *   else
2935 *   {
2936 *   AssertThrow(false,
2937 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
2938 *   }
2939 *   }
2940 *  
2941 *   template <int dim>
2942 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_6()
2943 *   {
2944 *   AssertThrow(dim==3, ExcMessage("The dimension has to be 3D!"));
2945 *  
2946 *   for (unsigned int i = 0; i < 80; ++i)
2947 *   m_logfile << "*";
2948 *   m_logfile << std::endl;
2949 *   m_logfile << "\t\t\t\tSphere inclusion (3D structured)" << std::endl;
2950 *   for (unsigned int i = 0; i < 80; ++i)
2951 *   m_logfile << "*";
2952 *   m_logfile << std::endl;
2953 *  
2954 *   Triangulation<dim> tria_inner;
2955 *   GridGenerator::hyper_ball(tria_inner, Point<dim>(), 0.5);
2956 *  
2957 *   Triangulation<dim> tria_outer;
2959 *   tria_outer, Point<dim>(), 0.5, std::sqrt(dim), 2 * dim);
2960 *  
2961 *   Triangulation<dim> tmp_triangulation;
2962 *  
2963 *   GridGenerator::merge_triangulations(tria_inner, tria_outer, tmp_triangulation);
2964 *  
2965 *   tmp_triangulation.reset_all_manifolds();
2966 *   tmp_triangulation.set_all_manifold_ids(0);
2967 *  
2968 *   for (const auto &cell : tmp_triangulation.cell_iterators())
2969 *   {
2970 *   for (const auto &face : cell->face_iterators())
2971 *   {
2972 *   bool face_at_sphere_boundary = true;
2973 *   for (const auto v : face->vertex_indices())
2974 *   {
2975 *   if (std::abs(face->vertex(v).norm_square() - 0.25) > 1e-12)
2976 *   face_at_sphere_boundary = false;
2977 *   }
2978 *   if (face_at_sphere_boundary)
2979 *   face->set_all_manifold_ids(1);
2980 *   }
2981 *   if (cell->center().norm_square() < 0.25)
2982 *   cell->set_material_id(1);
2983 *   else
2984 *   cell->set_material_id(0);
2985 *   }
2986 *  
2987 *   tmp_triangulation.set_manifold(1, SphericalManifold<dim>());
2988 *  
2989 *   TransfiniteInterpolationManifold<dim> transfinite_manifold;
2990 *   transfinite_manifold.initialize(tmp_triangulation);
2991 *   tmp_triangulation.set_manifold(0, transfinite_manifold);
2992 *  
2993 *   tmp_triangulation.refine_global(m_parameters.m_global_refine_times);
2994 *  
2995 *   std::set<typename Triangulation< dim >::active_cell_iterator >
2996 *   cells_to_remove;
2997 *  
2998 *   for (const auto &cell : tmp_triangulation.active_cell_iterators())
2999 *   {
3000 *   if ( cell->center()[0] < 0.0
3001 *   || cell->center()[1] < 0.0
3002 *   || cell->center()[2] < 0.0)
3003 *   {
3004 *   cells_to_remove.insert(cell);
3005 *   }
3006 *   }
3007 *  
3009 *   cells_to_remove,
3010 *   m_triangulation);
3011 *  
3012 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3013 *   for (const auto &face : cell->face_iterators())
3014 *   {
3015 *   if (face->at_boundary() == true)
3016 *   {
3017 *   if (std::fabs(face->center()[0] - 0.0 ) < 1.0e-9 )
3018 *   face->set_boundary_id(0);
3019 *   else if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9)
3020 *   face->set_boundary_id(1);
3021 *   else if (std::fabs(face->center()[2] - 0.0 ) < 1.0e-9)
3022 *   face->set_boundary_id(2);
3023 *   else if (std::fabs(face->center()[2] - 1.0 ) < 1.0e-9)
3024 *   face->set_boundary_id(3);
3025 *   else
3026 *   face->set_boundary_id(4);
3027 *   }
3028 *   }
3029 *  
3030 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
3031 *   {
3032 *   unsigned int material_id;
3033 *   double length_scale;
3034 *   bool initiation_point_refine_unfinished = true;
3035 *   while (initiation_point_refine_unfinished)
3036 *   {
3037 *   initiation_point_refine_unfinished = false;
3038 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3039 *   {
3040 *   if ( cell->center()[2] > 0.525
3041 *   && cell->center()[2] < 0.575
3042 *   && cell->center()[0] < 0.05
3043 *   && cell->center()[1] < 0.05 )
3044 *   {
3045 *   material_id = cell->material_id();
3046 *   length_scale = m_material_data[material_id][2];
3047 *   if ( std::cbrt(cell->measure())
3048 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3049 *   {
3050 *   cell->set_refine_flag();
3051 *   initiation_point_refine_unfinished = true;
3052 *   }
3053 *   }
3054 *   }
3055 *   m_triangulation.execute_coarsening_and_refinement();
3056 *   }
3057 *   }
3058 *   else
3059 *   {
3060 *   AssertThrow(false,
3061 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
3062 *   }
3063 *   }
3064 *  
3065 *   template <int dim>
3066 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_7()
3067 *   {
3068 *   AssertThrow(dim==3, ExcMessage("The dimension has to be 3D!"));
3069 *  
3070 *   for (unsigned int i = 0; i < 80; ++i)
3071 *   m_logfile << "*";
3072 *   m_logfile << std::endl;
3073 *   m_logfile << "\t\t\t\tSphere inclusion (3D structured version 2)" << std::endl;
3074 *   for (unsigned int i = 0; i < 80; ++i)
3075 *   m_logfile << "*";
3076 *   m_logfile << std::endl;
3077 *  
3078 *   Triangulation<dim> tria_inner;
3079 *   GridGenerator::hyper_ball(tria_inner, Point<dim>(), 0.49);
3080 *  
3081 *   Triangulation<dim> tria_outer;
3083 *   tria_outer, Point<dim>(), 0.49, std::sqrt(dim)*0.5, 2 * dim);
3084 *  
3085 *   Triangulation<dim> cube1;
3086 *   GridGenerator::hyper_rectangle(cube1, Point<dim>(0, 0, 0.5), Point<dim>(1, 1, 1.5));
3087 *   Triangulation<dim> cube2;
3088 *   GridGenerator::hyper_rectangle(cube2, Point<dim>(0, 0.5, -0.5), Point<dim>(1, 1.5, 0.5));
3089 *   Triangulation<dim> cube3;
3090 *   GridGenerator::hyper_rectangle(cube3, Point<dim>(0.5, -0.5, -0.5), Point<dim>(1.5, 0.5, 0.5));
3091 *  
3092 *   Triangulation<dim> tmp_triangulation;
3093 *   GridGenerator::merge_triangulations({&tria_inner, &tria_outer,
3094 *   &cube1, &cube2, &cube3}, tmp_triangulation);
3095 *  
3096 *   tmp_triangulation.reset_all_manifolds();
3097 *   tmp_triangulation.set_all_manifold_ids(0);
3098 *  
3099 *   for (const auto &cell : tmp_triangulation.cell_iterators())
3100 *   {
3101 *   for (const auto &face : cell->face_iterators())
3102 *   {
3103 *   bool face_at_sphere_boundary = true;
3104 *   for (const auto v : face->vertex_indices())
3105 *   {
3106 *   if (std::abs(face->vertex(v).norm_square() - 0.49 * 0.49) > 1e-12)
3107 *   face_at_sphere_boundary = false;
3108 *   }
3109 *   if (face_at_sphere_boundary)
3110 *   face->set_all_manifold_ids(1);
3111 *   }
3112 *   if (cell->center().norm_square() < 0.1)
3113 *   cell->set_material_id(1);
3114 *   else
3115 *   cell->set_material_id(0);
3116 *   }
3117 *  
3118 *   tmp_triangulation.set_manifold(1, SphericalManifold<dim>());
3119 *  
3120 *   TransfiniteInterpolationManifold<dim> transfinite_manifold;
3121 *   transfinite_manifold.initialize(tmp_triangulation);
3122 *   tmp_triangulation.set_manifold(0, transfinite_manifold);
3123 *  
3124 *   tmp_triangulation.refine_global(m_parameters.m_global_refine_times);
3125 *  
3126 *   std::set<typename Triangulation< dim >::active_cell_iterator >
3127 *   cells_to_remove;
3128 *  
3129 *   for (const auto &cell : tmp_triangulation.active_cell_iterators())
3130 *   {
3131 *   if ( cell->center()[0] < 0.0
3132 *   || cell->center()[1] < 0.0
3133 *   || cell->center()[2] < 0.0
3134 *   || cell->center()[0] > 1.0
3135 *   || cell->center()[1] > 1.0
3136 *   || cell->center()[2] > 1.0)
3137 *   {
3138 *   cells_to_remove.insert(cell);
3139 *   }
3140 *   }
3141 *  
3143 *   cells_to_remove,
3144 *   m_triangulation);
3145 *  
3146 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3147 *   for (const auto &face : cell->face_iterators())
3148 *   {
3149 *   if (face->at_boundary() == true)
3150 *   {
3151 *   if (std::fabs(face->center()[0] - 0.0 ) < 1.0e-9 )
3152 *   face->set_boundary_id(0);
3153 *   else if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9)
3154 *   face->set_boundary_id(1);
3155 *   else if (std::fabs(face->center()[2] - 0.0 ) < 1.0e-9)
3156 *   face->set_boundary_id(2);
3157 *   else if (std::fabs(face->center()[2] - 1.0 ) < 1.0e-9)
3158 *   face->set_boundary_id(3);
3159 *   else
3160 *   face->set_boundary_id(4);
3161 *   }
3162 *   }
3163 *  
3164 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
3165 *   {
3166 *   unsigned int material_id;
3167 *   double length_scale;
3168 *   bool initiation_point_refine_unfinished = true;
3169 *   while (initiation_point_refine_unfinished)
3170 *   {
3171 *   initiation_point_refine_unfinished = false;
3172 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3173 *   {
3174 *   if ( cell->center()[2] > 0.505
3175 *   && cell->center()[2] < 0.575
3176 *   && cell->center()[0] < 0.05
3177 *   && cell->center()[1] < 0.05 )
3178 *   {
3179 *   material_id = cell->material_id();
3180 *   length_scale = m_material_data[material_id][2];
3181 *   if ( std::cbrt(cell->measure())
3182 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3183 *   {
3184 *   cell->set_refine_flag();
3185 *   initiation_point_refine_unfinished = true;
3186 *   }
3187 *   }
3188 *   }
3189 *   m_triangulation.execute_coarsening_and_refinement();
3190 *   }
3191 *   }
3192 *   else
3193 *   {
3194 *   AssertThrow(false,
3195 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
3196 *   }
3197 *   }
3198 *  
3199 *  
3200 *   template <int dim>
3201 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_8()
3202 *   {
3203 *   AssertThrow(dim==3, ExcMessage("The dimension has to be 3D!"));
3204 *  
3205 *   for (unsigned int i = 0; i < 80; ++i)
3206 *   m_logfile << "*";
3207 *   m_logfile << std::endl;
3208 *   m_logfile << "\t\t\t\tSphere inclusion (3D structured version 2 with barriers)" << std::endl;
3209 *   for (unsigned int i = 0; i < 80; ++i)
3210 *   m_logfile << "*";
3211 *   m_logfile << std::endl;
3212 *  
3213 *   Triangulation<dim> tria_inner;
3214 *   GridGenerator::hyper_ball(tria_inner, Point<dim>(), 0.49);
3215 *  
3216 *   Triangulation<dim> tria_outer;
3218 *   tria_outer, Point<dim>(), 0.49, std::sqrt(dim)*0.5, 2 * dim);
3219 *  
3220 *   Triangulation<dim> cube1;
3221 *   GridGenerator::hyper_rectangle(cube1, Point<dim>(0, 0, 0.5), Point<dim>(1, 1, 1.5));
3222 *   Triangulation<dim> cube2;
3223 *   GridGenerator::hyper_rectangle(cube2, Point<dim>(0, 0.5, -0.5), Point<dim>(1, 1.5, 0.5));
3224 *   Triangulation<dim> cube3;
3225 *   GridGenerator::hyper_rectangle(cube3, Point<dim>(0.5, -0.5, -0.5), Point<dim>(1.5, 0.5, 0.5));
3226 *  
3227 *   Triangulation<dim> tmp_triangulation;
3228 *   GridGenerator::merge_triangulations({&tria_inner, &tria_outer,
3229 *   &cube1, &cube2, &cube3}, tmp_triangulation);
3230 *  
3231 *   tmp_triangulation.reset_all_manifolds();
3232 *   tmp_triangulation.set_all_manifold_ids(0);
3233 *  
3234 *   for (const auto &cell : tmp_triangulation.cell_iterators())
3235 *   {
3236 *   for (const auto &face : cell->face_iterators())
3237 *   {
3238 *   bool face_at_sphere_boundary = true;
3239 *   for (const auto v : face->vertex_indices())
3240 *   {
3241 *   if (std::abs(face->vertex(v).norm_square() - 0.49 * 0.49) > 1e-12)
3242 *   face_at_sphere_boundary = false;
3243 *   }
3244 *   if (face_at_sphere_boundary)
3245 *   face->set_all_manifold_ids(1);
3246 *   }
3247 *   if (cell->center().norm_square() < 0.1)
3248 *   cell->set_material_id(1);
3249 *   else
3250 *   cell->set_material_id(0);
3251 *   }
3252 *  
3253 *   tmp_triangulation.set_manifold(1, SphericalManifold<dim>());
3254 *  
3255 *   TransfiniteInterpolationManifold<dim> transfinite_manifold;
3256 *   transfinite_manifold.initialize(tmp_triangulation);
3257 *   tmp_triangulation.set_manifold(0, transfinite_manifold);
3258 *  
3259 *   tmp_triangulation.refine_global(m_parameters.m_global_refine_times);
3260 *  
3261 * @endcode
3262 *
3263 * some extra barriers
3264 *
3265 * @code
3266 *   for (const auto &cell : tmp_triangulation.cell_iterators())
3267 *   {
3268 *   if ( std::fabs(cell->center()[1] - 0.75) < 0.05
3269 *   && std::fabs(cell->center()[2] - 0.5625) < 0.05
3270 *   && std::fabs(cell->center()[0] - 0.0) < 0.2)
3271 *   cell->set_material_id(1);
3272 *  
3273 *   if ( std::fabs(cell->center()[1] - 0.0) < 0.2
3274 *   && std::fabs(cell->center()[2] - 0.5) < 0.1
3275 *   && std::fabs(cell->center()[0] - 0.75) < 0.05)
3276 *   cell->set_material_id(1);
3277 *   }
3278 *  
3279 *   std::set<typename Triangulation< dim >::active_cell_iterator >
3280 *   cells_to_remove;
3281 *  
3282 *   for (const auto &cell : tmp_triangulation.active_cell_iterators())
3283 *   {
3284 *   if ( cell->center()[0] < 0.0
3285 *   || cell->center()[1] < 0.0
3286 *   || cell->center()[2] < 0.0
3287 *   || cell->center()[0] > 1.0
3288 *   || cell->center()[1] > 1.0
3289 *   || cell->center()[2] > 1.0)
3290 *   {
3291 *   cells_to_remove.insert(cell);
3292 *   }
3293 *   }
3294 *  
3296 *   cells_to_remove,
3297 *   m_triangulation);
3298 *  
3299 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3300 *   for (const auto &face : cell->face_iterators())
3301 *   {
3302 *   if (face->at_boundary() == true)
3303 *   {
3304 *   if (std::fabs(face->center()[0] - 0.0 ) < 1.0e-9 )
3305 *   face->set_boundary_id(0);
3306 *   else if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9)
3307 *   face->set_boundary_id(1);
3308 *   else if (std::fabs(face->center()[2] - 0.0 ) < 1.0e-9)
3309 *   face->set_boundary_id(2);
3310 *   else if (std::fabs(face->center()[2] - 1.0 ) < 1.0e-9)
3311 *   face->set_boundary_id(3);
3312 *   else
3313 *   face->set_boundary_id(4);
3314 *   }
3315 *   }
3316 *  
3317 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
3318 *   {
3319 *   unsigned int material_id;
3320 *   double length_scale;
3321 *   bool initiation_point_refine_unfinished = true;
3322 *   while (initiation_point_refine_unfinished)
3323 *   {
3324 *   initiation_point_refine_unfinished = false;
3325 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3326 *   {
3327 *   if ( cell->center()[2] > 0.505
3328 *   && cell->center()[2] < 0.575
3329 *   && cell->center()[0] < 0.05
3330 *   && cell->center()[1] < 0.05 )
3331 *   {
3332 *   material_id = cell->material_id();
3333 *   length_scale = m_material_data[material_id][2];
3334 *   if ( std::cbrt(cell->measure())
3335 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3336 *   {
3337 *   cell->set_refine_flag();
3338 *   initiation_point_refine_unfinished = true;
3339 *   }
3340 *   }
3341 *   }
3342 *   m_triangulation.execute_coarsening_and_refinement();
3343 *   }
3344 *   }
3345 *   else
3346 *   {
3347 *   AssertThrow(false,
3348 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
3349 *   }
3350 *   }
3351 *  
3352 *  
3353 *   template <int dim>
3354 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_9()
3355 *   {
3356 *   AssertThrow(dim==2, ExcMessage("The dimension has to be 2D!"));
3357 *  
3358 *   for (unsigned int i = 0; i < 80; ++i)
3359 *   m_logfile << "*";
3360 *   m_logfile << std::endl;
3361 *   m_logfile << "\t\t\t\tL-shape bending (2D structured)" << std::endl;
3362 *   for (unsigned int i = 0; i < 80; ++i)
3363 *   m_logfile << "*";
3364 *   m_logfile << std::endl;
3365 *  
3366 *   GridIn<dim> gridin;
3367 *   gridin.attach_triangulation(m_triangulation);
3368 *   std::ifstream f("L-Shape.msh");
3369 *   gridin.read_msh(f);
3370 *  
3371 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3372 *   for (const auto &face : cell->face_iterators())
3373 *   {
3374 *   if (face->at_boundary() == true)
3375 *   {
3376 *   if (std::fabs(face->center()[1] - 0.0 ) < 1.0e-9 )
3377 *   face->set_boundary_id(0);
3378 *   else
3379 *   face->set_boundary_id(1);
3380 *   }
3381 *   }
3382 *  
3383 *   m_triangulation.refine_global(m_parameters.m_global_refine_times);
3384 *  
3385 *   if (m_parameters.m_refinement_strategy == "pre-refine")
3386 *   {
3387 *   unsigned int material_id;
3388 *   double length_scale;
3389 *   for (unsigned int i = 0; i < m_parameters.m_local_prerefine_times; i++)
3390 *   {
3391 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3392 *   {
3393 *   if ( (cell->center()[1] > 242.0)
3394 *   && (cell->center()[1] < 312.5)
3395 *   && (cell->center()[0] < 258.0) )
3396 *   {
3397 *   material_id = cell->material_id();
3398 *   length_scale = m_material_data[material_id][2];
3399 *   if ( std::sqrt(cell->measure())
3400 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3401 *   cell->set_refine_flag();
3402 *   }
3403 *   }
3404 *   m_triangulation.execute_coarsening_and_refinement();
3405 *   }
3406 *   }
3407 *   else if (m_parameters.m_refinement_strategy == "adaptive-refine")
3408 *   {
3409 *   unsigned int material_id;
3410 *   double length_scale;
3411 *   bool initiation_point_refine_unfinished = true;
3412 *   while (initiation_point_refine_unfinished)
3413 *   {
3414 *   initiation_point_refine_unfinished = false;
3415 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3416 *   {
3417 *   if ( (cell->center()[0] - 250) < 0.0
3418 *   && (cell->center()[0] - 240) > 0.0
3419 *   && std::fabs(cell->center()[1] - 250) < 10.0 )
3420 *   {
3421 *   material_id = cell->material_id();
3422 *   length_scale = m_material_data[material_id][2];
3423 *   if ( std::sqrt(cell->measure())
3424 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3425 *   {
3426 *   cell->set_refine_flag();
3427 *   initiation_point_refine_unfinished = true;
3428 *   }
3429 *   }
3430 *   }
3431 *   m_triangulation.execute_coarsening_and_refinement();
3432 *   }
3433 *   }
3434 *   else
3435 *   {
3436 *   AssertThrow(false,
3437 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
3438 *   }
3439 *   }
3440 *  
3441 *   template <int dim>
3442 *   void PhaseFieldMonolithicSolve<dim>::make_grid_case_11()
3443 *   {
3444 *   AssertThrow(dim==3, ExcMessage("The dimension has to be 3D!"));
3445 *  
3446 *   for (unsigned int i = 0; i < 80; ++i)
3447 *   m_logfile << "*";
3448 *   m_logfile << std::endl;
3449 *   m_logfile << "\t\t\t\tBrokenshire torsion (3D structured)" << std::endl;
3450 *   for (unsigned int i = 0; i < 80; ++i)
3451 *   m_logfile << "*";
3452 *   m_logfile << std::endl;
3453 *  
3454 *   Triangulation<2> triangulation_2d;
3455 *  
3456 *   double const length = 200.0;
3457 *   double const width = 50.0;
3458 *   double const height = 50.0;
3459 *   double const delta_L = 25.0;
3460 *   double const tan_theta = delta_L / (0.5*width);
3461 *  
3462 *   std::vector<unsigned int> repetitions(2, 1);
3463 *   repetitions[0] = 20;
3464 *   repetitions[1] = 5;
3465 *  
3466 *   Point<2> point1(0.0, 0.0);
3467 *   Point<2> point2(length, width);
3468 *  
3470 *   repetitions,
3471 *   point1,
3472 *   point2 );
3473 *  
3474 *   typename Triangulation<2>::vertex_iterator vertex_ptr;
3475 *   vertex_ptr = triangulation_2d.begin_active_vertex();
3476 *   while (vertex_ptr != triangulation_2d.end_vertex())
3477 *   {
3478 *   Point<2> & vertex_point = vertex_ptr->vertex();
3479 *  
3480 *   const double delta_x = (vertex_point(1) - 0.5*width) * tan_theta;
3481 *  
3482 *   if (std::fabs(vertex_point(0) - 0.5*length) < 1.0e-6)
3483 *   {
3484 *   vertex_point(0) += delta_x;
3485 *   }
3486 *   else if (std::fabs(vertex_point(0) + length/repetitions[0] - 0.5*length) < 1.0e-6)
3487 *   {
3488 *   vertex_point(0) += (delta_x + length/repetitions[0]*0.5);
3489 *   }
3490 *   else if (std::fabs(vertex_point(0) - length/repetitions[0] - 0.5*length) < 1.0e-6)
3491 *   {
3492 *   vertex_point(0) += (delta_x - length/repetitions[0]*0.5);
3493 *   }
3494 *   else if (vertex_point(0) < 0.5*length - length/repetitions[0] - 1.0e-6)
3495 *   {
3496 *   vertex_point(0) += (delta_x + length/repetitions[0]*0.5) * vertex_point(0)/(0.5*length - length/repetitions[0]);
3497 *   }
3498 *   else if (vertex_point(0) > 0.5*length + length/repetitions[0] + 1.0e-6)
3499 *   {
3500 *   vertex_point(0) += (delta_x - length/repetitions[0]*0.5) * (length - vertex_point(0))/(0.5*length - length/repetitions[0]);
3501 *   }
3502 *  
3503 *   ++vertex_ptr;
3504 *   }
3505 *  
3506 *   Triangulation<dim> tmp_triangulation;
3507 *   const unsigned int n_layer = repetitions[1] + 1;
3508 *   GridGenerator::extrude_triangulation(triangulation_2d, n_layer, height, tmp_triangulation);
3509 *  
3510 *   tmp_triangulation.refine_global(m_parameters.m_global_refine_times);
3511 *  
3512 *   std::set<typename Triangulation< dim >::active_cell_iterator >
3513 *   cells_to_remove;
3514 *  
3515 *   for (const auto &cell : tmp_triangulation.active_cell_iterators())
3516 *   {
3517 *   if ( (std::fabs(cell->center()[0] - (cell->center()[1] - 0.5*width)*tan_theta - 0.5*length) < 2.5)
3518 *   && cell->center()[2] > 0.5* height )
3519 *   {
3520 *   cells_to_remove.insert(cell);
3521 *   }
3522 *   }
3523 *  
3525 *   cells_to_remove,
3526 *   m_triangulation);
3527 *  
3528 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
3529 *   {
3530 *   unsigned int material_id;
3531 *   double length_scale;
3532 *   bool initiation_point_refine_unfinished = true;
3533 *   while (initiation_point_refine_unfinished)
3534 *   {
3535 *   initiation_point_refine_unfinished = false;
3536 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3537 *   {
3538 *   if ( (std::fabs(cell->center()[0] - (cell->center()[1] - 0.5*width)*tan_theta - 0.5*length) < 5.0)
3539 *   && cell->center()[2] <= 0.5*height
3540 *   && cell->center()[2] > 0.5*height - 5.0 )
3541 *   {
3542 *   material_id = cell->material_id();
3543 *   length_scale = m_material_data[material_id][2];
3544 *   if ( std::cbrt(cell->measure())
3545 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
3546 *   {
3547 *   cell->set_refine_flag();
3548 *   initiation_point_refine_unfinished = true;
3549 *   }
3550 *   }
3551 *   }
3552 *   m_triangulation.execute_coarsening_and_refinement();
3553 *   }
3554 *   }
3555 *   else
3556 *   {
3557 *   AssertThrow(false,
3558 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
3559 *   }
3560 *  
3561 *  
3562 *   for (const auto &cell : m_triangulation.active_cell_iterators())
3563 *   for (const auto &face : cell->face_iterators())
3564 *   {
3565 *   if (face->at_boundary() == true)
3566 *   {
3567 *   if (std::fabs(face->center()[0] - length) < 1.0e-6 )
3568 *   face->set_boundary_id(0);
3569 *   else if (std::fabs(face->center()[0] - 0.0) < 1.0e-6 )
3570 *   face->set_boundary_id(1);
3571 *   else
3572 *   face->set_boundary_id(2);
3573 *   }
3574 *   }
3575 *   }
3576 *  
3577 *   template <int dim>
3578 *   void PhaseFieldMonolithicSolve<dim>::setup_system()
3579 *   {
3580 *   m_timer.enter_subsection("Setup system");
3581 *  
3582 *   std::vector<unsigned int> block_component(m_n_components,
3583 *   m_u_dof); // displacement
3584 *   block_component[m_d_component] = m_d_dof; // phasefield
3585 *  
3586 *   m_dof_handler.distribute_dofs(m_fe);
3587 *   DoFRenumbering::Cuthill_McKee(m_dof_handler);
3588 *   DoFRenumbering::component_wise(m_dof_handler, block_component);
3589 *  
3590 *   m_constraints.clear();
3591 *   DoFTools::make_hanging_node_constraints(m_dof_handler, m_constraints);
3592 *   m_constraints.close();
3593 *  
3594 *   m_dofs_per_block =
3595 *   DoFTools::count_dofs_per_fe_block(m_dof_handler, block_component);
3596 *  
3597 *   m_logfile << "\t\tTriangulation:"
3598 *   << "\n\t\t\t Number of active cells: "
3599 *   << m_triangulation.n_active_cells()
3600 *   << "\n\t\t\t Number of used vertices: "
3601 *   << m_triangulation.n_used_vertices()
3602 *   << "\n\t\t\t Number of active edges: "
3603 *   << m_triangulation.n_active_lines()
3604 *   << "\n\t\t\t Number of active faces: "
3605 *   << m_triangulation.n_active_faces()
3606 *   << "\n\t\t\t Number of degrees of freedom (total): "
3607 *   << m_dof_handler.n_dofs()
3608 *   << "\n\t\t\t Number of degrees of freedom (disp): "
3609 *   << m_dofs_per_block[m_u_dof]
3610 *   << "\n\t\t\t Number of degrees of freedom (phasefield): "
3611 *   << m_dofs_per_block[m_d_dof]
3612 *   << std::endl;
3613 *  
3614 *   m_tangent_matrix.clear();
3615 *   {
3616 *   BlockDynamicSparsityPattern dsp(m_dofs_per_block, m_dofs_per_block);
3617 *  
3618 *   Table<2, DoFTools::Coupling> coupling(m_n_components, m_n_components);
3619 *   for (unsigned int ii = 0; ii < m_n_components; ++ii)
3620 *   for (unsigned int jj = 0; jj < m_n_components; ++jj)
3621 *   coupling[ii][jj] = DoFTools::always;
3622 *  
3624 *   m_dof_handler, coupling, dsp, m_constraints, false);
3625 *   m_sparsity_pattern.copy_from(dsp);
3626 *   }
3627 *  
3628 *   m_tangent_matrix.reinit(m_sparsity_pattern);
3629 *  
3630 *   m_system_rhs.reinit(m_dofs_per_block);
3631 *   m_solution.reinit(m_dofs_per_block);
3632 *  
3633 *   setup_qph();
3634 *  
3635 *   m_timer.leave_subsection();
3636 *   }
3637 *  
3638 *   template <int dim>
3639 *   void PhaseFieldMonolithicSolve<dim>::make_constraints(const unsigned int it_nr)
3640 *   {
3641 *   const bool apply_dirichlet_bc = (it_nr == 0);
3642 *  
3643 *   if (it_nr > 1)
3644 *   {
3645 *   if (m_parameters.m_output_iteration_history)
3646 *   m_logfile << " --- " << std::flush;
3647 *   return;
3648 *   }
3649 *  
3650 *   if (m_parameters.m_output_iteration_history)
3651 *   m_logfile << " CST " << std::flush;
3652 *  
3653 *   if (apply_dirichlet_bc)
3654 *   {
3655 *   m_constraints.clear();
3657 *   m_constraints);
3658 *  
3659 *   const FEValuesExtractors::Scalar x_displacement(0);
3660 *   const FEValuesExtractors::Scalar y_displacement(1);
3661 *   const FEValuesExtractors::Scalar z_displacement(2);
3662 *  
3663 *   const FEValuesExtractors::Vector displacements(0);
3664 *  
3665 *   if ( m_parameters.m_scenario == 1
3666 *   || m_parameters.m_scenario == 3)
3667 *   {
3668 * @endcode
3669 *
3670 * Dirichlet B,C. bottom surface
3671 *
3672 * @code
3673 *   const int boundary_id_bottom_surface = 0;
3675 *   boundary_id_bottom_surface,
3676 *   Functions::ZeroFunction<dim>(m_n_components),
3677 *   m_constraints,
3678 *   m_fe.component_mask(y_displacement));
3679 *  
3680 *   typename Triangulation<dim>::active_vertex_iterator vertex_itr;
3681 *   vertex_itr = m_triangulation.begin_active_vertex();
3682 *   std::vector<types::global_dof_index> node_xy(m_fe.dofs_per_vertex);
3683 *  
3684 *   for (; vertex_itr != m_triangulation.end_vertex(); ++vertex_itr)
3685 *   {
3686 *   if ( (std::fabs(vertex_itr->vertex()[0] - 0.0) < 1.0e-9)
3687 *   && (std::fabs(vertex_itr->vertex()[1] - 0.0) < 1.0e-9) )
3688 *   {
3689 *   node_xy = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3690 *   }
3691 *   }
3692 *   m_constraints.add_line(node_xy[0]);
3693 *   m_constraints.set_inhomogeneity(node_xy[0], 0.0);
3694 *  
3695 *   m_constraints.add_line(node_xy[1]);
3696 *   m_constraints.set_inhomogeneity(node_xy[1], 0.0);
3697 *  
3698 *   const int boundary_id_top_surface = 1;
3699 *   /*
3700 *   VectorTools::interpolate_boundary_values(m_dof_handler,
3701 *   boundary_id_top_surface,
3702 *   Functions::ZeroFunction<dim>(m_n_components),
3703 *   m_constraints,
3704 *   m_fe.component_mask(x_displacement));
3705 *   */
3706 *   const double time_inc = m_time.get_delta_t();
3707 *   double disp_magnitude = m_time.get_magnitude();
3709 *   boundary_id_top_surface,
3711 *   disp_magnitude*time_inc, m_n_components),
3712 *   m_constraints,
3713 *   m_fe.component_mask(y_displacement));
3714 *   }
3715 *   else if ( m_parameters.m_scenario == 2
3716 *   || m_parameters.m_scenario == 4)
3717 *   {
3718 * @endcode
3719 *
3720 * Dirichlet B,C. bottom surface
3721 *
3722 * @code
3723 *   const int boundary_id_bottom_surface = 0;
3725 *   boundary_id_bottom_surface,
3726 *   Functions::ZeroFunction<dim>(m_n_components),
3727 *   m_constraints,
3728 *   m_fe.component_mask(displacements));
3729 *  
3730 *   const int boundary_id_top_surface = 1;
3732 *   boundary_id_top_surface,
3733 *   Functions::ZeroFunction<dim>(m_n_components),
3734 *   m_constraints,
3735 *   m_fe.component_mask(y_displacement));
3736 *  
3737 *   const double time_inc = m_time.get_delta_t();
3738 *   double disp_magnitude = m_time.get_magnitude();
3740 *   boundary_id_top_surface,
3742 *   disp_magnitude*time_inc, m_n_components),
3743 *   m_constraints,
3744 *   m_fe.component_mask(x_displacement));
3745 *  
3746 *   const int boundary_id_side_surfaces = 2;
3748 *   boundary_id_side_surfaces,
3749 *   Functions::ZeroFunction<dim>(m_n_components),
3750 *   m_constraints,
3751 *   m_fe.component_mask(y_displacement));
3752 *   }
3753 *   else if (m_parameters.m_scenario == 5)
3754 *   {
3755 *   typename Triangulation<dim>::active_vertex_iterator vertex_itr;
3756 *   vertex_itr = m_triangulation.begin_active_vertex();
3757 *   std::vector<types::global_dof_index> node_bottomleft(m_fe.dofs_per_vertex);
3758 *   std::vector<types::global_dof_index> node_bottomright(m_fe.dofs_per_vertex);
3759 *   std::vector<types::global_dof_index> node_topcenter(m_fe.dofs_per_vertex);
3760 *  
3761 *   for (; vertex_itr != m_triangulation.end_vertex(); ++vertex_itr)
3762 *   {
3763 *   if ( (std::fabs(vertex_itr->vertex()[0] - 0.0) < 1.0e-9)
3764 *   && (std::fabs(vertex_itr->vertex()[1] - 0.0) < 1.0e-9) )
3765 *   {
3766 *   node_bottomleft = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3767 *   }
3768 *   if ( (std::fabs(vertex_itr->vertex()[0] - 8.0) < 1.0e-9)
3769 *   && (std::fabs(vertex_itr->vertex()[1] - 0.0) < 1.0e-9) )
3770 *   {
3771 *   node_bottomright = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3772 *   }
3773 *   if ( (std::fabs(vertex_itr->vertex()[0] - 4.0) < 1.0e-9)
3774 *   && (std::fabs(vertex_itr->vertex()[1] - 2.0) < 1.0e-9) )
3775 *   {
3776 *   node_topcenter = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3777 *   }
3778 *   }
3779 * @endcode
3780 *
3781 * bottom-left node fixed in both x- and y-directions
3782 *
3783 * @code
3784 *   m_constraints.add_line(node_bottomleft[0]);
3785 *   m_constraints.set_inhomogeneity(node_bottomleft[0], 0.0);
3786 *  
3787 *   m_constraints.add_line(node_bottomleft[1]);
3788 *   m_constraints.set_inhomogeneity(node_bottomleft[1], 0.0);
3789 *  
3790 * @endcode
3791 *
3792 * bottom-right node only fixed in y-direction
3793 *
3794 * @code
3795 *   m_constraints.add_line(node_bottomright[1]);
3796 *   m_constraints.set_inhomogeneity(node_bottomright[1], 0.0);
3797 *  
3798 * @endcode
3799 *
3800 * top-center node applied with y-displacement
3801 *
3802 * @code
3803 *   const double time_inc = m_time.get_delta_t();
3804 *   double disp_magnitude = m_time.get_magnitude();
3805 *  
3806 *   m_constraints.add_line(node_topcenter[1]);
3807 *   m_constraints.set_inhomogeneity(node_topcenter[1], disp_magnitude*time_inc);
3808 *   }
3809 *   else if ( m_parameters.m_scenario == 6
3810 *   || m_parameters.m_scenario == 7
3811 *   || m_parameters.m_scenario == 8)
3812 *   {
3813 *   const int x0_surface = 0;
3815 *   x0_surface,
3816 *   Functions::ZeroFunction<dim>(m_n_components),
3817 *   m_constraints,
3818 *   m_fe.component_mask(x_displacement));
3819 *   const int y0_surface = 1;
3821 *   y0_surface,
3822 *   Functions::ZeroFunction<dim>(m_n_components),
3823 *   m_constraints,
3824 *   m_fe.component_mask(y_displacement));
3825 *   const int z0_surface = 2;
3827 *   z0_surface,
3828 *   Functions::ZeroFunction<dim>(m_n_components),
3829 *   m_constraints,
3830 *   m_fe.component_mask(z_displacement));
3831 *  
3832 *   const int z1_surface = 3;
3833 *   const double time_inc = m_time.get_delta_t();
3834 *   double disp_magnitude = m_time.get_magnitude();
3836 *   z1_surface,
3838 *   disp_magnitude*time_inc, m_n_components),
3839 *   m_constraints,
3840 *   m_fe.component_mask(z_displacement));
3841 *   }
3842 *   else if (m_parameters.m_scenario == 9)
3843 *   {
3844 * @endcode
3845 *
3846 * Dirichlet B,C. bottom surface
3847 *
3848 * @code
3849 *   const int boundary_id_bottom_surface = 0;
3851 *   boundary_id_bottom_surface,
3852 *   Functions::ZeroFunction<dim>(m_n_components),
3853 *   m_constraints,
3854 *   m_fe.component_mask(displacements));
3855 *  
3856 *   typename Triangulation<dim>::active_vertex_iterator vertex_itr;
3857 *   vertex_itr = m_triangulation.begin_active_vertex();
3858 *   std::vector<types::global_dof_index> node_disp_control(m_fe.dofs_per_vertex);
3859 *  
3860 *   for (; vertex_itr != m_triangulation.end_vertex(); ++vertex_itr)
3861 *   {
3862 *   if ( (std::fabs(vertex_itr->vertex()[0] - 470.0) < 1.0e-9)
3863 *   && (std::fabs(vertex_itr->vertex()[1] - 250.0) < 1.0e-9) )
3864 *   {
3865 *   node_disp_control = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3866 * @endcode
3867 *
3868 * node applied with y-displacement
3869 *
3870 * @code
3871 *   const double time_inc = m_time.get_delta_t();
3872 *   double disp_magnitude = m_time.get_magnitude();
3873 *  
3874 *   m_constraints.add_line(node_disp_control[1]);
3875 *   m_constraints.set_inhomogeneity(node_disp_control[1], disp_magnitude*time_inc);
3876 *   }
3877 *   }
3878 *   }
3879 *   else if (m_parameters.m_scenario == 11)
3880 *   {
3881 * @endcode
3882 *
3883 * Dirichlet B,C. right surface
3884 *
3885 * @code
3886 *   const int boundary_id_right_surface = 0;
3888 *   boundary_id_right_surface,
3889 *   Functions::ZeroFunction<dim>(m_n_components),
3890 *   m_constraints,
3891 *   m_fe.component_mask(displacements));
3892 *  
3893 * @endcode
3894 *
3895 * Dirichlet B,C. left surface
3896 *
3897 * @code
3898 *   const int boundary_id_left_surface = 1;
3900 *   boundary_id_left_surface,
3901 *   Functions::ZeroFunction<dim>(m_n_components),
3902 *   m_constraints,
3903 *   m_fe.component_mask(x_displacement));
3904 *  
3905 *   typename Triangulation<dim>::active_vertex_iterator vertex_itr;
3906 *   vertex_itr = m_triangulation.begin_active_vertex();
3907 *   std::vector<types::global_dof_index> node_rotate(m_fe.dofs_per_vertex);
3908 *   double node_dist = 0.0;
3909 *   double disp_mag = 0.0;
3910 *   double angle_theta = 0.0;
3911 *   double disp_y = 0;
3912 *   double disp_z = 0;
3913 *  
3914 *   for (; vertex_itr != m_triangulation.end_vertex(); ++vertex_itr)
3915 *   {
3916 *   if (std::fabs(vertex_itr->vertex()[0] - 0.0) < 1.0e-9)
3917 *   {
3918 *   node_rotate = usr_utilities::get_vertex_dofs(vertex_itr, m_dof_handler);
3919 *   node_dist = std::sqrt( vertex_itr->vertex()[1] * vertex_itr->vertex()[1]
3920 *   + vertex_itr->vertex()[2] * vertex_itr->vertex()[2]);
3921 *  
3922 *   angle_theta = m_time.get_delta_t() * m_time.get_magnitude();
3923 *   disp_mag = node_dist * std::tan(angle_theta);
3924 *  
3925 *   if (node_dist > 0)
3926 *   {
3927 *   disp_y = vertex_itr->vertex()[2]/node_dist * disp_mag;
3928 *   disp_z = -vertex_itr->vertex()[1]/node_dist * disp_mag;
3929 *   }
3930 *   else
3931 *   {
3932 *   disp_y = 0.0;
3933 *   disp_z = 0.0;
3934 *   }
3935 *  
3936 *   m_constraints.add_line(node_rotate[1]);
3937 *   m_constraints.set_inhomogeneity(node_rotate[1], disp_y);
3938 *  
3939 *   m_constraints.add_line(node_rotate[2]);
3940 *   m_constraints.set_inhomogeneity(node_rotate[2], disp_z);
3941 *   }
3942 *   }
3943 *   }
3944 *   else
3945 *   Assert(false, ExcMessage("The scenario has not been implemented!"));
3946 *   }
3947 *   else // inhomogeneous constraints
3948 *   {
3949 *   if (m_constraints.has_inhomogeneities())
3950 *   {
3951 *   AffineConstraints<double> homogeneous_constraints(m_constraints);
3952 *   for (unsigned int dof = 0; dof != m_dof_handler.n_dofs(); ++dof)
3953 *   if (homogeneous_constraints.is_inhomogeneously_constrained(dof))
3954 *   homogeneous_constraints.set_inhomogeneity(dof, 0.0);
3955 *   m_constraints.clear();
3956 *   m_constraints.copy_from(homogeneous_constraints);
3957 *   }
3958 *   }
3959 *   m_constraints.close();
3960 *   }
3961 *  
3962 *   template <int dim>
3963 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_newton(const BlockVector<double> & solution_old)
3964 *   {
3965 *   m_timer.enter_subsection("Assemble system");
3966 *  
3967 *   if (m_parameters.m_output_iteration_history)
3968 *   m_logfile << " ASM_SYS " << std::flush;
3969 *  
3970 *   m_tangent_matrix = 0.0;
3971 *   m_system_rhs = 0.0;
3972 *  
3973 *   const UpdateFlags uf_cell(update_values | update_gradients |
3977 *  
3978 *   PerTaskData_ASM per_task_data(m_fe.n_dofs_per_cell());
3979 *   ScratchData_ASM scratch_data(m_fe, m_qf_cell, uf_cell, m_qf_face, uf_face, solution_old);
3980 *  
3981 *   auto worker =
3982 *   [this](const typename DoFHandler<dim>::active_cell_iterator &cell,
3983 *   ScratchData_ASM & scratch,
3984 *   PerTaskData_ASM & data)
3985 *   {
3986 *   this->assemble_system_newton_one_cell(cell, scratch, data);
3987 *   };
3988 *  
3989 *   auto copier = [this](const PerTaskData_ASM &data)
3990 *   {
3991 *   this->m_constraints.distribute_local_to_global(data.m_cell_matrix,
3992 *   data.m_cell_rhs,
3993 *   data.m_local_dof_indices,
3994 *   m_tangent_matrix,
3995 *   m_system_rhs);
3996 *   };
3997 *  
3999 *   m_dof_handler.active_cell_iterators(),
4000 *   worker,
4001 *   copier,
4002 *   scratch_data,
4003 *   per_task_data);
4004 *  
4005 *   m_timer.leave_subsection();
4006 *   }
4007 *  
4008 *  
4009 *   template <int dim>
4010 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_B0(const BlockVector<double> & solution_old)
4011 *   {
4012 *   m_timer.enter_subsection("Assemble B0");
4013 *  
4014 *   m_tangent_matrix = 0.0;
4015 *  
4016 *   const UpdateFlags uf_cell(update_values | update_gradients |
4020 *  
4021 *   PerTaskData_ASM per_task_data(m_fe.n_dofs_per_cell());
4022 *   ScratchData_ASM scratch_data(m_fe, m_qf_cell, uf_cell, m_qf_face, uf_face, solution_old);
4023 *  
4024 *   auto worker =
4025 *   [this](const typename DoFHandler<dim>::active_cell_iterator &cell,
4026 *   ScratchData_ASM & scratch,
4027 *   PerTaskData_ASM & data)
4028 *   {
4029 *   this->assemble_system_B0_one_cell(cell, scratch, data);
4030 *   };
4031 *  
4032 *   auto copier = [this](const PerTaskData_ASM &data)
4033 *   {
4034 *   this->m_constraints.distribute_local_to_global(data.m_cell_matrix,
4035 *   data.m_local_dof_indices,
4036 *   m_tangent_matrix);
4037 *   };
4038 *  
4040 *   m_dof_handler.active_cell_iterators(),
4041 *   worker,
4042 *   copier,
4043 *   scratch_data,
4044 *   per_task_data);
4045 *  
4046 *   m_timer.leave_subsection();
4047 *   }
4048 *  
4049 *   template <int dim>
4050 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_rhs_BFGS_parallel(const BlockVector<double> & solution_old,
4051 *   BlockVector<double> & system_rhs)
4052 *   {
4053 *   m_timer.enter_subsection("Assemble RHS");
4054 *  
4055 * @endcode
4056 *
4057 * m_logfile << " A_RHS " << std::flush;
4058 *
4059
4060 *
4061 *
4062 * @code
4063 *   system_rhs = 0.0;
4064 *  
4065 *   const UpdateFlags uf_cell(update_values | update_gradients |
4069 *  
4070 *   PerTaskData_ASM_RHS_BFGS per_task_data(m_fe.n_dofs_per_cell());
4071 *   ScratchData_ASM_RHS_BFGS scratch_data(m_fe, m_qf_cell, uf_cell, m_qf_face, uf_face, solution_old);
4072 *  
4073 *   auto worker =
4074 *   [this](const typename DoFHandler<dim>::active_cell_iterator &cell,
4075 *   ScratchData_ASM_RHS_BFGS & scratch,
4076 *   PerTaskData_ASM_RHS_BFGS & data)
4077 *   {
4078 *   this->assemble_system_rhs_BFGS_one_cell(cell, scratch, data);
4079 *   };
4080 *  
4081 *   auto copier = [this, &system_rhs](const PerTaskData_ASM_RHS_BFGS &data)
4082 *   {
4083 *   this->m_constraints.distribute_local_to_global(data.m_cell_rhs,
4084 *   data.m_local_dof_indices,
4085 *   system_rhs);
4086 *   };
4087 *  
4089 *   m_dof_handler.active_cell_iterators(),
4090 *   worker,
4091 *   copier,
4092 *   scratch_data,
4093 *   per_task_data);
4094 *  
4095 *   m_timer.leave_subsection();
4096 *   }
4097 *  
4098 *   template <int dim>
4099 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_rhs_BFGS_one_cell(
4100 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
4101 *   ScratchData_ASM_RHS_BFGS & scratch,
4102 *   PerTaskData_ASM_RHS_BFGS & data) const
4103 *   {
4104 *   data.reset();
4105 *   scratch.reset();
4106 *   scratch.m_fe_values.reinit(cell);
4107 *   cell->get_dof_indices(data.m_local_dof_indices);
4108 *  
4109 *   scratch.m_fe_values[m_d_fe].get_function_values(
4110 *   scratch.m_solution_previous_step, scratch.m_phasefield_previous_step_cell);
4111 *  
4112 *   const std::vector<std::shared_ptr<const PointHistory<dim>>> lqph =
4113 *   m_quadrature_point_history.get_data(cell);
4114 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
4115 *  
4116 *   const double time_ramp = (m_time.current() / m_time.end());
4117 *   std::vector<Tensor<1, dim>> rhs_values(m_n_q_points);
4118 *  
4119 *   right_hand_side(scratch.m_fe_values.get_quadrature_points(),
4120 *   rhs_values,
4121 *   m_parameters.m_x_component*1.0,
4122 *   m_parameters.m_y_component*1.0,
4123 *   m_parameters.m_z_component*1.0);
4124 *  
4125 *   const double delta_time = m_time.get_delta_t();
4126 *  
4127 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4128 *   {
4129 *   for (const unsigned int k : scratch.m_fe_values.dof_indices())
4130 *   {
4131 *   const unsigned int k_group = m_fe.system_to_base_index(k).first.first;
4132 *  
4133 *   if (k_group == m_u_dof)
4134 *   {
4135 *   scratch.m_Nx_disp[q_point][k] =
4136 *   scratch.m_fe_values[m_u_fe].value(k, q_point);
4137 *   scratch.m_grad_Nx_disp[q_point][k] =
4138 *   scratch.m_fe_values[m_u_fe].gradient(k, q_point);
4139 *   scratch.m_symm_grad_Nx_disp[q_point][k] =
4140 *   symmetrize(scratch.m_grad_Nx_disp[q_point][k]);
4141 *   }
4142 *   else if (k_group == m_d_dof)
4143 *   {
4144 *   scratch.m_Nx_phasefield[q_point][k] =
4145 *   scratch.m_fe_values[m_d_fe].value(k, q_point);
4146 *   scratch.m_grad_Nx_phasefield[q_point][k] =
4147 *   scratch.m_fe_values[m_d_fe].gradient(k, q_point);
4148 *   }
4149 *   else
4150 *   Assert(k_group <= m_d_dof, ExcInternalError());
4151 *   }
4152 *   }
4153 *  
4154 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4155 *   {
4156 *   const double length_scale = lqph[q_point]->get_length_scale();
4157 *   const double gc = lqph[q_point]->get_critical_energy_release_rate();
4158 *   const double eta = lqph[q_point]->get_viscosity();
4159 *   const double history_strain_energy = lqph[q_point]->get_history_max_positive_strain_energy();
4160 *   const double current_positive_strain_energy = lqph[q_point]->get_current_positive_strain_energy();
4161 *  
4162 *   double history_value = history_strain_energy;
4163 *   if (current_positive_strain_energy > history_strain_energy)
4164 *   history_value = current_positive_strain_energy;
4165 *  
4166 *   const double phasefield_value = lqph[q_point]->get_phase_field_value();
4167 *   const Tensor<1, dim> phasefield_grad = lqph[q_point]->get_phase_field_gradient();
4168 *  
4169 *   const std::vector<double> & N_phasefield = scratch.m_Nx_phasefield[q_point];
4170 *   const std::vector<Tensor<1, dim>> & grad_N_phasefield = scratch.m_grad_Nx_phasefield[q_point];
4171 *   const double old_phasefield = scratch.m_phasefield_previous_step_cell[q_point];
4172 *  
4173 *   const SymmetricTensor<2, dim> & cauchy_stress = lqph[q_point]->get_cauchy_stress();
4174 *  
4175 *   const std::vector<Tensor<1,dim>> & N_disp = scratch.m_Nx_disp[q_point];
4176 *   const std::vector<SymmetricTensor<2, dim>> & symm_grad_N_disp =
4177 *   scratch.m_symm_grad_Nx_disp[q_point];
4178 *   const double JxW = scratch.m_fe_values.JxW(q_point);
4179 *  
4180 *   SymmetricTensor<2, dim> symm_grad_Nx_i_x_C;
4181 *  
4182 *   for (const unsigned int i : scratch.m_fe_values.dof_indices())
4183 *   {
4184 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4185 *  
4186 *   if (i_group == m_u_dof)
4187 *   {
4188 *   data.m_cell_rhs(i) += (symm_grad_N_disp[i] * cauchy_stress) * JxW;
4189 *  
4190 * @endcode
4191 *
4192 * contributions from the body force to right-hand side
4193 *
4194 * @code
4195 *   data.m_cell_rhs(i) -= N_disp[i] * rhs_values[q_point] * JxW;
4196 *   }
4197 *   else if (i_group == m_d_dof)
4198 *   {
4199 *   data.m_cell_rhs(i) += ( gc * length_scale * grad_N_phasefield[i] * phasefield_grad
4200 *   + ( gc / length_scale * phasefield_value
4201 *   + eta / delta_time * (phasefield_value - old_phasefield)
4202 *   + degradation_function_derivative(phasefield_value) * history_value )
4203 *   * N_phasefield[i]
4204 *   ) * JxW;
4205 *   }
4206 *   else
4207 *   Assert(i_group <= m_d_dof, ExcInternalError());
4208 *   } // i
4209 *   } // q_point
4210 *  
4211 * @endcode
4212 *
4213 * if there is surface pressure, this surface pressure always applied to the
4214 * reference configuration
4215 *
4216 * @code
4217 *   const unsigned int face_pressure_id = 100;
4218 *   const double p0 = 0.0;
4219 *  
4220 *   for (const auto &face : cell->face_iterators())
4221 *   if (face->at_boundary() && face->boundary_id() == face_pressure_id)
4222 *   {
4223 *   scratch.m_fe_face_values.reinit(cell, face);
4224 *  
4225 *   for (const unsigned int f_q_point : scratch.m_fe_face_values.quadrature_point_indices())
4226 *   {
4227 *   const Tensor<1, dim> &N = scratch.m_fe_face_values.normal_vector(f_q_point);
4228 *  
4229 *   const double pressure = p0 * time_ramp;
4230 *   const Tensor<1, dim> traction = pressure * N;
4231 *  
4232 *   for (const unsigned int i : scratch.m_fe_values.dof_indices())
4233 *   {
4234 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4235 *  
4236 *   if (i_group == m_u_dof)
4237 *   {
4238 *   const unsigned int component_i = m_fe.system_to_component_index(i).first;
4239 *   const double Ni = scratch.m_fe_face_values.shape_value(i, f_q_point);
4240 *   const double JxW = scratch.m_fe_face_values.JxW(f_q_point);
4241 *   data.m_cell_rhs(i) -= (Ni * traction[component_i]) * JxW;
4242 *   }
4243 *   }
4244 *   }
4245 *   }
4246 *   }
4247 *  
4248 *   template <int dim>
4249 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_newton_one_cell(
4250 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
4251 *   ScratchData_ASM & scratch,
4252 *   PerTaskData_ASM & data) const
4253 *   {
4254 *   data.reset();
4255 *   scratch.reset();
4256 *   scratch.m_fe_values.reinit(cell);
4257 *   cell->get_dof_indices(data.m_local_dof_indices);
4258 *  
4259 *   scratch.m_fe_values[m_d_fe].get_function_values(
4260 *   scratch.m_solution_previous_step, scratch.m_phasefield_previous_step_cell);
4261 *  
4262 *   const std::vector<std::shared_ptr<const PointHistory<dim>>> lqph =
4263 *   m_quadrature_point_history.get_data(cell);
4264 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
4265 *  
4266 *   const double time_ramp = (m_time.current() / m_time.end());
4267 *   std::vector<Tensor<1, dim>> rhs_values(m_n_q_points);
4268 *  
4269 *   right_hand_side(scratch.m_fe_values.get_quadrature_points(),
4270 *   rhs_values,
4271 *   m_parameters.m_x_component*1.0,
4272 *   m_parameters.m_y_component*1.0,
4273 *   m_parameters.m_z_component*1.0);
4274 *  
4275 *   const double delta_time = m_time.get_delta_t();
4276 *  
4277 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4278 *   {
4279 *   for (const unsigned int k : scratch.m_fe_values.dof_indices())
4280 *   {
4281 *   const unsigned int k_group = m_fe.system_to_base_index(k).first.first;
4282 *  
4283 *   if (k_group == m_u_dof)
4284 *   {
4285 *   scratch.m_Nx_disp[q_point][k] =
4286 *   scratch.m_fe_values[m_u_fe].value(k, q_point);
4287 *   scratch.m_grad_Nx_disp[q_point][k] =
4288 *   scratch.m_fe_values[m_u_fe].gradient(k, q_point);
4289 *   scratch.m_symm_grad_Nx_disp[q_point][k] =
4290 *   symmetrize(scratch.m_grad_Nx_disp[q_point][k]);
4291 *   }
4292 *   else if (k_group == m_d_dof)
4293 *   {
4294 *   scratch.m_Nx_phasefield[q_point][k] =
4295 *   scratch.m_fe_values[m_d_fe].value(k, q_point);
4296 *   scratch.m_grad_Nx_phasefield[q_point][k] =
4297 *   scratch.m_fe_values[m_d_fe].gradient(k, q_point);
4298 *   }
4299 *   else
4300 *   Assert(k_group <= m_d_dof, ExcInternalError());
4301 *   }
4302 *   }
4303 *  
4304 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4305 *   {
4306 *   const double length_scale = lqph[q_point]->get_length_scale();
4307 *   const double gc = lqph[q_point]->get_critical_energy_release_rate();
4308 *   const double eta = lqph[q_point]->get_viscosity();
4309 *   const double history_strain_energy = lqph[q_point]->get_history_max_positive_strain_energy();
4310 *   const double current_positive_strain_energy = lqph[q_point]->get_current_positive_strain_energy();
4311 *  
4312 *   double history_value = history_strain_energy;
4313 *   if (current_positive_strain_energy > history_strain_energy)
4314 *   history_value = current_positive_strain_energy;
4315 *  
4316 *   const double phasefield_value = lqph[q_point]->get_phase_field_value();
4317 *   const Tensor<1, dim> phasefield_grad = lqph[q_point]->get_phase_field_gradient();
4318 *  
4319 *   const std::vector<double> & N_phasefield = scratch.m_Nx_phasefield[q_point];
4320 *   const std::vector<Tensor<1, dim>> & grad_N_phasefield = scratch.m_grad_Nx_phasefield[q_point];
4321 *   const double old_phasefield = scratch.m_phasefield_previous_step_cell[q_point];
4322 *  
4323 *   const SymmetricTensor<2, dim> & cauchy_stress = lqph[q_point]->get_cauchy_stress();
4324 *   const SymmetricTensor<2, dim> & cauchy_stress_positive = lqph[q_point]->get_cauchy_stress_positive();
4325 *   const SymmetricTensor<4, dim> & mechanical_C = lqph[q_point]->get_mechanical_C();
4326 *  
4327 *   const std::vector<Tensor<1,dim>> & N_disp = scratch.m_Nx_disp[q_point];
4328 *   const std::vector<SymmetricTensor<2, dim>> & symm_grad_N_disp =
4329 *   scratch.m_symm_grad_Nx_disp[q_point];
4330 *   const double JxW = scratch.m_fe_values.JxW(q_point);
4331 *  
4332 *   SymmetricTensor<2, dim> symm_grad_Nx_i_x_C;
4333 *  
4334 *   for (const unsigned int i : scratch.m_fe_values.dof_indices())
4335 *   {
4336 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4337 *  
4338 *   if (i_group == m_u_dof)
4339 *   {
4340 *   data.m_cell_rhs(i) -= (symm_grad_N_disp[i] * cauchy_stress) * JxW;
4341 *  
4342 * @endcode
4343 *
4344 * contributions from the body force to right-hand side
4345 *
4346 * @code
4347 *   data.m_cell_rhs(i) += N_disp[i] * rhs_values[q_point] * JxW;
4348 *   }
4349 *   else if (i_group == m_d_dof)
4350 *   {
4351 *   data.m_cell_rhs(i) -= ( gc * length_scale * grad_N_phasefield[i] * phasefield_grad
4352 *   + ( gc / length_scale * phasefield_value
4353 *   + eta / delta_time * (phasefield_value - old_phasefield)
4354 *   + degradation_function_derivative(phasefield_value) * history_value )
4355 *   * N_phasefield[i]
4356 *   ) * JxW;
4357 *   }
4358 *   else
4359 *   Assert(i_group <= m_d_dof, ExcInternalError());
4360 *  
4361 *   if (i_group == m_u_dof)
4362 *   {
4363 *   symm_grad_Nx_i_x_C = symm_grad_N_disp[i] * mechanical_C;
4364 *   }
4365 *  
4366 *   for (const unsigned int j : scratch.m_fe_values.dof_indices())
4367 *   {
4368 *   const unsigned int j_group = m_fe.system_to_base_index(j).first.first;
4369 *  
4370 *   if ((i_group == j_group) && (i_group == m_u_dof))
4371 *   {
4372 *   data.m_cell_matrix(i, j) += symm_grad_Nx_i_x_C * symm_grad_N_disp[j] * JxW;
4373 *   }
4374 *   else if ((i_group == j_group) && (i_group == m_d_dof))
4375 *   {
4376 *   data.m_cell_matrix(i, j) += ( ( gc/length_scale + eta/delta_time +
4377 *   degradation_function_2nd_order_derivative(phasefield_value)
4378 *   * history_value )
4379 *   * N_phasefield[i] * N_phasefield[j]
4380 *   + gc * length_scale * grad_N_phasefield[i] * grad_N_phasefield[j]
4381 *   ) * JxW;
4382 *   }
4383 *   else if ((i_group == m_u_dof) && (j_group == m_d_dof))
4384 *   {
4385 *   data.m_cell_matrix(i, j) += symm_grad_N_disp[i] * cauchy_stress_positive
4386 *   * degradation_function_derivative(phasefield_value)
4387 *   * N_phasefield[j] * JxW;
4388 *   }
4389 *   else if ((i_group == m_d_dof) && (j_group == m_u_dof))
4390 *   {
4391 *   if (current_positive_strain_energy > history_strain_energy)
4392 *   data.m_cell_matrix(i, j) += N_phasefield[i]
4393 *   * degradation_function_derivative(phasefield_value)
4394 *   * cauchy_stress_positive
4395 *   * symm_grad_N_disp[j]
4396 *   * JxW;
4397 *   else
4398 *   data.m_cell_matrix(i, j) += 0.0;
4399 *   }
4400 *   else
4401 *   Assert((i_group <= m_d_dof) && (j_group <= m_d_dof),
4402 *   ExcInternalError());
4403 *   } // j
4404 *   } // i
4405 *   } // q_point
4406 *  
4407 * @endcode
4408 *
4409 * if there is surface pressure, this surface pressure always applied to the
4410 * reference configuration
4411 *
4412 * @code
4413 *   const unsigned int face_pressure_id = 100;
4414 *   const double p0 = 0.0;
4415 *  
4416 *   for (const auto &face : cell->face_iterators())
4417 *   if (face->at_boundary() && face->boundary_id() == face_pressure_id)
4418 *   {
4419 *   scratch.m_fe_face_values.reinit(cell, face);
4420 *  
4421 *   for (const unsigned int f_q_point : scratch.m_fe_face_values.quadrature_point_indices())
4422 *   {
4423 *   const Tensor<1, dim> &N = scratch.m_fe_face_values.normal_vector(f_q_point);
4424 *  
4425 *   const double pressure = p0 * time_ramp;
4426 *   const Tensor<1, dim> traction = pressure * N;
4427 *  
4428 *   for (const unsigned int i : scratch.m_fe_values.dof_indices())
4429 *   {
4430 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4431 *  
4432 *   if (i_group == m_u_dof)
4433 *   {
4434 *   const unsigned int component_i = m_fe.system_to_component_index(i).first;
4435 *   const double Ni = scratch.m_fe_face_values.shape_value(i, f_q_point);
4436 *   const double JxW = scratch.m_fe_face_values.JxW(f_q_point);
4437 *   data.m_cell_rhs(i) += (Ni * traction[component_i]) * JxW;
4438 *   }
4439 *   }
4440 *   }
4441 *   }
4442 *   }
4443 *  
4444 *   template <int dim>
4445 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_B0_one_cell(
4446 *   const typename DoFHandler<dim>::active_cell_iterator &cell,
4447 *   ScratchData_ASM & scratch,
4448 *   PerTaskData_ASM & data) const
4449 *   {
4450 *   data.reset();
4451 *   scratch.reset();
4452 *   scratch.m_fe_values.reinit(cell);
4453 *   cell->get_dof_indices(data.m_local_dof_indices);
4454 *  
4455 *   scratch.m_fe_values[m_d_fe].get_function_values(
4456 *   scratch.m_solution_previous_step, scratch.m_phasefield_previous_step_cell);
4457 *  
4458 *   const std::vector<std::shared_ptr<const PointHistory<dim>>> lqph =
4459 *   m_quadrature_point_history.get_data(cell);
4460 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
4461 *  
4462 *   const double delta_time = m_time.get_delta_t();
4463 *  
4464 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4465 *   {
4466 *   for (const unsigned int k : scratch.m_fe_values.dof_indices())
4467 *   {
4468 *   const unsigned int k_group = m_fe.system_to_base_index(k).first.first;
4469 *  
4470 *   if (k_group == m_u_dof)
4471 *   {
4472 *   scratch.m_Nx_disp[q_point][k] =
4473 *   scratch.m_fe_values[m_u_fe].value(k, q_point);
4474 *   scratch.m_grad_Nx_disp[q_point][k] =
4475 *   scratch.m_fe_values[m_u_fe].gradient(k, q_point);
4476 *   scratch.m_symm_grad_Nx_disp[q_point][k] =
4477 *   symmetrize(scratch.m_grad_Nx_disp[q_point][k]);
4478 *   }
4479 *   else if (k_group == m_d_dof)
4480 *   {
4481 *   scratch.m_Nx_phasefield[q_point][k] =
4482 *   scratch.m_fe_values[m_d_fe].value(k, q_point);
4483 *   scratch.m_grad_Nx_phasefield[q_point][k] =
4484 *   scratch.m_fe_values[m_d_fe].gradient(k, q_point);
4485 *   }
4486 *   else
4487 *   Assert(k_group <= m_d_dof, ExcInternalError());
4488 *   }
4489 *   }
4490 *  
4491 *   for (const unsigned int q_point : scratch.m_fe_values.quadrature_point_indices())
4492 *   {
4493 *   const double length_scale = lqph[q_point]->get_length_scale();
4494 *   const double gc = lqph[q_point]->get_critical_energy_release_rate();
4495 *   const double eta = lqph[q_point]->get_viscosity();
4496 *   const double history_strain_energy = lqph[q_point]->get_history_max_positive_strain_energy();
4497 *   const double current_positive_strain_energy = lqph[q_point]->get_current_positive_strain_energy();
4498 *  
4499 *   double history_value = history_strain_energy;
4500 *   if (current_positive_strain_energy > history_strain_energy)
4501 *   history_value = current_positive_strain_energy;
4502 *  
4503 *   const double phasefield_value = lqph[q_point]->get_phase_field_value();
4504 *  
4505 *   const std::vector<double> & N_phasefield = scratch.m_Nx_phasefield[q_point];
4506 *   const std::vector<Tensor<1, dim>> & grad_N_phasefield = scratch.m_grad_Nx_phasefield[q_point];
4507 *  
4508 * @endcode
4509 *
4510 * const SymmetricTensor<2, dim> & cauchy_stress_positive = lqph[q_point]->get_cauchy_stress_positive();
4511 *
4512 * @code
4513 *   const SymmetricTensor<4, dim> & mechanical_C = lqph[q_point]->get_mechanical_C();
4514 *  
4515 *   const std::vector<SymmetricTensor<2, dim>> & symm_grad_N_disp =
4516 *   scratch.m_symm_grad_Nx_disp[q_point];
4517 *   const double JxW = scratch.m_fe_values.JxW(q_point);
4518 *  
4519 *   SymmetricTensor<2, dim> symm_grad_Nx_i_x_C;
4520 *  
4521 *   for (const unsigned int i : scratch.m_fe_values.dof_indices())
4522 *   {
4523 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4524 *  
4525 *   if (i_group == m_u_dof)
4526 *   {
4527 *   symm_grad_Nx_i_x_C = symm_grad_N_disp[i] * mechanical_C;
4528 *   }
4529 *  
4530 *   for (const unsigned int j : scratch.m_fe_values.dof_indices())
4531 *   {
4532 *   const unsigned int j_group = m_fe.system_to_base_index(j).first.first;
4533 *  
4534 *   if ((i_group == j_group) && (i_group == m_u_dof))
4535 *   {
4536 *   data.m_cell_matrix(i, j) += symm_grad_Nx_i_x_C * symm_grad_N_disp[j] * JxW;
4537 *   }
4538 *   else if ((i_group == j_group) && (i_group == m_d_dof))
4539 *   {
4540 *   data.m_cell_matrix(i, j) += ( ( gc/length_scale + eta/delta_time
4541 *   + degradation_function_2nd_order_derivative(phasefield_value)
4542 *   * history_value )
4543 *   * N_phasefield[i] * N_phasefield[j]
4544 *   + gc * length_scale * grad_N_phasefield[i] * grad_N_phasefield[j]
4545 *   ) * JxW;
4546 *   }
4547 *   else
4548 *   Assert((i_group <= m_d_dof) && (j_group <= m_d_dof),
4549 *   ExcInternalError());
4550 *   } // j
4551 *   } // i
4552 *   } // q_point
4553 *   }
4554 *  
4555 *   template <int dim>
4556 *   void PhaseFieldMonolithicSolve<dim>::assemble_system_rhs_BFGS(const BlockVector<double> & solution_old,
4557 *   BlockVector<double> & system_rhs)
4558 *   {
4559 *   m_timer.enter_subsection("Assemble RHS");
4560 *  
4561 * @endcode
4562 *
4563 * m_logfile << " A_RHS " << std::flush;
4564 *
4565
4566 *
4567 *
4568 * @code
4569 *   system_rhs = 0.0;
4570 *  
4571 *   Vector<double> cell_rhs(m_dofs_per_cell);
4572 *   std::vector<types::global_dof_index> local_dof_indices(m_dofs_per_cell);
4573 *  
4574 *   const double time_ramp = (m_time.current() / m_time.end());
4575 *   const double delta_time = m_time.get_delta_t();
4576 *  
4577 *   std::vector<Tensor<1, dim>> rhs_values(m_n_q_points);
4578 *   const UpdateFlags uf_cell(update_values | update_gradients |
4582 *  
4583 *   FEValues<dim> fe_values(m_fe, m_qf_cell, uf_cell);
4584 *   FEFaceValues<dim> fe_face_values(m_fe, m_qf_face, uf_face);
4585 *  
4586 * @endcode
4587 *
4588 * shape function values for displacement field
4589 *
4590 * @code
4591 *   std::vector<std::vector<Tensor<1, dim>>>
4592 *   Nx_disp(m_qf_cell.size(), std::vector<Tensor<1, dim>>(m_dofs_per_cell));
4593 *   std::vector<std::vector<Tensor<2, dim>>>
4594 *   grad_Nx_disp(m_qf_cell.size(), std::vector<Tensor<2, dim>>(m_dofs_per_cell));
4595 *   std::vector<std::vector<SymmetricTensor<2, dim>>>
4596 *   symm_grad_Nx_disp(m_qf_cell.size(), std::vector<SymmetricTensor<2, dim>>(m_dofs_per_cell));
4597 *  
4598 * @endcode
4599 *
4600 * shape function values for phase field
4601 *
4602 * @code
4603 *   std::vector<std::vector<double>>
4604 *   Nx_phasefield(m_qf_cell.size(), std::vector<double>(m_dofs_per_cell));
4605 *   std::vector<std::vector<Tensor<1, dim>>>
4606 *   grad_Nx_phasefield(m_qf_cell.size(), std::vector<Tensor<1, dim>>(m_dofs_per_cell));
4607 *  
4608 *   std::vector<double> phasefield_previous_step_cell(m_qf_cell.size());
4609 *  
4610 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
4611 *   {
4612 *   const std::vector<std::shared_ptr< PointHistory<dim>>> lqph =
4613 *   m_quadrature_point_history.get_data(cell);
4614 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
4615 *  
4616 *   cell_rhs = 0.0;
4617 *   fe_values.reinit(cell);
4618 *   right_hand_side(fe_values.get_quadrature_points(),
4619 *   rhs_values,
4620 *   m_parameters.m_x_component*time_ramp,
4621 *   m_parameters.m_y_component*time_ramp,
4622 *   m_parameters.m_z_component*time_ramp);
4623 *  
4624 *   fe_values[m_d_fe].get_function_values(
4625 *   solution_old, phasefield_previous_step_cell);
4626 *  
4627 *   for (const unsigned int q_point : fe_values.quadrature_point_indices())
4628 *   {
4629 *   for (const unsigned int k : fe_values.dof_indices())
4630 *   {
4631 *   const unsigned int k_group = m_fe.system_to_base_index(k).first.first;
4632 *  
4633 *   if (k_group == m_u_dof)
4634 *   {
4635 *   Nx_disp[q_point][k] = fe_values[m_u_fe].value(k, q_point);
4636 *   grad_Nx_disp[q_point][k] = fe_values[m_u_fe].gradient(k, q_point);
4637 *   symm_grad_Nx_disp[q_point][k] = symmetrize(grad_Nx_disp[q_point][k]);
4638 *   }
4639 *   else if (k_group == m_d_dof)
4640 *   {
4641 *   Nx_phasefield[q_point][k] = fe_values[m_d_fe].value(k, q_point);
4642 *   grad_Nx_phasefield[q_point][k] = fe_values[m_d_fe].gradient(k, q_point);
4643 *   }
4644 *   else
4645 *   Assert(k_group <= m_d_dof, ExcInternalError());
4646 *   }
4647 *   }
4648 *  
4649 *   for (const unsigned int q_point : fe_values.quadrature_point_indices())
4650 *   {
4651 *   const double length_scale = lqph[q_point]->get_length_scale();
4652 *   const double gc = lqph[q_point]->get_critical_energy_release_rate();
4653 *   const double eta = lqph[q_point]->get_viscosity();
4654 *   const double history_strain_energy = lqph[q_point]->get_history_max_positive_strain_energy();
4655 *   const double current_positive_strain_energy = lqph[q_point]->get_current_positive_strain_energy();
4656 *  
4657 *   double history_value = history_strain_energy;
4658 *   if (current_positive_strain_energy > history_strain_energy)
4659 *   history_value = current_positive_strain_energy;
4660 *  
4661 *   const double phasefield_value = lqph[q_point]->get_phase_field_value();
4662 *   const Tensor<1, dim> phasefield_grad = lqph[q_point]->get_phase_field_gradient();
4663 *  
4664 *   const std::vector<double> & N_phasefield = Nx_phasefield[q_point];
4665 *   const std::vector<Tensor<1, dim>> & grad_N_phasefield = grad_Nx_phasefield[q_point];
4666 *   const double old_phasefield = phasefield_previous_step_cell[q_point];
4667 *  
4668 *   const SymmetricTensor<2, dim> & cauchy_stress = lqph[q_point]->get_cauchy_stress();
4669 *  
4670 *   const std::vector<Tensor<1,dim>> & N = Nx_disp[q_point];
4671 *   const std::vector<SymmetricTensor<2, dim>> & symm_grad_N = symm_grad_Nx_disp[q_point];
4672 *   const double JxW = fe_values.JxW(q_point);
4673 *  
4674 *   for (const unsigned int i : fe_values.dof_indices())
4675 *   {
4676 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4677 *  
4678 *   if (i_group == m_u_dof)
4679 *   {
4680 *   cell_rhs(i) += (symm_grad_N[i] * cauchy_stress) * JxW;
4681 * @endcode
4682 *
4683 * contributions from the body force to right-hand side
4684 *
4685 * @code
4686 *   cell_rhs(i) -= N[i] * rhs_values[q_point] * JxW;
4687 *   }
4688 *   else if (i_group == m_d_dof)
4689 *   {
4690 *   cell_rhs(i) += ( gc * length_scale * grad_N_phasefield[i] * phasefield_grad
4691 *   + ( gc / length_scale * phasefield_value
4692 *   + eta / delta_time * (phasefield_value - old_phasefield)
4693 *   + degradation_function_derivative(phasefield_value) * history_value )
4694 *   * N_phasefield[i]
4695 *   ) * JxW;
4696 *   }
4697 *   else
4698 *   Assert(i_group <= m_d_dof, ExcInternalError());
4699 *   }
4700 *   }
4701 *  
4702 * @endcode
4703 *
4704 * if there is surface pressure, this surface pressure always applied to the
4705 * reference configuration
4706 *
4707 * @code
4708 *   const unsigned int face_pressure_id = 100;
4709 *   const double p0 = 0.0;
4710 *  
4711 *   for (const auto &face : cell->face_iterators())
4712 *   {
4713 *   if (face->at_boundary() && face->boundary_id() == face_pressure_id)
4714 *   {
4715 *   fe_face_values.reinit(cell, face);
4716 *  
4717 *   for (const unsigned int f_q_point : fe_face_values.quadrature_point_indices())
4718 *   {
4719 *   const Tensor<1, dim> &N = fe_face_values.normal_vector(f_q_point);
4720 *  
4721 *   const double pressure = p0 * time_ramp;
4722 *   const Tensor<1, dim> traction = pressure * N;
4723 *  
4724 *   for (const unsigned int i : fe_values.dof_indices())
4725 *   {
4726 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
4727 *  
4728 *   if (i_group == m_u_dof)
4729 *   {
4730 *   const unsigned int component_i = m_fe.system_to_component_index(i).first;
4731 *   const double Ni = fe_face_values.shape_value(i, f_q_point);
4732 *   const double JxW = fe_face_values.JxW(f_q_point);
4733 *   cell_rhs(i) -= (Ni * traction[component_i]) * JxW;
4734 *   }
4735 *   }
4736 *   }
4737 *   }
4738 *   }
4739 *  
4740 *   cell->get_dof_indices(local_dof_indices);
4741 *   for (const unsigned int i : fe_values.dof_indices())
4742 *   system_rhs(local_dof_indices[i]) += cell_rhs(i);
4743 *   } // for (const auto &cell : m_dof_handler.active_cell_iterators())
4744 *  
4745 *   m_timer.leave_subsection();
4746 *   }
4747 *  
4748 *   template <int dim>
4749 *   void PhaseFieldMonolithicSolve<dim>::update_history_field_step()
4750 *   {
4751 *   m_logfile << "\t\tUpdate history variable" << std::endl;
4752 *  
4753 *   for (const auto &cell : m_triangulation.active_cell_iterators())
4754 *   {
4755 *   std::vector<std::shared_ptr< PointHistory<dim>>> lqph =
4756 *   m_quadrature_point_history.get_data(cell);
4757 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
4758 *  
4759 *   for (unsigned int q_point = 0; q_point < m_n_q_points; ++q_point)
4760 *   {
4761 *   lqph[q_point]->update_history_variable();
4762 *   }
4763 *   }
4764 *   }
4765 *  
4766 *   template <int dim>
4767 *   double PhaseFieldMonolithicSolve<dim>::line_search_stepsize_gradient_based(const BlockVector<double> & BFGS_p_vector,
4768 *   const BlockVector<double> & solution_delta)
4769 *   {
4770 *   BlockVector<double> g_old(m_system_rhs);
4771 *  
4772 * @endcode
4773 *
4774 * BFGS_p_vector is the search direction
4775 *
4776 * @code
4777 *   BlockVector<double> solution_delta_trial(solution_delta);
4778 * @endcode
4779 *
4780 * take a full step size 1.0
4781 *
4782 * @code
4783 *   solution_delta_trial.add(1.0, BFGS_p_vector);
4784 *  
4785 *   update_qph_incremental(solution_delta_trial, m_solution, false);
4786 *  
4787 *   BlockVector<double> g_new(m_dofs_per_block);
4788 *   assemble_system_rhs_BFGS_parallel(m_solution, g_new);
4789 *  
4790 *   BlockVector<double> y_old(m_dofs_per_block);
4791 *  
4792 *   y_old = g_new - g_old;
4793 *  
4794 *   double alpha = 1.0;
4795 *  
4796 *   double alpha_old = 0.0;
4797 *  
4798 *   double delta_alpha_old = alpha - alpha_old;
4799 *  
4800 *   double delta_alpha_new;
4801 *  
4802 *   unsigned int ls_max = 10;
4803 *  
4804 *   for (unsigned int i = 1; i <= ls_max; ++i)
4805 *   {
4806 *   delta_alpha_new = -delta_alpha_old
4807 *   * (g_new * BFGS_p_vector)/(y_old * BFGS_p_vector);
4808 *   alpha += delta_alpha_new;
4809 *  
4810 *   if (std::fabs(delta_alpha_new) < 1.0e-5)
4811 *   break;
4812 *  
4813 *   if (i == ls_max)
4814 *   {
4815 *   alpha = 1.0;
4816 *   break;
4817 *   }
4818 *  
4819 *   g_old = g_new;
4820 *  
4821 * @endcode
4822 *
4823 * BFGS_p_vector is the search direction
4824 *
4825 * @code
4826 *   solution_delta_trial = solution_delta;
4827 *   solution_delta_trial.add(alpha, BFGS_p_vector);
4828 *   update_qph_incremental(solution_delta_trial, m_solution, false);
4829 *   assemble_system_rhs_BFGS_parallel(m_solution, g_new);
4830 *  
4831 *   y_old = g_new - g_old;
4832 *  
4833 *   delta_alpha_old = delta_alpha_new;
4834 *   }
4835 *  
4836 *   if (alpha < 1.0e-3)
4837 *   alpha = 1.0;
4838 *  
4839 *   return alpha;
4840 *   }
4841 *  
4842 *   template <int dim>
4843 *   double PhaseFieldMonolithicSolve<dim>::line_search_stepsize_strong_wolfe(const double phi_0,
4844 *   const double phi_0_prime,
4845 *   const BlockVector<double> & BFGS_p_vector,
4846 *   const BlockVector<double> & solution_delta)
4847 *   {
4848 * @endcode
4849 *
4850 * AssertThrow(phi_0_prime < 0,
4851 * ExcMessage("The derivative of phi at alpha = 0 should be negative!"));
4852 *
4853
4854 *
4855 * Some line search parameters
4856 *
4857 * @code
4858 *   const double c1 = 0.0001;
4859 *   const double c2 = 0.9;
4860 *   const double alpha_max = 100.0;
4861 *   const unsigned int max_iter = 20;
4862 *   double alpha = 1.0;
4863 *  
4864 *   double phi_old = phi_0;
4865 *   double phi_prime_old = phi_0_prime;
4866 *   double alpha_old = 0.0;
4867 *  
4868 *   double phi, phi_prime;
4869 *  
4870 *   std::pair<double, double> current_phi_phi_prime;
4871 *  
4872 *   unsigned int i = 0;
4873 *   for (; i < max_iter; ++i)
4874 *   {
4875 *   current_phi_phi_prime = calculate_phi_and_phi_prime(alpha, BFGS_p_vector, solution_delta);
4876 *   phi = current_phi_phi_prime.first;
4877 *   phi_prime = current_phi_phi_prime.second;
4878 *  
4879 *   if ( ( phi > (phi_0 + c1 * alpha * phi_0_prime) )
4880 *   || ( i > 0 && phi > phi_old ) )
4881 *   {
4882 *   return line_search_zoom_strong_wolfe(phi_old, phi_prime_old, alpha_old,
4883 *   phi, phi_prime, alpha,
4884 *   phi_0, phi_0_prime, BFGS_p_vector,
4885 *   c1, c2, max_iter, solution_delta);
4886 *   }
4887 *  
4888 *   if (std::fabs(phi_prime) <= c2 * std::fabs(phi_0_prime))
4889 *   {
4890 *   return alpha;
4891 *   }
4892 *  
4893 *   if (phi_prime >= 0)
4894 *   {
4895 *   return line_search_zoom_strong_wolfe(phi, phi_prime, alpha,
4896 *   phi_old, phi_prime_old, alpha_old,
4897 *   phi_0, phi_0_prime, BFGS_p_vector,
4898 *   c1, c2, max_iter, solution_delta);
4899 *   }
4900 *  
4901 *   phi_old = phi;
4902 *   phi_prime_old = phi_prime;
4903 *   alpha_old = alpha;
4904 *  
4905 *   alpha = std::min(2.0*alpha, alpha_max);
4906 *  
4907 * @endcode
4908 *
4909 * AssertThrow(alpha < alpha_max,
4910 * ExcMessage("alpha is bigger than alpha_max, line search failed!"));
4911 *
4912 * @code
4913 *   }
4914 *  
4915 * @endcode
4916 *
4917 * AssertThrow(i < max_iter,
4918 * ExcMessage("max number attempts arrived, line search failed!"));
4919 * Instead of terminating the program, we can just take a full step.
4920 *
4921 * @code
4922 *   if (i == max_iter)
4923 *   alpha = 1.0;
4924 *  
4925 *   return alpha;
4926 *   }
4927 *  
4928 *   template <int dim>
4929 *   double PhaseFieldMonolithicSolve<dim>::
4930 *   line_search_zoom_strong_wolfe(double phi_low, double phi_low_prime, double alpha_low,
4931 *   double phi_high, double phi_high_prime, double alpha_high,
4932 *   double phi_0, double phi_0_prime, const BlockVector<double> & BFGS_p_vector,
4933 *   double c1, double c2, unsigned int max_iter, const BlockVector<double> & solution_delta)
4934 *   {
4935 *   double alpha = 0;
4936 *   std::pair<double, double> current_phi_phi_prime;
4937 *   double phi, phi_prime;
4938 *  
4939 *   unsigned int i = 0;
4940 *   for (; i < max_iter; ++i)
4941 *   {
4942 * @endcode
4943 *
4944 * a simple bisection is faster than cubic interpolation
4945 *
4946 * @code
4947 *   alpha = 0.5 * (alpha_low + alpha_high);
4948 * @endcode
4949 *
4950 * alpha = line_search_interpolation_cubic(alpha_low, phi_low, phi_low_prime,
4951 * alpha_high, phi_high, phi_high_prime);
4952 *
4953 * @code
4954 *   current_phi_phi_prime = calculate_phi_and_phi_prime(alpha, BFGS_p_vector, solution_delta);
4955 *   phi = current_phi_phi_prime.first;
4956 *   phi_prime = current_phi_phi_prime.second;
4957 *  
4958 *   if ( (phi > phi_0 + c1 * alpha * phi_0_prime)
4959 *   || (phi > phi_low) )
4960 *   {
4961 *   alpha_high = alpha;
4962 *   phi_high = phi;
4963 *   phi_high_prime = phi_prime;
4964 *   }
4965 *   else
4966 *   {
4967 *   if (std::fabs(phi_prime) <= c2 * std::fabs(phi_0_prime))
4968 *   {
4969 * @endcode
4970 *
4971 * if (alpha < 1.0e-3)
4972 * alpha = 1.0e-3;
4973 *
4974 * @code
4975 *   return alpha;
4976 *   }
4977 *  
4978 *   if (phi_prime * (alpha_high - alpha_low) >= 0.0)
4979 *   {
4980 *   alpha_high = alpha_low;
4981 *   phi_high_prime = phi_low_prime;
4982 *   phi_high = phi_low;
4983 *   }
4984 *  
4985 *   alpha_low = alpha;
4986 *   phi_low_prime = phi_prime;
4987 *   phi_low = phi;
4988 *   }
4989 *   }
4990 *  
4991 *   if (alpha < 1.0e-3)
4992 *   alpha = 1.0;
4993 *  
4994 * @endcode
4995 *
4996 * avoid unused variable warnings from compiler
4997 *
4998 * @code
4999 *   (void)phi_high;
5000 *   (void)phi_high_prime;
5001 *   return alpha;
5002 *   }
5003 *  
5004 *   template <int dim>
5005 *   double PhaseFieldMonolithicSolve<dim>::
5006 *   line_search_interpolation_cubic(const double alpha_0, const double phi_0, const double phi_0_prime,
5007 *   const double alpha_1, const double phi_1, const double phi_1_prime)
5008 *   {
5009 *   const double d1 = phi_0_prime + phi_1_prime - 3.0 * (phi_0 - phi_1) / (alpha_0 - alpha_1);
5010 *  
5011 *   const double temp = d1 * d1 - phi_0_prime * phi_1_prime;
5012 *  
5013 *   if (temp < 0.0)
5014 *   return 0.5 * (alpha_0 + alpha_1);
5015 *  
5016 *   int sign;
5017 *   if (alpha_1 > alpha_0)
5018 *   sign = 1;
5019 *   else
5020 *   sign = -1;
5021 *  
5022 *   const double d2 = sign * std::sqrt(temp);
5023 *  
5024 *   const double alpha = alpha_1 - (alpha_1 - alpha_0)
5025 *   * (phi_1_prime + d2 - d1) / (phi_1_prime - phi_0_prime + 2*d2);
5026 *  
5027 *   if ( (alpha_1 > alpha_0)
5028 *   && (alpha > alpha_1 || alpha < alpha_0))
5029 *   return 0.5 * (alpha_0 + alpha_1);
5030 *  
5031 *   if ( (alpha_0 > alpha_1)
5032 *   && (alpha > alpha_0 || alpha < alpha_1))
5033 *   return 0.5 * (alpha_0 + alpha_1);
5034 *  
5035 *   return alpha;
5036 *   }
5037 *  
5038 *   template <int dim>
5039 *   std::pair<double, double> PhaseFieldMonolithicSolve<dim>::
5040 *   calculate_phi_and_phi_prime(const double alpha,
5041 *   const BlockVector<double> & BFGS_p_vector,
5042 *   const BlockVector<double> & solution_delta)
5043 *   {
5044 * @endcode
5045 *
5046 * the first component is phi(alpha), the second component is phi_prime(alpha),
5047 *
5048 * @code
5049 *   std::pair<double, double> phi_values;
5050 *  
5051 *   BlockVector<double> solution_delta_trial(solution_delta);
5052 *   solution_delta_trial.add(alpha, BFGS_p_vector);
5053 *  
5054 *   update_qph_incremental(solution_delta_trial, m_solution, false);
5055 *  
5056 *   BlockVector<double> system_rhs(m_dofs_per_block);
5057 *   assemble_system_rhs_BFGS_parallel(m_solution, system_rhs);
5058 * @endcode
5059 *
5060 * m_constraints.condense(system_rhs);
5061 *
5062
5063 *
5064 *
5065 * @code
5066 *   phi_values.first = calculate_energy_functional();
5067 *   phi_values.second = system_rhs * BFGS_p_vector;
5068 *   return phi_values;
5069 *   }
5070 *  
5071 *   template <int dim>
5072 *   void PhaseFieldMonolithicSolve<dim>::LBFGS_B0(BlockVector<double> & LBFGS_r_vector,
5073 *   BlockVector<double> & LBFGS_q_vector)
5074 *   {
5075 *   m_timer.enter_subsection("Solve B0");
5076 *  
5077 *   assemble_system_B0(m_solution);
5078 *  
5079 *   if (m_parameters.m_type_linear_solver == "Direct")
5080 *   {
5081 *   SparseDirectUMFPACK A_direct;
5082 *   A_direct.initialize(m_tangent_matrix);
5083 *   A_direct.vmult(LBFGS_r_vector,
5084 *   LBFGS_q_vector);
5085 *   }
5086 *   else if (m_parameters.m_type_linear_solver == "CG")
5087 *   {
5088 *   /*
5089 *   SolverControl solver_control(1e6, 1e-9);
5090 *   SolverCG<BlockVector<double>> cg(solver_control);
5091 *  
5092 *   PreconditionJacobi<BlockSparseMatrix<double>> preconditioner;
5093 *   preconditioner.initialize(m_tangent_matrix, 1.0);
5094 *  
5095 *   cg.solve(m_tangent_matrix,
5096 *   LBFGS_r_vector,
5097 *   LBFGS_q_vector,
5098 *   preconditioner);
5099 *   */
5100 *   SolverControl solver_control_uu(1e6, 1e-9);
5101 *   SolverCG<Vector<double>> cg_uu(solver_control_uu);
5102 *  
5103 *   PreconditionJacobi<SparseMatrix<double>> preconditioner_uu;
5104 *   preconditioner_uu.initialize(m_tangent_matrix.block(m_u_dof, m_u_dof), 1.0);
5105 *   cg_uu.solve(m_tangent_matrix.block(m_u_dof, m_u_dof),
5106 *   LBFGS_r_vector.block(m_u_dof),
5107 *   LBFGS_q_vector.block(m_u_dof),
5108 *   preconditioner_uu);
5109 *  
5110 *   SolverControl solver_control_dd(1e6, 1e-15);
5111 *   SolverCG<Vector<double>> cg_dd(solver_control_dd);
5112 *  
5113 *   PreconditionJacobi<SparseMatrix<double>> preconditioner_dd;
5114 *   preconditioner_dd.initialize(m_tangent_matrix.block(m_d_dof, m_d_dof), 1.0);
5115 *   cg_dd.solve(m_tangent_matrix.block(m_d_dof, m_d_dof),
5116 *   LBFGS_r_vector.block(m_d_dof),
5117 *   LBFGS_q_vector.block(m_d_dof),
5118 *   preconditioner_dd);
5119 *   }
5120 *   else
5121 *   {
5122 *   AssertThrow(false,
5123 *   ExcMessage("Selected linear solver not implemented!"));
5124 *   }
5125 *  
5126 *   m_timer.leave_subsection();
5127 *   }
5128 *  
5129 *   template <int dim>
5130 *   std::vector<double>
5131 *   PhaseFieldMonolithicSolve<dim>::solve_linear_system(BlockVector<double> & newton_update)
5132 *   {
5133 *   m_timer.enter_subsection("Solve coupled linear system");
5134 *  
5135 *   if (m_parameters.m_output_iteration_history)
5136 *   m_logfile << " SLV " << std::flush;
5137 *  
5138 *   std::vector<double> linear_solver_parameters(3);
5139 *   /*
5140 *   {
5141 *   SolverControl solver_control(1e6, 1e-9);
5142 *   SolverCG<Vector<double>> cg(solver_control);
5143 *   cg.connect_condition_number_slot(
5144 *   [&] (double condition_number)
5145 *   {
5146 *   linear_solver_parameters[0] = condition_number;
5147 * @endcode
5148 *
5149 * m_logfile << " Estimated condition number = "<< condition_number << std::endl;
5150 *
5151 * @code
5152 *   },
5153 *   false);
5154 *  
5155 *   PreconditionSSOR<SparseMatrix<double>> preconditioner;
5156 *   preconditioner.initialize(m_system_matrix_displacement, 1.2);
5157 *  
5158 *   cg.solve(m_system_matrix_displacement,
5159 *   newton_update,
5160 *   m_system_rhs_displacement,
5161 *   preconditioner);
5162 *  
5163 * @endcode
5164 *
5165 * m_logfile << " " << solver_control.last_step()
5166 * << " CG iterations needed to obtain convergence." << std::endl;
5167 *
5168 * @code
5169 *   linear_solver_parameters[1] = solver_control.last_step();
5170 *   linear_solver_parameters[2] = solver_control.last_value();
5171 *   }
5172 *   */
5173 *   SparseDirectUMFPACK A_direct;
5174 *   A_direct.initialize(m_tangent_matrix);
5175 *   A_direct.vmult(newton_update,
5176 *   m_system_rhs);
5177 *  
5178 *   m_constraints.distribute(newton_update);
5179 *  
5180 *   m_timer.leave_subsection();
5181 *   return linear_solver_parameters;
5182 *   }
5183 *  
5184 *   template <int dim>
5185 *   void PhaseFieldMonolithicSolve<dim>::print_conv_header_newton()
5186 *   {
5187 *   static const unsigned int l_width = 135;
5188 *   m_logfile << '\t' << '\t';
5189 *   for (unsigned int i = 0; i < l_width; ++i)
5190 *   m_logfile << '_';
5191 *   m_logfile << std::endl;
5192 *  
5193 *   m_logfile << " SOLVER STEP (Newton) "
5194 *   << " | Cond No. Lin_Iter Lin_Res Res_Norm "
5195 *   << " Res_u Res_d Inc_Norm "
5196 *   << " Inc_u Inc_d" << std::endl;
5197 *  
5198 *   m_logfile << '\t' << '\t';
5199 *   for (unsigned int i = 0; i < l_width; ++i)
5200 *   m_logfile << '_';
5201 *   m_logfile << std::endl;
5202 *   }
5203 *  
5204 *   template <int dim>
5205 *   void PhaseFieldMonolithicSolve<dim>::print_conv_header_BFGS()
5206 *   {
5207 *   static const unsigned int l_width = 125;
5208 *   m_logfile << '\t' << '\t';
5209 *   for (unsigned int i = 0; i < l_width; ++i)
5210 *   m_logfile << '_';
5211 *   m_logfile << std::endl;
5212 *  
5213 *   m_logfile << " SOLVER STEP (BFGS) "
5214 *   << " | Line Search alpha Energy Res_Norm "
5215 *   << " Res_u Res_d Inc_Norm "
5216 *   << " Inc_u Inc_d" << std::endl;
5217 *  
5218 *   m_logfile << '\t' << '\t';
5219 *   for (unsigned int i = 0; i < l_width; ++i)
5220 *   m_logfile << '_';
5221 *   m_logfile << std::endl;
5222 *   }
5223 *  
5224 *   template <int dim>
5225 *   void PhaseFieldMonolithicSolve<dim>::print_conv_header_LBFGS()
5226 *   {
5227 *   static const unsigned int l_width = 120;
5228 *   m_logfile << '\t' << '\t';
5229 *   for (unsigned int i = 0; i < l_width; ++i)
5230 *   m_logfile << '_';
5231 *   m_logfile << std::endl;
5232 *  
5233 *   m_logfile << " SOLVER STEP (LBFGS) "
5234 *   << " | LS-alpha Energy Res_Norm "
5235 *   << " Res_u Res_d Inc_Norm "
5236 *   << " Inc_u Inc_d" << std::endl;
5237 *  
5238 *   m_logfile << '\t' << '\t';
5239 *   for (unsigned int i = 0; i < l_width; ++i)
5240 *   m_logfile << '_';
5241 *   m_logfile << std::endl;
5242 *   }
5243 *  
5244 *   template <int dim>
5245 *   bool PhaseFieldMonolithicSolve<dim>::
5246 *   solve_nonlinear_timestep_newton(BlockVector<double> & solution_delta)
5247 *   {
5248 *   BlockVector<double> newton_update(m_dofs_per_block);
5249 *  
5250 *   m_error_residual.reset();
5251 *   m_error_residual_0.reset();
5252 *   m_error_residual_norm.reset();
5253 *   m_error_update.reset();
5254 *   m_error_update_0.reset();
5255 *   m_error_update_norm.reset();
5256 *  
5257 *   if (m_parameters.m_output_iteration_history)
5258 *   print_conv_header_newton();
5259 *  
5260 *   unsigned int newton_iteration = 0;
5261 *   for (; newton_iteration < m_parameters.m_max_iterations_NR; ++newton_iteration)
5262 *   {
5263 *   if (m_parameters.m_output_iteration_history)
5264 *   m_logfile << '\t' << '\t' << std::setw(2) << newton_iteration << ' '
5265 *   << std::flush;
5266 *  
5267 *   make_constraints(newton_iteration);
5268 *   assemble_system_newton(m_solution);
5269 *  
5270 *   get_error_residual(m_error_residual);
5271 *   if (newton_iteration == 0)
5272 *   m_error_residual_0 = m_error_residual;
5273 *  
5274 *   m_error_residual_norm = m_error_residual;
5275 *   m_error_residual_norm.normalize(m_error_residual_0);
5276 *  
5277 *   if (newton_iteration > 0 && m_error_update_norm.m_u <= m_parameters.m_tol_u_incr
5278 *   && m_error_residual_norm.m_u <= m_parameters.m_tol_u_residual
5279 *   && m_error_update_norm.m_d <= m_parameters.m_tol_d_incr
5280 *   && m_error_residual_norm.m_d <= m_parameters.m_tol_d_residual)
5281 *   {
5282 *   if (m_parameters.m_output_iteration_history)
5283 *   {
5284 *   m_logfile << " CONVERGED!";
5285 *   m_logfile << " | " << std::fixed << std::setprecision(3) << std::setw(7)
5286 *   << std::scientific
5287 *   << " " << " ---- "
5288 *   << " " << " ---- "
5289 *   << " " << " ---- "
5290 *   << " " << m_error_residual_norm.m_norm
5291 *   << " " << m_error_residual_norm.m_u
5292 *   << " " << m_error_residual_norm.m_d
5293 *   << " " << m_error_update_norm.m_norm
5294 *   << " " << m_error_update_norm.m_u
5295 *   << " " << m_error_update_norm.m_d
5296 *   << " " << std::endl;
5297 *  
5298 *   m_logfile << '\t' << '\t';
5299 *   for (unsigned int i = 0; i < 135; ++i)
5300 *   m_logfile << '_';
5301 *   m_logfile << std::endl;
5302 *   }
5303 *  
5304 *   m_logfile << "\t\tConvergence is reached after "
5305 *   << newton_iteration << " Newton iterations."<< std::endl;
5306 *  
5307 *   m_logfile << "\t\tResidual information of convergence:" << std::endl;
5308 *  
5309 *   m_logfile << "\t\t\tRelative residual of disp. equation: "
5310 *   << m_error_residual_norm.m_u << std::endl;
5311 *  
5312 *   m_logfile << "\t\t\tAbsolute residual of disp. equation: "
5313 *   << m_error_residual_norm.m_u * m_error_residual_0.m_u << std::endl;
5314 *  
5315 *   m_logfile << "\t\t\tRelative residual of phasefield equation: "
5316 *   << m_error_residual_norm.m_d << std::endl;
5317 *  
5318 *   m_logfile << "\t\t\tAbsolute residual of phasefield equation: "
5319 *   << m_error_residual_norm.m_d * m_error_residual_0.m_d << std::endl;
5320 *  
5321 *   m_logfile << "\t\t\tRelative increment of disp.: "
5322 *   << m_error_update_norm.m_u << std::endl;
5323 *  
5324 *   m_logfile << "\t\t\tAbsolute increment of disp.: "
5325 *   << m_error_update_norm.m_u * m_error_update_0.m_u << std::endl;
5326 *  
5327 *   m_logfile << "\t\t\tRelative increment of phasefield: "
5328 *   << m_error_update_norm.m_d << std::endl;
5329 *  
5330 *   m_logfile << "\t\t\tAbsolute increment of phasefield: "
5331 *   << m_error_update_norm.m_d * m_error_update_0.m_d << std::endl;
5332 *  
5333 * @endcode
5334 *
5335 * break;
5336 *
5337 * @code
5338 *   return true;
5339 *   }
5340 *  
5341 *   std::vector<double> linear_solver_parameters(3);
5342 *  
5343 *   linear_solver_parameters = solve_linear_system(newton_update);
5344 *  
5345 *   get_error_update(newton_update, m_error_update);
5346 *   if (newton_iteration == 0)
5347 *   m_error_update_0 = m_error_update;
5348 *  
5349 *   m_error_update_norm = m_error_update;
5350 *   m_error_update_norm.normalize(m_error_update_0);
5351 *  
5352 *   solution_delta += newton_update;
5353 *   update_qph_incremental(solution_delta, m_solution, true);
5354 *  
5355 *   if (m_parameters.m_output_iteration_history)
5356 *   {
5357 *   m_logfile << " | " << std::fixed << std::setprecision(3) << std::setw(7)
5358 *   << std::scientific
5359 *   << " " << linear_solver_parameters[0]
5360 *   << " " << linear_solver_parameters[1]
5361 *   << " " << linear_solver_parameters[2]
5362 *   << " " << m_error_residual_norm.m_norm
5363 *   << " " << m_error_residual_norm.m_u
5364 *   << " " << m_error_residual_norm.m_d
5365 *   << " " << m_error_update_norm.m_norm
5366 *   << " " << m_error_update_norm.m_u
5367 *   << " " << m_error_update_norm.m_d
5368 *   << " " << std::endl;
5369 *   }
5370 *   }
5371 *  
5372 * @endcode
5373 *
5374 * AssertThrow(newton_iteration < m_parameters.m_max_iterations_NR,
5375 * ExcMessage("No convergence in Newton-Raphson nonlinear solver!"));
5376 *
5377 * @code
5378 *   return false;
5379 *   }
5380 *  
5381 *   template <int dim>
5382 *   void PhaseFieldMonolithicSolve<dim>::
5383 *   solve_nonlinear_timestep_BFGS(BlockVector<double> & solution_delta)
5384 *   {
5385 *   AssertThrow(false,
5386 *   ExcMessage("BFGS requires too much memory. Please use L-BFGS!"));
5387 *  
5388 *   BlockVector<double> BFGS_update(m_dofs_per_block);
5389 *  
5390 *   m_error_residual.reset();
5391 *   m_error_residual_0.reset();
5392 *   m_error_residual_norm.reset();
5393 *   m_error_update.reset();
5394 *   m_error_update_0.reset();
5395 *   m_error_update_norm.reset();
5396 *  
5397 *   print_conv_header_BFGS();
5398 *  
5399 *   unsigned int BFGS_iteration = 0;
5400 *  
5401 * @endcode
5402 *
5403 * Initial guess B_0, which is a full matrix and takes a lot of memory
5404 *
5405 * @code
5406 *   FullMatrix<double> BFGS_matrix = IdentityMatrix(m_dof_handler.n_dofs());
5407 *   Vector<double> BFGS_r_vector(m_dof_handler.n_dofs());
5408 *   Vector<double> BFGS_p_vector(m_dof_handler.n_dofs());
5409 *   Vector<double> BFGS_y_vector(m_dof_handler.n_dofs());
5410 *   Vector<double> BFGS_temp_vector(m_dof_handler.n_dofs());
5411 *  
5412 *   double line_search_parameter, rho;
5413 *  
5414 * @endcode
5415 *
5416 * Most likely, we will not be able to create a second full matrix since
5417 * we will run out of memory on a laptop workstation
5418 *
5419 * @code
5420 *   FullMatrix<double> temp_matrix_1(m_dof_handler.n_dofs());
5421 *   FullMatrix<double> temp_matrix_2(m_dof_handler.n_dofs());
5422 *  
5423 *   for (; BFGS_iteration < m_parameters.m_max_iterations_BFGS; ++BFGS_iteration)
5424 *   {
5425 *   m_logfile << '\t' << '\t' << std::setw(2) << BFGS_iteration << ' '
5426 *   << std::flush;
5427 *  
5428 *   make_constraints(BFGS_iteration);
5429 *  
5430 * @endcode
5431 *
5432 * At the first step, we simply distribute the inhomogeneous part of
5433 * the constraints
5434 *
5435 * @code
5436 *   if (BFGS_iteration == 0)
5437 *   {
5438 *   m_constraints.distribute(BFGS_update);
5439 *   solution_delta += BFGS_update;
5440 *   m_logfile << " --- " << std::flush;
5441 *   m_logfile << " --- " << std::flush;
5442 *   update_qph_incremental(solution_delta, m_solution, false);
5443 *   m_logfile << " --- |" << std::flush;
5444 *   m_logfile << std::endl;
5445 *   continue;
5446 *   }
5447 *   else if (BFGS_iteration == 1)
5448 *   {
5449 * @endcode
5450 *
5451 * Calculate the residual vector r. NOTICE that in the context of
5452 * BFGS, this r is the gradient of the energy functional (objective function),
5453 * NOT the negative gradient of the energy functional
5454 *
5455 * @code
5456 *   assemble_system_rhs_BFGS(m_solution, m_system_rhs);
5457 *  
5458 * @endcode
5459 *
5460 * We cannot simply zero out the dofs that are constrained, since we might
5461 * have hanging node constraints. In this case, we need to modify the RHS
5462 * as C^T * b, which C contains entries of 0.5 (x_3 = 0.5*x_1 + 0.5*x_2)
5463 * for (unsigned int i = 0; i < m_dof_handler.n_dofs(); ++i)
5464 * if (m_constraints.is_constrained(i))
5465 * m_system_rhs(i) = 0.0;
5466 *
5467
5468 *
5469 * if m_constraints has inhomogeneity, we cannot call m_constraints.condense(m_system_rhs),
5470 * since the m_system_matrix needs to be provided to modify the RHS properly. However, this
5471 * error will not be detected in the release mode and only will be detected on the debug mode
5472 *
5473 * @code
5474 *   m_constraints.condense(m_system_rhs);
5475 *   }
5476 *  
5477 *   m_logfile << " --- " << std::flush;
5478 *   m_logfile << " --- " << std::flush;
5479 *   m_logfile << " --- " << std::flush;
5480 *  
5481 *   get_error_residual(m_error_residual);
5482 *   if (BFGS_iteration == 1)
5483 *   m_error_residual_0 = m_error_residual;
5484 *  
5485 *   m_error_residual_norm = m_error_residual;
5486 *   m_error_residual_norm.normalize(m_error_residual_0);
5487 *  
5488 *   if (BFGS_iteration > 1 && m_error_update_norm.m_u <= m_parameters.m_tol_u_incr
5489 *   && m_error_residual_norm.m_u <= m_parameters.m_tol_u_residual
5490 *   && m_error_update_norm.m_d <= m_parameters.m_tol_d_incr
5491 *   && m_error_residual_norm.m_d <= m_parameters.m_tol_d_residual)
5492 *   {
5493 *   m_logfile << " CONVERGED!";
5494 *   m_logfile << "| " << std::fixed << std::setprecision(3) << std::setw(7)
5495 *   << std::scientific
5496 *   << " " << " ---- "
5497 *   << " " << " ---- "
5498 *   << " " << " ---- "
5499 *   << " " << m_error_residual_norm.m_norm
5500 *   << " " << m_error_residual_norm.m_u
5501 *   << " " << m_error_residual_norm.m_d
5502 *   << " " << m_error_update_norm.m_norm
5503 *   << " " << m_error_update_norm.m_u
5504 *   << " " << m_error_update_norm.m_d
5505 *   << " " << std::endl;
5506 *  
5507 *   m_logfile << '\t' << '\t';
5508 *   for (unsigned int i = 0; i < 135; ++i)
5509 *   m_logfile << '_';
5510 *   m_logfile << std::endl;
5511 *  
5512 *   break;
5513 *   }
5514 *  
5515 * @endcode
5516 *
5517 * BFGS algorithm
5518 *
5519 * @code
5520 *   BFGS_r_vector = m_system_rhs;
5521 *   BFGS_matrix.vmult(BFGS_p_vector, BFGS_r_vector);
5522 *   BFGS_p_vector *= -1.0;
5523 *   m_constraints.distribute(BFGS_p_vector);
5524 *  
5525 * @endcode
5526 *
5527 * We need a line search algorithm to decide line_search_parameter
5528 *
5529 * @code
5530 *   const double phi_0 = calculate_energy_functional();
5531 *   const double phi_0_prime = BFGS_r_vector * BFGS_p_vector;
5532 *  
5533 *   BlockVector<double> BFGS_p_vector_block(m_dofs_per_block);
5534 *   BFGS_p_vector_block = BFGS_p_vector;
5535 *   line_search_parameter = line_search_stepsize_strong_wolfe(phi_0,
5536 *   phi_0_prime,
5537 *   BFGS_p_vector_block,
5538 *   solution_delta);
5539 *  
5540 *   BFGS_p_vector *= line_search_parameter;
5541 *   BFGS_update = BFGS_p_vector;
5542 *  
5543 *   get_error_update(BFGS_update, m_error_update);
5544 *   if (BFGS_iteration == 1)
5545 *   m_error_update_0 = m_error_update;
5546 *  
5547 *   m_error_update_norm = m_error_update;
5548 *   m_error_update_norm.normalize(m_error_update_0);
5549 *  
5550 *   solution_delta += BFGS_update;
5551 *   update_qph_incremental(solution_delta, m_solution, false);
5552 *  
5553 *   BFGS_y_vector = m_system_rhs;
5554 *   BFGS_y_vector *= -1.0;
5555 *   assemble_system_rhs_BFGS(m_solution, m_system_rhs);
5556 *   m_constraints.condense(m_system_rhs);
5557 *   BFGS_temp_vector = m_system_rhs;
5558 *   BFGS_y_vector += BFGS_temp_vector;
5559 *  
5560 * @endcode
5561 *
5562 * rho should be positive with the proper line search
5563 *
5564 * @code
5565 *   rho = BFGS_y_vector * BFGS_p_vector;
5566 *   rho = 1.0/rho;
5567 *  
5568 *   if (rho < 0)
5569 *   m_logfile << "Rho is negative!" << std::endl;
5570 *  
5571 * @endcode
5572 *
5573 * In the first step, we scale the identity matrix as
5574 * the BFGS matrix
5575 *
5576 * @code
5577 *   if (BFGS_iteration == 1)
5578 *   {
5579 *   double scale_parameter = (BFGS_y_vector * BFGS_p_vector) / (BFGS_y_vector.norm_sqr());
5580 *   BFGS_matrix *= scale_parameter;
5581 *   }
5582 *  
5583 *   temp_matrix_1.outer_product(BFGS_p_vector, BFGS_y_vector);
5584 *   temp_matrix_2 = IdentityMatrix(m_dof_handler.n_dofs());
5585 *   temp_matrix_2.add(-rho, temp_matrix_1);
5586 *  
5587 *   temp_matrix_2.mmult(temp_matrix_1, BFGS_matrix);
5588 *   temp_matrix_1.mTmult(BFGS_matrix, temp_matrix_2);
5589 *  
5590 *   temp_matrix_1.outer_product(BFGS_p_vector, BFGS_p_vector);
5591 *  
5592 *   BFGS_matrix.add(rho, temp_matrix_1);
5593 *  
5594 *   const double energy_functional = calculate_energy_functional();
5595 *  
5596 *   m_logfile << " | " << std::fixed << std::setprecision(3) << std::setw(7)
5597 *   << std::scientific
5598 *   << " " << line_search_parameter
5599 *   << " " << energy_functional
5600 *   << " " << m_error_residual_norm.m_norm
5601 *   << " " << m_error_residual_norm.m_u
5602 *   << " " << m_error_residual_norm.m_d
5603 *   << " " << m_error_update_norm.m_norm
5604 *   << " " << m_error_update_norm.m_u
5605 *   << " " << m_error_update_norm.m_d
5606 *   << " " << std::endl;
5607 *   }
5608 *  
5609 *   AssertThrow(BFGS_iteration < m_parameters.m_max_iterations_BFGS,
5610 *   ExcMessage("No convergence in BFGS nonlinear solver!"));
5611 *   }
5612 *  
5613 *   template <int dim>
5614 *   void PhaseFieldMonolithicSolve<dim>::
5615 *   solve_nonlinear_timestep_LBFGS(BlockVector<double> & solution_delta,
5616 *   BlockVector<double> & LBFGS_update_refine)
5617 *   {
5618 *   BlockVector<double> LBFGS_update(m_dofs_per_block);
5619 *  
5620 *   LBFGS_update = 0.0;
5621 *  
5622 *   m_error_residual.reset();
5623 *   m_error_residual_0.reset();
5624 *   m_error_residual_norm.reset();
5625 *   m_error_update.reset();
5626 *   m_error_update_0.reset();
5627 *   m_error_update_norm.reset();
5628 *  
5629 *   if (m_parameters.m_output_iteration_history)
5630 *   print_conv_header_LBFGS();
5631 *  
5632 *   unsigned int LBFGS_iteration = 0;
5633 *  
5634 *   BlockVector<double> LBFGS_r_vector(m_dofs_per_block);
5635 *   BlockVector<double> LBFGS_y_vector(m_dofs_per_block);
5636 *   BlockVector<double> LBFGS_q_vector(m_dofs_per_block);
5637 *   BlockVector<double> LBFGS_s_vector(m_dofs_per_block);
5638 *   std::list<std::pair< std::pair<BlockVector<double>,
5640 *   double>> LBFGS_vector_list;
5641 *  
5642 *   const unsigned int LBFGS_m = m_parameters.m_LBFGS_m;
5643 *   std::list<double> LBFGS_alpha_list;
5644 *  
5645 *   double line_search_parameter = 0.0;
5646 *   double LBFGS_beta = 0.0;
5647 *   double rho = 0.0;
5648 *  
5649 *   for (; LBFGS_iteration < m_parameters.m_max_iterations_BFGS; ++LBFGS_iteration)
5650 *   {
5651 *   if (m_parameters.m_output_iteration_history)
5652 *   m_logfile << '\t' << '\t' << std::setw(2) << LBFGS_iteration << ' '
5653 *   << std::flush;
5654 *  
5655 *   make_constraints(LBFGS_iteration);
5656 *  
5657 * @endcode
5658 *
5659 * At the first step, we simply distribute the inhomogeneous part of
5660 * the constraints
5661 *
5662 * @code
5663 *   if (LBFGS_iteration == 0)
5664 *   {
5665 * @endcode
5666 *
5667 * use the solution from the previous solve on the
5668 * refined mesh as initial guess
5669 *
5670 * @code
5671 *   LBFGS_update = LBFGS_update_refine;
5672 *  
5673 *   m_constraints.distribute(LBFGS_update);
5674 *   solution_delta += LBFGS_update;
5675 *   if (m_parameters.m_output_iteration_history)
5676 *   {
5677 *   m_logfile << " --- " << std::flush;
5678 *   m_logfile << " --- " << std::flush;
5679 *   }
5680 *   update_qph_incremental(solution_delta, m_solution, false);
5681 *   if (m_parameters.m_output_iteration_history)
5682 *   {
5683 *   m_logfile << " --- |" << std::flush;
5684 *   m_logfile << std::endl;
5685 *   }
5686 *   continue;
5687 *   }
5688 *   else if (LBFGS_iteration == 1)
5689 *   {
5690 * @endcode
5691 *
5692 * Calculate the residual vector r. NOTICE that in the context of
5693 * BFGS, this r is the gradient of the energy functional (objective function),
5694 * NOT the negative gradient of the energy functional
5695 *
5696 * @code
5697 *   assemble_system_rhs_BFGS_parallel(m_solution, m_system_rhs);
5698 *  
5699 * @endcode
5700 *
5701 * We cannot simply zero out the dofs that are constrained, since we might
5702 * have hanging node constraints. In this case, we need to modify the RHS
5703 * as C^T * b, which C contains entries of 0.5 (x_3 = 0.5*x_1 + 0.5*x_2)
5704 * for (unsigned int i = 0; i < m_dof_handler.n_dofs(); ++i)
5705 * if (m_constraints.is_constrained(i))
5706 * m_system_rhs(i) = 0.0;
5707 *
5708
5709 *
5710 * if m_constraints has inhomogeneity, we cannot call m_constraints.condense(m_system_rhs),
5711 * since the m_system_matrix needs to be provided to modify the RHS properly. However, this
5712 * error will not be detected in the release mode and only will be detected on the debug mode
5713 * if we use assemble_system_rhs_BFGS_parallel, then condense() is not necessary
5714 * m_constraints.condense(m_system_rhs);
5715 *
5716 * @code
5717 *   }
5718 *   if (m_parameters.m_output_iteration_history)
5719 *   {
5720 *   m_logfile << " --- " << std::flush;
5721 *   m_logfile << " --- " << std::flush;
5722 *   m_logfile << " --- " << std::flush;
5723 *   }
5724 *  
5725 *   get_error_residual(m_error_residual);
5726 *   if (LBFGS_iteration == 1)
5727 *   m_error_residual_0 = m_error_residual;
5728 *  
5729 *   m_error_residual_norm = m_error_residual;
5730 * @endcode
5731 *
5732 * For three-point bending problem and 3D problem, we use absolute residual
5733 * for convergence test
5734 *
5735 * @code
5736 *   if (m_parameters.m_relative_residual)
5737 *   m_error_residual_norm.normalize(m_error_residual_0);
5738 *  
5739 *   if (LBFGS_iteration > 1 && m_error_update_norm.m_u <= m_parameters.m_tol_u_incr
5740 *   && m_error_residual_norm.m_u <= m_parameters.m_tol_u_residual
5741 *   && m_error_update_norm.m_d <= m_parameters.m_tol_d_incr
5742 *   && m_error_residual_norm.m_d <= m_parameters.m_tol_d_residual
5743 *   )
5744 *   {
5745 *   if (m_parameters.m_output_iteration_history)
5746 *   {
5747 *   m_logfile << " | ";
5748 *   m_logfile << " CONVERGED! " << std::fixed << std::setprecision(3) << std::setw(7)
5749 *   << std::scientific
5750 *   << " ---- "
5751 *   << " " << m_error_residual_norm.m_norm
5752 *   << " " << m_error_residual_norm.m_u
5753 *   << " " << m_error_residual_norm.m_d
5754 *   << " " << m_error_update_norm.m_norm
5755 *   << " " << m_error_update_norm.m_u
5756 *   << " " << m_error_update_norm.m_d
5757 *   << " " << std::endl;
5758 *  
5759 *   m_logfile << '\t' << '\t';
5760 *   for (unsigned int i = 0; i < 120; ++i)
5761 *   m_logfile << '_';
5762 *   m_logfile << std::endl;
5763 *   }
5764 *  
5765 *   m_logfile << "\t\tConvergence is reached after "
5766 *   << LBFGS_iteration << " L-BFGS iterations."<< std::endl;
5767 *  
5768 *   m_logfile << "\t\tResidual information of convergence:" << std::endl;
5769 *  
5770 *   if (m_parameters.m_relative_residual)
5771 *   {
5772 *   m_logfile << "\t\t\tRelative residual of disp. equation: "
5773 *   << m_error_residual_norm.m_u << std::endl;
5774 *  
5775 *   m_logfile << "\t\t\tAbsolute residual of disp. equation: "
5776 *   << m_error_residual_norm.m_u * m_error_residual_0.m_u << std::endl;
5777 *  
5778 *   m_logfile << "\t\t\tRelative residual of phasefield equation: "
5779 *   << m_error_residual_norm.m_d << std::endl;
5780 *  
5781 *   m_logfile << "\t\t\tAbsolute residual of phasefield equation: "
5782 *   << m_error_residual_norm.m_d * m_error_residual_0.m_d << std::endl;
5783 *  
5784 *   m_logfile << "\t\t\tRelative increment of disp.: "
5785 *   << m_error_update_norm.m_u << std::endl;
5786 *  
5787 *   m_logfile << "\t\t\tAbsolute increment of disp.: "
5788 *   << m_error_update_norm.m_u * m_error_update_0.m_u << std::endl;
5789 *  
5790 *   m_logfile << "\t\t\tRelative increment of phasefield: "
5791 *   << m_error_update_norm.m_d << std::endl;
5792 *  
5793 *   m_logfile << "\t\t\tAbsolute increment of phasefield: "
5794 *   << m_error_update_norm.m_d * m_error_update_0.m_d << std::endl;
5795 *   }
5796 *   else
5797 *   {
5798 *   m_logfile << "\t\t\tAbsolute residual of disp. equation: "
5799 *   << m_error_residual_norm.m_u << std::endl;
5800 *  
5801 *   m_logfile << "\t\t\tAbsolute residual of phasefield equation: "
5802 *   << m_error_residual_norm.m_d << std::endl;
5803 *  
5804 *   m_logfile << "\t\t\tAbsolute increment of disp.: "
5805 *   << m_error_update_norm.m_u << std::endl;
5806 *  
5807 *   m_logfile << "\t\t\tAbsolute increment of phasefield: "
5808 *   << m_error_update_norm.m_d << std::endl;
5809 *   }
5810 *  
5811 *   break;
5812 *   }
5813 *  
5814 * @endcode
5815 *
5816 * LBFGS algorithm
5817 *
5818 * @code
5819 *   LBFGS_q_vector = m_system_rhs;
5820 *  
5821 *   LBFGS_alpha_list.clear();
5822 *   for (auto itr = LBFGS_vector_list.begin(); itr != LBFGS_vector_list.end(); ++itr)
5823 *   {
5824 *   LBFGS_s_vector = (itr->first).first;
5825 *   LBFGS_y_vector = (itr->first).second;
5826 *   rho = itr->second;
5827 *  
5828 *   const double alpha = rho * (LBFGS_s_vector * LBFGS_q_vector);
5829 *   LBFGS_alpha_list.push_back(alpha);
5830 *  
5831 *   LBFGS_q_vector.add(-alpha, LBFGS_y_vector);
5832 *   }
5833 *   /*
5834 *   double scale_gamma = 0.0;
5835 *   if (LBFGS_iteration == 1)
5836 *   {
5837 *   scale_gamma = 1.0;
5838 *   }
5839 *   else
5840 *   {
5841 *   LBFGS_s_vector = LBFGS_vector_list.front().first.first;
5842 *   LBFGS_y_vector = LBFGS_vector_list.front().first.second;
5843 *   scale_gamma = (LBFGS_s_vector * LBFGS_y_vector)/(LBFGS_y_vector * LBFGS_y_vector);
5844 *   }
5845 *  
5846 *   LBFGS_q_vector *= scale_gamma;
5847 *   LBFGS_r_vector = LBFGS_q_vector;
5848 *   */
5849 *   LBFGS_B0(LBFGS_r_vector,
5850 *   LBFGS_q_vector);
5851 *  
5852 *   for (auto itr = LBFGS_vector_list.rbegin(); itr != LBFGS_vector_list.rend(); ++itr)
5853 *   {
5854 *   LBFGS_s_vector = (itr->first).first;
5855 *   LBFGS_y_vector = (itr->first).second;
5856 *   rho = itr->second;
5857 *  
5858 *   LBFGS_beta = rho * (LBFGS_y_vector * LBFGS_r_vector);
5859 *  
5860 *   const double alpha = LBFGS_alpha_list.back();
5861 *   LBFGS_alpha_list.pop_back();
5862 *  
5863 *   LBFGS_r_vector.add(alpha - LBFGS_beta, LBFGS_s_vector);
5864 *   }
5865 *  
5866 *   LBFGS_r_vector *= -1.0; // this is the p_vector (search direction)
5867 *  
5868 *   m_constraints.distribute(LBFGS_r_vector);
5869 *  
5870 * @endcode
5871 *
5872 * We need a line search algorithm to decide line_search_parameter
5873 *
5874 * @code
5875 *   if(m_parameters.m_type_line_search == "StrongWolfe")
5876 *   {
5877 *   const double phi_0 = calculate_energy_functional();
5878 *   const double phi_0_prime = m_system_rhs * LBFGS_r_vector;
5879 *  
5880 *   line_search_parameter = line_search_stepsize_strong_wolfe(phi_0,
5881 *   phi_0_prime,
5882 *   LBFGS_r_vector,
5883 *   solution_delta);
5884 *   }
5885 *   else if(m_parameters.m_type_line_search == "GradientBased")
5886 *   {
5887 * @endcode
5888 *
5889 * LBFGS_r_vector is the search direction
5890 *
5891 * @code
5892 *   line_search_parameter = line_search_stepsize_gradient_based(LBFGS_r_vector,
5893 *   solution_delta);
5894 *   }
5895 *   else
5896 *   {
5897 *   Assert(false, ExcMessage("An unknown line search method is called!"));
5898 *   }
5899 *  
5900 *   LBFGS_r_vector *= line_search_parameter;
5901 *   LBFGS_update = LBFGS_r_vector;
5902 *  
5903 *   get_error_update(LBFGS_update, m_error_update);
5904 *   if (LBFGS_iteration == 1)
5905 *   m_error_update_0 = m_error_update;
5906 *  
5907 *   m_error_update_norm = m_error_update;
5908 * @endcode
5909 *
5910 * For three-point bending problem and the sphere inclusion problem,
5911 * we use absolute residual for convergence test
5912 *
5913 * @code
5914 *   if (m_parameters.m_relative_residual)
5915 *   m_error_update_norm.normalize(m_error_update_0);
5916 *  
5917 *   solution_delta += LBFGS_update;
5918 *   update_qph_incremental(solution_delta, m_solution, false);
5919 *  
5920 *   LBFGS_y_vector = m_system_rhs;
5921 *   LBFGS_y_vector *= -1.0;
5922 *   assemble_system_rhs_BFGS_parallel(m_solution, m_system_rhs);
5923 * @endcode
5924 *
5925 * if we use assemble_system_rhs_BFGS_parallel, then condense() is not necessary
5926 * m_constraints.condense(m_system_rhs);
5927 *
5928 * @code
5929 *   LBFGS_y_vector += m_system_rhs;
5930 *  
5931 *   LBFGS_s_vector = LBFGS_update;
5932 *  
5933 *   const double g_norm = m_system_rhs.l2_norm();
5934 *  
5935 *   const double yxs = LBFGS_y_vector * LBFGS_s_vector;
5936 *  
5937 *   const double sxs = LBFGS_s_vector * LBFGS_s_vector;
5938 *  
5939 *   if (yxs/sxs >= 1.0e-6 * g_norm)
5940 *   {
5941 *   if (LBFGS_iteration > LBFGS_m)
5942 *   LBFGS_vector_list.pop_back();
5943 *  
5944 *   rho = 1.0 / yxs;
5945 *  
5946 *   LBFGS_vector_list.push_front(std::make_pair(std::make_pair(LBFGS_s_vector,
5947 *   LBFGS_y_vector),
5948 *   rho));
5949 *   }
5950 *  
5951 *   if (m_parameters.m_output_iteration_history)
5952 *   {
5953 *   const double energy_functional = calculate_energy_functional();
5954 *  
5955 *   m_logfile << " | " << std::fixed << std::setprecision(3) << std::setw(1)
5956 *   << std::scientific
5957 *   << "" << line_search_parameter
5958 *   << std::fixed << std::setprecision(6) << std::setw(1)
5959 *   << std::scientific
5960 *   << " " << energy_functional
5961 *   << std::fixed << std::setprecision(3) << std::setw(1)
5962 *   << std::scientific
5963 *   << " " << m_error_residual_norm.m_norm
5964 *   << " " << m_error_residual_norm.m_u
5965 *   << " " << m_error_residual_norm.m_d
5966 *   << " " << m_error_update_norm.m_norm
5967 *   << " " << m_error_update_norm.m_u
5968 *   << " " << m_error_update_norm.m_d
5969 *   << " " << std::endl;
5970 *   }
5971 *   }
5972 *  
5973 *   AssertThrow(LBFGS_iteration < m_parameters.m_max_iterations_BFGS,
5974 *   ExcMessage("No convergence in L-BFGS nonlinear solver!"));
5975 *   }
5976 *  
5977 *   template <int dim>
5978 *   void PhaseFieldMonolithicSolve<dim>::output_results() const
5979 *   {
5980 *   m_timer.enter_subsection("Output results");
5981 *  
5982 *   DataOut<dim> data_out;
5983 *  
5984 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
5985 *   data_component_interpretation(
5987 *  
5988 *   data_component_interpretation.push_back(
5990 *  
5991 *   std::vector<std::string> solution_name(dim, "displacement");
5992 *   solution_name.emplace_back("phasefield");
5993 *  
5994 *   data_out.attach_dof_handler(m_dof_handler);
5995 *   data_out.add_data_vector(m_solution,
5996 *   solution_name,
5998 *   data_component_interpretation);
5999 *  
6000 *  
6001 *   Vector<double> cell_material_id(m_triangulation.n_active_cells());
6002 * @endcode
6003 *
6004 * output material ID for each cell
6005 *
6006 * @code
6007 *   for (const auto &cell : m_triangulation.active_cell_iterators())
6008 *   {
6009 *   cell_material_id(cell->active_cell_index()) = cell->material_id();
6010 *   }
6011 *   data_out.add_data_vector(cell_material_id, "materialID");
6012 *  
6013 * @endcode
6014 *
6015 * Stress L2 projection
6016 *
6017 * @code
6018 *   DoFHandler<dim> stresses_dof_handler_L2(m_triangulation);
6019 *   FE_Q<dim> stresses_fe_L2(m_parameters.m_poly_degree); //FE_Q element is continuous
6020 *   stresses_dof_handler_L2.distribute_dofs(stresses_fe_L2);
6021 *   AffineConstraints<double> constraints;
6022 *   constraints.clear();
6023 *   DoFTools::make_hanging_node_constraints(stresses_dof_handler_L2, constraints);
6024 *   constraints.close();
6025 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
6026 *   data_component_interpretation_stress(1,
6028 *  
6029 *   for (unsigned int i = 0; i < dim; ++i)
6030 *   for (unsigned int j = i; j < dim; ++j)
6031 *   {
6032 *   Vector<double> stress_field_L2;
6033 *   stress_field_L2.reinit(stresses_dof_handler_L2.n_dofs());
6034 *  
6035 *   MappingQ<dim> mapping(m_parameters.m_poly_degree + 1);
6036 *   VectorTools::project(mapping,
6037 *   stresses_dof_handler_L2,
6038 *   constraints,
6039 *   m_qf_cell,
6040 *   [&] (const typename DoFHandler<dim>::active_cell_iterator & cell,
6041 *   const unsigned int q) -> double
6042 *   {
6043 *   return m_quadrature_point_history.get_data(cell)[q]->get_cauchy_stress()[i][j];
6044 *   },
6045 *   stress_field_L2);
6046 *  
6047 *   std::string stress_name = "Cauchy_stress_" + std::to_string(i+1) + std::to_string(j+1)
6048 *   + "_L2";
6049 *  
6050 *   data_out.add_data_vector(stresses_dof_handler_L2,
6051 *   stress_field_L2,
6052 *   stress_name,
6053 *   data_component_interpretation_stress);
6054 *   }
6055 *  
6056 *   data_out.build_patches(m_parameters.m_poly_degree);
6057 *  
6058 *   std::ofstream output("Solution-" + std::to_string(dim) + "d-" +
6059 *   Utilities::int_to_string(m_time.get_timestep(),4) + ".vtu");
6060 *  
6061 *   data_out.write_vtu(output);
6062 *   m_timer.leave_subsection();
6063 *   }
6064 *  
6065 *   template <int dim>
6066 *   void PhaseFieldMonolithicSolve<dim>::calculate_reaction_force(unsigned int face_ID)
6067 *   {
6068 *   m_timer.enter_subsection("Calculate reaction force");
6069 *  
6070 *   BlockVector<double> system_rhs;
6071 *   system_rhs.reinit(m_dofs_per_block);
6072 *  
6073 *   Vector<double> cell_rhs(m_dofs_per_cell);
6074 *   std::vector<types::global_dof_index> local_dof_indices(m_dofs_per_cell);
6075 *  
6076 *   const double time_ramp = (m_time.current() / m_time.end());
6077 *   std::vector<Tensor<1, dim>> rhs_values(m_n_q_points);
6078 *   const UpdateFlags uf_cell(update_values | update_gradients |
6082 *  
6083 *   FEValues<dim> fe_values(m_fe, m_qf_cell, uf_cell);
6084 *   FEFaceValues<dim> fe_face_values(m_fe, m_qf_face, uf_face);
6085 *  
6086 * @endcode
6087 *
6088 * shape function values for displacement field
6089 *
6090 * @code
6091 *   std::vector<std::vector<Tensor<1, dim>>>
6092 *   Nx(m_qf_cell.size(), std::vector<Tensor<1, dim>>(m_dofs_per_cell));
6093 *   std::vector<std::vector<Tensor<2, dim>>>
6094 *   grad_Nx(m_qf_cell.size(), std::vector<Tensor<2, dim>>(m_dofs_per_cell));
6095 *   std::vector<std::vector<SymmetricTensor<2, dim>>>
6096 *   symm_grad_Nx(m_qf_cell.size(), std::vector<SymmetricTensor<2, dim>>(m_dofs_per_cell));
6097 *  
6098 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
6099 *   {
6100 * @endcode
6101 *
6102 * if calculate_reaction_force() is defined as const, then
6103 * we also need to put a const in std::shared_ptr,
6104 * that is, std::shared_ptr<const PointHistory<dim>>
6105 *
6106 * @code
6107 *   const std::vector<std::shared_ptr< PointHistory<dim>>> lqph =
6108 *   m_quadrature_point_history.get_data(cell);
6109 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
6110 *   cell_rhs = 0.0;
6111 *   fe_values.reinit(cell);
6112 *   right_hand_side(fe_values.get_quadrature_points(),
6113 *   rhs_values,
6114 *   m_parameters.m_x_component*time_ramp,
6115 *   m_parameters.m_y_component*time_ramp,
6116 *   m_parameters.m_z_component*time_ramp);
6117 *  
6118 *   for (const unsigned int q_point : fe_values.quadrature_point_indices())
6119 *   {
6120 *   for (const unsigned int k : fe_values.dof_indices())
6121 *   {
6122 *   const unsigned int k_group = m_fe.system_to_base_index(k).first.first;
6123 *  
6124 *   if (k_group == m_u_dof)
6125 *   {
6126 *   Nx[q_point][k] = fe_values[m_u_fe].value(k, q_point);
6127 *   grad_Nx[q_point][k] = fe_values[m_u_fe].gradient(k, q_point);
6128 *   symm_grad_Nx[q_point][k] = symmetrize(grad_Nx[q_point][k]);
6129 *   }
6130 *   }
6131 *   }
6132 *  
6133 *   for (const unsigned int q_point : fe_values.quadrature_point_indices())
6134 *   {
6135 *   const SymmetricTensor<2, dim> & cauchy_stress = lqph[q_point]->get_cauchy_stress();
6136 *  
6137 *   const std::vector<Tensor<1,dim>> & N = Nx[q_point];
6138 *   const std::vector<SymmetricTensor<2, dim>> & symm_grad_N = symm_grad_Nx[q_point];
6139 *   const double JxW = fe_values.JxW(q_point);
6140 *  
6141 *   for (const unsigned int i : fe_values.dof_indices())
6142 *   {
6143 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
6144 *  
6145 *   if (i_group == m_u_dof)
6146 *   {
6147 *   cell_rhs(i) -= (symm_grad_N[i] * cauchy_stress) * JxW;
6148 * @endcode
6149 *
6150 * contributions from the body force to right-hand side
6151 *
6152 * @code
6153 *   cell_rhs(i) += N[i] * rhs_values[q_point] * JxW;
6154 *   }
6155 *   }
6156 *   }
6157 *  
6158 * @endcode
6159 *
6160 * if there is surface pressure, this surface pressure always applied to the
6161 * reference configuration
6162 *
6163 * @code
6164 *   const unsigned int face_pressure_id = 100;
6165 *   const double p0 = 0.0;
6166 *  
6167 *   for (const auto &face : cell->face_iterators())
6168 *   {
6169 *   if (face->at_boundary() && face->boundary_id() == face_pressure_id)
6170 *   {
6171 *   fe_face_values.reinit(cell, face);
6172 *  
6173 *   for (const unsigned int f_q_point : fe_face_values.quadrature_point_indices())
6174 *   {
6175 *   const Tensor<1, dim> &N = fe_face_values.normal_vector(f_q_point);
6176 *  
6177 *   const double pressure = p0 * time_ramp;
6178 *   const Tensor<1, dim> traction = pressure * N;
6179 *  
6180 *   for (const unsigned int i : fe_values.dof_indices())
6181 *   {
6182 *   const unsigned int i_group = m_fe.system_to_base_index(i).first.first;
6183 *  
6184 *   if (i_group == m_u_dof)
6185 *   {
6186 *   const unsigned int component_i = m_fe.system_to_component_index(i).first;
6187 *   const double Ni = fe_face_values.shape_value(i, f_q_point);
6188 *   const double JxW = fe_face_values.JxW(f_q_point);
6189 *   cell_rhs(i) += (Ni * traction[component_i]) * JxW;
6190 *   }
6191 *   }
6192 *   }
6193 *   }
6194 *   }
6195 *  
6196 *   cell->get_dof_indices(local_dof_indices);
6197 *   for (const unsigned int i : fe_values.dof_indices())
6198 *   system_rhs(local_dof_indices[i]) += cell_rhs(i);
6199 *   } // for (const auto &cell : m_dof_handler.active_cell_iterators())
6200 *  
6201 * @endcode
6202 *
6203 * The difference between the above assembled system_rhs and m_system_rhs
6204 * is that m_system_rhs is condensed by the m_constraints, which zero out
6205 * the rhs values associated with the constrained DOFs and modify the rhs
6206 * values associated with the unconstrained DOFs.
6207 *
6208
6209 *
6210 *
6211 * @code
6212 *   std::vector< types::global_dof_index > mapping;
6213 *   std::set<types::boundary_id> boundary_ids;
6214 *   boundary_ids.insert(face_ID);
6216 *   boundary_ids,
6217 *   mapping);
6218 *  
6219 *   std::vector<double> reaction_force(dim, 0.0);
6220 *  
6221 *   for (unsigned int i = 0; i < m_dofs_per_block[m_u_dof]; ++i)
6222 *   {
6223 *   if (mapping[i] != numbers::invalid_dof_index)
6224 *   {
6225 *   reaction_force[i % dim] += system_rhs.block(m_u_dof)(i);
6226 *   }
6227 *   }
6228 *  
6229 *   for (unsigned int i = 0; i < dim; i++)
6230 *   m_logfile << "\t\tReaction force in direction " << i << " on boundary ID " << face_ID
6231 *   << " = "
6232 *   << std::fixed << std::setprecision(3) << std::setw(1)
6233 *   << std::scientific
6234 *   << reaction_force[i] << std::endl;
6235 *  
6236 *   std::pair<double, std::vector<double>> time_force;
6237 *   time_force.first = m_time.current();
6238 *   time_force.second = reaction_force;
6239 *   m_history_reaction_force.push_back(time_force);
6240 *  
6241 *   m_timer.leave_subsection();
6242 *   }
6243 *  
6244 *   template <int dim>
6245 *   void PhaseFieldMonolithicSolve<dim>::write_history_data()
6246 *   {
6247 *   m_logfile << "\t\tWrite history data ... \n"<<std::endl;
6248 *  
6249 *   std::ofstream myfile_reaction_force ("Reaction_force.hist");
6250 *   if (myfile_reaction_force.is_open())
6251 *   {
6252 *   myfile_reaction_force << 0.0 << "\t";
6253 *   if (dim == 2)
6254 *   myfile_reaction_force << 0.0 << "\t"
6255 *   << 0.0 << std::endl;
6256 *   if (dim == 3)
6257 *   myfile_reaction_force << 0.0 << "\t"
6258 *   << 0.0 << "\t"
6259 *   << 0.0 << std::endl;
6260 *  
6261 *   for (const auto &time_force : m_history_reaction_force)
6262 *   {
6263 *   myfile_reaction_force << time_force.first << "\t";
6264 *   if (dim == 2)
6265 *   myfile_reaction_force << time_force.second[0] << "\t"
6266 *   << time_force.second[1] << std::endl;
6267 *   if (dim == 3)
6268 *   myfile_reaction_force << time_force.second[0] << "\t"
6269 *   << time_force.second[1] << "\t"
6270 *   << time_force.second[2] << std::endl;
6271 *   }
6272 *   myfile_reaction_force.close();
6273 *   }
6274 *   else
6275 *   m_logfile << "Unable to open file";
6276 *  
6277 *   std::ofstream myfile_energy ("Energy.hist");
6278 *   if (myfile_energy.is_open())
6279 *   {
6280 *   myfile_energy << std::fixed << std::setprecision(10) << std::scientific
6281 *   << 0.0 << "\t"
6282 *   << 0.0 << "\t"
6283 *   << 0.0 << "\t"
6284 *   << 0.0 << std::endl;
6285 *  
6286 *   for (const auto &time_energy : m_history_energy)
6287 *   {
6288 *   myfile_energy << std::fixed << std::setprecision(10) << std::scientific
6289 *   << time_energy.first << "\t"
6290 *   << time_energy.second[0] << "\t"
6291 *   << time_energy.second[1] << "\t"
6292 *   << time_energy.second[2] << std::endl;
6293 *   }
6294 *   myfile_energy.close();
6295 *   }
6296 *   else
6297 *   m_logfile << "Unable to open file";
6298 *   }
6299 *  
6300 *   template <int dim>
6301 *   double PhaseFieldMonolithicSolve<dim>::calculate_energy_functional() const
6302 *   {
6303 *   double energy_functional = 0.0;
6304 *  
6305 *   FEValues<dim> fe_values(m_fe, m_qf_cell, update_JxW_values);
6306 *  
6307 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
6308 *   {
6309 *   fe_values.reinit(cell);
6310 *  
6311 *   const std::vector<std::shared_ptr<const PointHistory<dim>>> lqph =
6312 *   m_quadrature_point_history.get_data(cell);
6313 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
6314 *  
6315 *   for (unsigned int q_point = 0; q_point < m_n_q_points; ++q_point)
6316 *   {
6317 *   const double JxW = fe_values.JxW(q_point);
6318 *   energy_functional += lqph[q_point]->get_total_strain_energy() * JxW;
6319 *   energy_functional += lqph[q_point]->get_crack_energy_dissipation() * JxW;
6320 *   }
6321 *   }
6322 *  
6323 *   return energy_functional;
6324 *   }
6325 *  
6326 *   template <int dim>
6327 *   std::pair<double, double>
6328 *   PhaseFieldMonolithicSolve<dim>::calculate_total_strain_energy_and_crack_energy_dissipation() const
6329 *   {
6330 *   double total_strain_energy = 0.0;
6331 *   double crack_energy_dissipation = 0.0;
6332 *  
6333 *   FEValues<dim> fe_values(m_fe, m_qf_cell, update_JxW_values);
6334 *  
6335 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
6336 *   {
6337 *   fe_values.reinit(cell);
6338 *  
6339 *   const std::vector<std::shared_ptr<const PointHistory<dim>>> lqph =
6340 *   m_quadrature_point_history.get_data(cell);
6341 *   Assert(lqph.size() == m_n_q_points, ExcInternalError());
6342 *  
6343 *   for (unsigned int q_point = 0; q_point < m_n_q_points; ++q_point)
6344 *   {
6345 *   const double JxW = fe_values.JxW(q_point);
6346 *   total_strain_energy += lqph[q_point]->get_total_strain_energy() * JxW;
6347 *   crack_energy_dissipation += lqph[q_point]->get_crack_energy_dissipation() * JxW;
6348 *   }
6349 *   }
6350 *  
6351 *   return std::make_pair(total_strain_energy, crack_energy_dissipation);
6352 *   }
6353 *  
6354 *  
6355 *   template <int dim>
6356 *   bool PhaseFieldMonolithicSolve<dim>::local_refine_and_solution_transfer(BlockVector<double> & solution_delta,
6357 *   BlockVector<double> & LBFGS_update_refine)
6358 *   {
6359 * @endcode
6360 *
6361 * This is the solution at (n+1) obtained from the old (coarse) mesh
6362 *
6363 * @code
6364 *   BlockVector<double> solution_next_step(m_dofs_per_block);
6365 *   solution_next_step = m_solution + solution_delta;
6366 *   bool mesh_is_same = true;
6367 *   bool cell_refine_flag = true;
6368 *  
6369 *   unsigned int material_id;
6370 *   double length_scale;
6371 *   double cell_length;
6372 *   while(cell_refine_flag)
6373 *   {
6374 *   cell_refine_flag = false;
6375 *  
6376 *   std::vector<types::global_dof_index> local_dof_indices(m_fe.dofs_per_cell);
6377 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
6378 *   {
6379 *   cell->get_dof_indices(local_dof_indices);
6380 *  
6381 *   for (unsigned int i = 0; i< m_fe.dofs_per_cell; ++i)
6382 *   {
6383 *   const unsigned int comp_i = m_fe.system_to_component_index(i).first;
6384 *   if (comp_i == m_d_component) //phasefield component
6385 *   {
6386 *   if ( solution_next_step(local_dof_indices[i])
6387 *   > m_parameters.m_phasefield_refine_threshold )
6388 *   {
6389 *   material_id = cell->material_id();
6390 *   length_scale = m_material_data[material_id][2];
6391 *   if (dim == 2)
6392 *   cell_length = std::sqrt(cell->measure());
6393 *   else
6394 *   cell_length = std::cbrt(cell->measure());
6395 *   if ( cell_length
6396 *   > length_scale * m_parameters.m_allowed_max_h_l_ratio )
6397 *   {
6398 *   if (cell->level() < m_parameters.m_max_allowed_refinement_level)
6399 *   {
6400 *   cell->set_refine_flag();
6401 *   break;
6402 *   }
6403 *   }
6404 *   }
6405 *   }
6406 *   }
6407 *   }
6408 *  
6409 *   for (const auto &cell : m_dof_handler.active_cell_iterators())
6410 *   {
6411 *   if (cell->refine_flag_set())
6412 *   {
6413 *   cell_refine_flag = true;
6414 *   break;
6415 *   }
6416 *   }
6417 *  
6418 * @endcode
6419 *
6420 * if any cell is refined, we need to project the solution
6421 * to the newly refined mesh
6422 *
6423 * @code
6424 *   if (cell_refine_flag)
6425 *   {
6426 *   mesh_is_same = false;
6427 *  
6428 *   std::vector<BlockVector<double> > old_solutions(2);
6429 *   old_solutions[0] = solution_next_step;
6430 *   old_solutions[1] = m_solution;
6431 *  
6432 *   m_triangulation.prepare_coarsening_and_refinement();
6433 *   SolutionTransfer<dim, BlockVector<double>> solution_transfer(m_dof_handler);
6434 *   solution_transfer.prepare_for_coarsening_and_refinement(old_solutions);
6435 *   m_triangulation.execute_coarsening_and_refinement();
6436 *  
6437 *   setup_system();
6438 *  
6439 *   std::vector<BlockVector<double>> tmp_solutions(2);
6440 *   tmp_solutions[0].reinit(m_dofs_per_block);
6441 *   tmp_solutions[1].reinit(m_dofs_per_block);
6442 *   solution_transfer.interpolate(tmp_solutions);
6443 *   solution_next_step = tmp_solutions[0];
6444 *   m_solution = tmp_solutions[1];
6445 *  
6446 * @endcode
6447 *
6448 * make sure the projected solutions still satisfy
6449 * hanging node constraints
6450 *
6451 * @code
6452 *   m_constraints.distribute(solution_next_step);
6453 *   m_constraints.distribute(m_solution);
6454 *   } // if (cell_refine_flag)
6455 *   } // while(cell_refine_flag)
6456 *  
6457 * @endcode
6458 *
6459 * calculate field variables for newly refined cells
6460 *
6461 * @code
6462 *   if (!mesh_is_same)
6463 *   {
6464 *   BlockVector<double> temp_solution_delta(m_dofs_per_block);
6465 *   BlockVector<double> temp_previous_solution(m_dofs_per_block);
6466 *   temp_solution_delta = 0.0;
6467 *   temp_previous_solution = 0.0;
6468 *   update_qph_incremental(temp_solution_delta, temp_previous_solution, false);
6469 *   update_history_field_step();
6470 *  
6471 * @endcode
6472 *
6473 * initial guess for the resolve on the refined mesh
6474 *
6475 * @code
6476 *   LBFGS_update_refine = solution_next_step - m_solution;
6477 *   }
6478 *  
6479 *   return mesh_is_same;
6480 *   }
6481 *  
6482 *   template <int dim>
6483 *   void PhaseFieldMonolithicSolve<dim>::print_parameter_information()
6484 *   {
6485 *   m_logfile << "Scenario number = " << m_parameters.m_scenario << std::endl;
6486 *   m_logfile << "Log file = " << m_parameters.m_logfile_name << std::endl;
6487 *   m_logfile << "Write iteration history to log file? = " << std::boolalpha
6488 *   << m_parameters.m_output_iteration_history << std::endl;
6489 *   m_logfile << "Nonlinear solver type = " << m_parameters.m_type_nonlinear_solver << std::endl;
6490 *   m_logfile << "Line search type = " << m_parameters.m_type_line_search << std::endl;
6491 *   m_logfile << "Linear solver type = " << m_parameters.m_type_linear_solver << std::endl;
6492 *   m_logfile << "Mesh refinement strategy = " << m_parameters.m_refinement_strategy << std::endl;
6493 *   m_logfile << "L-BFGS_m = " << m_parameters.m_LBFGS_m << std::endl;
6494 *   m_logfile << "Global refinement times = " << m_parameters.m_global_refine_times << std::endl;
6495 *   m_logfile << "Local prerefinement times = " <<m_parameters. m_local_prerefine_times << std::endl;
6496 *   m_logfile << "Maximum adaptive refinement times allowed in each step = "
6497 *   << m_parameters.m_max_adaptive_refine_times << std::endl;
6498 *   m_logfile << "Maximum allowed cell refinement level = "
6499 *   << m_parameters.m_max_allowed_refinement_level << std::endl;
6500 *   m_logfile << "Phasefield-based refinement threshold value = "
6501 *   << m_parameters.m_phasefield_refine_threshold << std::endl;
6502 *   m_logfile << "Allowed maximum h/l ratio = " << m_parameters.m_allowed_max_h_l_ratio << std::endl;
6503 *   m_logfile << "total number of material types = " << m_parameters.m_total_material_regions << std::endl;
6504 *   m_logfile << "material data file name = " << m_parameters.m_material_file_name << std::endl;
6505 *   if (m_parameters.m_reaction_force_face_id >= 0)
6506 *   m_logfile << "Calculate reaction forces on Face ID = " << m_parameters.m_reaction_force_face_id << std::endl;
6507 *   else
6508 *   m_logfile << "No need to calculate reaction forces." << std::endl;
6509 *  
6510 *   if (m_parameters.m_relative_residual)
6511 *   m_logfile << "Relative residual for convergence." << std::endl;
6512 *   else
6513 *   m_logfile << "Absolute residual for convergence." << std::endl;
6514 *  
6515 *   m_logfile << "Body force = (" << m_parameters.m_x_component << ", "
6516 *   << m_parameters.m_y_component << ", "
6517 *   << m_parameters.m_z_component << ") (N/m^3)"
6518 *   << std::endl;
6519 *  
6520 *   m_logfile << "End time = " << m_parameters.m_end_time << std::endl;
6521 *   m_logfile << "Time data file name = " << m_parameters.m_time_file_name << std::endl;
6522 *   }
6523 *  
6524 *   template <int dim>
6525 *   void PhaseFieldMonolithicSolve<dim>::run()
6526 *   {
6527 *   print_parameter_information();
6528 *  
6529 *   read_material_data(m_parameters.m_material_file_name,
6530 *   m_parameters.m_total_material_regions);
6531 *  
6532 *   std::vector<std::array<double, 4>> time_table;
6533 *  
6534 *   read_time_data(m_parameters.m_time_file_name, time_table);
6535 *  
6536 *   make_grid();
6537 *   setup_system();
6538 *   output_results();
6539 *  
6540 *   m_time.increment(time_table);
6541 *  
6542 *   while(m_time.current() < m_time.end() + m_time.get_delta_t()*1.0e-6)
6543 *   {
6544 *   m_logfile << std::endl
6545 *   << "Timestep " << m_time.get_timestep() << " @ " << m_time.current()
6546 *   << 's' << std::endl;
6547 *  
6548 *   bool mesh_is_same = false;
6549 *  
6550 * @endcode
6551 *
6552 * initial guess for the resolve on the refined mesh
6553 *
6554 * @code
6555 *   BlockVector<double> LBFGS_update_refine(m_dofs_per_block);
6556 *   LBFGS_update_refine = 0.0;
6557 *  
6558 * @endcode
6559 *
6560 * local adaptive mesh refinement loop
6561 *
6562 * @code
6563 *   unsigned int adp_refine_iteration = 0;
6564 *   for (; adp_refine_iteration < m_parameters.m_max_adaptive_refine_times + 1; ++adp_refine_iteration)
6565 *   {
6566 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
6567 *   m_logfile << "\tAdaptive refinement-"<< adp_refine_iteration << ": " << std::endl;
6568 *  
6569 *   BlockVector<double> solution_delta(m_dofs_per_block);
6570 *   solution_delta = 0.0;
6571 *  
6572 *   if (m_parameters.m_type_nonlinear_solver == "Newton")
6573 *   {
6574 *   bool newton_success = false;
6575 *   newton_success = solve_nonlinear_timestep_newton(solution_delta);
6576 *   AssertThrow(newton_success,
6577 *   ExcMessage("No convergence in Newton-Raphson nonlinear solver!"));
6578 *   /*
6579 * @endcode
6580 *
6581 * if Newton-Raphson failed, use LBFGS solver
6582 *
6583 * @code
6584 *   if (!newton_success)
6585 *   {
6586 *   solution_delta = 0.0;
6587 *   solve_nonlinear_timestep_LBFGS(solution_delta, LBFGS_update_refine);
6588 *   }
6589 *   */
6590 *   }
6591 *   else if (m_parameters.m_type_nonlinear_solver == "BFGS")
6592 *   solve_nonlinear_timestep_BFGS(solution_delta);
6593 *   else if (m_parameters.m_type_nonlinear_solver == "LBFGS")
6594 *   solve_nonlinear_timestep_LBFGS(solution_delta, LBFGS_update_refine);
6595 *   else
6596 *   AssertThrow(false, ExcMessage("Nonlinear solver type not implemented"));
6597 *  
6598 *   if (m_parameters.m_refinement_strategy == "adaptive-refine")
6599 *   {
6600 *  
6601 *   if (adp_refine_iteration == m_parameters.m_max_adaptive_refine_times)
6602 *   {
6603 *   m_solution += solution_delta;
6604 *   break;
6605 *   }
6606 *  
6607 *   mesh_is_same = local_refine_and_solution_transfer(solution_delta,
6608 *   LBFGS_update_refine);
6609 *  
6610 *   if (mesh_is_same)
6611 *   {
6612 *   m_solution += solution_delta;
6613 *   break;
6614 *   }
6615 *   }
6616 *   else if (m_parameters.m_refinement_strategy == "pre-refine")
6617 *   {
6618 *   m_solution += solution_delta;
6619 *   break;
6620 *   }
6621 *   else
6622 *   {
6623 *   AssertThrow(false,
6624 *   ExcMessage("Selected mesh refinement strategy not implemented!"));
6625 *   }
6626 *   } // for (; adp_refine_iteration < m_parameters.m_max_adaptive_refine_times; ++adp_refine_iteration)
6627 *  
6628 * @endcode
6629 *
6630 * AssertThrow(adp_refine_iteration < m_parameters.m_max_adaptive_refine_times,
6631 * ExcMessage("Number of local adaptive mesh refinement exceeds allowed maximum times!"));
6632 *
6633
6634 *
6635 *
6636 * @code
6637 *   update_history_field_step();
6638 * @endcode
6639 *
6640 * output vtk files every 10 steps if there are too
6641 * many time steps
6642 * if (m_time.get_timestep() % 10 == 0)
6643 *
6644 * @code
6645 *   output_results();
6646 *  
6647 *   double energy_functional_current = calculate_energy_functional();
6648 *   m_logfile << "\t\tEnergy functional (J) = " << std::fixed << std::setprecision(10) << std::scientific
6649 *   << energy_functional_current << std::endl;
6650 *  
6651 *   std::pair<double, double> energy_pair = calculate_total_strain_energy_and_crack_energy_dissipation();
6652 *   m_logfile << "\t\tTotal strain energy (J) = " << std::fixed << std::setprecision(10) << std::scientific
6653 *   << energy_pair.first << std::endl;
6654 *   m_logfile << "\t\tCrack energy dissipation (J) = " << std::fixed << std::setprecision(10) << std::scientific
6655 *   << energy_pair.second << std::endl;
6656 *  
6657 *   std::pair<double, std::array<double, 3>> time_energy;
6658 *   time_energy.first = m_time.current();
6659 *   time_energy.second[0] = energy_pair.first;
6660 *   time_energy.second[1] = energy_pair.second;
6661 *   time_energy.second[2] = energy_pair.first + energy_pair.second;
6662 *   m_history_energy.push_back(time_energy);
6663 *  
6664 *   int face_ID = m_parameters.m_reaction_force_face_id;
6665 *   if (face_ID >= 0)
6666 *   calculate_reaction_force(face_ID);
6667 *  
6668 *   write_history_data();
6669 *  
6670 *   m_time.increment(time_table);
6671 *   } // while(m_time.current() < m_time.end() + m_time.get_delta_t()*1.0e-6)
6672 *   }
6673 *   } // namespace PhaseField
6674 *  
6675 *  
6676 *   int main(int argc, char* argv[])
6677 *   {
6678 *  
6679 *   using namespace dealii;
6680 *  
6681 *   if (argc != 2)
6682 *   AssertThrow(false,
6683 *   ExcMessage("The number of arguments provided to the program has to be 2!"));
6684 *  
6685 *   const unsigned int dim = std::stoi(argv[1]);
6686 *   if (dim == 2 )
6687 *   {
6688 *   PhaseField::PhaseFieldMonolithicSolve<2> FEQ1Full("parameters.prm");
6689 *   FEQ1Full.run();
6690 *   }
6691 *   else if (dim == 3)
6692 *   {
6693 *   PhaseField::PhaseFieldMonolithicSolve<3> SphereInclusion3D("parameters.prm");
6694 *   SphereInclusion3D.run();
6695 *   }
6696 *   else
6697 *   {
6698 *   AssertThrow(false,
6699 *   ExcMessage("Dimension has to be either 2 or 3"));
6700 *   }
6701 *  
6702 *   return 0;
6703 *   }
6704 * @endcode
6705
6706
6707*/
*  iterator end()
*  const Number height
*  *  for(const auto &cell :triangulation.active_cell_iterators())
*  *  int main(int argc, char **argv)
*  *  *  struct InterferenceTaperTransform *  
virtual size_type size() const override
void reinit(const unsigned int n_blocks, const size_type block_size=0, const bool omit_zeroing_entries=false)
void reinit(const Triangulation< dim, spacedim > &tria)
Definition fe_q.h:552
void attach_triangulation(Triangulation< dim, spacedim > &tria)
Definition grid_in.cc:155
void write_vtu(const Triangulation< dim, spacedim > &tria, std::ostream &out) const
Definition grid_out.cc:3557
Definition point.h:111
void initialize(const MatrixType &A, const AdditionalData &parameters=AdditionalData())
void initialize(const SparsityPattern &sparsity_pattern)
constexpr void clear()
@ wall_times
Definition timer.h:753
void initialize(const Triangulation< dim, spacedim > &triangulation)
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
Point< 2 > second
Definition grid_out.cc:4640
Point< 2 > first
Definition grid_out.cc:4639
unsigned int vertex_indices[2]
#define Assert(cond, exc)
#define AssertThrow(cond, exc)
typename ActiveSelector::active_cell_iterator active_cell_iterator
LinearOperator< Range, Domain, Payload > linear_operator(const OperatorExemplar &, const Matrix &)
void loop(IteratorType begin, std_cxx20::type_identity_t< IteratorType > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, AssemblerType &assembler, const LoopControl &lctrl=LoopControl())
Definition loop.h:562
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
UpdateFlags
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
void reset_all_manifolds()
std::vector< index_type > data
Definition mpi.cc:734
std::size_t size
Definition mpi.cc:733
const Event initial
Definition event.cc:69
Expression fabs(const Expression &x)
Expression sign(const Expression &x)
void component_wise(DoFHandler< dim, spacedim > &dof_handler, const std::vector< unsigned int > &target_component=std::vector< unsigned int >())
void Cuthill_McKee(DoFHandler< dim, spacedim > &dof_handler, const bool reversed_numbering=false, const bool use_constraints=false, const std::vector< types::global_dof_index > &starting_indices=std::vector< types::global_dof_index >())
std::vector< types::global_dof_index > count_dofs_per_fe_block(const DoFHandler< dim, spacedim > &dof, const std::vector< unsigned int > &target_block=std::vector< unsigned int >())
void map_dof_to_boundary_indices(const DoFHandler< dim, spacedim > &dof_handler, std::vector< types::global_dof_index > &mapping)
void hyper_shell(Triangulation< dim, spacedim > &tria, const Point< spacedim > &center, const double inner_radius, const double outer_radius, const unsigned int n_cells=0, bool colorize=false)
void hyper_rectangle(Triangulation< dim, spacedim > &tria, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void extrude_triangulation(const Triangulation< 2, 2 > &input, const unsigned int n_slices, const double height, Triangulation< 3, 3 > &result, const bool copy_manifold_ids=false, const std::vector< types::manifold_id > &manifold_priorities={})
void hyper_ball(Triangulation< dim, spacedim > &tria, const Point< spacedim > &center={}, const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=false)
void subdivided_hyper_rectangle(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void create_triangulation_with_removed_cells(const Triangulation< dim, spacedim > &input_triangulation, const std::set< typename Triangulation< dim, spacedim >::active_cell_iterator > &cells_to_remove, Triangulation< dim, spacedim > &result)
void merge_triangulations(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result, const double duplicated_vertex_tolerance=1.0e-12, const bool copy_manifold_ids=false, const bool copy_boundary_ids=false)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
double volume(const Triangulation< dim, spacedim > &tria)
@ matrix
Contents is actually a matrix.
constexpr char N
constexpr char T
constexpr types::blas_int zero
void L2(Vector< number > &result, const FEValuesBase< dim > &fe, const std::vector< double > &input, const double factor=1.)
Definition l2.h:157
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition utilities.cc:210
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
*  *  *  ScaleZFunction< dim, Number, components >::ScaleZFunction *  component(component)
*  *  if(update_pressure &update_flags) *  compute_pressure(constitutive_request
*  *  *  *  std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters   const
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition utilities.cc:464
void interpolate_boundary_values(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const std::map< types::boundary_id, const Function< spacedim, number > * > &function_map, std::map< types::global_dof_index, number > &boundary_values, const ComponentMask &component_mask={})
void project(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const AffineConstraints< typename VectorType::value_type > &constraints, const Quadrature< dim > &quadrature, const Function< spacedim, typename VectorType::value_type > &function, VectorType &vec, const bool enforce_zero_boundary=false, const Quadrature< dim - 1 > &q_boundary=(dim > 1 ? QGauss< dim - 1 >(2) :Quadrature< dim - 1 >()), const bool project_to_boundary_first=false)
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)
void run(const std::vector< std::vector< Iterator > > &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
constexpr types::global_dof_index invalid_dof_index
Definition types.h:259
STL namespace.
::VectorizedArray< Number, width > tan(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int material_id
Definition types.h:182
unsigned int boundary_id
Definition types.h:159
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
constexpr Number trace(const SymmetricTensor< 2, dim2, Number > &)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)