KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
mixed_generic_criteria.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Jordi Cotela, Riccardo Rossi, Carlos Roig and Ruben Zorrilla
11 //
12 
13 #pragma once
14 
15 // System includes
16 
17 // External includes
18 
19 // Project includes
20 #include "includes/define.h"
21 #include "includes/model_part.h"
22 #include "convergence_criteria.h"
23 
24 // Application includes
25 
26 namespace Kratos
27 {
30 
33 
35 
40 template< class TSparseSpace, class TDenseSpace >
41 class MixedGenericCriteria : public ConvergenceCriteria< TSparseSpace, TDenseSpace >
42 {
43 public:
46 
48 
50 
52 
53  typedef typename BaseType::TDataType TDataType;
54 
56 
58 
60 
61  typedef std::vector<std::tuple<const VariableData*, TDataType, TDataType>> ConvergenceVariableListType;
62 
63  typedef std::size_t KeyType;
64 
68 
70 
72  : BaseType(),
73  mVariableSize(0)
74  {
75  }
76 
81  explicit MixedGenericCriteria(Kratos::Parameters ThisParameters)
82  : MixedGenericCriteria(GenerateConvergenceVariableListFromParameters(ThisParameters))
83  {
84  }
85 
92  MixedGenericCriteria(const ConvergenceVariableListType& rConvergenceVariablesList)
93  : BaseType()
94  , mVariableSize([&] (const ConvergenceVariableListType& rList) -> int {return rList.size();} (rConvergenceVariablesList))
95  , mVariableDataVector([&] (const ConvergenceVariableListType& rList) -> std::vector<const VariableData*> {
96  int i = 0;
97  std::vector<const VariableData*> aux_vect(mVariableSize);
98  for (const auto &r_tup : rList) {
99  aux_vect[i++] = std::get<0>(r_tup);
100  }
101  return aux_vect;
102  } (rConvergenceVariablesList))
103  , mRatioToleranceVector([&] (const ConvergenceVariableListType& rList) -> std::vector<TDataType> {
104  int i = 0;
105  std::vector<TDataType> aux_vect(mVariableSize);
106  for (const auto &r_tup : rList) {
107  aux_vect[i++] = std::get<1>(r_tup);
108  }
109  return aux_vect;
110  } (rConvergenceVariablesList))
111  , mAbsToleranceVector([&] (const ConvergenceVariableListType& rList) -> std::vector<TDataType> {
112  int i = 0;
113  std::vector<TDataType> aux_vect(mVariableSize);
114  for (const auto &r_tup : rList) {
115  aux_vect[i++] = std::get<2>(r_tup);
116  }
117  return aux_vect;
118  } (rConvergenceVariablesList))
119  , mLocalKeyMap([&] (const ConvergenceVariableListType& rList) -> std::unordered_map<KeyType, KeyType> {
120  KeyType local_key = 0;
121  std::unordered_map<KeyType, KeyType> aux_map;
122  for (const auto &r_tup : rList) {
123  const auto *p_var_data = std::get<0>(r_tup);
124  if (aux_map.find(p_var_data->Key()) != aux_map.end()) {
125  KRATOS_ERROR << "Convergence variable " << p_var_data->Name() << " is repeated. Check the input convergence variable list." << std::endl;
126  } else {
127  KRATOS_ERROR_IF(p_var_data->IsComponent()) << "Trying to check convergence with the " << p_var_data->Name() << " component variable. Use the corresponding vector one." << std::endl;
128  aux_map[p_var_data->Key()] = local_key++;
129  }
130  }
131  return aux_map;
132  } (rConvergenceVariablesList))
133  {}
134 
137  {}
138 
142 
143 
147 
152  typename BaseType::Pointer Create(Parameters ThisParameters) const override
153  {
154  return Kratos::make_shared<ClassType>(ThisParameters);
155  }
156 
158 
167  ModelPart& rModelPart,
168  DofsArrayType& rDofSet,
169  const TSystemMatrixType& A,
170  const TSystemVectorType& Dx,
171  const TSystemVectorType& b) override
172  {
173  // Check if we are solving for something
174  if (TSparseSpace::Size(Dx) != 0) {
175  // Calculate the convergence ratio and absolute norms
176  const auto convergence_norms = CalculateConvergenceNorms(rModelPart, rDofSet, Dx);
177 
178  // Output convergence status
179  OutputConvergenceStatus(convergence_norms);
180 
181  // Check convergence
182  return CheckConvergence(convergence_norms);
183  } else {
184  // Case in which all the DOFs are constrained!
185  return true;
186  }
187  }
188 
193  static std::string Name()
194  {
195  return "mixed_generic_criteria";
196  }
197 
201 
202 
206 
207 
211 
213  std::string Info() const override
214  {
215  return "MixedGenericCriteria";
216  }
217 
219  void PrintInfo(std::ostream& rOStream) const override
220  {
221  rOStream << Info();
222  }
223 
225  void PrintData(std::ostream& rOStream) const override
226  {
227  rOStream << Info();
228  }
229 
231 protected:
234 
235 
239 
240 
244 
245 
249 
255  int GetVariableSize() const
256  {
257  return mVariableSize;
258  }
259 
265  std::vector<const VariableData*> GetVariableDataVector() const
266  {
267  return mVariableDataVector;
268  }
269 
275  std::vector<TDataType> GetRatioToleranceVector() const
276  {
277  return mRatioToleranceVector;
278  }
279 
285  std::vector<TDataType> GetAbsToleranceVector() const
286  {
287  return mAbsToleranceVector;
288  }
289 
295  std::unordered_map<KeyType, KeyType>& GetLocalKeyMap()
296  {
297  return mLocalKeyMap;
298  }
299 
308  std::tuple<std::vector<TDataType>, std::vector<TDataType>> CalculateConvergenceNorms(
309  const ModelPart& rModelPart,
310  const DofsArrayType& rDofSet,
311  const TSystemVectorType& rDx)
312  {
313  // Initialize
314  std::vector<int> dofs_count(mVariableSize, 0);
315  std::vector<TDataType> solution_norms_vector(mVariableSize, 0.0);
316  std::vector<TDataType> increase_norms_vector(mVariableSize, 0.0);
317 
318  // Accumulate the norm values
319  GetNormValues(rModelPart, rDofSet, rDx, dofs_count, solution_norms_vector, increase_norms_vector);
320 
321  // Synchronize the norm values
322  const auto& r_data_comm = rModelPart.GetCommunicator().GetDataCommunicator();
323  auto global_solution_norms_vector = r_data_comm.SumAll(solution_norms_vector);
324  auto global_increase_norms_vector = r_data_comm.SumAll(increase_norms_vector);
325  auto global_dofs_count = r_data_comm.SumAll(dofs_count);
326 
327  // Check division by zero in global solution norms
328  const double zero_tol = 1.0e-12;
329  for(int i = 0; i < mVariableSize; i++) {
330  if (global_solution_norms_vector[i] < zero_tol) {
331  global_solution_norms_vector[i] = 1.0;
332  }
333  }
334 
335  // Calculate the norm values
336  std::vector<TDataType> var_ratio(mVariableSize, 0.0);
337  std::vector<TDataType> var_abs(mVariableSize, 0.0);
338  for(int i = 0; i < mVariableSize; i++) {
339  var_ratio[i] = std::sqrt(global_increase_norms_vector[i] / global_solution_norms_vector[i]);
340  var_abs[i] = std::sqrt(global_increase_norms_vector[i]) / static_cast<TDataType>(global_dofs_count[i]);
341  }
342 
343  // Output the ratio and absolute norms as a tuple
344  return std::make_tuple(var_ratio, var_abs);
345  }
346 
353  const std::tuple<std::vector<TDataType>,
354  std::vector<TDataType>>& rConvergenceNorms)
355  {
356  const auto& var_ratio = std::get<0>(rConvergenceNorms);
357  const auto& var_abs = std::get<1>(rConvergenceNorms);
358 
359  if (this->GetEchoLevel() > 0) {
360  std::ostringstream stringbuf;
361  stringbuf << "CONVERGENCE CHECK:\n";
362 
363  const int max_length_var_name = (*std::max_element(mVariableDataVector.begin(), mVariableDataVector.end(), [](const VariableData* p_var_data_1, const VariableData* p_var_data_2){
364  return p_var_data_1->Name().length() < p_var_data_2->Name().length();
365  }))->Name().length();
366 
367  for(int i = 0; i < mVariableSize; i++) {
368  const auto r_var_data = mVariableDataVector[i];
369  const int key_map = mLocalKeyMap[r_var_data->Key()];
370  const std::string space_str(max_length_var_name-r_var_data->Name().length(), ' ');
371  stringbuf << " " << r_var_data->Name() << space_str <<" : ratio = " << var_ratio[key_map] << "; exp.ratio = " << mRatioToleranceVector[key_map] << " abs = " << var_abs[key_map] << " exp.abs = " << mAbsToleranceVector[key_map] << "\n";
372  }
373  KRATOS_INFO("") << stringbuf.str();
374  }
375  }
376 
385  const std::tuple<std::vector<TDataType>,
386  std::vector<TDataType>>& rConvergenceNorms)
387  {
388  bool is_converged = true;
389  const auto& var_ratio = std::get<0>(rConvergenceNorms);
390  const auto& var_abs = std::get<1>(rConvergenceNorms);
391 
392  for (int i = 0; i < mVariableSize; i++) {
393  const auto r_var_data = mVariableDataVector[i];
394  const int key_map = mLocalKeyMap[r_var_data->Key()];
395  is_converged &= var_ratio[key_map] <= mRatioToleranceVector[key_map] || var_abs[key_map] <= mAbsToleranceVector[key_map];
396  }
397 
398  // Note that this check ensures that all the convergence variables fulfil either the relative or the absolute criterion
399  if (is_converged) {
400  KRATOS_INFO_IF("", this->GetEchoLevel() > 0) << "*** CONVERGENCE IS ACHIEVED ***" << std::endl;
401  return true;
402  } else {
403  return false;
404  }
405  }
406 
416  typename DofsArrayType::const_iterator itDof,
417  int& rVarLocalKey) const
418  {
419  const auto &r_current_variable = itDof->GetVariable();
420  const KeyType key = r_current_variable.IsComponent() ? r_current_variable.GetSourceVariable().Key() : r_current_variable.Key();
421  auto key_find = this->mLocalKeyMap.find(key);
422  bool found = true;
423  if (key_find == this->mLocalKeyMap.end()) {
424  found = false;
425  } else {
426  rVarLocalKey = key_find->second;;
427  }
428  return found;
429  }
430 
431 
435 
436 
440 
441 
445 
446 
448 private:
451 
452 
456 
457  const int mVariableSize;
458  const std::vector<const VariableData*> mVariableDataVector;
459  const std::vector<TDataType> mRatioToleranceVector;
460  const std::vector<TDataType> mAbsToleranceVector;
461  std::unordered_map<KeyType, KeyType> mLocalKeyMap;
462 
466 
467 
471 
483  virtual void GetNormValues(
484  const ModelPart& rModelPart,
485  const DofsArrayType& rDofSet,
486  const TSystemVectorType& rDx,
487  std::vector<int>& rDofsCount,
488  std::vector<TDataType>& rSolutionNormsVector,
489  std::vector<TDataType>& rIncreaseNormsVector) const
490  {
491  int n_dofs = rDofSet.size();
492 
493  // Loop over Dofs
494 #pragma omp parallel
495  {
496  // Local thread variables
497  int dof_id;
498  TDataType dof_dx;
499  TDataType dof_value;
500 
501  // Local reduction variables
502  std::vector<TDataType> var_solution_norm_reduction(mVariableSize);
503  std::vector<TDataType> var_correction_norm_reduction(mVariableSize);
504  std::vector<int> dofs_counter_reduction(mVariableSize);
505  for (int i = 0; i < mVariableSize; i++) {
506  var_solution_norm_reduction[i] = 0.0;
507  var_correction_norm_reduction[i] = 0.0;
508  dofs_counter_reduction[i] = 0;
509  }
510 
511 #pragma omp for
512  for (int i = 0; i < n_dofs; i++) {
513  auto it_dof = rDofSet.begin() + i;
514  if (it_dof->IsFree()) {
515  dof_id = it_dof->EquationId();
516  dof_value = it_dof->GetSolutionStepValue(0);
517  dof_dx = TSparseSpace::GetValue(rDx, dof_id);
518 
519  int var_local_key;
520  bool key_found = FindVarLocalKey(it_dof,var_local_key);
521  if (!key_found) {
522  // the dof does not belong to the list of variables
523  // we are checking for convergence, so we skip it
524  continue;
525  }
526  var_solution_norm_reduction[var_local_key] += dof_value * dof_value;
527  var_correction_norm_reduction[var_local_key] += dof_dx * dof_dx;
528  dofs_counter_reduction[var_local_key]++;
529  }
530  }
531 
532 #pragma omp critical
533  {
534  for (int i = 0; i < mVariableSize; i++) {
535  rDofsCount[i] += dofs_counter_reduction[i];
536  rSolutionNormsVector[i] += var_solution_norm_reduction[i];
537  rIncreaseNormsVector[i] += var_correction_norm_reduction[i];
538  }
539  }
540  }
541  }
542 
548  static ConvergenceVariableListType GenerateConvergenceVariableListFromParameters(Kratos::Parameters ThisParameters)
549  {
550  // Iterate over variables
551  ConvergenceVariableListType aux_list;
552  if (!ThisParameters.Has("convergence_variables_list")) return aux_list;
553  Kratos::Parameters convergence_variables_list = ThisParameters["convergence_variables_list"];
554  for (auto param : convergence_variables_list) {
555  if (param.Has("variable")) {
556  const std::string& r_variable_name = param["variable"].GetString();
557 
558  // Variable pointer
559  const VariableData* p_variable = KratosComponents<Variable<double>>::Has(r_variable_name) ? dynamic_cast<const VariableData*>(&KratosComponents<Variable<double>>::Get(r_variable_name)) : dynamic_cast<const VariableData*>(&KratosComponents<Variable<array_1d<double, 3>>>::Get(r_variable_name));
560 
561  // Tolerances
562  const double rel_tol = param.Has("relative_tolerance") ? param["relative_tolerance"].GetDouble() : 1.0e-4;
563  const double abs_tol = param.Has("absolute_tolerance") ? param["absolute_tolerance"].GetDouble() : 1.0e-9;
564 
565  // Push back list
566  aux_list.push_back(std::make_tuple(p_variable, rel_tol, abs_tol));
567  }
568  }
569 
570  return aux_list;
571  }
572 
576 
577 
581 
582 
586 
587 
589 };
591 
593 }
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
This is the base class to define the different convergence criterion considered.
Definition: convergence_criteria.h:58
TSparseSpace::MatrixType TSystemMatrixType
Matrix type definition.
Definition: convergence_criteria.h:72
TSparseSpace::DataType TDataType
Data type definition.
Definition: convergence_criteria.h:70
TSparseSpace::VectorType TSystemVectorType
Vector type definition.
Definition: convergence_criteria.h:74
Convergence criteria for mixed vector-scalar problems.
Definition: mixed_generic_criteria.h:42
MixedGenericCriteria(const ConvergenceVariableListType &rConvergenceVariablesList)
Construct a new Mixed Generic Criteria object Construct the mixed generic convergence criteria from a...
Definition: mixed_generic_criteria.h:92
std::unordered_map< KeyType, KeyType > & GetLocalKeyMap()
Get the Local Key Map object Returns a reference to the variable key local map.
Definition: mixed_generic_criteria.h:295
bool FindVarLocalKey(typename DofsArrayType::const_iterator itDof, int &rVarLocalKey) const
Finds the var local key in the mLocalKeyMap for a gifen DOF. If the variable does not exist in mLocal...
Definition: mixed_generic_criteria.h:415
int GetVariableSize() const
Get the Variable Size object Get the number of variables to be checked.
Definition: mixed_generic_criteria.h:255
BaseType::TDataType TDataType
Definition: mixed_generic_criteria.h:53
MixedGenericCriteria< TSparseSpace, TDenseSpace > ClassType
Definition: mixed_generic_criteria.h:51
bool CheckConvergence(const std::tuple< std::vector< TDataType >, std::vector< TDataType >> &rConvergenceNorms)
Method to check convergence This method checks the convergence of the provided norms with the user-de...
Definition: mixed_generic_criteria.h:384
std::vector< std::tuple< const VariableData *, TDataType, TDataType > > ConvergenceVariableListType
Definition: mixed_generic_criteria.h:61
std::vector< TDataType > GetAbsToleranceVector() const
Get the Abs Tolerance Vector object Get the member vector containing the absolute tolerances for each...
Definition: mixed_generic_criteria.h:285
std::vector< const VariableData * > GetVariableDataVector() const
Get the Variable Data Vector object Get the member vector that stores pointers to the variables to ch...
Definition: mixed_generic_criteria.h:265
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: mixed_generic_criteria.h:219
BaseType::TSystemMatrixType TSystemMatrixType
Definition: mixed_generic_criteria.h:57
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: mixed_generic_criteria.h:225
BaseType::TSystemVectorType TSystemVectorType
Definition: mixed_generic_criteria.h:59
MixedGenericCriteria()
Constructor.
Definition: mixed_generic_criteria.h:71
virtual void OutputConvergenceStatus(const std::tuple< std::vector< TDataType >, std::vector< TDataType >> &rConvergenceNorms)
Method to output the convergence status This method prints the convergence status to the screen for e...
Definition: mixed_generic_criteria.h:352
BaseType::DofsArrayType DofsArrayType
Definition: mixed_generic_criteria.h:55
static std::string Name()
Returns the name of the class as used in the settings (snake_case format)
Definition: mixed_generic_criteria.h:193
MixedGenericCriteria(Kratos::Parameters ThisParameters)
Default constructor. (with parameters)
Definition: mixed_generic_criteria.h:81
ConvergenceCriteria< TSparseSpace, TDenseSpace > BaseType
Definition: mixed_generic_criteria.h:49
std::size_t KeyType
Definition: mixed_generic_criteria.h:63
bool PostCriteria(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &A, const TSystemVectorType &Dx, const TSystemVectorType &b) override
Compute relative and absolute error.
Definition: mixed_generic_criteria.h:166
std::vector< TDataType > GetRatioToleranceVector() const
Get the Ratio Tolerance Vector object Get the member vector containing the ratio tolerances for each ...
Definition: mixed_generic_criteria.h:275
std::string Info() const override
Turn back information as a string.
Definition: mixed_generic_criteria.h:213
std::tuple< std::vector< TDataType >, std::vector< TDataType > > CalculateConvergenceNorms(const ModelPart &rModelPart, const DofsArrayType &rDofSet, const TSystemVectorType &rDx)
Calculate the convergence norms This method calculates the convergence norms for all the variables to...
Definition: mixed_generic_criteria.h:308
BaseType::Pointer Create(Parameters ThisParameters) const override
Create method.
Definition: mixed_generic_criteria.h:152
KRATOS_CLASS_POINTER_DEFINITION(MixedGenericCriteria)
~MixedGenericCriteria() override
Destructor.
Definition: mixed_generic_criteria.h:136
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
Communicator & GetCommunicator()
Definition: model_part.h:1821
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
bool Has(const std::string &rEntry) const
This method checks if the Parameter contains a certain entry.
Definition: kratos_parameters.cpp:520
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
boost::indirect_iterator< typename TContainerType::const_iterator > const_iterator
Definition: pointer_vector_set.h:96
This class is the base of variables and variable's components which contains their common data.
Definition: variable_data.h:49
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO(label)
Definition: logger.h:250
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
bool Has(const std::string &ModelerName)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:24
TSpaceType::IndexType Size(TSpaceType &dummy, typename TSpaceType::VectorType const &rV)
Definition: add_strategies_to_python.cpp:111
Parameters GetValue(Parameters &rParameters, const std::string &rEntry)
Definition: add_kratos_parameters_to_python.cpp:53
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
n_dofs
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:151
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
tuple const
Definition: ode_solve.py:403
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17