LCOV - code coverage report
Current view: top level - src/postprocessors - FauxGrainTracker.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 98 105 93.3 %
Date: 2025-09-04 07:55:36 Functions: 14 15 93.3 %
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 "FauxGrainTracker.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "MooseMesh.h"
      14             : #include "MooseVariable.h"
      15             : #include "Assembly.h"
      16             : 
      17             : registerMooseObject("PhaseFieldApp", FauxGrainTracker);
      18             : 
      19             : InputParameters
      20         110 : FauxGrainTracker::validParams()
      21             : {
      22         110 :   InputParameters params = GrainTrackerInterface::validParams();
      23         110 :   params.addClassDescription("Fake grain tracker object for cases where the number of grains is "
      24             :                              "equal to the number of order parameters.");
      25             : 
      26         110 :   return params;
      27           0 : }
      28             : 
      29          55 : FauxGrainTracker::FauxGrainTracker(const InputParameters & parameters)
      30             :   : FeatureFloodCount(parameters),
      31             :     GrainTrackerInterface(),
      32          55 :     _grain_count(0),
      33          55 :     _n_vars(_vars.size()),
      34         110 :     _tracking_step(getParam<int>("tracking_step"))
      35             : {
      36             :   // initialize faux data with identity map
      37          55 :   _op_to_grains.resize(_n_vars);
      38         363 :   for (MooseIndex(_op_to_grains) i = 0; i < _op_to_grains.size(); ++i)
      39         308 :     _op_to_grains[i] = i;
      40             : 
      41          55 :   _empty_var_to_features.resize(_n_vars, FeatureFloodCount::invalid_id);
      42          55 : }
      43             : 
      44         275 : FauxGrainTracker::~FauxGrainTracker() {}
      45             : 
      46             : Real
      47      121954 : FauxGrainTracker::getEntityValue(dof_id_type entity_id,
      48             :                                  FeatureFloodCount::FieldType field_type,
      49             :                                  std::size_t var_idx) const
      50             : {
      51             :   if (var_idx == FeatureFloodCount::invalid_size_t)
      52             :     var_idx = 0;
      53             : 
      54             :   mooseAssert(var_idx < _n_vars, "Index out of range");
      55             : 
      56      121954 :   switch (field_type)
      57             :   {
      58      114479 :     case FieldType::UNIQUE_REGION:
      59             :     case FieldType::VARIABLE_COLORING:
      60             :     {
      61             :       auto entity_it = _entity_id_to_var_num.find(entity_id);
      62             : 
      63      114479 :       if (entity_it != _entity_id_to_var_num.end())
      64       85024 :         return entity_it->second;
      65             :       else
      66             :         return -1;
      67             :       break;
      68             :     }
      69             : 
      70        7475 :     case FieldType::CENTROID:
      71             :     {
      72        7475 :       if (_periodic_node_map.size())
      73           0 :         mooseDoOnce(mooseWarning(
      74             :             "Centroids are not correct when using periodic boundaries, contact the MOOSE team"));
      75             : 
      76             :       // If this element contains the centroid of one of features, return it's index
      77        7475 :       const auto * elem_ptr = _mesh.elemPtr(entity_id);
      78       17459 :       for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
      79             :       {
      80       10049 :         const auto centroid = _centroid.find(var_num);
      81       10049 :         if (centroid != _centroid.end())
      82       10049 :           if (elem_ptr->contains_point(centroid->second))
      83             :             return 1;
      84             :       }
      85             : 
      86             :       return 0;
      87             :     }
      88             : 
      89             :     // We don't want to error here because this should be a drop in replacement for the real grain
      90             :     // tracker.
      91             :     // Instead we'll just return zero and continue
      92             :     default:
      93             :       return 0;
      94             :   }
      95             : 
      96             :   return 0;
      97             : }
      98             : 
      99             : const std::vector<unsigned int> &
     100      501325 : FauxGrainTracker::getVarToFeatureVector(dof_id_type elem_id) const
     101             : {
     102             :   const auto pos = _entity_var_to_features.find(elem_id);
     103      501325 :   if (pos != _entity_var_to_features.end())
     104             :   {
     105             :     mooseAssert(pos->second.size() == _n_vars, "Variable to feature vector not sized properly");
     106      501325 :     return pos->second;
     107             :   }
     108             :   else
     109           0 :     return _empty_var_to_features;
     110             : }
     111             : 
     112             : unsigned int
     113          51 : FauxGrainTracker::getFeatureVar(unsigned int feature_id) const
     114             : {
     115          51 :   return feature_id;
     116             : }
     117             : 
     118             : std::size_t
     119           0 : FauxGrainTracker::getNumberActiveGrains() const
     120             : {
     121           0 :   return _variables_used.size();
     122             : }
     123             : 
     124             : std::size_t
     125         194 : FauxGrainTracker::getTotalFeatureCount() const
     126             : {
     127         194 :   return _grain_count;
     128             : }
     129             : 
     130             : Point
     131     8121876 : FauxGrainTracker::getGrainCentroid(unsigned int grain_index) const
     132             : {
     133             :   const auto grain_center = _centroid.find(grain_index);
     134             :   mooseAssert(grain_center != _centroid.end(),
     135             :               "Grain " << grain_index << " does not exist in data structure");
     136             : 
     137     8121876 :   return grain_center->second;
     138             : }
     139             : 
     140             : void
     141         100 : FauxGrainTracker::initialize()
     142             : {
     143             :   _entity_id_to_var_num.clear();
     144             :   _entity_var_to_features.clear();
     145             :   _variables_used.clear();
     146         100 :   if (_is_elemental)
     147             :   {
     148             :     _volume.clear();
     149             :     _vol_count.clear();
     150             :     _centroid.clear();
     151             :   }
     152         100 : }
     153             : 
     154             : void
     155         100 : FauxGrainTracker::execute()
     156             : {
     157         200 :   TIME_SECTION("execute", 2, "Executing grain tracker");
     158             : 
     159      266722 :   for (const auto & current_elem : _mesh.getMesh().active_local_element_ptr_range())
     160             :   {
     161             :     // Loop over elements or nodes and populate the data structure with the first variable with a
     162             :     // value above a threshold
     163      133261 :     if (_is_elemental)
     164             :     {
     165      121386 :       std::vector<Point> centroid(1, current_elem->vertex_average());
     166      121386 :       _fe_problem.reinitElemPhys(current_elem, centroid, 0);
     167             : 
     168      121386 :       auto entity = current_elem->id();
     169             :       auto insert_pair =
     170      121386 :           moose_try_emplace(_entity_var_to_features,
     171             :                             entity,
     172      242772 :                             std::vector<unsigned int>(_n_vars, FeatureFloodCount::invalid_id));
     173             :       auto & vec_ref = insert_pair.first->second;
     174             : 
     175      306378 :       for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
     176             :       {
     177      302101 :         auto entity_value = _vars[var_num]->sln()[0];
     178             : 
     179      302101 :         if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) ||
     180           0 :             (!_use_less_than_threshold_comparison && (entity_value <= _threshold)))
     181             :         {
     182      117109 :           _entity_id_to_var_num[current_elem->id()] = var_num;
     183      117109 :           _variables_used.insert(var_num);
     184      117109 :           _volume[var_num] += _assembly.elementVolume(current_elem);
     185      117109 :           _vol_count[var_num]++;
     186             :           // Sum the centroid values for now, we'll average them later
     187      117109 :           _centroid[var_num] += current_elem->vertex_average();
     188      117109 :           vec_ref[var_num] = var_num;
     189      117109 :           break;
     190             :         }
     191             :       }
     192      121386 :     }
     193             :     else
     194             :     {
     195       11875 :       unsigned int n_nodes = current_elem->n_vertices();
     196       59375 :       for (unsigned int i = 0; i < n_nodes; ++i)
     197             :       {
     198       47500 :         const Node * current_node = current_elem->node_ptr(i);
     199             : 
     200      242270 :         for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
     201             :         {
     202      241802 :           auto entity_value = _vars[var_num]->getNodalValue(*current_node);
     203      241802 :           if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) ||
     204           0 :               (!_use_less_than_threshold_comparison && (entity_value <= _threshold)))
     205             :           {
     206       47032 :             _entity_id_to_var_num[current_node->id()] = var_num;
     207       47032 :             _variables_used.insert(var_num);
     208       47032 :             break;
     209             :           }
     210             :         }
     211             :       }
     212             :     }
     213         100 :   }
     214             : 
     215         148 :   _grain_count = std::max(_grain_count, _variables_used.size());
     216         100 : }
     217             : 
     218             : void
     219         100 : FauxGrainTracker::finalize()
     220             : {
     221         200 :   TIME_SECTION("finalize", 2, "Finalizing grain tracker");
     222             : 
     223         100 :   _communicator.set_union(_variables_used);
     224         100 :   _communicator.set_union(_entity_id_to_var_num);
     225             : 
     226         100 :   if (_is_elemental)
     227         474 :     for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num)
     228             :     {
     229             :       /**
     230             :        * Convert elements of the maps into simple values or vector of Real.
     231             :        * libMesh's _communicator.sum() does not work on std::maps
     232             :        */
     233             :       unsigned int vol_count;
     234         399 :       std::vector<Real> grain_data(4);
     235             : 
     236         399 :       const auto count = _vol_count.find(var_num);
     237         399 :       if (count != _vol_count.end())
     238         385 :         vol_count = count->second;
     239             : 
     240         399 :       const auto vol = _volume.find(var_num);
     241         399 :       if (vol != _volume.end())
     242         385 :         grain_data[0] = vol->second;
     243             : 
     244         399 :       const auto centroid = _centroid.find(var_num);
     245         399 :       if (centroid != _centroid.end())
     246             :       {
     247         385 :         grain_data[1] = centroid->second(0);
     248         385 :         grain_data[2] = centroid->second(1);
     249         385 :         grain_data[3] = centroid->second(2);
     250             :       }
     251             :       // combine centers & volumes from all MPI ranks
     252             :       gatherSum(vol_count);
     253             :       gatherSum(grain_data);
     254         399 :       _volume[var_num] = grain_data[0];
     255         399 :       _centroid[var_num] = {grain_data[1], grain_data[2], grain_data[3]};
     256         399 :       _centroid[var_num] /= vol_count;
     257         399 :     }
     258         100 : }
     259             : 
     260             : Real
     261         100 : FauxGrainTracker::getValue() const
     262             : {
     263         100 :   return static_cast<Real>(_variables_used.size());
     264             : }
     265             : 
     266             : bool
     267          51 : FauxGrainTracker::doesFeatureIntersectBoundary(unsigned int /*feature_id*/) const
     268             : {
     269          51 :   mooseDoOnce(mooseWarning("FauxGrainTracker::doesFeatureIntersectboundary() is unimplemented"));
     270             : 
     271          51 :   return false;
     272             : }

Generated by: LCOV version 1.14