LCOV - code coverage report
Current view: top level - src/loops - ProjectMaterialProperties.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 71 85 83.5 %
Date: 2025-08-08 20:01:16 Functions: 9 9 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             : // MOOSE includes
      11             : #include "ProjectMaterialProperties.h"
      12             : #include "Problem.h"
      13             : #include "FEProblem.h"
      14             : #include "MaterialPropertyStorage.h"
      15             : #include "MaterialData.h"
      16             : #include "Assembly.h"
      17             : #include "AuxKernel.h"
      18             : 
      19             : #include "libmesh/threads.h"
      20             : #include "libmesh/elem.h"
      21             : 
      22         464 : ProjectMaterialProperties::ProjectMaterialProperties(
      23             :     bool refine,
      24             :     FEProblemBase & fe_problem,
      25             :     MaterialPropertyStorage & material_props,
      26             :     MaterialPropertyStorage & bnd_material_props,
      27         464 :     std::vector<std::vector<std::unique_ptr<Assembly>>> & assembly)
      28             :   : ThreadedElementLoop<ConstElemPointerRange>(fe_problem),
      29         464 :     _refine(refine),
      30         464 :     _fe_problem(fe_problem),
      31         464 :     _material_props(material_props),
      32         464 :     _bnd_material_props(bnd_material_props),
      33         464 :     _assembly(assembly),
      34         464 :     _need_internal_side_material(false),
      35         928 :     _materials(_fe_problem.getRegularMaterialsWarehouse()),
      36         464 :     _discrete_materials(_fe_problem.getDiscreteMaterialWarehouse())
      37             : {
      38         464 : }
      39             : 
      40             : // Splitting Constructor
      41          13 : ProjectMaterialProperties::ProjectMaterialProperties(ProjectMaterialProperties & x,
      42          13 :                                                      Threads::split split)
      43             :   : ThreadedElementLoop<ConstElemPointerRange>(x, split),
      44          13 :     _refine(x._refine),
      45          13 :     _fe_problem(x._fe_problem),
      46          13 :     _material_props(x._material_props),
      47          13 :     _bnd_material_props(x._bnd_material_props),
      48          13 :     _assembly(x._assembly),
      49          13 :     _need_internal_side_material(x._need_internal_side_material),
      50          13 :     _materials(x._materials),
      51          13 :     _discrete_materials(x._discrete_materials)
      52             : {
      53          13 : }
      54             : 
      55         490 : ProjectMaterialProperties::~ProjectMaterialProperties() {}
      56             : 
      57             : void
      58         319 : ProjectMaterialProperties::subdomainChanged()
      59             : {
      60         319 :   _need_internal_side_material = _fe_problem.needSubdomainMaterialOnSide(_subdomain, _tid);
      61         319 : }
      62             : 
      63             : void
      64        5863 : ProjectMaterialProperties::onElement(const Elem * elem)
      65             : {
      66             :   // This check mirrors the check in ComputeMaterialsObjectThread::onElement as it must because it
      67             :   // is possible that there are no materials on this element's subdomain, e.g. if we are doing
      68             :   // mortar, in which case the properties will not have been resized in
      69             :   // ComputeMaterialsObjectThread::onElement, and consequently if we were to proceed we would get
      70             :   // bad access errors
      71        6143 :   if (!_materials.hasActiveBlockObjects(elem->subdomain_id(), _tid) &&
      72         280 :       !_discrete_materials.hasActiveBlockObjects(elem->subdomain_id(), _tid))
      73         280 :     return;
      74             : 
      75        5583 :   _assembly[_tid][0]->reinit(elem);
      76             : 
      77        5583 :   if (_refine)
      78             :   {
      79        4298 :     if (_mesh.doingPRefinement())
      80             :     {
      81         900 :       const auto & p_refinement_map = _mesh.getPRefinementMap(*elem);
      82         900 :       _material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
      83             :                                                         p_refinement_map,
      84         900 :                                                         *_assembly[_tid][0]->qRule(),
      85         900 :                                                         *_assembly[_tid][0]->qRuleFace(),
      86             :                                                         _tid,
      87             :                                                         *elem,
      88             :                                                         -1);
      89             :     }
      90             :     else
      91             :     {
      92             :       const std::vector<std::vector<QpMap>> & refinement_map =
      93        3398 :           _mesh.getRefinementMap(*elem, -1, -1, -1);
      94             : 
      95        3398 :       _material_props.prolongStatefulProps(
      96        3398 :           _mesh.processor_id(),
      97             :           refinement_map,
      98        3398 :           *_assembly[_tid][0]->qRule(),
      99        3398 :           *_assembly[_tid][0]->qRuleFace(),
     100             :           _material_props, // Passing in the same properties to do volume to volume projection
     101             :           _tid,
     102             :           *elem,
     103             :           -1,
     104             :           -1,
     105             :           -1); // Gets us volume projection
     106             :     }
     107             :   }
     108             :   else
     109             :   {
     110        1285 :     if (_mesh.doingPRefinement())
     111             :     {
     112           0 :       const auto & p_coarsening_map = _mesh.getPCoarseningMap(*elem);
     113           0 :       _material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
     114             :                                                         p_coarsening_map,
     115           0 :                                                         *_assembly[_tid][0]->qRule(),
     116           0 :                                                         *_assembly[_tid][0]->qRuleFace(),
     117             :                                                         _tid,
     118             :                                                         *elem,
     119             :                                                         -1);
     120             :     }
     121             :     else
     122             :     {
     123             :       const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map =
     124        1285 :           _mesh.getCoarseningMap(*elem, -1);
     125             : 
     126        1285 :       _material_props.restrictStatefulProps(coarsening_map,
     127        1285 :                                             _mesh.coarsenedElementChildren(elem),
     128        1285 :                                             *_assembly[_tid][0]->qRule(),
     129        1285 :                                             *_assembly[_tid][0]->qRuleFace(),
     130             :                                             _tid,
     131             :                                             *elem,
     132             :                                             -1);
     133             :     }
     134             :   }
     135             : }
     136             : 
     137             : void
     138        2278 : ProjectMaterialProperties::onBoundary(const Elem * elem,
     139             :                                       unsigned int side,
     140             :                                       BoundaryID bnd_id,
     141             :                                       const Elem * /*lower_d_elem = nullptr*/)
     142             : {
     143        2794 :   if (_fe_problem.needBoundaryMaterialOnSide(bnd_id, _tid) &&
     144         516 :       _bnd_material_props.hasStatefulProperties())
     145             :   {
     146         516 :     _assembly[_tid][0]->reinit(elem, side);
     147             : 
     148         516 :     if (_refine)
     149             :     {
     150         372 :       if (_mesh.doingPRefinement())
     151             :       {
     152           0 :         const auto & p_refinement_map = _mesh.getPRefinementSideMap(*elem);
     153           0 :         _bnd_material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
     154             :                                                               p_refinement_map,
     155           0 :                                                               *_assembly[_tid][0]->qRule(),
     156           0 :                                                               *_assembly[_tid][0]->qRuleFace(),
     157             :                                                               _tid,
     158             :                                                               *elem,
     159             :                                                               side);
     160             :       }
     161             :       else
     162             :       {
     163             :         const std::vector<std::vector<QpMap>> & refinement_map =
     164         372 :             _mesh.getRefinementMap(*elem, side, -1, side);
     165             : 
     166         372 :         _bnd_material_props.prolongStatefulProps(
     167         372 :             _mesh.processor_id(),
     168             :             refinement_map,
     169         372 :             *_assembly[_tid][0]->qRule(),
     170         372 :             *_assembly[_tid][0]->qRuleFace(),
     171             :             _bnd_material_props, // Passing in the same properties to do side_to_side projection
     172             :             _tid,
     173             :             *elem,
     174             :             side,
     175             :             -1,
     176             :             side); // Gets us side to side projection
     177             :       }
     178             :     }
     179             :     else
     180             :     {
     181         144 :       if (_mesh.doingPRefinement())
     182             :       {
     183           0 :         const auto & p_coarsening_map = _mesh.getPCoarseningSideMap(*elem);
     184           0 :         _bnd_material_props.updateStatefulPropsForPRefinement(_mesh.processor_id(),
     185             :                                                               p_coarsening_map,
     186           0 :                                                               *_assembly[_tid][0]->qRule(),
     187           0 :                                                               *_assembly[_tid][0]->qRuleFace(),
     188             :                                                               _tid,
     189             :                                                               *elem,
     190             :                                                               side);
     191             :       }
     192             :       else
     193             :       {
     194             :         const std::vector<std::pair<unsigned int, QpMap>> & coarsening_map =
     195         144 :             _mesh.getCoarseningMap(*elem, side);
     196             : 
     197         144 :         _bnd_material_props.restrictStatefulProps(coarsening_map,
     198         144 :                                                   _mesh.coarsenedElementChildren(elem),
     199         144 :                                                   *_assembly[_tid][0]->qRule(),
     200         144 :                                                   *_assembly[_tid][0]->qRuleFace(),
     201             :                                                   _tid,
     202             :                                                   *elem,
     203             :                                                   side);
     204             :       }
     205             :     }
     206             :   }
     207        2278 : }
     208             : 
     209             : void
     210       24570 : ProjectMaterialProperties::onInternalSide(const Elem * elem, unsigned int /*side*/)
     211             : {
     212       24570 :   if (_need_internal_side_material &&
     213           0 :       _refine) // If we're refining then we need to also project "internal" child sides.
     214             :   {
     215           0 :     mooseError("I'm pretty sure we're not handling stateful material property prolongation or "
     216             :                "restriction correctly on internal sides");
     217             :     for (unsigned int child = 0; child < elem->n_children(); child++)
     218             :     {
     219             :       const Elem * child_elem = elem->child_ptr(child);
     220             : 
     221             :       for (unsigned int side = 0; side < child_elem->n_sides(); side++)
     222             :       {
     223             :         if (!elem->is_child_on_side(child, side)) // Otherwise we already projected it
     224             :         {
     225             :           const std::vector<std::vector<QpMap>> & refinement_map =
     226             :               _mesh.getRefinementMap(*elem, -1, child, side);
     227             : 
     228             :           _bnd_material_props.prolongStatefulProps(
     229             :               _mesh.processor_id(),
     230             :               refinement_map,
     231             :               *_assembly[_tid][0]->qRule(),
     232             :               *_assembly[_tid][0]->qRuleFace(),
     233             :               _material_props, // Passing in the same properties to do side_to_side projection
     234             :               _tid,
     235             :               *elem,
     236             :               -1,
     237             :               child,
     238             :               side); // Gets us volume to side projection
     239             :         }
     240             :       }
     241             :     }
     242             :   }
     243       24570 : }
     244             : 
     245             : void
     246          13 : ProjectMaterialProperties::join(const ProjectMaterialProperties & /*y*/)
     247             : {
     248          13 : }

Generated by: LCOV version 1.14