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