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 76 : ContactSplit::validParams() 19 : { 20 76 : InputParameters params = Split::validParams(); 21 152 : params.addParam<std::vector<BoundaryName>>("contact_primary", 22 : "Primary surface list for included contacts"); 23 152 : params.addParam<std::vector<BoundaryName>>("contact_secondary", 24 : "Secondary surface list for included contacts"); 25 152 : params.addParam<std::vector<int>>( 26 : "contact_displaced", 27 : {}, 28 : "List of indicators whether displaced mesh is used to define included contact"); 29 152 : params.addParam<std::vector<BoundaryName>>("uncontact_primary", 30 : "Primary surface list for excluded contacts"); 31 152 : params.addParam<std::vector<BoundaryName>>("uncontact_secondary", 32 : "Secondary surface list for excluded contacts"); 33 152 : params.addParam<std::vector<int>>( 34 : "uncontact_displaced", 35 : {}, 36 : "List of indicators whether displaced mesh is used to define excluded contact"); 37 152 : params.addRequiredParam<bool>("include_all_contact_nodes", 38 : "Whether to include all nodes on the contact surfaces"); 39 76 : 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 76 : return params; 43 0 : } 44 : 45 38 : ContactSplit::ContactSplit(const InputParameters & params) 46 : : Split(params), 47 76 : _contact_pairs(getParam<BoundaryName, BoundaryName>("contact_primary", "contact_secondary")), 48 76 : _contact_displaced(getParam<std::vector<int>>("contact_displaced")), 49 76 : _uncontact_pairs( 50 : getParam<BoundaryName, BoundaryName>("uncontact_primary", "uncontact_secondary")), 51 76 : _uncontact_displaced(getParam<std::vector<int>>("uncontact_displaced")), 52 114 : _include_all_contact_nodes(getParam<bool>("include_all_contact_nodes")) 53 : { 54 38 : 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 38 : if (_contact_displaced.empty()) 61 19 : _contact_displaced.resize(_contact_pairs.size()); 62 : 63 38 : 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 38 : if (!_uncontact_displaced.size()) 70 19 : _uncontact_displaced.resize(_uncontact_pairs.size()); 71 38 : } 72 : 73 : void 74 38 : ContactSplit::setup(NonlinearSystemBase & nl, const std::string & prefix) 75 : { 76 : // A reference to the PetscOptions 77 38 : Moose::PetscSupport::PetscOptions & po = _fe_problem.getPetscOptions(); 78 : // prefix 79 76 : const std::string dmprefix = '-' + prefix + "dm_moose_"; 80 : 81 : // contacts options 82 38 : if (!_contact_pairs.empty()) 83 : { 84 : // append PETSc options 85 38 : po.pairs.emplace_back(dmprefix + "ncontacts", Moose::stringify(_contact_pairs.size())); 86 : 87 38 : for (std::size_t j = 0; j < _contact_pairs.size(); ++j) 88 : { 89 38 : auto opt = dmprefix + "contact_" + Moose::stringify(j); 90 38 : po.pairs.emplace_back(opt, Moose::stringify(_contact_pairs[j], ",")); 91 : 92 19 : if (_contact_displaced[j]) 93 38 : po.pairs.emplace_back(opt + "_displaced", "yes"); 94 : } 95 : } 96 : 97 : // uncontacts options 98 38 : if (!_uncontact_pairs.empty()) 99 : { 100 38 : po.pairs.emplace_back(dmprefix + "nuncontacts", Moose::stringify(_uncontact_pairs.size())); 101 : 102 38 : for (std::size_t j = 0; j < _uncontact_pairs.size(); ++j) 103 : { 104 38 : auto opt = dmprefix + "uncontact_" + Moose::stringify(j); 105 38 : po.pairs.emplace_back(opt, Moose::stringify(_uncontact_pairs[j], ",")); 106 : 107 19 : if (_uncontact_displaced[j]) 108 38 : 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 38 : po.pairs.emplace_back(dmprefix + "includeAllContactNodes", 115 38 : _include_all_contact_nodes ? "yes" : "no"); 116 38 : Split::setup(nl, prefix); 117 38 : }