ASPECT
utilities.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2024 by the authors of the ASPECT code.
3 
4  This file is part of ASPECT.
5 
6  ASPECT is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)
9  any later version.
10 
11  ASPECT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with ASPECT; see the file LICENSE. If not see
18  <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 #ifndef _aspect_utilities_h
23 #define _aspect_utilities_h
24 
25 #include <aspect/global.h>
26 
27 #include <array>
28 #include <random>
29 #include <deal.II/base/point.h>
37 
39 #include <aspect/structured_data.h>
40 
41 #include <mpi.h>
42 
43 
44 namespace aspect
45 {
46  template <int dim> class SimulatorAccess;
47 
48  namespace GeometryModel
49  {
50  template <int dim> class Interface;
51  }
52 
57  namespace Utilities
58  {
73  using namespace ::Utilities;
74 
75 
89  template <typename T>
90  std::vector<T>
91  possibly_extend_from_1_to_N (const std::vector<T> &values,
92  const unsigned int N,
93  const std::string &id_text);
94 
102  namespace MapParsing
103  {
108  struct Options
109  {
119  std::vector<std::string> list_of_allowed_keys;
120 
128  std::vector<std::string> list_of_required_keys;
129 
135  std::string property_name;
136 
145 
146  /*
147  * Whether to allow for some keys in list_of_required_keys to be
148  * not set to any values, i.e. they do not appear at all.
149  * This also allows a completely empty map.
150  */
152 
162 
172 
181  std::vector<unsigned int> n_values_per_key;
182 
187  Options() = delete;
188 
199  Options(const std::vector<std::string> &list_of_required_keys,
200  const std::string &property_name)
201  :
206  allow_missing_keys(false),
207  store_values_per_key(false),
208  check_values_per_key(false),
210  {}
211  };
212 
238  std::vector<double>
239  parse_map_to_double_array(const std::string &input_string,
240  Options &options);
241  }
242 
317  std::vector<double>
318  parse_map_to_double_array (const std::string &key_value_map,
319  const std::vector<std::string> &list_of_keys,
320  const bool expects_background_field,
321  const std::string &property_name,
322  const bool allow_multiple_values_per_key = false,
323  const std::unique_ptr<std::vector<unsigned int>> &n_values_per_key = nullptr,
324  const bool allow_missing_keys = false);
325 
339  template <typename T>
340  Table<2,T>
341  parse_input_table (const std::string &input_string,
342  const unsigned int n_rows,
343  const unsigned int n_columns,
344  const std::string &property_name);
345 
358  template <int dim>
359  std::vector<std::string>
360  expand_dimensional_variable_names (const std::vector<std::string> &var_declarations);
361 
368  template <int dim>
370  const ComponentMask &component_mask);
371 
381  template <int dim>
382  std::vector<Point<dim>> get_unit_support_points(const SimulatorAccess<dim> &simulator_access);
383 
384 
385 
391  template <int dim>
392  bool
394  const parallel::distributed::Triangulation<dim> &triangulation,
395  const Point<dim> &point,
396  const MPI_Comm mpi_communicator);
397 
398 
399  namespace Coordinates
400  {
401 
407  template <int dim>
408  std::array<double,dim>
409  WGS84_coordinates(const ::Point<dim> &position);
410 
421  template <int dim>
422  std::array<double,dim>
423  cartesian_to_spherical_coordinates(const ::Point<dim> &position);
424 
430  template <int dim>
432  spherical_to_cartesian_coordinates(const std::array<double,dim> &scoord);
433 
439  template <int dim>
442  const ::Point<dim> &position);
443 
444 
450  template <int dim>
451  std::array<double,3>
452  cartesian_to_ellipsoidal_coordinates(const ::Point<3> &position,
453  const double semi_major_axis_a,
454  const double eccentricity);
455 
460  template <int dim>
461  ::Point<3>
462  ellipsoidal_to_cartesian_coordinates(const std::array<double,3> &phi_theta_d,
463  const double semi_major_axis_a,
464  const double eccentricity);
465 
466 
473  string_to_coordinate_system (const std::string &);
474  }
475 
476 
481  template <int dim>
482  bool
483  polygon_contains_point(const std::vector<Point<2>> &point_list,
484  const ::Point<2> &point);
485 
491  template <int dim>
492  double
493  signed_distance_to_polygon(const std::vector<Point<2>> &point_list,
494  const ::Point<2> &point);
495 
496 
503  double
504  distance_to_line(const std::array<::Point<2>,2> &point_list,
505  const ::Point<2> &point);
506 
514  template <int dim>
515  std::array<Tensor<1,dim>,dim-1>
517 
523  rotation_matrix_from_axis (const Tensor<1,3> &rotation_axis,
524  const double rotation_angle);
525 
534  const Tensor<1,3> &point_two);
535 
572  std::pair<double,double> real_spherical_harmonic( unsigned int l, // degree
573  unsigned int m, // order
574  double theta, // colatitude (radians)
575  double phi ); // longitude (radians)
576 
580  struct ThousandSep : std::numpunct<char>
581  {
582  protected:
583  char do_thousands_sep() const override
584  {
585  return ',';
586  }
587 
588  std::string do_grouping() const override
589  {
590  return "\003"; // groups of 3 digits (this string is in octal format)
591  }
592 
593  };
594 
607  bool fexists(const std::string &filename);
608 
622  bool fexists(const std::string &filename,
623  const MPI_Comm comm);
624 
630  bool filename_is_url(const std::string &filename);
631 
651  std::string
652  read_and_distribute_file_content(const std::string &filename,
653  const MPI_Comm comm);
654 
667  void
668  collect_and_write_file_content(const std::string &filename,
669  const std::string &file_content,
670  const MPI_Comm comm);
671 
685  int
686  mkdirp(std::string pathname, const mode_t mode = 0755);
687 
699  void create_directory(const std::string &pathname,
700  const MPI_Comm comm,
701  const bool silent);
702 
707  namespace tk
708  {
712  class spline
713  {
714  public:
724  void set_points(const std::vector<double> &x,
725  const std::vector<double> &y,
726  const bool cubic_spline = true,
727  const bool monotone_spline = false);
731  double operator() (double x) const;
732 
733  private:
737  std::vector<double> m_x;
738 
745  std::vector<double> m_a, m_b, m_c, m_y;
746  };
747  }
748 
756  inline
757  void
758  extract_composition_values_at_q_point (const std::vector<std::vector<double>> &composition_values,
759  const unsigned int q,
760  std::vector<double> &composition_values_at_q_point);
761 
766  std::string
767  expand_ASPECT_SOURCE_DIR (const std::string &location);
768 
773  std::string parenthesize_if_nonempty (const std::string &s);
774 
778  bool
779  string_to_bool(const std::string &s);
780 
784  std::vector<bool>
785  string_to_bool(const std::vector<std::string> &s);
786 
790  unsigned int
791  string_to_unsigned_int(const std::string &s);
792 
796  std::vector<unsigned int>
797  string_to_unsigned_int(const std::vector<std::string> &s);
798 
803  bool has_unique_entries (const std::vector<std::string> &strings);
804 
805 
806 
828  double weighted_p_norm_average (const std::vector<double> &weights,
829  const std::vector<double> &values,
830  const double p);
831 
832 
858  template <typename T>
859  T derivative_of_weighted_p_norm_average (const double averaged_parameter,
860  const std::vector<double> &weights,
861  const std::vector<double> &values,
862  const std::vector<T> &derivatives,
863  const double p);
895  template <int dim>
896  double compute_spd_factor(const double eta,
898  const SymmetricTensor<2,dim> &dviscosities_dstrain_rate,
899  const double SPD_safety_factor);
900 
904  template <int dim>
905  Point<dim> convert_array_to_point(const std::array<double,dim> &array);
906 
910  template <int dim>
911  std::array<double,dim> convert_point_to_array(const Point<dim> &point);
912 
920  class Operator
921  {
922  public:
927  {
934  };
935 
941 
946 
951  double operator() (const double x, const double y) const;
952 
957  bool operator== (const operation op) const;
958 
959  private:
964  };
965 
970  std::vector<Operator> create_model_operator_list(const std::vector<std::string> &operator_names);
971 
975  const std::string get_model_operator_options();
976 
982  template <int dim>
984 
988  template <int dim>
990  {
991  public:
996  const GeometryModel::Interface<dim> &geometry_model);
997 
1002  NaturalCoordinate(const std::array<double, dim> &coord,
1003  const Utilities::Coordinates::CoordinateSystem &coord_system);
1004 
1009  std::array<double,dim> &get_coordinates();
1010 
1015  const std::array<double,dim> &get_coordinates() const;
1016 
1021  std::array<double,dim-1> get_surface_coordinates() const;
1022 
1027  double get_depth_coordinate() const;
1028 
1029  private:
1035 
1039  std::array<double,dim> coordinates;
1040  };
1041 
1042 
1061  template <int dim, typename VectorType>
1062  void
1064  const DoFHandler<dim> &dof_handler,
1065  const unsigned int component_index,
1066  const Quadrature<dim> &quadrature,
1067  const std::function<void(
1068  const typename DoFHandler<dim>::active_cell_iterator &,
1069  const std::vector<Point<dim>> &,
1070  std::vector<double> &)> &function,
1071  VectorType &vec_result);
1072 
1096  void throw_linear_solver_failure_exception(const std::string &solver_name,
1097  const std::string &function_name,
1098  const std::vector<SolverControl> &solver_controls,
1099  const std::exception &exc,
1100  const MPI_Comm mpi_communicator,
1101  const std::string &output_filename = "");
1102 
1113  template <int dim>
1115  {
1116  public:
1127  const std::function<Tensor<1,dim> (const Point<dim> &)> &function_object);
1128  };
1129 
1136  template <typename T>
1137  inline
1138  std::vector<std::size_t>
1139  compute_sorting_permutation(const std::vector<T> &vector);
1140 
1148  template <typename T>
1149  inline
1150  std::vector<T>
1152  const std::vector<T> &vector,
1153  const std::vector<std::size_t> &permutation_vector);
1154 
1167  std::vector<Tensor<2,3>>
1168  rotation_matrices_random_draw_volume_weighting(const std::vector<double> &volume_fractions,
1169  const std::vector<Tensor<2,3>> &rotation_matrices,
1170  const unsigned int n_output_matrices,
1171  std::mt19937 &random_number_generator);
1172 
1176  double wrap_angle(const double angle);
1177 
1182  std::array<double,3> zxz_euler_angles_from_rotation_matrix(const Tensor<2,3> &rotation_matrix);
1183 
1189  const double theta,
1190  const double phi2);
1191 
1192  }
1193 
1194 
1195 // inline implementations:
1196 #ifndef DOXYGEN
1197  namespace Utilities
1198  {
1199 
1200  template <typename T>
1201  inline
1202  std::vector<T>
1203  possibly_extend_from_1_to_N (const std::vector<T> &values,
1204  const unsigned int N,
1205  const std::string &id_text)
1206  {
1207  if (values.size() == 1)
1208  {
1209  return std::vector<T> (N, values[0]);
1210  }
1211  else if (values.size() == N)
1212  {
1213  return values;
1214  }
1215  else
1216  {
1217  // Non-specified behavior
1218  AssertThrow(false,
1219  ExcMessage("Length of " + id_text + " list must be " +
1220  "either one or " + Utilities::to_string(N) +
1221  ". Currently it is " + Utilities::to_string(values.size()) + "."));
1222  }
1223 
1224  // This should never happen, but return an empty vector so the compiler
1225  // will be happy
1226  return std::vector<T> ();
1227  }
1228 
1229  inline
1230  void
1231  extract_composition_values_at_q_point (const std::vector<std::vector<double>> &composition_values,
1232  const unsigned int q,
1233  std::vector<double> &composition_values_at_q_point)
1234  {
1235  Assert(q<composition_values.size(), ExcInternalError());
1236  Assert(composition_values_at_q_point.size() > 0,
1237  ExcInternalError());
1238 
1239  for (unsigned int k=0; k < composition_values_at_q_point.size(); ++k)
1240  {
1241  Assert(composition_values[k].size() == composition_values_at_q_point.size(),
1242  ExcInternalError());
1243  composition_values_at_q_point[k] = composition_values[k][q];
1244  }
1245  }
1246 
1247  template <typename T>
1248  inline
1249  std::vector<std::size_t>
1250  compute_sorting_permutation(const std::vector<T> &vector)
1251  {
1252  std::vector<std::size_t> p(vector.size());
1253  std::iota(p.begin(), p.end(), 0);
1254  std::sort(p.begin(), p.end(),
1255  [&](std::size_t i, std::size_t j)
1256  {
1257  return vector[i] < vector[j];
1258  });
1259  return p;
1260  }
1261 
1262  template <typename T>
1263  inline
1264  std::vector<T>
1266  const std::vector<T> &vector,
1267  const std::vector<std::size_t> &permutation_vector)
1268  {
1269  std::vector<T> sorted_vec(vector.size());
1270  std::transform(permutation_vector.begin(), permutation_vector.end(), sorted_vec.begin(),
1271  [&](std::size_t i)
1272  {
1273  return vector[i];
1274  });
1275  return sorted_vec;
1276  }
1277 
1281  namespace Tensors
1282  {
1288  template <int dim, class Iterator>
1289  inline
1291  to_symmetric_tensor(const Iterator begin,
1292  const Iterator end)
1293  {
1295  (void) end;
1296 
1297  SymmetricTensor<2,dim> output;
1298 
1299  Iterator next = begin;
1300  for (unsigned int i=0; i < SymmetricTensor<2,dim>::n_independent_components; ++i, ++next)
1302 
1303  return output;
1304  }
1305 
1310  template <int dim, class Iterator>
1311  inline
1312  void
1313  unroll_symmetric_tensor_into_array(const SymmetricTensor<2,dim> &tensor,
1314  const Iterator begin,
1315  const Iterator end)
1316  {
1318  (void) end;
1319 
1320  Iterator next = begin;
1321  for (unsigned int i=0; i < SymmetricTensor<2,dim>::n_independent_components; ++i, ++next)
1323  }
1324 
1329  rotate_full_stiffness_tensor(const Tensor<2,3> &rotation_tensor, const SymmetricTensor<4,3> &input_tensor);
1330 
1336  rotate_voigt_stiffness_matrix(const Tensor<2,3> &rotation_tensor, const SymmetricTensor<2,6> &input_tensor);
1337 
1342  rotate_kelvin_tensor(const Tensor<2,3> &rotation_tensor, const SymmetricTensor<2,6> &input_tensor);
1343 
1349  to_voigt_stiffness_matrix(const SymmetricTensor<4,3> &input_tensor);
1350 
1356  to_full_stiffness_tensor(const SymmetricTensor<2,6> &input_tensor);
1357 
1362  Tensor<1,21>
1363  to_voigt_stiffness_vector(const SymmetricTensor<2,6> &input_tensor);
1364 
1370  to_voigt_stiffness_matrix(const Tensor<1,21> &input_tensor);
1371 
1376  Tensor<1,21>
1377  to_voigt_stiffness_vector(const SymmetricTensor<4,3> &input);
1378 
1379 
1384  template <int dim>
1385  const Tensor<dim,dim> &levi_civita();
1386 
1387  // Declare the existence of a specialization:
1388  template <>
1389  const Tensor<3,3> &levi_civita<3>();
1390 
1402  template <int dim>
1404  consistent_deviator(const SymmetricTensor<2,dim> &input);
1405 
1419  template <int dim>
1420  double
1421  consistent_second_invariant_of_deviatoric_tensor(const SymmetricTensor<2,dim> &input);
1422  }
1423 
1424  }
1425 #endif
1426 }
1427 
1428 #endif
*  *  iterator begin()
const unsigned int n_components
NaturalCoordinate(const std::array< double, dim > &coord, const Utilities::Coordinates::CoordinateSystem &coord_system)
Utilities::Coordinates::CoordinateSystem coordinate_system
Definition: utilities.h:1034
const std::array< double, dim > & get_coordinates() const
std::array< double, dim > & get_coordinates()
std::array< double, dim > coordinates
Definition: utilities.h:1039
NaturalCoordinate(Point< dim > &position, const GeometryModel::Interface< dim > &geometry_model)
std::array< double, dim-1 > get_surface_coordinates() const
bool operator==(const operation op) const
double operator()(const double x, const double y) const
Operator(const operation op)
VectorFunctionFromVelocityFunctionObject(const unsigned int n_components, const std::function< Tensor< 1, dim >(const Point< dim > &)> &function_object)
std::vector< double > m_x
Definition: utilities.h:737
void set_points(const std::vector< double > &x, const std::vector< double > &y, const bool cubic_spline=true, const bool monotone_spline=false)
std::vector< double > m_a
Definition: utilities.h:745
std::vector< double > m_c
Definition: utilities.h:745
double operator()(double x) const
std::vector< double > m_y
Definition: utilities.h:745
std::vector< double > m_b
Definition: utilities.h:745
#define DEAL_II_DEPRECATED
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::size_t size
std::string to_string(const number value, const unsigned int digits=numbers::invalid_unsigned_int)
Tensor< 1, dim > spherical_to_cartesian_vector(const Tensor< 1, dim > &spherical_vector, const ::Point< dim > &position)
std::array< double, dim > WGS84_coordinates(const ::Point< dim > &position)
std::array< double, dim > cartesian_to_spherical_coordinates(const ::Point< dim > &position)
std::array< double, 3 > cartesian_to_ellipsoidal_coordinates(const ::Point< 3 > &position, const double semi_major_axis_a, const double eccentricity)
CoordinateSystem string_to_coordinate_system(const std::string &)
::Point< dim > spherical_to_cartesian_coordinates(const std::array< double, dim > &scoord)
::Point< 3 > ellipsoidal_to_cartesian_coordinates(const std::array< double, 3 > &phi_theta_d, const double semi_major_axis_a, const double eccentricity)
std::vector< double > parse_map_to_double_array(const std::string &input_string, Options &options)
Tensor< 2, 3 > rotation_matrix_from_axis(const Tensor< 1, 3 > &rotation_axis, const double rotation_angle)
double wrap_angle(const double angle)
std::array< double, dim > convert_point_to_array(const Point< dim > &point)
std::vector< std::string > expand_dimensional_variable_names(const std::vector< std::string > &var_declarations)
unsigned int string_to_unsigned_int(const std::string &s)
T derivative_of_weighted_p_norm_average(const double averaged_parameter, const std::vector< double > &weights, const std::vector< double > &values, const std::vector< T > &derivatives, const double p)
Point< dim > convert_array_to_point(const std::array< double, dim > &array)
bool filename_is_url(const std::string &filename)
bool polygon_contains_point(const std::vector< Point< 2 >> &point_list, const ::Point< 2 > &point)
Tensor< 2, 3 > zxz_euler_angles_to_rotation_matrix(const double phi1, const double theta, const double phi2)
bool fexists(const std::string &filename)
double signed_distance_to_polygon(const std::vector< Point< 2 >> &point_list, const ::Point< 2 > &point)
double compute_spd_factor(const double eta, const SymmetricTensor< 2, dim > &strain_rate, const SymmetricTensor< 2, dim > &dviscosities_dstrain_rate, const double SPD_safety_factor)
double distance_to_line(const std::array<::Point< 2 >, 2 > &point_list, const ::Point< 2 > &point)
std::array< Tensor< 1, dim >, dim-1 > orthogonal_vectors(const Tensor< 1, dim > &v)
Tensor< 2, 3 > compute_rotation_matrix_for_slice(const Tensor< 1, 3 > &point_one, const Tensor< 1, 3 > &point_two)
std::pair< double, double > real_spherical_harmonic(unsigned int l, unsigned int m, double theta, double phi)
std::vector< T > possibly_extend_from_1_to_N(const std::vector< T > &values, const unsigned int N, const std::string &id_text)
int mkdirp(std::string pathname, const mode_t mode=0755)
std::string expand_ASPECT_SOURCE_DIR(const std::string &location)
double weighted_p_norm_average(const std::vector< double > &weights, const std::vector< double > &values, const double p)
bool point_is_in_triangulation(const Mapping< dim > &mapping, const parallel::distributed::Triangulation< dim > &triangulation, const Point< dim > &point, const MPI_Comm mpi_communicator)
std::string parenthesize_if_nonempty(const std::string &s)
bool has_unique_entries(const std::vector< std::string > &strings)
IndexSet extract_locally_active_dofs_with_component(const DoFHandler< dim > &dof_handler, const ComponentMask &component_mask)
std::vector< Operator > create_model_operator_list(const std::vector< std::string > &operator_names)
std::array< double, 3 > zxz_euler_angles_from_rotation_matrix(const Tensor< 2, 3 > &rotation_matrix)
bool string_to_bool(const std::string &s)
DEAL_II_DEPRECATED std::vector< double > parse_map_to_double_array(const std::string &key_value_map, const std::vector< std::string > &list_of_keys, const bool expects_background_field, const std::string &property_name, const bool allow_multiple_values_per_key=false, const std::unique_ptr< std::vector< unsigned int >> &n_values_per_key=nullptr, const bool allow_missing_keys=false)
void project_cellwise(const Mapping< dim > &mapping, const DoFHandler< dim > &dof_handler, const unsigned int component_index, const Quadrature< dim > &quadrature, const std::function< void(const typename DoFHandler< dim >::active_cell_iterator &, const std::vector< Point< dim >> &, std::vector< double > &)> &function, VectorType &vec_result)
const std::string get_model_operator_options()
void create_directory(const std::string &pathname, const MPI_Comm comm, const bool silent)
void extract_composition_values_at_q_point(const std::vector< std::vector< double >> &composition_values, const unsigned int q, std::vector< double > &composition_values_at_q_point)
SymmetricTensor< 2, dim > nth_basis_for_symmetric_tensors(const unsigned int k)
std::vector< Tensor< 2, 3 > > rotation_matrices_random_draw_volume_weighting(const std::vector< double > &volume_fractions, const std::vector< Tensor< 2, 3 >> &rotation_matrices, const unsigned int n_output_matrices, std::mt19937 &random_number_generator)
void throw_linear_solver_failure_exception(const std::string &solver_name, const std::string &function_name, const std::vector< SolverControl > &solver_controls, const std::exception &exc, const MPI_Comm mpi_communicator, const std::string &output_filename="")
std::vector< T > apply_permutation(const std::vector< T > &vector, const std::vector< std::size_t > &permutation_vector)
std::string read_and_distribute_file_content(const std::string &filename, const MPI_Comm comm)
Table< 2, T > parse_input_table(const std::string &input_string, const unsigned int n_rows, const unsigned int n_columns, const std::string &property_name)
std::vector< std::size_t > compute_sorting_permutation(const std::vector< T > &vector)
void collect_and_write_file_content(const std::string &filename, const std::string &file_content, const MPI_Comm comm)
std::vector< Point< dim > > get_unit_support_points(const SimulatorAccess< dim > &simulator_access)
std::vector< std::string > list_of_allowed_keys
Definition: utilities.h:119
std::vector< std::string > list_of_required_keys
Definition: utilities.h:128
Options(const std::vector< std::string > &list_of_required_keys, const std::string &property_name)
Definition: utilities.h:199
std::vector< unsigned int > n_values_per_key
Definition: utilities.h:181
char do_thousands_sep() const override
Definition: utilities.h:583
std::string do_grouping() const override
Definition: utilities.h:588