From 72007d1a14feffae569db64f59aa71f1b120b3d2 Mon Sep 17 00:00:00 2001 From: matekelemen Date: Sun, 26 Nov 2023 17:56:33 +0100 Subject: [PATCH] import master-slave constraint insertion --- kratos/includes/mesh.h | 22 +++-- kratos/sources/model_part.cpp | 150 +++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 71 deletions(-) diff --git a/kratos/includes/mesh.h b/kratos/includes/mesh.h index 44defa7fc017..29d0293ae297 100644 --- a/kratos/includes/mesh.h +++ b/kratos/includes/mesh.h @@ -728,11 +728,23 @@ class Mesh : public DataValueContainer, public Flags return mpMasterSlaveConstraints->size(); } - /** Inserts a master-slave constraint in the mesh. - */ - void AddMasterSlaveConstraint(typename MasterSlaveConstraintType::Pointer pNewMasterSlaveConstraint) - { - mpMasterSlaveConstraints->insert(mpMasterSlaveConstraints->begin(), pNewMasterSlaveConstraint); + /// @brief Insert a @ref MasterSlaveConstraint. + /// @returns @a false if a constraint with identical ID already exists + /// in the mesh and the insertion did not take place, @a true + /// otherwise. + bool AddMasterSlaveConstraint(typename MasterSlaveConstraintType::Pointer pNewMasterSlaveConstraint) + { + const auto it_existing_constraint = mpMasterSlaveConstraints->find(pNewMasterSlaveConstraint->Id()); + if (it_existing_constraint == mpMasterSlaveConstraints->end()) { + // PointerVectorSet::insert takes a position argument to insert the + // item at but ignores it, which makes it completely irrelevant to + // properly compute (an estimate) of the new constraint's position + // in the container => pass begin as position. + const auto it_insert_position = mpMasterSlaveConstraints->begin(); + mpMasterSlaveConstraints->insert(it_insert_position, pNewMasterSlaveConstraint); + return true; + } + return false; } /** Returns the MasterSlaveConstraint::Pointer corresponding to it's identifier */ diff --git a/kratos/sources/model_part.cpp b/kratos/sources/model_part.cpp index 2ee64c7ec1b4..b068ff42cd0c 100644 --- a/kratos/sources/model_part.cpp +++ b/kratos/sources/model_part.cpp @@ -1229,45 +1229,53 @@ void ModelPart::AddMasterSlaveConstraints(std::vector const& MasterSl KRATOS_CATCH(""); } -/** Inserts an master-slave constraint in the current mesh. - */ +/// @brief Construct a new @ref MasterSlaveConstraint and insert it into the specified @ref Mesh. +/// @note The constraint is created by the root @ref ModelPart and inserted into the root mesh as well. +/// @throws if a constraint with the same ID already exists in the target mesh. ModelPart::MasterSlaveConstraintType::Pointer ModelPart::CreateNewMasterSlaveConstraint(const std::string& ConstraintName, - IndexType Id, - ModelPart::DofsVectorType& rMasterDofsVector, - ModelPart::DofsVectorType& rSlaveDofsVector, - const ModelPart::MatrixType& RelationMatrix, - const ModelPart::VectorType& ConstantVector, - IndexType ThisIndex) + IndexType Id, + ModelPart::DofsVectorType& rMasterDofsVector, + ModelPart::DofsVectorType& rSlaveDofsVector, + const ModelPart::MatrixType& RelationMatrix, + const ModelPart::VectorType& ConstantVector, + IndexType ThisIndex) { KRATOS_TRY - if (IsSubModelPart()) - { - ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint = mpParentModelPart->CreateNewMasterSlaveConstraint(ConstraintName, Id, rMasterDofsVector, - rSlaveDofsVector, - RelationMatrix, - ConstantVector, - ThisIndex); - GetMesh(ThisIndex).AddMasterSlaveConstraint(p_new_constraint); - GetMesh(ThisIndex).MasterSlaveConstraints().Unique(); - - return p_new_constraint; - } + MeshType& r_mesh = GetMesh(ThisIndex); + ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint; - auto existing_constraint_iterator = GetMesh(ThisIndex).MasterSlaveConstraints().find(Id); - KRATOS_ERROR_IF(existing_constraint_iterator != GetMesh(ThisIndex).MasterSlaveConstraintsEnd() ) - << "trying to construct an master-slave constraint with ID " << Id << " however a constraint with the same Id already exists"; - - - //create the new element - ModelPart::MasterSlaveConstraintType const& r_clone_constraint = KratosComponents::Get(ConstraintName); - ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint = r_clone_constraint.Create(Id, rMasterDofsVector, - rSlaveDofsVector, - RelationMatrix, - ConstantVector); + if (IsSubModelPart()) { + // Defer constraint construction to the root model part + p_new_constraint = mpParentModelPart->CreateNewMasterSlaveConstraint( + ConstraintName, + Id, + rMasterDofsVector, + rSlaveDofsVector, + RelationMatrix, + ConstantVector, + ThisIndex); + + // Add the constraint + if (&r_mesh != &mpParentModelPart->GetMesh(ThisIndex)) { + KRATOS_ERROR_IF_NOT(r_mesh.AddMasterSlaveConstraint(p_new_constraint)) + << "trying to insert a master-slave constraint with ID " + << Id << " but a constraint with the same ID already exists\n"; + } + } else /*IsSubModelPart*/ { + // Construct the new constraint + ModelPart::MasterSlaveConstraintType const& r_registered_constraint = KratosComponents::Get(ConstraintName); + p_new_constraint = r_registered_constraint.Create( + Id, + rMasterDofsVector, + rSlaveDofsVector, + RelationMatrix, + ConstantVector); - GetMesh(ThisIndex).AddMasterSlaveConstraint(p_new_constraint); - GetMesh(ThisIndex).MasterSlaveConstraints().Unique(); + KRATOS_ERROR_IF_NOT(r_mesh.AddMasterSlaveConstraint(p_new_constraint)) + << "trying to insert a master-slave constraint with ID " + << Id << " but a constraint with the same ID already exists\n"; + } return p_new_constraint; KRATOS_CATCH("") @@ -1284,46 +1292,56 @@ ModelPart::MasterSlaveConstraintType::Pointer ModelPart::CreateNewMasterSlaveCon const double Constant, IndexType ThisIndex) { + KRATOS_ERROR_IF_NOT(rMasterNode.HasDofFor(rMasterVariable)) + << "master node " << rMasterNode.Id() << " has no variable " << rMasterVariable.Name() << "\n"; - KRATOS_TRY - if (rMasterNode.HasDofFor(rMasterVariable) && rSlaveNode.HasDofFor(rSlaveVariable) ) - { - if (IsSubModelPart()) - { - ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint = mpParentModelPart->CreateNewMasterSlaveConstraint(ConstraintName, Id, rMasterNode, - rMasterVariable, - rSlaveNode, - rSlaveVariable, - Weight, - Constant, - ThisIndex); - - GetMesh(ThisIndex).AddMasterSlaveConstraint(p_new_constraint); - GetMesh(ThisIndex).MasterSlaveConstraints().Unique(); - return p_new_constraint; - } + KRATOS_ERROR_IF_NOT(rSlaveNode.HasDofFor(rSlaveVariable)) + << "slave node " << rSlaveNode.Id() << " has no variable " << rSlaveVariable.Name() << "\n"; - KRATOS_ERROR_IF(GetMesh(ThisIndex).HasMasterSlaveConstraint(Id)) - << "trying to construct an master-slave constraint with ID " << Id << " however a constraint with the same Id already exists"; + KRATOS_TRY + ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint; + MeshType& r_mesh = this->GetMesh(ThisIndex); - //create the new element + if (IsSubModelPart()) { + // Defer constraint construction to the root model part + p_new_constraint = mpParentModelPart->CreateNewMasterSlaveConstraint( + ConstraintName, + Id, + rMasterNode, + rMasterVariable, + rSlaveNode, + rSlaveVariable, + Weight, + Constant, + ThisIndex); + + // Insert the constraint + if (&r_mesh != &mpParentModelPart->GetMesh(ThisIndex)) { + KRATOS_ERROR_IF_NOT(r_mesh.AddMasterSlaveConstraint(p_new_constraint)) + << "trying to insert a master-slave constraint with ID " + << Id << " but a constraint with the same ID already exists\n"; + } + } else { /*IsSubModelPart*/ + // Construct the new constraint ModelPart::MasterSlaveConstraintType const& r_clone_constraint = KratosComponents::Get(ConstraintName); - ModelPart::MasterSlaveConstraintType::Pointer p_new_constraint = r_clone_constraint.Create(Id, rMasterNode, - rMasterVariable, - rSlaveNode, - rSlaveVariable, - Weight, - Constant); - - GetMesh(ThisIndex).AddMasterSlaveConstraint(p_new_constraint); - GetMesh(ThisIndex).MasterSlaveConstraints().Unique(); - return p_new_constraint; - } else - { - KRATOS_ERROR << "Master or Slave node does not have requested DOF " <