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.
displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h
Go to the documentation of this file.
1 // KRATOS ______ __ __ _____ __ __ __
2 // / ____/___ ____ / /_____ ______/ /_/ ___// /________ _______/ /___ ___________ _/ /
3 // / / / __ \/ __ \/ __/ __ `/ ___/ __/\__ \/ __/ ___/ / / / ___/ __/ / / / ___/ __ `/ /
4 // / /___/ /_/ / / / / /_/ /_/ / /__/ /_ ___/ / /_/ / / /_/ / /__/ /_/ /_/ / / / /_/ / /
5 // \____/\____/_/ /_/\__/\__,_/\___/\__//____/\__/_/ \__,_/\___/\__/\__,_/_/ \__,_/_/ MECHANICS
6 //
7 // License: BSD License
8 // license: ContactStructuralMechanicsApplication/license.txt
9 //
10 // Main authors: Vicente Mataix Ferrandiz
11 //
12 
13 #pragma once
14 
15 // System includes
16 
17 // External includes
18 
19 // Project includes
26 
27 namespace Kratos
28 {
31 
34 
38 
42 
46 
49 
59 template< class TSparseSpace,
60  class TDenseSpace >
62  : public ConvergenceCriteria< TSparseSpace, TDenseSpace >
63 {
64 public:
65 
68 
71 
73  KRATOS_DEFINE_LOCAL_FLAG( ENSURE_CONTACT );
74  KRATOS_DEFINE_LOCAL_FLAG( PRINTING_OUTPUT );
75  KRATOS_DEFINE_LOCAL_FLAG( TABLE_IS_INITIALIZED );
76  KRATOS_DEFINE_LOCAL_FLAG( ROTATION_DOF_IS_CONSIDERED );
78  KRATOS_DEFINE_LOCAL_FLAG( INITIAL_RESIDUAL_IS_SET );
79 
82 
85 
88 
91 
94 
96  using SparseSpaceType = TSparseSpace;
97 
99  using TablePrinterPointerType = TableStreamUtility::Pointer;
100 
102  using IndexType = std::size_t;
103 
105  static constexpr double Tolerance = std::numeric_limits<double>::epsilon();
106 
110 
115  : BaseType()
116  {
117  }
118 
124  : BaseType()
125  {
126  // Validate and assign defaults
127  ThisParameters = this->ValidateAndAssignParameters(ThisParameters, this->GetDefaultParameters());
128  this->AssignSettings(ThisParameters);
129  }
130 
145  const double DispRatioTolerance,
146  const double DispAbsTolerance,
147  const double RotRatioTolerance,
148  const double RotAbsTolerance,
149  const double LMNormalRatioTolerance,
150  const double LMNormalAbsTolerance,
151  const double LMTangentStickRatioTolerance,
152  const double LMTangentStickAbsTolerance,
153  const double LMTangentSlipRatioTolerance,
154  const double LMTangentSlipAbsTolerance,
155  const double NormalTangentRatio,
156  const bool EnsureContact = false,
157  const bool PureSlip = false,
158  const bool PrintingOutput = false
159  )
160  : BaseType()
161  {
162  // Set local flags
163  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ENSURE_CONTACT, EnsureContact);
164  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT, PrintingOutput);
165  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::TABLE_IS_INITIALIZED, false);
166  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED, false);
167  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP, PureSlip);
168  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::INITIAL_RESIDUAL_IS_SET, false);
169 
170  // The displacement residual
171  mDispRatioTolerance = DispRatioTolerance;
172  mDispAbsTolerance = DispAbsTolerance;
173 
174  // The rotation residual
175  mRotRatioTolerance = RotRatioTolerance;
176  mRotAbsTolerance = RotAbsTolerance;
177 
178  // The normal contact residual
179  mLMNormalRatioTolerance = LMNormalRatioTolerance;
180  mLMNormalAbsTolerance = LMNormalAbsTolerance;
181 
182  // The tangent contact residual
183  mLMTangentStickRatioTolerance = LMTangentStickRatioTolerance;
184  mLMTangentStickAbsTolerance = LMTangentStickAbsTolerance;
185  mLMTangentSlipRatioTolerance = LMTangentSlipRatioTolerance;
186  mLMTangentSlipAbsTolerance = LMTangentSlipAbsTolerance;
187 
188  // We get the ratio between the normal and tangent that will accepted as converged
189  mNormalTangentRatio = NormalTangentRatio;
190  }
191 
192  //* Copy constructor.
194  :BaseType(rOther)
195  ,mOptions(rOther.mOptions)
196  ,mDispRatioTolerance(rOther.mDispRatioTolerance)
197  ,mDispAbsTolerance(rOther.mDispAbsTolerance)
198  ,mDispInitialResidualNorm(rOther.mDispInitialResidualNorm)
199  ,mDispCurrentResidualNorm(rOther.mDispCurrentResidualNorm)
200  ,mRotRatioTolerance(rOther.mRotRatioTolerance)
201  ,mRotAbsTolerance(rOther.mRotAbsTolerance)
202  ,mRotInitialResidualNorm(rOther.mRotInitialResidualNorm)
203  ,mRotCurrentResidualNorm(rOther.mRotCurrentResidualNorm)
204  ,mLMNormalRatioTolerance(rOther.mLMNormalRatioTolerance)
205  ,mLMNormalAbsTolerance(rOther.mLMNormalAbsTolerance)
206  ,mLMTangentStickRatioTolerance(rOther.mLMTangentStickRatioTolerance)
207  ,mLMTangentStickAbsTolerance(rOther.mLMTangentStickAbsTolerance)
208  ,mLMTangentSlipRatioTolerance(rOther.mLMTangentSlipRatioTolerance)
209  ,mLMTangentSlipAbsTolerance(rOther.mLMTangentSlipAbsTolerance)
210  ,mNormalTangentRatio(rOther.mNormalTangentRatio)
211  {
212  }
213 
216 
220 
224 
229  typename BaseType::Pointer Create(Parameters ThisParameters) const override
230  {
231  return Kratos::make_shared<ClassType>(ThisParameters);
232  }
233 
244  ModelPart& rModelPart,
245  DofsArrayType& rDofSet,
246  const TSystemMatrixType& rA,
247  const TSystemVectorType& rDx,
248  const TSystemVectorType& rb
249  ) override
250  {
251  if (SparseSpaceType::Size(rb) != 0) { //if we are solving for something
252 
253  // Getting process info
254  ProcessInfo& r_process_info = rModelPart.GetProcessInfo();
255 
256  // Initialize
257  double disp_residual_solution_norm = 0.0, rot_residual_solution_norm = 0.0,normal_lm_solution_norm = 0.0, normal_lm_increase_norm = 0.0, tangent_lm_stick_solution_norm = 0.0, tangent_lm_slip_solution_norm = 0.0, tangent_lm_stick_increase_norm = 0.0, tangent_lm_slip_increase_norm = 0.0;
258  IndexType disp_dof_num(0),rot_dof_num(0),lm_dof_num(0),lm_stick_dof_num(0),lm_slip_dof_num(0);
259 
260  // The nodes array
261  auto& r_nodes_array = rModelPart.Nodes();
262 
263  // Auxiliary values
264  struct AuxValues {
265  std::size_t dof_id = 0;
266  double residual_dof_value = 0.0, dof_value = 0.0, dof_incr = 0.0;
267  };
268  const bool pure_slip = mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP);
269 
270  // The number of active dofs
271  const std::size_t number_active_dofs = rb.size();
272 
273  // Auxiliary displacement DoF check
274  const std::function<bool(const VariableData&)> check_without_rot =
275  [](const VariableData& rCurrVar) -> bool {return true;};
276  const std::function<bool(const VariableData&)> check_with_rot =
277  [](const VariableData& rCurrVar) -> bool {return ((rCurrVar == DISPLACEMENT_X) || (rCurrVar == DISPLACEMENT_Y) || (rCurrVar == DISPLACEMENT_Z));};
278  const auto* p_check_disp = (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) ? &check_with_rot : &check_without_rot;
279 
280  // Loop over Dofs
282  std::tie(disp_residual_solution_norm,rot_residual_solution_norm,normal_lm_solution_norm,normal_lm_increase_norm,tangent_lm_slip_solution_norm,tangent_lm_slip_increase_norm, tangent_lm_stick_solution_norm,tangent_lm_stick_increase_norm,disp_dof_num,rot_dof_num,lm_dof_num, lm_slip_dof_num, lm_stick_dof_num) = block_for_each<ThirteenReduction>(rDofSet, AuxValues(), [this,&number_active_dofs,p_check_disp,&pure_slip,&r_nodes_array,&rb,&rDx](Dof<double>& rDof, AuxValues& aux_values) {
283  aux_values.dof_id = rDof.EquationId();
284  aux_values.dof_id = rDof.EquationId();
285 
286  // Check dof id is solved
287  if (aux_values.dof_id < number_active_dofs) {
288  if (mActiveDofs[aux_values.dof_id] == 1) {
289  const auto& r_curr_var = rDof.GetVariable();
290  if (r_curr_var == VECTOR_LAGRANGE_MULTIPLIER_X || r_curr_var == VECTOR_LAGRANGE_MULTIPLIER_Y || r_curr_var == VECTOR_LAGRANGE_MULTIPLIER_Z) {
291  // The normal of the node (TODO: how to solve this without accesing all the time to the database?)
292  const auto it_node = r_nodes_array.find(rDof.Id());
293 
294  aux_values.dof_value = rDof.GetSolutionStepValue(0);
295  aux_values.dof_incr = rDx[aux_values.dof_id];
296 
297  const double mu = it_node->GetValue(FRICTION_COEFFICIENT);
298  if (mu < std::numeric_limits<double>::epsilon()) {
299  return std::make_tuple(0.0,0.0,std::pow(aux_values.dof_value, 2),std::pow(aux_values.dof_incr, 2),0.0,0.0,0.0,0.0,0,0,1,0,0);
300  } else {
301  const double normal = it_node->FastGetSolutionStepValue(NORMAL)[r_curr_var.GetComponentIndex()];
302  const double normal_dof_value = aux_values.dof_value * normal;
303  const double normal_dof_incr = aux_values.dof_incr * normal;
304 
305  if (it_node->Is(SLIP) || pure_slip) {
306  return std::make_tuple(0.0,0.0,std::pow(normal_dof_value, 2),std::pow(normal_dof_incr, 2),std::pow(aux_values.dof_value - normal_dof_value, 2),std::pow(aux_values.dof_incr - normal_dof_incr, 2),0.0,0.0,0,0,1,1,0);
307  } else {
308  return std::make_tuple(0.0,0.0,std::pow(normal_dof_value, 2),std::pow(normal_dof_incr, 2),0.0,0.0,std::pow(aux_values.dof_value - normal_dof_value, 2),std::pow(aux_values.dof_incr - normal_dof_incr, 2),0,0,1,0,1);
309  }
310  }
311  } else if ((*p_check_disp)(r_curr_var)) {
312  aux_values.residual_dof_value = rb[aux_values.dof_id];
313  return std::make_tuple(std::pow(aux_values.residual_dof_value, 2),0.0,0.0,0.0,0.0,0.0,0.0,0.0,1,0,0,0,0);
314  } else { // We will assume is rotation dof
315  KRATOS_DEBUG_ERROR_IF_NOT((r_curr_var == ROTATION_X) || (r_curr_var == ROTATION_Y) || (r_curr_var == ROTATION_Z)) << "Variable must be a ROTATION and it is: " << r_curr_var.Name() << std::endl;
316  aux_values.residual_dof_value = rb[aux_values.dof_id];
317  return std::make_tuple(0.0,std::pow(aux_values.residual_dof_value, 2),0.0,0.0,0.0,0.0,0.0,0.0,0,1,0,0,0);
318  }
319  }
320  }
321  return std::make_tuple(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0,0,0,0);
322  });
323 
324  if(normal_lm_increase_norm < Tolerance) normal_lm_increase_norm = 1.0;
325  if(tangent_lm_stick_increase_norm < Tolerance) tangent_lm_stick_increase_norm = 1.0;
326  if(tangent_lm_slip_increase_norm < Tolerance) tangent_lm_slip_increase_norm = 1.0;
327  KRATOS_ERROR_IF(mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ENSURE_CONTACT) && normal_lm_solution_norm < Tolerance) << "ERROR::CONTACT LOST::ARE YOU SURE YOU ARE SUPPOSED TO HAVE CONTACT?" << std::endl;
328 
329  mDispCurrentResidualNorm = disp_residual_solution_norm;
330  mRotCurrentResidualNorm = rot_residual_solution_norm;
331 
332  const double normal_lm_ratio = std::sqrt(normal_lm_increase_norm/normal_lm_solution_norm);
333  const double tangent_lm_slip_ratio = tangent_lm_slip_solution_norm > Tolerance ? std::sqrt(tangent_lm_slip_increase_norm/tangent_lm_slip_solution_norm) : 0.0;
334  const double tangent_lm_stick_ratio = tangent_lm_stick_solution_norm > Tolerance ? std::sqrt(tangent_lm_stick_increase_norm/tangent_lm_stick_solution_norm) : 0.0;
335 
336  const double normal_lm_abs = std::sqrt(normal_lm_increase_norm)/static_cast<double>(lm_dof_num);
337  const double tangent_lm_stick_abs = lm_stick_dof_num > 0 ? std::sqrt(tangent_lm_stick_increase_norm)/ static_cast<double>(lm_stick_dof_num) : 0.0;
338  const double tangent_lm_slip_abs = lm_slip_dof_num > 0 ? std::sqrt(tangent_lm_slip_increase_norm)/ static_cast<double>(lm_slip_dof_num) : 0.0;
339 
340  const double normal_tangent_stick_ratio = tangent_lm_stick_abs/normal_lm_abs;
341  const double normal_tangent_slip_ratio = tangent_lm_slip_abs/normal_lm_abs;
342 
343  double residual_disp_ratio, residual_rot_ratio;
344 
345  // We initialize the solution
346  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::INITIAL_RESIDUAL_IS_SET)) {
347  mDispInitialResidualNorm = (disp_residual_solution_norm < Tolerance) ? 1.0 : disp_residual_solution_norm;
348  residual_disp_ratio = 1.0;
349  if (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) {
350  mRotInitialResidualNorm = (rot_residual_solution_norm < Tolerance) ? 1.0 : rot_residual_solution_norm;
351  residual_rot_ratio = 1.0;
352  }
353  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::INITIAL_RESIDUAL_IS_SET, true);
354  }
355 
356  // We calculate the ratio of the displacements
357  residual_disp_ratio = mDispCurrentResidualNorm/mDispInitialResidualNorm;
358 
359  // We calculate the ratio of the rotations
360  residual_rot_ratio = mRotCurrentResidualNorm/mRotInitialResidualNorm;
361 
362  // We calculate the absolute norms
363  double residual_disp_abs = mDispCurrentResidualNorm/disp_dof_num;
364  double residual_rot_abs = mRotCurrentResidualNorm/rot_dof_num;
365 
366  // We print the results // TODO: Replace for the new log
367  if (rModelPart.GetCommunicator().MyPID() == 0 && this->GetEchoLevel() > 0) {
368  if (r_process_info.Has(TABLE_UTILITY)) {
369  std::cout.precision(4);
370  TablePrinterPointerType p_table = r_process_info[TABLE_UTILITY];
371  auto& r_table = p_table->GetTable();
372  if (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) {
373  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP)) {
374  r_table << residual_disp_ratio << mDispRatioTolerance << residual_disp_abs << mDispAbsTolerance << residual_rot_ratio << mRotRatioTolerance << residual_rot_abs << mRotAbsTolerance << normal_lm_ratio << mLMNormalRatioTolerance << normal_lm_abs << mLMNormalAbsTolerance << tangent_lm_stick_ratio << mLMTangentStickRatioTolerance << tangent_lm_stick_abs << mLMTangentSlipAbsTolerance << tangent_lm_slip_ratio << mLMTangentSlipRatioTolerance << tangent_lm_slip_abs << mLMTangentStickAbsTolerance;
375  } else {
376  r_table << residual_disp_ratio << mDispRatioTolerance << residual_disp_abs << mDispAbsTolerance << residual_rot_ratio << mRotRatioTolerance << residual_rot_abs << mRotAbsTolerance << normal_lm_ratio << mLMNormalRatioTolerance << normal_lm_abs << mLMNormalAbsTolerance << tangent_lm_slip_ratio << mLMTangentSlipRatioTolerance << tangent_lm_slip_abs << mLMTangentSlipAbsTolerance;
377  }
378  } else {
379  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP)) {
380  r_table << residual_disp_ratio << mDispRatioTolerance << residual_disp_abs << mDispAbsTolerance << normal_lm_ratio << mLMNormalRatioTolerance << normal_lm_abs << mLMNormalAbsTolerance << tangent_lm_stick_ratio << mLMTangentStickRatioTolerance << tangent_lm_stick_abs << mLMTangentSlipAbsTolerance << tangent_lm_slip_ratio << mLMTangentSlipRatioTolerance << tangent_lm_slip_abs << mLMTangentStickAbsTolerance;
381  } else {
382  r_table << residual_disp_ratio << mDispRatioTolerance << residual_disp_abs << mDispAbsTolerance << normal_lm_ratio << mLMNormalRatioTolerance << normal_lm_abs << mLMNormalAbsTolerance << tangent_lm_slip_ratio << mLMTangentSlipRatioTolerance << tangent_lm_slip_abs << mLMTangentSlipAbsTolerance;
383  }
384  }
385  } else {
386  std::cout.precision(4);
387  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT)) {
388  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("MIXED CONVERGENCE CHECK") << "\tSTEP: " << r_process_info[STEP] << "\tNL ITERATION: " << r_process_info[NL_ITERATION_NUMBER] << std::endl << std::scientific;
389  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("\tDISPLACEMENT: RATIO = ") << residual_disp_ratio << BOLDFONT(" EXP.RATIO = ") << mDispRatioTolerance << BOLDFONT(" ABS = ") << residual_disp_abs << BOLDFONT(" EXP.ABS = ") << mDispAbsTolerance << std::endl;
390  if (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) {
391  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("\tROTATION: RATIO = ") << residual_rot_ratio << BOLDFONT(" EXP.RATIO = ") << mRotRatioTolerance << BOLDFONT(" ABS = ") << residual_rot_abs << BOLDFONT(" EXP.ABS = ") << mRotAbsTolerance << std::endl;
392  }
393  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("\tNORMAL LAGRANGE MUL: RATIO = ") << normal_lm_ratio << BOLDFONT(" EXP.RATIO = ") << mLMNormalRatioTolerance << BOLDFONT(" ABS = ") << normal_lm_abs << BOLDFONT(" EXP.ABS = ") << mLMNormalAbsTolerance << std::endl;
394  KRATOS_INFO_IF("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria", mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP)) << BOLDFONT(" STICK LAGRANGE MUL:\tRATIO = ") << tangent_lm_stick_ratio << BOLDFONT(" EXP.RATIO = ") << mLMTangentStickRatioTolerance << BOLDFONT(" ABS = ") << tangent_lm_stick_abs << BOLDFONT(" EXP.ABS = ") << mLMTangentStickAbsTolerance << std::endl;
395  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT(" SLIP LAGRANGE MUL:\tRATIO = ") << tangent_lm_slip_ratio << BOLDFONT(" EXP.RATIO = ") << mLMTangentSlipRatioTolerance << BOLDFONT(" ABS = ") << tangent_lm_slip_abs << BOLDFONT(" EXP.ABS = ") << mLMTangentSlipAbsTolerance << std::endl;
396  } else {
397  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "MIXED CONVERGENCE CHECK" << "\tSTEP: " << r_process_info[STEP] << "\tNL ITERATION: " << r_process_info[NL_ITERATION_NUMBER] << std::endl << std::scientific;
398  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "\tDISPLACEMENT: RATIO = " << residual_disp_ratio << " EXP.RATIO = " << mDispRatioTolerance << " ABS = " << residual_disp_abs << " EXP.ABS = " << mDispAbsTolerance << std::endl;
399  if (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) {
400  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "\tROTATION: RATIO = " << residual_rot_ratio << " EXP.RATIO = " << mRotRatioTolerance << " ABS = " << residual_rot_abs << " EXP.ABS = " << mRotAbsTolerance << std::endl;
401  }
402  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "\tNORMAL LAGRANGE MUL: RATIO = " << normal_lm_ratio << " EXP.RATIO = " << mLMNormalRatioTolerance << " ABS = " << normal_lm_abs << " EXP.ABS = " << mLMNormalAbsTolerance << std::endl;
403  KRATOS_INFO_IF("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria", mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP)) << " STICK LAGRANGE MUL:\tRATIO = " << tangent_lm_stick_ratio << " EXP.RATIO = " << mLMTangentStickRatioTolerance << " ABS = " << tangent_lm_stick_abs << " EXP.ABS = " << mLMTangentStickAbsTolerance << std::endl;
404  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << " SLIP LAGRANGE MUL:\tRATIO = " << tangent_lm_slip_ratio << " EXP.RATIO = " << mLMTangentSlipRatioTolerance << " ABS = " << tangent_lm_slip_abs << " EXP.ABS = " << mLMTangentSlipAbsTolerance << std::endl;
405  }
406  }
407  }
408 
409  // NOTE: Here we don't include the tangent counter part
410  r_process_info[CONVERGENCE_RATIO] = (residual_disp_ratio > normal_lm_ratio) ? residual_disp_ratio : normal_lm_ratio;
411  r_process_info[RESIDUAL_NORM] = (normal_lm_abs > mLMNormalAbsTolerance) ? normal_lm_abs : mLMNormalAbsTolerance;
412 
413  // We check if converged
414  const bool disp_converged = (residual_disp_ratio <= mDispRatioTolerance || residual_disp_abs <= mDispAbsTolerance);
415  const bool rot_converged = (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) ? (residual_rot_ratio <= mRotRatioTolerance || residual_rot_abs <= mRotAbsTolerance) : true;
416  const bool lm_converged = (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ENSURE_CONTACT) && normal_lm_solution_norm < Tolerance) ? true : (normal_lm_ratio <= mLMNormalRatioTolerance || normal_lm_abs <= mLMNormalAbsTolerance) && (tangent_lm_stick_ratio <= mLMTangentStickRatioTolerance || tangent_lm_stick_abs <= mLMTangentStickAbsTolerance || normal_tangent_stick_ratio <= mNormalTangentRatio) && (tangent_lm_slip_ratio <= mLMTangentSlipRatioTolerance || tangent_lm_slip_abs <= mLMTangentSlipAbsTolerance || normal_tangent_slip_ratio <= mNormalTangentRatio);
417 
418  if ( disp_converged && rot_converged && lm_converged ) {
419  if (rModelPart.GetCommunicator().MyPID() == 0 && this->GetEchoLevel() > 0) {
420  if (r_process_info.Has(TABLE_UTILITY)) {
421  TablePrinterPointerType p_table = r_process_info[TABLE_UTILITY];
422  auto& r_table = p_table->GetTable();
423  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT))
424  r_table << BOLDFONT(FGRN(" Achieved"));
425  else
426  r_table << "Achieved";
427  } else {
428  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT))
429  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("\tConvergence") << " is " << BOLDFONT(FGRN("achieved")) << std::endl;
430  else
431  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "\tConvergence is achieved" << std::endl;
432  }
433  }
434  return true;
435  } else {
436  if (rModelPart.GetCommunicator().MyPID() == 0 && this->GetEchoLevel() > 0) {
437  if (r_process_info.Has(TABLE_UTILITY)) {
438  TablePrinterPointerType p_table = r_process_info[TABLE_UTILITY];
439  auto& r_table = p_table->GetTable();
440  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT))
441  r_table << BOLDFONT(FRED(" Not achieved"));
442  else
443  r_table << "Not achieved";
444  } else {
445  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT))
446  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << BOLDFONT("\tConvergence") << " is " << BOLDFONT(FRED(" not achieved")) << std::endl;
447  else
448  KRATOS_INFO("DisplacementLagrangeMultiplierMixedFrictionalContactCriteria") << "\tConvergence is not achieved" << std::endl;
449  }
450  }
451  return false;
452  }
453  } else // In this case all the displacements are imposed!
454  return true;
455  }
456 
461  void Initialize( ModelPart& rModelPart) override
462  {
463  // Initialize
464  BaseType::mConvergenceCriteriaIsInitialized = true;
465 
466  // Check rotation dof
467  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED, ContactUtilities::CheckModelPartHasRotationDoF(rModelPart));
468 
469  // Initialize header
470  ProcessInfo& r_process_info = rModelPart.GetProcessInfo();
471  if (r_process_info.Has(TABLE_UTILITY) && mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::TABLE_IS_INITIALIZED)) {
472  TablePrinterPointerType p_table = r_process_info[TABLE_UTILITY];
473  auto& r_table = p_table->GetTable();
474  r_table.AddColumn("DP RATIO", 10);
475  r_table.AddColumn("EXP. RAT", 10);
476  r_table.AddColumn("ABS", 10);
477  r_table.AddColumn("EXP. ABS", 10);
478  if (mOptions.Is(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED)) {
479  r_table.AddColumn("RT RATIO", 10);
480  r_table.AddColumn("EXP. RAT", 10);
481  r_table.AddColumn("ABS", 10);
482  r_table.AddColumn("EXP. ABS", 10);
483  }
484  r_table.AddColumn("N.LM RATIO", 10);
485  r_table.AddColumn("EXP. RAT", 10);
486  r_table.AddColumn("ABS", 10);
487  r_table.AddColumn("EXP. ABS", 10);
488  if (mOptions.IsNot(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP)) {
489  r_table.AddColumn("STI. RATIO", 10);
490  r_table.AddColumn("EXP. RAT", 10);
491  r_table.AddColumn("ABS", 10);
492  r_table.AddColumn("EXP. ABS", 10);
493  }
494  r_table.AddColumn("SLIP RATIO", 10);
495  r_table.AddColumn("EXP. RAT", 10);
496  r_table.AddColumn("ABS", 10);
497  r_table.AddColumn("EXP. ABS", 10);
498  r_table.AddColumn("CONVERGENCE", 15);
499  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::TABLE_IS_INITIALIZED, true);
500  }
501  }
502 
512  ModelPart& rModelPart,
513  DofsArrayType& rDofSet,
514  const TSystemMatrixType& rA,
515  const TSystemVectorType& rDx,
516  const TSystemVectorType& rb
517  ) override
518  {
519  // Initialize flags
520  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::INITIAL_RESIDUAL_IS_SET, false);
521 
522  // Filling mActiveDofs when MPC exist
523  ConstraintUtilities::ComputeActiveDofs(rModelPart, mActiveDofs, rDofSet);
524  }
525 
535  ModelPart& rModelPart,
536  DofsArrayType& rDofSet,
537  const TSystemMatrixType& rA,
538  const TSystemVectorType& rDx,
539  const TSystemVectorType& rb
540  ) override
541  {
542  // Calling base criteria
543  BaseType::FinalizeNonLinearIteration(rModelPart, rDofSet, rA, rDx, rb);
544 
545  // The current process info
546  ProcessInfo& r_process_info = rModelPart.GetProcessInfo();
547  r_process_info.SetValue(ACTIVE_SET_COMPUTED, false);
548  }
549 
555  {
556  Parameters default_parameters = Parameters(R"(
557  {
558  "name" : "displacement_lagrangemultiplier_mixed_frictional_contact_criteria",
559  "ensure_contact" : false,
560  "pure_slip" : false,
561  "print_convergence_criterion" : false,
562  "residual_relative_tolerance" : 1.0e-4,
563  "residual_absolute_tolerance" : 1.0e-9,
564  "rotation_residual_relative_tolerance" : 1.0e-4,
565  "rotation_residual_absolute_tolerance" : 1.0e-9,
566  "contact_displacement_relative_tolerance" : 1.0e-4,
567  "contact_displacement_absolute_tolerance" : 1.0e-9,
568  "frictional_stick_contact_displacement_relative_tolerance" : 1.0e-4,
569  "frictional_stick_contact_residual_relative_tolerance" : 1.0e-9,
570  "frictional_slip_contact_displacement_relative_tolerance" : 1.0e-4,
571  "frictional_slip_contact_residual_relative_tolerance" : 1.0e-9,
572  "ratio_normal_tangent_threshold" : 1.0e-4
573  })");
574 
575  // Getting base class default parameters
576  const Parameters base_default_parameters = BaseType::GetDefaultParameters();
577  default_parameters.RecursivelyAddMissingParameters(base_default_parameters);
578  return default_parameters;
579  }
580 
585  static std::string Name()
586  {
587  return "displacement_lagrangemultiplier_mixed_frictional_contact_criteria";
588  }
589 
593 
597 
601 
603  std::string Info() const override
604  {
605  return "DisplacementLagrangeMultiplierMixedFrictionalContactCriteria";
606  }
607 
609  void PrintInfo(std::ostream& rOStream) const override
610  {
611  rOStream << Info();
612  }
613 
615  void PrintData(std::ostream& rOStream) const override
616  {
617  rOStream << Info();
618  }
619 
621 protected:
624 
628 
632 
636 
641  void AssignSettings(const Parameters ThisParameters) override
642  {
643  BaseType::AssignSettings(ThisParameters);
644 
645  // The displacement residual
646  mDispRatioTolerance = ThisParameters["residual_relative_tolerance"].GetDouble();
647  mDispAbsTolerance = ThisParameters["residual_absolute_tolerance"].GetDouble();
648 
649  // The rotation residual
650  mRotRatioTolerance = ThisParameters["rotation_residual_relative_tolerance"].GetDouble();
651  mRotAbsTolerance = ThisParameters["rotation_residual_absolute_tolerance"].GetDouble();
652 
653  // The normal contact solution
654  mLMNormalRatioTolerance = ThisParameters["contact_displacement_relative_tolerance"].GetDouble();
655  mLMNormalAbsTolerance = ThisParameters["contact_displacement_absolute_tolerance"].GetDouble();
656 
657  // The tangent contact solution
658  mLMTangentStickRatioTolerance = ThisParameters["frictional_stick_contact_displacement_relative_tolerance"].GetDouble();
659  mLMTangentStickAbsTolerance = ThisParameters["frictional_stick_contact_residual_relative_tolerance"].GetDouble();
660  mLMTangentSlipRatioTolerance = ThisParameters["frictional_slip_contact_displacement_relative_tolerance"].GetDouble();
661  mLMTangentSlipAbsTolerance = ThisParameters["frictional_slip_contact_residual_relative_tolerance"].GetDouble();
662 
663  // We get the ratio between the normal and tangent that will accepted as converged
664  mNormalTangentRatio = ThisParameters["ratio_normal_tangent_threshold"].GetDouble();
665 
666  // Set local flags
667  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ENSURE_CONTACT, ThisParameters["ensure_contact"].GetBool());
668  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PRINTING_OUTPUT, ThisParameters["print_convergence_criterion"].GetBool());
669  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::TABLE_IS_INITIALIZED, false);
670  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::ROTATION_DOF_IS_CONSIDERED, false);
671  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::PURE_SLIP, ThisParameters["pure_slip"].GetBool());
672  mOptions.Set(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria::INITIAL_RESIDUAL_IS_SET, false);
673  }
674 
676 private:
679 
683 
684  Flags mOptions;
685 
686  double mDispRatioTolerance;
687  double mDispAbsTolerance;
688  double mDispInitialResidualNorm;
689  double mDispCurrentResidualNorm;
690 
691  double mRotRatioTolerance;
692  double mRotAbsTolerance;
693  double mRotInitialResidualNorm;
694  double mRotCurrentResidualNorm;
695 
696  double mLMNormalRatioTolerance;
697  double mLMNormalAbsTolerance;
698 
699  double mLMTangentStickRatioTolerance;
700  double mLMTangentStickAbsTolerance;
701 
702  double mLMTangentSlipRatioTolerance;
703  double mLMTangentSlipAbsTolerance;
704 
705  double mNormalTangentRatio;
706 
707  std::vector<int> mActiveDofs;
708 
710 }; // Kratos DisplacementLagrangeMultiplierMixedFrictionalContactCriteria
711 
714 
716 template<class TSparseSpace, class TDenseSpace>
717 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::ENSURE_CONTACT(Kratos::Flags::Create(0));
718 template<class TSparseSpace, class TDenseSpace>
719 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::PRINTING_OUTPUT(Kratos::Flags::Create(1));
720 template<class TSparseSpace, class TDenseSpace>
721 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::TABLE_IS_INITIALIZED(Kratos::Flags::Create(2));
722 template<class TSparseSpace, class TDenseSpace>
723 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::ROTATION_DOF_IS_CONSIDERED(Kratos::Flags::Create(3));
724 template<class TSparseSpace, class TDenseSpace>
725 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::PURE_SLIP(Kratos::Flags::Create(4));
726 template<class TSparseSpace, class TDenseSpace>
727 const Kratos::Flags DisplacementLagrangeMultiplierMixedFrictionalContactCriteria<TSparseSpace, TDenseSpace>::INITIAL_RESIDUAL_IS_SET(Kratos::Flags::Create(5));
728 }
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
virtual int MyPID() const
Definition: communicator.cpp:91
static bool CheckModelPartHasRotationDoF(ModelPart &rModelPart)
This method checks that the modelpart has a rotation DoF.
Definition: contact_utilities.cpp:147
This is the base class to define the different convergence criterion considered.
Definition: convergence_criteria.h:58
int GetEchoLevel()
This returns the level of echo for the solving strategy.
Definition: convergence_criteria.h:209
virtual Parameters ValidateAndAssignParameters(Parameters ThisParameters, const Parameters DefaultParameters) const
This method validate and assign default parameters.
Definition: convergence_criteria.h:466
TSparseSpace::MatrixType TSystemMatrixType
Matrix type definition.
Definition: convergence_criteria.h:72
ModelPart::DofsArrayType DofsArrayType
DoF array type definition.
Definition: convergence_criteria.h:81
TSparseSpace::VectorType TSystemVectorType
Vector type definition.
Definition: convergence_criteria.h:74
bool Has(const Variable< TDataType > &rThisVariable) const
Checks if the data container has a value associated with a given variable.
Definition: data_value_container.h:382
void SetValue(const Variable< TDataType > &rThisVariable, TDataType const &rValue)
Sets the value for a given variable.
Definition: data_value_container.h:320
Convergence criteria for contact problems.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:63
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
EquationIdType EquationId() const
Definition: dof.h:324
Definition: flags.h:58
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
bool Is(Flags const &rOther) const
Definition: flags.h:274
static Flags Create(IndexType ThisPosition, bool Value=true)
Definition: flags.h:138
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
Communicator & GetCommunicator()
Definition: model_part.h:1821
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
void RecursivelyAddMissingParameters(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing contain at least all parameters...
Definition: kratos_parameters.cpp:1457
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
utility function to do a sum reduction
Definition: reduction_utilities.h:68
static IndexType Size(VectorType const &rV)
return size of vector rV
Definition: ublas_space.h:190
This class is the base of variables and variable's components which contains their common data.
Definition: variable_data.h:49
#define FGRN(x)
Definition: color_utilities.h:27
#define FRED(x)
Definition: color_utilities.h:26
#define BOLDFONT(x)
Definition: color_utilities.h:34
DisplacementLagrangeMultiplierMixedFrictionalContactCriteria(Kratos::Parameters ThisParameters)
Default constructor. (with parameters)
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:123
TSparseSpace SparseSpaceType
The sparse space used.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:96
static constexpr double Tolerance
The epsilon tolerance definition.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:105
BaseType::Pointer Create(Parameters ThisParameters) const override
Create method.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:229
static std::string Name()
Returns the name of the class as used in the settings (snake_case format)
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:585
DisplacementLagrangeMultiplierMixedFrictionalContactCriteria(const double DispRatioTolerance, const double DispAbsTolerance, const double RotRatioTolerance, const double RotAbsTolerance, const double LMNormalRatioTolerance, const double LMNormalAbsTolerance, const double LMTangentStickRatioTolerance, const double LMTangentStickAbsTolerance, const double LMTangentSlipRatioTolerance, const double LMTangentSlipAbsTolerance, const double NormalTangentRatio, const bool EnsureContact=false, const bool PureSlip=false, const bool PrintingOutput=false)
Default constructor.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:144
DisplacementLagrangeMultiplierMixedFrictionalContactCriteria()
Default constructor.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:114
void Initialize(ModelPart &rModelPart) override
This function initialize the convergence criteria.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:461
typename BaseType::TSystemMatrixType TSystemMatrixType
The sparse matrix type.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:90
bool PostCriteria(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &rA, const TSystemVectorType &rDx, const TSystemVectorType &rb) override
Compute relative and absolute error.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:243
void InitializeSolutionStep(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &rA, const TSystemVectorType &rDx, const TSystemVectorType &rb) override
This function initializes the solution step.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:511
std::string Info() const override
Turn back information as a string.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:603
void FinalizeNonLinearIteration(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &rA, const TSystemVectorType &rDx, const TSystemVectorType &rb) override
This function finalizes the non-linear iteration.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:534
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:615
TableStreamUtility::Pointer TablePrinterPointerType
The table stream definition TODO: Replace by logger.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:99
typename BaseType::TSystemVectorType TSystemVectorType
The dense vector type.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:93
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:609
Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:554
KRATOS_CLASS_POINTER_DEFINITION(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria)
Pointer definition of DisplacementLagrangeMultiplierMixedFrictionalContactCriteria.
std::size_t IndexType
The index type definition.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:102
DisplacementLagrangeMultiplierMixedFrictionalContactCriteria(DisplacementLagrangeMultiplierMixedFrictionalContactCriteria const &rOther)
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:193
~DisplacementLagrangeMultiplierMixedFrictionalContactCriteria() override=default
Destructor.
void AssignSettings(const Parameters ThisParameters) override
This method assigns settings to member variables.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:641
typename BaseType::DofsArrayType DofsArrayType
The dofs array type.
Definition: displacement_lagrangemultiplier_mixed_frictional_contact_criteria.h:87
#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
void ComputeActiveDofs(ModelPart &rModelPart, std::vector< int > &rActiveDofs, const ModelPart::DofsArrayType &rDofSet)
This method computes the active dofs.
Definition: constraint_utilities.cpp:26
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
REACTION_CHECK_STIFFNESS_FACTOR INNER_LOOP_ITERATION DISTANCE_THRESHOLD ACTIVE_CHECK_FACTOR AUXILIAR_COORDINATES NORMAL_GAP WEIGHTED_GAP WEIGHTED_SCALAR_RESIDUAL bool
Definition: contact_structural_mechanics_application_variables.h:93
Definition: reduction_utilities.h:310