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 14943 : ComputeNodalUserObjectsThread::ComputeNodalUserObjectsThread(FEProblemBase & fe_problem, 23 14943 : const TheWarehouse::Query & query) 24 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(fe_problem), 25 14943 : _query(query), 26 14943 : _aux_sys(fe_problem.getAuxiliarySystem()) 27 : { 28 14943 : } 29 : 30 : // Splitting Constructor 31 1357 : ComputeNodalUserObjectsThread::ComputeNodalUserObjectsThread(ComputeNodalUserObjectsThread & x, 32 1357 : Threads::split split) 33 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(x, split), 34 1357 : _query(x._query), 35 1357 : _aux_sys(x._aux_sys) 36 : { 37 1357 : } 38 : 39 17657 : ComputeNodalUserObjectsThread::~ComputeNodalUserObjectsThread() {} 40 : 41 : void 42 33650 : ComputeNodalUserObjectsThread::subdomainChanged() 43 : { 44 33650 : std::vector<NodalUserObject *> objs; 45 33650 : _query.clone() 46 33650 : .condition<AttribThread>(_tid) 47 67300 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 48 33650 : .queryInto(objs); 49 : 50 33650 : std::set<TagID> needed_vector_tags; 51 79032 : for (const auto obj : objs) 52 : { 53 45382 : auto & vector_tags = obj->getFEVariableCoupleableVectorTags(); 54 45382 : needed_vector_tags.insert(vector_tags.begin(), vector_tags.end()); 55 : } 56 33650 : _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_vector_tags, _tid); 57 33650 : } 58 : 59 : void 60 1378639 : ComputeNodalUserObjectsThread::onNode(ConstNodeRange::const_iterator & node_it) 61 : { 62 1378639 : const Node * node = *node_it; 63 : 64 1378639 : const auto & block_ids = _aux_sys.mesh().getNodeBlockIds(*node); 65 1378639 : if (_block_ids != block_ids) 66 : { 67 33650 : _block_ids.clear(); 68 33650 : _block_ids.insert(block_ids.begin(), block_ids.end()); 69 33650 : subdomainChanged(); 70 : } 71 : 72 1378639 : _fe_problem.reinitNode(node, _tid); 73 : 74 1378639 : std::vector<NodalUserObject *> objs; 75 : 76 : // Boundary Restricted 77 1378639 : std::vector<BoundaryID> nodeset_ids; 78 1378639 : _fe_problem.mesh().getMesh().get_boundary_info().boundary_ids(node, nodeset_ids); 79 1838214 : for (const auto & bnd : nodeset_ids) 80 : { 81 459575 : _query.clone() 82 459575 : .condition<AttribThread>(_tid) 83 459575 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 84 919150 : .condition<AttribBoundaries>(bnd, true) 85 459575 : .queryInto(objs); 86 536786 : for (const auto & uo : objs) 87 : { 88 77211 : uo->execute(); 89 : 90 : // update the aux solution vector if writable coupled variables are used 91 77211 : if (uo->hasWritableCoupledVariables()) 92 : { 93 64 : Threads::spin_mutex::scoped_lock lock(writable_variable_mutex); 94 128 : for (auto * var : uo->getWritableCoupledVariables()) 95 64 : var->insert(_aux_sys.solution()); 96 64 : } 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 1378639 : std::set<NodalUserObject *> computed; 108 2768801 : for (const auto & block : block_ids) 109 : { 110 1390162 : _query.clone() 111 1390162 : .condition<AttribThread>(_tid) 112 2780324 : .condition<AttribInterfaces>(Interfaces::NodalUserObject) 113 1390162 : .condition<AttribSubdomains>(block) 114 1390162 : .queryInto(objs); 115 : 116 2629507 : for (const auto & uo : objs) 117 1239345 : if (!uo->isUniqueNodeExecute() || computed.count(uo) == 0) 118 : { 119 1239249 : uo->execute(); 120 : 121 : // update the aux solution vector if writable coupled variables are used 122 1239249 : if (uo->hasWritableCoupledVariables()) 123 : { 124 32 : Threads::spin_mutex::scoped_lock lock(writable_variable_mutex); 125 64 : for (auto * var : uo->getWritableCoupledVariables()) 126 32 : var->insert(_aux_sys.solution()); 127 32 : } 128 : 129 1239249 : computed.insert(uo); 130 : } 131 : } 132 1378639 : } 133 : 134 : void 135 1357 : ComputeNodalUserObjectsThread::join(const ComputeNodalUserObjectsThread & /*y*/) 136 : { 137 1357 : } 138 : 139 : void 140 16300 : ComputeNodalUserObjectsThread::printGeneralExecutionInformation() const 141 : { 142 16300 : if (!_fe_problem.shouldPrintExecution(_tid)) 143 16210 : 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 : }