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 "ComputeInitialConditionThread.h" 11 : #include "FEProblem.h" 12 : #include "DisplacedProblem.h" 13 : #include "Assembly.h" 14 : #include "InitialCondition.h" 15 : 16 55828 : ComputeInitialConditionThread::ComputeInitialConditionThread(FEProblemBase & fe_problem) 17 55828 : : _fe_problem(fe_problem) 18 : { 19 55828 : } 20 : 21 5208 : ComputeInitialConditionThread::ComputeInitialConditionThread(ComputeInitialConditionThread & x, 22 5208 : Threads::split /*split*/) 23 5208 : : _fe_problem(x._fe_problem), _target_vars(x._target_vars) 24 : { 25 5208 : } 26 : 27 2037 : ComputeInitialConditionThread::ComputeInitialConditionThread( 28 2037 : FEProblemBase & fe_problem, const std::set<VariableName> * target_vars) 29 2037 : : _fe_problem(fe_problem), _target_vars(target_vars) 30 : { 31 2037 : } 32 : 33 : void 34 63073 : ComputeInitialConditionThread::operator()(const ConstElemRange & range) 35 : { 36 63073 : ParallelUniqueId puid; 37 63073 : _tid = puid.id; 38 63073 : const auto current_ic_state = _fe_problem.getCurrentICState(); 39 : 40 63073 : const InitialConditionWarehouse & warehouse = _fe_problem.getInitialConditionWarehouse(); 41 63073 : printGeneralExecutionInformation(); 42 : 43 : // Iterate over all the elements in the range 44 9577654 : for (const auto & elem : range) 45 : { 46 9514588 : const unsigned int n_nodes = elem->n_nodes(); 47 : 48 : // we need to execute objects that are for all subdomains covered by this 49 : // elements' nodes. 50 9514588 : std::set<SubdomainID> block_ids; 51 62122447 : for (unsigned int n = 0; n < n_nodes; n++) 52 : { 53 52607859 : auto node = elem->node_ptr(n); 54 52607859 : const auto & ids = _fe_problem.mesh().getNodeBlockIds(*node); 55 52607859 : block_ids.insert(ids.begin(), ids.end()); 56 : } 57 : 58 : // we need to remember the order the variables originally are provided in 59 : // since the ics dependencies are resolved to handle the inter-variable 60 : // dependencies correctly. 61 9514588 : std::vector<MooseVariableFEBase *> order; 62 : 63 : // group all initial condition objects by variable. so we can compute all 64 : // its dof values at once and copy into solution vector once. This is 65 : // necessary because we have to collect extra off-block ic objects from 66 : // nodes shared between subdomains for cases where the off-block ic "wins" 67 : // on the interface. The grouping is required because we need to have all 68 : // the dof values for the element determined together so we can compute 69 : // the correct qp values, etc. for the variable. 70 9514588 : std::map<MooseVariableFEBase *, std::vector<std::shared_ptr<InitialConditionBase>>> groups; 71 19789852 : for (auto id : block_ids) 72 10275264 : if (warehouse.hasActiveBlockObjects(id, _tid)) 73 3816727 : for (auto ic : warehouse.getActiveBlockObjects(id, _tid)) 74 : { 75 4925946 : if ((id != elem->subdomain_id() && !ic->variable().isNodal()) || 76 2410707 : ic->getState() != current_ic_state) 77 104532 : continue; 78 : 79 : // Skip initial conditions based on target variable usage 80 2410707 : const auto & var_name = ic->variable().name(); 81 2410707 : if (_target_vars && !_target_vars->count(var_name)) 82 254 : continue; 83 : 84 2410453 : order.push_back(&(ic->variable())); 85 2410453 : groups[&(ic->variable())].push_back(ic); 86 2515239 : } 87 : 88 9514588 : _fe_problem.setCurrentSubdomainID(elem, _tid); 89 9514588 : _fe_problem.prepare(elem, _tid); 90 9514588 : _fe_problem.reinitElem(elem, _tid); 91 : 92 11925034 : for (auto var : order) 93 : { 94 2410453 : DenseVector<Real> Ue; 95 2410453 : auto & vec = groups[var]; 96 : 97 : // because of all the off-node shenanigans/grouping above, per-variable 98 : // objects could possible have their order jumbled - so re-sort just in 99 : // case. 100 : try 101 : { 102 2410453 : DependencyResolverInterface::sort<std::shared_ptr<InitialConditionBase>>(vec); 103 : } 104 0 : catch (CyclicDependencyException<std::shared_ptr<InitialConditionBase>> & e) 105 : { 106 0 : DependencyResolverInterface::cyclicDependencyError<std::shared_ptr<InitialConditionBase>>( 107 : e, "Cyclic dependency detected in object ordering"); 108 0 : } 109 : 110 4722677 : for (auto ic : vec) 111 2312231 : ic->compute(); 112 2410446 : vec.clear(); 113 : 114 : // Now that all dofs are set for this variable, solemnize the solution. 115 2410446 : var->insert(var->sys().solution()); 116 2410446 : } 117 9514581 : } 118 63066 : } 119 : 120 : void 121 5207 : ComputeInitialConditionThread::join(const ComputeInitialConditionThread & /*y*/) 122 : { 123 5207 : } 124 : 125 : void 126 63073 : ComputeInitialConditionThread::printGeneralExecutionInformation() const 127 : { 128 63073 : const auto & ic_wh = _fe_problem.getInitialConditionWarehouse(); 129 63073 : if (_fe_problem.shouldPrintExecution(_tid) && ic_wh.hasActiveObjects()) 130 : { 131 71 : const auto & console = _fe_problem.console(); 132 71 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 133 71 : console << "[DBG] Executing initial conditions on elements on " << execute_on << std::endl; 134 71 : console << "[DBG] Unordered list:" << std::endl; 135 142 : console << ic_wh.activeObjectsToFormattedString() << std::endl; 136 71 : console << "[DBG] The order of execution is defined by dependency resolution on every element" 137 71 : << std::endl; 138 : } 139 63073 : }