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 57581 : ComputeInitialConditionThread::ComputeInitialConditionThread(FEProblemBase & fe_problem) 17 57581 : : _fe_problem(fe_problem) 18 : { 19 57581 : } 20 : 21 4864 : ComputeInitialConditionThread::ComputeInitialConditionThread(ComputeInitialConditionThread & x, 22 4864 : Threads::split /*split*/) 23 4864 : : _fe_problem(x._fe_problem) 24 : { 25 4864 : } 26 : 27 2191 : ComputeInitialConditionThread::ComputeInitialConditionThread( 28 2191 : FEProblemBase & fe_problem, const std::set<VariableName> * target_vars) 29 2191 : : _fe_problem(fe_problem), _target_vars(target_vars) 30 : { 31 2191 : } 32 : 33 : void 34 64636 : ComputeInitialConditionThread::operator()(const ConstElemRange & range) 35 : { 36 64636 : ParallelUniqueId puid; 37 64636 : _tid = puid.id; 38 64636 : const auto current_ic_state = _fe_problem.getCurrentICState(); 39 : 40 64636 : const InitialConditionWarehouse & warehouse = _fe_problem.getInitialConditionWarehouse(); 41 64636 : printGeneralExecutionInformation(); 42 : 43 : // Iterate over all the elements in the range 44 10469616 : for (const auto & elem : range) 45 : { 46 10404989 : 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 10404989 : std::set<SubdomainID> block_ids; 51 68286066 : for (unsigned int n = 0; n < n_nodes; n++) 52 : { 53 57881077 : auto node = elem->node_ptr(n); 54 57881077 : const auto & ids = _fe_problem.mesh().getNodeBlockIds(*node); 55 57881077 : 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 10404989 : 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 10404989 : std::map<MooseVariableFEBase *, std::vector<std::shared_ptr<InitialConditionBase>>> groups; 71 21436912 : for (auto id : block_ids) 72 11031923 : if (warehouse.hasActiveBlockObjects(id, _tid)) 73 4093535 : for (auto ic : warehouse.getActiveBlockObjects(id, _tid)) 74 : { 75 5176764 : if ((id != elem->subdomain_id() && !ic->variable().isNodal()) || 76 2541076 : ic->getState() != current_ic_state) 77 94612 : continue; 78 : 79 : // Skip initial conditions based on target variable usage 80 2541076 : const auto & var_name = ic->variable().name(); 81 2541076 : if (_target_vars && !_target_vars->count(var_name)) 82 134 : continue; 83 : 84 2540942 : order.push_back(&(ic->variable())); 85 2540942 : groups[&(ic->variable())].push_back(ic); 86 2635688 : } 87 : 88 10404989 : _fe_problem.setCurrentSubdomainID(elem, _tid); 89 10404989 : _fe_problem.prepare(elem, _tid); 90 10404989 : _fe_problem.reinitElem(elem, _tid); 91 : 92 12945922 : for (auto var : order) 93 : { 94 2540942 : DenseVector<Real> Ue; 95 2540942 : 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 2540942 : 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 4994028 : for (auto ic : vec) 111 2453095 : ic->compute(); 112 2540933 : vec.clear(); 113 : 114 : // Now that all dofs are set for this variable, solemnize the solution. 115 2540933 : var->insert(var->sys().solution()); 116 2540933 : } 117 10404980 : } 118 64627 : } 119 : 120 : void 121 4863 : ComputeInitialConditionThread::join(const ComputeInitialConditionThread & /*y*/) 122 : { 123 4863 : } 124 : 125 : void 126 64636 : ComputeInitialConditionThread::printGeneralExecutionInformation() const 127 : { 128 64636 : const auto & ic_wh = _fe_problem.getInitialConditionWarehouse(); 129 64636 : if (_fe_problem.shouldPrintExecution(_tid) && ic_wh.hasActiveObjects()) 130 : { 131 80 : const auto & console = _fe_problem.console(); 132 80 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 133 80 : console << "[DBG] Executing initial conditions on elements on " << execute_on << std::endl; 134 80 : console << "[DBG] Unordered list:" << std::endl; 135 160 : console << ic_wh.activeObjectsToFormattedString() << std::endl; 136 80 : console << "[DBG] The order of execution is defined by dependency resolution on every element" 137 80 : << std::endl; 138 : } 139 64636 : }