Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "ContactSplit.h" 11 : #include "InputParameters.h" 12 : #include "FEProblem.h" 13 : #include "Conversion.h" 14 : 15 : registerMooseObject("ContactApp", ContactSplit); 16 : 17 : InputParameters 18 72 : ContactSplit::validParams() 19 : { 20 72 : InputParameters params = Split::validParams(); 21 144 : params.addParam<std::vector<BoundaryName>>("contact_primary", 22 : "Primary surface list for included contacts"); 23 144 : params.addParam<std::vector<BoundaryName>>("contact_secondary", 24 : "Secondary surface list for included contacts"); 25 144 : params.addParam<std::vector<int>>( 26 : "contact_displaced", 27 : {}, 28 : "List of indicators whether displaced mesh is used to define included contact"); 29 144 : params.addParam<std::vector<BoundaryName>>("uncontact_primary", 30 : "Primary surface list for excluded contacts"); 31 144 : params.addParam<std::vector<BoundaryName>>("uncontact_secondary", 32 : "Secondary surface list for excluded contacts"); 33 144 : params.addParam<std::vector<int>>( 34 : "uncontact_displaced", 35 : {}, 36 : "List of indicators whether displaced mesh is used to define excluded contact"); 37 144 : params.addRequiredParam<bool>("include_all_contact_nodes", 38 : "Whether to include all nodes on the contact surfaces"); 39 72 : params.addClassDescription("Split-based preconditioner that partitions the domain into DOFs " 40 : "directly involved in contact (on contact surfaces) and those " 41 : "that are not"); 42 72 : return params; 43 0 : } 44 : 45 36 : ContactSplit::ContactSplit(const InputParameters & params) 46 : : Split(params), 47 72 : _contact_pairs(getParam<BoundaryName, BoundaryName>("contact_primary", "contact_secondary")), 48 72 : _contact_displaced(getParam<std::vector<int>>("contact_displaced")), 49 72 : _uncontact_pairs( 50 : getParam<BoundaryName, BoundaryName>("uncontact_primary", "uncontact_secondary")), 51 72 : _uncontact_displaced(getParam<std::vector<int>>("uncontact_displaced")), 52 108 : _include_all_contact_nodes(getParam<bool>("include_all_contact_nodes")) 53 : { 54 36 : if (!_contact_displaced.empty() && _contact_pairs.size() != _contact_displaced.size()) 55 0 : mooseError("Primary and displaced contact lists must have matching sizes: ", 56 0 : _contact_pairs.size(), 57 : " != ", 58 0 : _contact_displaced.size()); 59 : 60 36 : if (_contact_displaced.empty()) 61 18 : _contact_displaced.resize(_contact_pairs.size()); 62 : 63 36 : if (!_uncontact_displaced.empty() && _uncontact_pairs.size() != _uncontact_displaced.size()) 64 0 : mooseError("Primary and displaced uncontact lists must have matching sizes: ", 65 0 : _uncontact_pairs.size(), 66 : " != ", 67 0 : _uncontact_displaced.size()); 68 : 69 36 : if (!_uncontact_displaced.size()) 70 18 : _uncontact_displaced.resize(_uncontact_pairs.size()); 71 36 : } 72 : 73 : void 74 36 : ContactSplit::setup(NonlinearSystemBase & nl, const std::string & prefix) 75 : { 76 : // A reference to the PetscOptions 77 36 : Moose::PetscSupport::PetscOptions & po = _fe_problem.getPetscOptions(); 78 : // prefix 79 36 : const std::string dmprefix = prefix + "dm_moose_"; 80 : 81 : // contacts options 82 36 : if (!_contact_pairs.empty()) 83 : { 84 : // append PETSc options 85 36 : po.pairs.emplace_back(dmprefix + "ncontacts", Moose::stringify(_contact_pairs.size())); 86 : 87 36 : for (std::size_t j = 0; j < _contact_pairs.size(); ++j) 88 : { 89 36 : auto opt = dmprefix + "contact_" + Moose::stringify(j); 90 36 : po.pairs.emplace_back(opt, Moose::stringify(_contact_pairs[j], ",")); 91 : 92 18 : if (_contact_displaced[j]) 93 36 : po.pairs.emplace_back(opt + "_displaced", "yes"); 94 : } 95 : } 96 : 97 : // uncontacts options 98 36 : if (!_uncontact_pairs.empty()) 99 : { 100 36 : po.pairs.emplace_back(dmprefix + "nuncontacts", Moose::stringify(_uncontact_pairs.size())); 101 : 102 36 : for (std::size_t j = 0; j < _uncontact_pairs.size(); ++j) 103 : { 104 36 : auto opt = dmprefix + "uncontact_" + Moose::stringify(j); 105 36 : po.pairs.emplace_back(opt, Moose::stringify(_uncontact_pairs[j], ",")); 106 : 107 18 : if (_uncontact_displaced[j]) 108 36 : po.pairs.emplace_back(opt + "_displaced", "yes"); 109 : } 110 : } 111 : 112 : // Whether to include all nodes on the contact surfaces 113 : // into the contact subsolver 114 36 : po.pairs.emplace_back(dmprefix + "includeAllContactNodes", 115 36 : _include_all_contact_nodes ? "yes" : "no"); 116 36 : Split::setup(nl, prefix); 117 36 : }