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 "ComputeNodalUserObjectsThread.h" 11 : 12 : // MOOSE includes 13 : #include "FEProblem.h" 14 : #include "MooseMesh.h" 15 : #include "NodalUserObject.h" 16 : #include "AuxiliarySystem.h" 17 : 18 : #include "libmesh/threads.h" 19 : 20 : Threads::spin_mutex ComputeNodalUserObjectsThread::writable_variable_mutex; 21 : 22 16407 : ComputeNodalUserObjectsThread::ComputeNodalUserObjectsThread(FEProblemBase & fe_problem, 23 16407 : const TheWarehouse::Query & query) 24 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(fe_problem), 25 16407 : _query(query), 26 16407 : _aux_sys(fe_problem.getAuxiliarySystem()) 27 : { 28 16407 : } 29 : 30 : // Splitting Constructor 31 1361 : ComputeNodalUserObjectsThread::ComputeNodalUserObjectsThread(ComputeNodalUserObjectsThread & x, 32 1361 : Threads::split split) 33 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(x, split), 34 1361 : _query(x._query), 35 1361 : _aux_sys(x._aux_sys) 36 : { 37 1361 : } 38 : 39 19129 : ComputeNodalUserObjectsThread::~ComputeNodalUserObjectsThread() {} 40 : 41 : void 42 36729 : ComputeNodalUserObjectsThread::subdomainChanged() 43 : { 44 36729 : std::vector<NodalUserObject *> objs; 45 36729 : _query.clone() 46 36729 : .condition<AttribThread>(_tid) 47 73458 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 48 36729 : .queryInto(objs); 49 : 50 36729 : std::set<TagID> needed_vector_tags; 51 85428 : for (const auto obj : objs) 52 : { 53 48699 : auto & vector_tags = obj->getFEVariableCoupleableVectorTags(); 54 48699 : needed_vector_tags.insert(vector_tags.begin(), vector_tags.end()); 55 : } 56 36729 : _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_vector_tags, _tid); 57 36729 : } 58 : 59 : void 60 1556430 : ComputeNodalUserObjectsThread::onNode(ConstNodeRange::const_iterator & node_it) 61 : { 62 1556430 : const Node * node = *node_it; 63 : 64 1556430 : const auto & block_ids = _aux_sys.mesh().getNodeBlockIds(*node); 65 1556430 : if (_block_ids != block_ids) 66 : { 67 36729 : _block_ids.clear(); 68 36729 : _block_ids.insert(block_ids.begin(), block_ids.end()); 69 36729 : subdomainChanged(); 70 : } 71 : 72 1556430 : _fe_problem.reinitNode(node, _tid); 73 : 74 1556430 : std::vector<NodalUserObject *> objs; 75 : 76 : // Boundary Restricted 77 1556430 : std::vector<BoundaryID> nodeset_ids; 78 1556430 : _fe_problem.mesh().getMesh().get_boundary_info().boundary_ids(node, nodeset_ids); 79 2076023 : for (const auto & bnd : nodeset_ids) 80 : { 81 519593 : _query.clone() 82 519593 : .condition<AttribThread>(_tid) 83 519593 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 84 1039186 : .condition<AttribBoundaries>(bnd, true) 85 519593 : .queryInto(objs); 86 606286 : for (const auto & uo : objs) 87 : { 88 86693 : uo->execute(); 89 : 90 : // update the aux solution vector if writable coupled variables are used 91 86693 : if (uo->hasWritableCoupledVariables()) 92 : { 93 72 : Threads::spin_mutex::scoped_lock lock(writable_variable_mutex); 94 144 : for (auto * var : uo->getWritableCoupledVariables()) 95 72 : var->insert(_aux_sys.solution()); 96 72 : } 97 : } 98 : } 99 : 100 : // Block Restricted 101 : // NodalUserObjects may be block restricted, in this case by default the execute() method is 102 : // called for each subdomain that the node "belongs". This may be disabled in the NodalUserObject 103 : // by setting "unique_node_execute = true". 104 : 105 : // To enforce the unique execution this vector is populated and checked if the unique flag is 106 : // enabled. 107 1556430 : std::set<NodalUserObject *> computed; 108 3125226 : for (const auto & block : block_ids) 109 : { 110 1568796 : _query.clone() 111 1568796 : .condition<AttribThread>(_tid) 112 3137592 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 113 1568796 : .condition<AttribSubdomains>(block) 114 1568796 : .queryInto(objs); 115 : 116 2959452 : for (const auto & uo : objs) 117 1390656 : if (!uo->isUniqueNodeExecute() || computed.count(uo) == 0) 118 : { 119 1390548 : uo->execute(); 120 : 121 : // update the aux solution vector if writable coupled variables are used 122 1390548 : if (uo->hasWritableCoupledVariables()) 123 : { 124 36 : Threads::spin_mutex::scoped_lock lock(writable_variable_mutex); 125 72 : for (auto * var : uo->getWritableCoupledVariables()) 126 36 : var->insert(_aux_sys.solution()); 127 36 : } 128 : 129 1390548 : computed.insert(uo); 130 : } 131 : } 132 1556430 : } 133 : 134 : void 135 1361 : ComputeNodalUserObjectsThread::join(const ComputeNodalUserObjectsThread & /*y*/) 136 : { 137 1361 : } 138 : 139 : void 140 17768 : ComputeNodalUserObjectsThread::printGeneralExecutionInformation() const 141 : { 142 17768 : if (!_fe_problem.shouldPrintExecution(_tid)) 143 17678 : return; 144 : 145 : // Get all nodal UOs 146 90 : std::vector<MooseObject *> nodal_uos; 147 90 : _query.clone() 148 90 : .condition<AttribThread>(_tid) 149 180 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 150 90 : .queryInto(nodal_uos); 151 : 152 90 : if (nodal_uos.size()) 153 : { 154 90 : const auto & console = _fe_problem.console(); 155 90 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 156 90 : console << "[DBG] Computing nodal user objects on " << execute_on << std::endl; 157 90 : mooseDoOnce( 158 : console << "[DBG] Ordering on nodes:" << std::endl; 159 : console << "[DBG] - boundary restricted user objects" << std::endl; 160 : console << "[DBG] - block restricted user objects" << std::endl; 161 : console << "[DBG] Nodal UOs executed on each node will differ based on these restrictions" 162 : << std::endl;); 163 : 164 90 : auto message = ConsoleUtils::mooseObjectVectorToString(nodal_uos); 165 90 : message = "Order of execution:\n" + message; 166 90 : console << ConsoleUtils::formatString(message, "[DBG]") << std::endl; 167 90 : } 168 90 : }