LCOV - code coverage report
Current view: top level - src/loops - ComputeNodalKernelBCJacobiansThread.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 70 77 90.9 %
Date: 2025-07-17 01:28:37 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          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 "ComputeNodalKernelBCJacobiansThread.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "Assembly.h"
      14             : #include "AuxiliarySystem.h"
      15             : #include "FEProblem.h"
      16             : #include "MooseVariableFE.h"
      17             : #include "NodalKernelBase.h"
      18             : #include "NonlinearSystemBase.h"
      19             : 
      20             : #include "libmesh/threads.h"
      21             : 
      22          53 : ComputeNodalKernelBCJacobiansThread::ComputeNodalKernelBCJacobiansThread(
      23             :     FEProblemBase & fe_problem,
      24             :     NonlinearSystemBase & nl,
      25             :     MooseObjectTagWarehouse<NodalKernelBase> & nodal_kernels,
      26          53 :     const std::set<TagID> & tags)
      27             :   : ThreadedNodeLoop<ConstBndNodeRange, ConstBndNodeRange::const_iterator>(fe_problem),
      28          53 :     _fe_problem(fe_problem),
      29          53 :     _nl(nl),
      30         106 :     _aux_sys(fe_problem.getAuxiliarySystem()),
      31          53 :     _tags(tags),
      32          53 :     _nodal_kernels(nodal_kernels),
      33          53 :     _num_cached(0)
      34             : {
      35          53 : }
      36             : 
      37             : // Splitting Constructor
      38           5 : ComputeNodalKernelBCJacobiansThread::ComputeNodalKernelBCJacobiansThread(
      39           5 :     ComputeNodalKernelBCJacobiansThread & x, Threads::split split)
      40             :   : ThreadedNodeLoop<ConstBndNodeRange, ConstBndNodeRange::const_iterator>(x, split),
      41           5 :     _fe_problem(x._fe_problem),
      42           5 :     _nl(x._nl),
      43           5 :     _aux_sys(x._aux_sys),
      44           5 :     _tags(x._tags),
      45           5 :     _nodal_kernels(x._nodal_kernels),
      46           5 :     _num_cached(0)
      47             : {
      48           5 : }
      49             : 
      50             : void
      51          58 : ComputeNodalKernelBCJacobiansThread::pre()
      52             : {
      53          58 :   _num_cached = 0;
      54             : 
      55          58 :   if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags())
      56          58 :     _nkernel_warehouse = &_nodal_kernels;
      57           0 :   else if (_tags.size() == 1)
      58           0 :     _nkernel_warehouse = &(_nodal_kernels.getMatrixTagObjectWarehouse(*(_tags.begin()), _tid));
      59             :   else
      60           0 :     _nkernel_warehouse = &(_nodal_kernels.getMatrixTagsObjectWarehouse(_tags, _tid));
      61          58 : }
      62             : 
      63             : void
      64        1644 : ComputeNodalKernelBCJacobiansThread::onNode(ConstBndNodeRange::const_iterator & node_it)
      65             : {
      66        1644 :   const BndNode * bnode = *node_it;
      67             : 
      68        1644 :   BoundaryID boundary_id = bnode->_bnd_id;
      69             : 
      70        1644 :   auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
      71        3846 :   for (const auto & it : ce)
      72             :   {
      73        2202 :     MooseVariableFEBase & ivariable = *(it.first);
      74        2202 :     MooseVariableFEBase & jvariable = *(it.second);
      75             : 
      76        2202 :     unsigned int ivar = ivariable.number();
      77        2202 :     unsigned int jvar = jvariable.number();
      78             : 
      79             :     // The NodalKernels that are active and are coupled to the jvar in question
      80        2202 :     std::vector<std::shared_ptr<NodalKernelBase>> active_involved_kernels;
      81             : 
      82        2202 :     if (_nkernel_warehouse->hasActiveBoundaryObjects(boundary_id, _tid))
      83             :     {
      84             :       // Loop over each NodalKernel to see if it's involved with the jvar
      85        1590 :       const auto & objects = _nkernel_warehouse->getActiveBoundaryObjects(boundary_id, _tid);
      86        3372 :       for (const auto & nodal_kernel : objects)
      87             :       {
      88        1782 :         if (nodal_kernel->variable().number() == ivar)
      89             :         {
      90             :           // If this NodalKernel is acting on the jvar add it to the list and short-circuit the
      91             :           // loop
      92        1590 :           if (nodal_kernel->variable().number() == jvar)
      93             :           {
      94        1494 :             active_involved_kernels.push_back(nodal_kernel);
      95        1494 :             continue;
      96             :           }
      97             : 
      98             :           // See if this NodalKernel is coupled to the jvar
      99             :           const std::vector<MooseVariableFEBase *> & coupled_vars =
     100          96 :               nodal_kernel->getCoupledMooseVars();
     101          96 :           for (const auto & var : coupled_vars)
     102             :           {
     103           0 :             if (var->number() == jvar)
     104             :             {
     105           0 :               active_involved_kernels.push_back(nodal_kernel);
     106           0 :               break; // It only takes one
     107             :             }
     108             :           }
     109             :         }
     110             :       }
     111             :     }
     112             : 
     113             :     // Did we find any NodalKernels coupled to this jvar?
     114        2202 :     if (!active_involved_kernels.empty())
     115             :     {
     116             :       // prepare variables
     117        1494 :       for (auto * var : _aux_sys._nodal_vars[_tid])
     118           0 :         var->prepareAux();
     119             : 
     120        1494 :       if (_nkernel_warehouse->hasActiveBoundaryObjects(boundary_id, _tid))
     121             :       {
     122        1494 :         Node * node = bnode->_node;
     123        1494 :         if (node->processor_id() == _fe_problem.processor_id())
     124             :         {
     125        1168 :           _fe_problem.reinitNodeFace(node, boundary_id, _tid);
     126        2336 :           for (const auto & nodal_kernel : active_involved_kernels)
     127             :           {
     128        1168 :             nodal_kernel->setSubdomains(Moose::NodeArg::undefined_subdomain_connection);
     129        1168 :             nodal_kernel->computeOffDiagJacobian(jvar);
     130             :           }
     131             : 
     132        1168 :           _num_cached++;
     133             :         }
     134             :       }
     135             : 
     136        1494 :       if (_num_cached == 20) // cache 20 nodes worth before adding into the jacobian
     137             :       {
     138          48 :         _num_cached = 0;
     139             :         // vectors are thread-safe, but matrices are not yet
     140          48 :         Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     141          48 :         _fe_problem.addCachedJacobian(_tid);
     142          48 :       }
     143             :     }
     144        2202 :   }
     145        1644 : }
     146             : 
     147             : void
     148           5 : ComputeNodalKernelBCJacobiansThread::join(const ComputeNodalKernelBCJacobiansThread & /*y*/)
     149             : {
     150           5 : }
     151             : 
     152             : void
     153          58 : ComputeNodalKernelBCJacobiansThread::printGeneralExecutionInformation() const
     154             : {
     155          58 :   if (!_fe_problem.shouldPrintExecution(_tid) || !_nkernel_warehouse->hasActiveBoundaryObjects())
     156          48 :     return;
     157             : 
     158          10 :   const auto & console = _fe_problem.console();
     159          10 :   const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
     160             :   console << "[DBG] Computing nodal kernel & boundary conditions contribution to the Jacobian on "
     161          10 :              "boundary nodes on "
     162          10 :           << execute_on << std::endl;
     163          10 :   console << "[DBG] Ordering on boundaries they are defined on:" << std::endl;
     164          10 :   console << _nkernel_warehouse->activeObjectsToFormattedString() << std::endl;
     165             : }

Generated by: LCOV version 1.14