LCOV - code coverage report
Current view: top level - src/reporters - ElementExtremeMaterialPropertyReporter.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 86 94 91.5 %
Date: 2026-05-29 20:35:17 Functions: 14 14 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 "ElementExtremeMaterialPropertyReporter.h"
      11             : 
      12             : #include "metaphysicl/raw_type.h"
      13             : #include "libmesh/parallel.h"
      14             : #include "libmesh/parallel_algebra.h"
      15             : 
      16             : #include <algorithm>
      17             : #include <limits>
      18             : 
      19             : registerMooseObject("MooseApp", ElementExtremeMaterialPropertyReporter);
      20             : registerMooseObject("MooseApp", ADElementExtremeMaterialPropertyReporter);
      21             : 
      22             : template <bool is_ad>
      23             : InputParameters
      24        6222 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::validParams()
      25             : {
      26        6222 :   InputParameters params = ElementReporter::validParams();
      27             : 
      28       24888 :   params.addRequiredParam<MaterialPropertyName>("material_property",
      29             :                                                 "Material property for which to find the extreme. "
      30             :                                                 "The value of this property is always reported.");
      31       24888 :   MooseEnum type_options("max=0 min=1");
      32       24888 :   params.addRequiredParam<MooseEnum>("value_type",
      33             :                                      type_options,
      34             :                                      "Type of extreme value to report: 'max' "
      35             :                                      "reports the maximum value and 'min' reports "
      36             :                                      "the minimum value.");
      37             : 
      38       24888 :   params.addParam<std::vector<MaterialPropertyName>>(
      39             :       "additional_reported_properties",
      40             :       {},
      41             :       "Additional material properties reported at the location of the extreme value");
      42        6222 :   params.addClassDescription(
      43             :       "Determines the location of the minimum or maximum value of a material property over a "
      44             :       "volume, and provides its coordinates and optionally other requested data at that location.");
      45             : 
      46       12444 :   return params;
      47        6222 : }
      48             : 
      49             : template <bool is_ad>
      50          52 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::ElementExtremeMaterialPropertyReporterTempl(
      51             :     const InputParameters & parameters)
      52             :   : ElementReporter(parameters),
      53          52 :     _mat_prop(getGenericMaterialProperty<Real, is_ad>("material_property")),
      54         104 :     _type(getParam<MooseEnum>("value_type").template getEnum<ExtremeType>()),
      55          52 :     _extreme_value(declareValueByName<Real>("extreme_value")),
      56          52 :     _coordinates(declareValueByName<Point>("coordinates")),
      57         104 :     _qp(0)
      58             : {
      59             :   const auto & mat_prop_names =
      60         104 :       getParam<std::vector<MaterialPropertyName>>("additional_reported_properties");
      61             :   // TODO: Add more options for the type of reported properties. Currently these have to be
      62             :   //       either Real (if using the non-AD version of this, or ADReal if using the AD version).
      63             :   //       ElementMaterialSampler can get multiple types (int, real, unsigned), maybe do
      64             :   //       something like that and also get AD and non-AD verisons.
      65         156 :   for (const auto & mpn : mat_prop_names)
      66             :   {
      67         104 :     _additional_reported_properties.push_back(&getGenericMaterialPropertyByName<Real, is_ad>(mpn));
      68         104 :     _additional_reported_property_values.push_back(&declareValueByName<Real>(mpn));
      69             :   }
      70          52 : }
      71             : 
      72             : template <bool is_ad>
      73             : void
      74          48 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::initialize()
      75             : {
      76          48 :   switch (_type)
      77             :   {
      78          24 :     case ExtremeType::MAX:
      79          24 :       _extreme_value = -std::numeric_limits<Real>::max();
      80          24 :       break;
      81             : 
      82          24 :     case ExtremeType::MIN:
      83          24 :       _extreme_value = std::numeric_limits<Real>::max();
      84          24 :       break;
      85             :   }
      86          48 :   _coordinates = Point(0., 0., 0.);
      87         144 :   for (const auto i : index_range(_additional_reported_properties))
      88          96 :     *_additional_reported_property_values[i] = 0.0;
      89          48 : }
      90             : 
      91             : template <bool is_ad>
      92             : void
      93         128 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::execute()
      94             : {
      95         256 :   for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
      96         128 :     computeQpValue();
      97         128 : }
      98             : 
      99             : template <bool is_ad>
     100             : void
     101         128 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::computeQpValue()
     102             : {
     103         128 :   const Real raw_mat_val = MetaPhysicL::raw_value(_mat_prop[_qp]);
     104         128 :   switch (_type)
     105             :   {
     106          64 :     case ExtremeType::MAX:
     107          64 :       if (raw_mat_val > _extreme_value)
     108             :       {
     109          32 :         _extreme_value = raw_mat_val;
     110          32 :         _coordinates = _q_point[_qp];
     111          96 :         for (const auto i : index_range(_additional_reported_properties))
     112          64 :           *_additional_reported_property_values[i] =
     113          64 :               MetaPhysicL::raw_value((*_additional_reported_properties[i])[_qp]);
     114             :       }
     115          64 :       break;
     116             : 
     117          64 :     case ExtremeType::MIN:
     118          64 :       if (raw_mat_val < _extreme_value)
     119             :       {
     120          40 :         _extreme_value = raw_mat_val;
     121          40 :         _coordinates = _q_point[_qp];
     122         120 :         for (const auto i : index_range(_additional_reported_properties))
     123          80 :           *_additional_reported_property_values[i] =
     124          80 :               MetaPhysicL::raw_value((*_additional_reported_properties[i])[_qp]);
     125             :       }
     126          64 :       break;
     127             :   }
     128         128 : }
     129             : 
     130             : template <bool is_ad>
     131             : void
     132          44 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::finalize()
     133             : {
     134          44 :   unsigned int rank = 0;
     135             : 
     136          44 :   switch (_type)
     137             :   {
     138          22 :     case ExtremeType::MAX:
     139          22 :       _communicator.maxloc(_extreme_value, rank);
     140          22 :       break;
     141          22 :     case ExtremeType::MIN:
     142          22 :       _communicator.minloc(_extreme_value, rank);
     143          22 :       break;
     144             :   }
     145             : 
     146          44 :   const auto prop_size = _additional_reported_property_values.size();
     147          44 :   std::vector<Real> ev_rep_prop_vals(prop_size, 0.);
     148             : 
     149          44 :   _communicator.broadcast(_coordinates, rank);
     150          44 :   if (rank == processor_id())
     151          96 :     for (const auto i : make_range(prop_size))
     152          64 :       ev_rep_prop_vals[i] = *_additional_reported_property_values[i];
     153          44 :   _communicator.broadcast(ev_rep_prop_vals, rank, /*identical_sizes=*/true);
     154         132 :   for (const auto i : make_range(prop_size))
     155          88 :     *_additional_reported_property_values[i] = ev_rep_prop_vals[i];
     156          44 : }
     157             : 
     158             : template <bool is_ad>
     159             : void
     160           4 : ElementExtremeMaterialPropertyReporterTempl<is_ad>::threadJoin(const UserObject & uo)
     161             : {
     162           4 :   const auto & rpt = static_cast<const ElementExtremeMaterialPropertyReporterTempl<is_ad> &>(uo);
     163           4 :   const auto prop_size = _additional_reported_property_values.size();
     164             : 
     165           4 :   switch (_type)
     166             :   {
     167           2 :     case ExtremeType::MAX:
     168           2 :       if (rpt._extreme_value > _extreme_value)
     169             :       {
     170           0 :         _extreme_value = rpt._extreme_value;
     171           0 :         _coordinates = rpt._coordinates;
     172           0 :         for (const auto i : make_range(prop_size))
     173           0 :           *_additional_reported_property_values[i] = *(rpt._additional_reported_property_values[i]);
     174             :       }
     175           2 :       break;
     176             : 
     177           2 :     case ExtremeType::MIN:
     178           2 :       if (rpt._extreme_value < _extreme_value)
     179             :       {
     180           0 :         _extreme_value = rpt._extreme_value;
     181           0 :         _coordinates = rpt._coordinates;
     182           0 :         for (const auto i : make_range(prop_size))
     183           0 :           *_additional_reported_property_values[i] = *(rpt._additional_reported_property_values[i]);
     184             :       }
     185           2 :       break;
     186             :   }
     187           4 : }
     188             : 
     189             : template class ElementExtremeMaterialPropertyReporterTempl<false>;
     190             : template class ElementExtremeMaterialPropertyReporterTempl<true>;

Generated by: LCOV version 1.14