LCOV - code coverage report
Current view: top level - src/loops - ComputeDiracThread.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 75 87 86.2 %
Date: 2025-07-17 01:28:37 Functions: 9 12 75.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 "ComputeDiracThread.h"
      11             : 
      12             : // Moose Includes
      13             : #include "ParallelUniqueId.h"
      14             : #include "DiracKernel.h"
      15             : #include "Problem.h"
      16             : #include "NonlinearSystem.h"
      17             : #include "MooseVariableFE.h"
      18             : #include "Assembly.h"
      19             : #include "ThreadedElementLoop.h"
      20             : 
      21             : #include "libmesh/threads.h"
      22             : 
      23       35838 : ComputeDiracThread::ComputeDiracThread(FEProblemBase & feproblem,
      24             :                                        const std::set<TagID> & tags,
      25       35838 :                                        bool is_jacobian)
      26             :   : ThreadedElementLoop<DistElemRange>(feproblem),
      27       35838 :     _is_jacobian(is_jacobian),
      28       71676 :     _nl(feproblem.currentNonlinearSystem()),
      29       35838 :     _tags(tags),
      30       35838 :     _dirac_kernels(_nl.getDiracKernelWarehouse())
      31             : {
      32       35838 : }
      33             : 
      34             : // Splitting Constructor
      35           0 : ComputeDiracThread::ComputeDiracThread(ComputeDiracThread & x, Threads::split split)
      36             :   : ThreadedElementLoop<DistElemRange>(x, split),
      37           0 :     _is_jacobian(x._is_jacobian),
      38           0 :     _nl(x._nl),
      39           0 :     _tags(x._tags),
      40           0 :     _dirac_kernels(x._dirac_kernels)
      41             : {
      42           0 : }
      43             : 
      44       35838 : ComputeDiracThread::~ComputeDiracThread() {}
      45             : 
      46             : void
      47       35838 : ComputeDiracThread::pre()
      48             : {
      49             :   // Force TID=0 because we run this object _NON THREADED_
      50             :   // Take this out if we ever get Dirac's working with threads!
      51       35838 :   _tid = 0;
      52       35838 : }
      53             : 
      54             : void
      55       30521 : ComputeDiracThread::subdomainChanged()
      56             : {
      57       30521 :   _fe_problem.subdomainSetup(_subdomain, _tid);
      58             : 
      59       30521 :   std::set<MooseVariableFEBase *> needed_moose_vars;
      60       30521 :   _dirac_kernels.updateVariableDependency(needed_moose_vars, _tid);
      61             : 
      62             :   // Update material dependencies
      63       30521 :   std::unordered_set<unsigned int> needed_mat_props;
      64       30521 :   _dirac_kernels.updateMatPropDependency(needed_mat_props, _tid);
      65             : 
      66       30521 :   _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid);
      67       30521 :   _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid);
      68             : 
      69             :   // If users pass a empty vector or a full size of vector,
      70             :   // we take all kernels
      71       30521 :   if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags())
      72       20603 :     _dirac_warehouse = &_dirac_kernels;
      73             :   // If we have one tag only,  We call tag based storage
      74        9918 :   else if (_tags.size() == 1)
      75           0 :     _dirac_warehouse = _is_jacobian
      76           0 :                            ? &(_dirac_kernels.getMatrixTagObjectWarehouse(*(_tags.begin()), _tid))
      77           0 :                            : &(_dirac_kernels.getVectorTagObjectWarehouse(*(_tags.begin()), _tid));
      78             :   // This one may be expensive, and hopefully we do not use it so often
      79             :   else
      80       19756 :     _dirac_warehouse = _is_jacobian ? &(_dirac_kernels.getMatrixTagsObjectWarehouse(_tags, _tid))
      81        9838 :                                     : &(_dirac_kernels.getVectorTagsObjectWarehouse(_tags, _tid));
      82       30521 : }
      83             : 
      84             : void
      85      303320 : ComputeDiracThread::onElement(const Elem * elem)
      86             : {
      87      303320 :   const bool has_dirac_kernels_on_elem = _fe_problem.reinitDirac(elem, _tid);
      88      303320 :   if (!has_dirac_kernels_on_elem)
      89           0 :     return;
      90             : 
      91      303320 :   std::set<MooseVariableFEBase *> needed_moose_vars;
      92      303320 :   const auto & dkernels = _dirac_warehouse->getActiveObjects(_tid);
      93             : 
      94             :   // Only call reinitMaterials() if one or more DiracKernels has
      95             :   // actually called getMaterialProperty().  Loop over all the
      96             :   // DiracKernels and check whether this is the case.
      97      617839 :   for (const auto & dirac_kernel : dkernels)
      98             :   {
      99             :     // If any of the DiracKernels have had getMaterialProperty()
     100             :     // called, we need to reinit Materials.
     101      321218 :     if (dirac_kernel->getMaterialPropertyCalled())
     102             :     {
     103        6699 :       _fe_problem.reinitMaterials(_subdomain, _tid, /*swap_stateful=*/false);
     104        6699 :       break;
     105             :     }
     106             :   }
     107             : 
     108      625374 :   for (const auto & dirac_kernel : dkernels)
     109             :   {
     110      322054 :     if (!dirac_kernel->hasPointsOnElem(elem))
     111       15100 :       continue;
     112      306954 :     else if (!_is_jacobian)
     113             :     {
     114      269579 :       dirac_kernel->computeResidual();
     115      269579 :       continue;
     116             :     }
     117             : 
     118             :     // Get a list of coupled variables from the SubProblem
     119             :     const auto & coupling_entries =
     120       37375 :         dirac_kernel->subProblem().assembly(_tid, _nl.number()).couplingEntries();
     121             : 
     122             :     // Loop over the list of coupled variable pairs
     123      110359 :     for (const auto & it : coupling_entries)
     124             :     {
     125       72984 :       const MooseVariableFEBase * const ivariable = it.first;
     126       72984 :       const MooseVariableFEBase * const jvariable = it.second;
     127             : 
     128             :       // A variant of the check that is in
     129             :       // ComputeFullJacobianThread::computeJacobian().  We
     130             :       // only want to call computeOffDiagJacobian() if both
     131             :       // variables are active on this subdomain, and the
     132             :       // off-diagonal variable actually has dofs.
     133       72984 :       if (dirac_kernel->variable().number() == ivariable->number() &&
     134      110519 :           ivariable->activeOnSubdomain(_subdomain) && jvariable->activeOnSubdomain(_subdomain) &&
     135       37535 :           (jvariable->numberOfDofs() > 0))
     136             :       {
     137       37535 :         dirac_kernel->prepareShapes(jvariable->number());
     138       37535 :         dirac_kernel->computeOffDiagJacobian(jvariable->number());
     139             :       }
     140             :     }
     141             :   }
     142             : 
     143             :   // Note that we do not call swapBackMaterials() here as they were
     144             :   // never swapped in the first place.  This avoids messing up
     145             :   // stored values of stateful material properties.
     146      303320 : }
     147             : 
     148             : void
     149      303320 : ComputeDiracThread::postElement(const Elem * /*elem*/)
     150             : {
     151      303320 :   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
     152      303320 :   if (!_is_jacobian)
     153      266124 :     _fe_problem.addResidual(_tid);
     154             :   else
     155       37196 :     _fe_problem.addJacobian(_tid);
     156      303320 : }
     157             : 
     158             : void
     159       35838 : ComputeDiracThread::post()
     160             : {
     161       35838 :   _fe_problem.clearActiveElementalMooseVariables(_tid);
     162       35838 :   _fe_problem.clearActiveMaterialProperties(_tid);
     163       35838 : }
     164             : 
     165             : void
     166           0 : ComputeDiracThread::join(const ComputeDiracThread & /*y*/)
     167             : {
     168           0 : }
     169             : 
     170             : void
     171       35838 : ComputeDiracThread::printGeneralExecutionInformation() const
     172             : {
     173       35838 :   if (!_fe_problem.shouldPrintExecution(_tid))
     174       31630 :     return;
     175        4208 :   const auto & console = _fe_problem.console();
     176        4208 :   console << "[DBG] Executing Dirac Kernels on " << _fe_problem.getCurrentExecuteOnFlag().name()
     177        4208 :           << std::endl;
     178             : }
     179             : 
     180             : void
     181       30521 : ComputeDiracThread::printBlockExecutionInformation() const
     182             : {
     183       36953 :   if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain) ||
     184        6432 :       !_dirac_warehouse->hasActiveBlockObjects(_subdomain, _tid))
     185       24089 :     return;
     186             : 
     187        6432 :   const auto & dkernels = _dirac_warehouse->getActiveBlockObjects(_subdomain, _tid);
     188        6432 :   const auto & console = _fe_problem.console();
     189        6432 :   console << "[DBG] Ordering of DiracKernels on subdomain " << _subdomain << std::endl;
     190        6432 :   printExecutionOrdering<DiracKernelBase>(dkernels, false);
     191        6432 :   _blocks_exec_printed.insert(_subdomain);
     192             : }

Generated by: LCOV version 1.14