53 template<
class TSparseSpace,
class TDenseSpace>
135 return Kratos::make_shared<ClassType>(ThisParameters);
165 rNode.
SetValue(CONTACT_FORCE, zero_array);
170 ComputeWeightedGap(rModelPart);
200 if (r_process_info[NL_ITERATION_NUMBER] > 0) {
202 const double reaction_check_stiffness_factor = r_process_info.
Has(REACTION_CHECK_STIFFNESS_FACTOR) ? r_process_info.
GetValue(REACTION_CHECK_STIFFNESS_FACTOR) : 1.0e-12;
205 ComputeWeightedGap(rModelPart);
208 std::size_t sub_contact_counter = 0;
209 CounterContactModelParts(rModelPart, sub_contact_counter);
212 Parameters mapping_parameters =
Parameters(R
"({"distance_threshold" : 1.0e24, "update_interface" : false, "origin_variable" : "REACTION", "mapping_coefficient" : -1.0e0})" );
213 if (r_process_info.
Has(DISTANCE_THRESHOLD)) {
214 mapping_parameters[
"distance_threshold"].
SetDouble(r_process_info[DISTANCE_THRESHOLD]);
217 for (std::size_t i_contact = 0; i_contact < sub_contact_counter; ++i_contact) {
218 auto& r_sub = r_contact_model_part.
GetSubModelPart(
"ContactSub" + std::to_string(i_contact));
219 auto& r_sub_master = r_sub.
GetSubModelPart(
"MasterSubModelPart" + std::to_string(i_contact));
220 auto& r_sub_slave = r_sub.
GetSubModelPart(
"SlaveSubModelPart" + std::to_string(i_contact));
227 Properties::Pointer p_properties = rModelPart.
Elements().begin()->pGetProperties();
228 for (
auto& r_elements : rModelPart.
Elements()) {
229 if (r_elements.pGetProperties()->Has(YOUNG_MODULUS)) {
230 p_properties = r_elements.pGetProperties();
235 IndexType is_active_set_converged = 0, is_slip_converged = 0;
239 const double young_modulus = p_properties->Has(YOUNG_MODULUS) ? p_properties->GetValue(YOUNG_MODULUS) : 0.0;
240 const double auxiliary_check = young_modulus > 0.0 ? -(reaction_check_stiffness_factor * young_modulus) : 0.0;
243 auto& r_nodes_array = r_contact_model_part.Nodes();
246 if (rModelPart.
IsNot(SLIP)) {
247 is_active_set_converged = block_for_each<SumReduction<IndexType>>(r_nodes_array, [&](
Node& rNode) {
248 if (rNode.Is(SLAVE)) {
252 const double nodal_area = rNode.Has(NODAL_AREA) ? rNode.GetValue(NODAL_AREA) : 1.0;
253 const double gap = rNode.FastGetSolutionStepValue(WEIGHTED_GAP)/nodal_area;
255 const double contact_force =
inner_prod(r_total_force, r_normal);
256 const double contact_pressure = contact_force/rNode.GetValue(NODAL_MAUX);
258 if (contact_pressure < auxiliary_check || gap < 0.0) {
260 rNode.SetValue(CONTACT_FORCE, contact_force/rNode.GetValue(NODAL_PAUX) * r_normal);
261 rNode.SetValue(NORMAL_CONTACT_STRESS, contact_pressure);
262 if (rNode.IsNot(ACTIVE)) {
263 rNode.Set(ACTIVE,
true);
267 if (rNode.Is(ACTIVE)) {
268 rNode.Set(ACTIVE,
false);
277 std::tie(is_active_set_converged, is_slip_converged) = block_for_each<TwoReduction>(r_nodes_array, [&](
Node& rNode) {
278 if (rNode.
Is(SLAVE)) {
279 const double auxiliary_check = young_modulus > 0.0 ? -(reaction_check_stiffness_factor * young_modulus) : 0.0;
281 const array_1d<double, 3>& r_total_force = rNode.FastGetSolutionStepValue(REACTION);
283 const double nodal_area = rNode.Has(NODAL_AREA) ? rNode.GetValue(NODAL_AREA) : 1.0;
284 const double gap = rNode.FastGetSolutionStepValue(WEIGHTED_GAP)/nodal_area;
285 const array_1d<double, 3>& r_normal = rNode.FastGetSolutionStepValue(NORMAL);
286 const double contact_force = inner_prod(r_total_force, r_normal);
287 const double normal_contact_pressure = contact_force/rNode.GetValue(NODAL_MAUX);
289 if (normal_contact_pressure < auxiliary_check || gap < 0.0) {
291 rNode.SetValue(CONTACT_FORCE, r_total_force/rNode.GetValue(NODAL_PAUX));
292 rNode.SetValue(NORMAL_CONTACT_STRESS, normal_contact_pressure);
293 if (rNode.IsNot(ACTIVE)) {
294 rNode.Set(ACTIVE, true);
295 return std::make_tuple(1,0);
299 const double tangential_contact_pressure = norm_2(r_total_force - contact_force * r_normal)/rNode.GetValue(NODAL_MAUX);
300 const bool is_slip = rNode.Is(SLIP);
301 const double mu = rNode.GetValue(FRICTION_COEFFICIENT);
303 if (tangential_contact_pressure <= - mu * contact_force) {
304 rNode.SetValue(TANGENTIAL_CONTACT_STRESS, tangential_contact_pressure);
306 rNode.Set(SLIP, false);
307 return std::make_tuple(0,1);
310 rNode.SetValue(TANGENTIAL_CONTACT_STRESS, - mu * contact_force);
312 rNode.Set(SLIP, true);
313 return std::make_tuple(0,1);
317 if (rNode.Is(ACTIVE)) {
318 rNode.Set(ACTIVE, false);
320 return std::make_tuple(1,0);
324 return std::make_tuple(0,0);
329 auto& r_conditions_array = rModelPart.GetSubModelPart(
"ComputingContact").Conditions();
333 for (
auto& r_node : r_slave_geometry) {
334 if (r_node.IsNot(ACTIVE)) {
340 if (
counter == r_slave_geometry.size()) {
341 rCond.Set(ACTIVE, false);
343 if (rCond.Has(CONSTRAINT_POINTER)) {
344 auto p_const = rCond.GetValue(CONSTRAINT_POINTER);
347 p_const->Set(ACTIVE, false);
349 KRATOS_ERROR <<
"Contact conditions must have defined CONSTRAINT_POINTER" << std::endl;
355 const bool active_set_converged = (is_active_set_converged == 0 ? true :
false);
356 const bool slip_set_converged = (is_slip_converged == 0 ? true :
false);
358 if (rModelPart.GetCommunicator().MyPID() == 0 && this->GetEchoLevel() > 0) {
359 if (active_set_converged) {
364 if (slip_set_converged) {
371 return (active_set_converged && slip_set_converged);
383 BaseType::Initialize(rModelPart);
394 "name" : "mpc_contact_criteria"
398 const Parameters base_default_parameters = BaseType::GetDefaultParameters();
400 return default_parameters;
409 return "mpc_contact_criteria";
425 std::string
Info()
const override
427 return "MPCContactCriteria";
465 BaseType::AssignSettings(ThisParameters);
489 void ComputeWeightedGap(
ModelPart& rModelPart)
493 if (rModelPart.
Is(SLIP)) {
498 VariableUtils().SetHistoricalVariableToZero(WEIGHTED_GAP, r_nodes_array);
502 ContactUtilities::ComputeExplicitContributionConditions(rModelPart.
GetSubModelPart(
"ComputingContact"));
510 void CounterContactModelParts(
512 std::size_t& rCounter
515 for (
auto& r_name : rModelPart.GetSubModelPartNames()) {
516 if (r_name.find(
"ContactSub") != std::string::npos && r_name.find(
"ComputingContactSub") == std::string::npos) {
519 auto& r_sub = rModelPart.GetSubModelPart(r_name);
520 if (r_sub.IsSubModelPart()) {
521 CounterContactModelParts(r_sub, rCounter);
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
Base class for all Conditions.
Definition: condition.h:59
This is the base class to define the different convergence criterion considered.
Definition: convergence_criteria.h:58
virtual bool PostCriteria(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &rA, const TSystemVectorType &rDx, const TSystemVectorType &rb)
Criterias that need to be called after getting the solution.
Definition: convergence_criteria.h:261
virtual Parameters ValidateAndAssignParameters(Parameters ThisParameters, const Parameters DefaultParameters) const
This method validate and assign default parameters.
Definition: convergence_criteria.h:466
virtual bool PreCriteria(ModelPart &rModelPart, DofsArrayType &rDofSet, const TSystemMatrixType &rA, const TSystemVectorType &rDx, const TSystemVectorType &rb)
Criterias that need to be called before getting the solution.
Definition: convergence_criteria.h:241
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
The CouplingGeometry connects two or more geometries of different types and entities.
Definition: coupling_geometry.h:41
static constexpr IndexType Master
Definition: coupling_geometry.h:72
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
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
bool Is(Flags const &rOther) const
Definition: flags.h:274
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
ModelPart & GetSubModelPart(std::string const &SubModelPartName)
Definition: model_part.cpp:2029
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
TVariableType::Type & FastGetSolutionStepValue(const TVariableType &rThisVariable)
Definition: node.h:435
void SetValue(const TVariableType &rThisVariable, typename TVariableType::Type const &rValue)
Definition: node.h:493
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
void SetDouble(const double Value)
This method sets the double contained in the current Parameter.
Definition: kratos_parameters.cpp:787
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
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
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
This class wraps automatically the different types mof mappers.
Definition: simple_mortar_mapper_wrapper_process.h:54
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: simple_mortar_mapper_wrapper_process.h:224
utility function to do a sum reduction
Definition: reduction_utilities.h:68
This class implements a set of auxiliar, already parallelized, methods to perform some common tasks r...
Definition: variable_utils.h:63
void SetHistoricalVariableToZero(const Variable< TType > &rVariable, NodesContainerType &rNodes)
Sets the nodal value of any variable to zero.
Definition: variable_utils.h:757
void SetNonHistoricalVariableToZero(const Variable< TType > &rVariable, TContainerType &rContainer)
Sets the nodal value of any variable to zero.
Definition: variable_utils.h:724
#define FGRN(x)
Definition: color_utilities.h:27
#define FRED(x)
Definition: color_utilities.h:26
#define BOLDFONT(x)
Definition: color_utilities.h:34
#define KRATOS_INFO(label)
Definition: logger.h:250
Kratos::ModelPart ModelPart
Definition: kratos_wrapper.h:31
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
void block_for_each(TIterator itBegin, TIterator itEnd, TFunction &&rFunction)
Execute a functor on all items of a range in parallel.
Definition: parallel_utilities.h:299
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
int counter
Definition: script_THERMAL_CORRECT.py:218
Definition: reduction_utilities.h:310