LCOV - code coverage report
Current view: top level - src/loops - FlagElementsThread.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 48 49 98.0 %
Date: 2025-07-17 01:28:37 Functions: 4 4 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 "FlagElementsThread.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "AuxiliarySystem.h"
      14             : #include "DisplacedProblem.h"
      15             : #include "FEProblem.h"
      16             : #include "Marker.h"
      17             : #include "MooseVariableFE.h"
      18             : #include "Problem.h"
      19             : 
      20             : #include "libmesh/threads.h"
      21             : 
      22             : // C++ includes
      23             : #include <cmath> // provides round, not std::round (see http://www.cplusplus.com/reference/cmath/round/)
      24             : 
      25        4833 : FlagElementsThread::FlagElementsThread(FEProblemBase & fe_problem,
      26             :                                        std::vector<Number> & serialized_solution,
      27             :                                        unsigned int max_h_level,
      28             :                                        const std::string & marker_name,
      29        4833 :                                        bool is_serialized_solution)
      30             :   : ThreadedElementLoop<ConstElemRange>(fe_problem),
      31        4833 :     _fe_problem(fe_problem),
      32        4833 :     _displaced_problem(_fe_problem.getDisplacedProblem()),
      33        4833 :     _aux_sys(fe_problem.getAuxiliarySystem()),
      34        4833 :     _system_number(_aux_sys.number()),
      35        4833 :     _adaptivity(_fe_problem.adaptivity()),
      36        4833 :     _field_var(_fe_problem.getVariable(
      37             :         0, marker_name, Moose::VarKindType::VAR_ANY, Moose::VarFieldType::VAR_FIELD_ANY)),
      38        4833 :     _field_var_number(_field_var.number()),
      39        4833 :     _serialized_solution(serialized_solution),
      40        4833 :     _max_h_level(max_h_level),
      41        4833 :     _is_serialized_solution(is_serialized_solution)
      42             : {
      43        4833 : }
      44             : 
      45             : // Splitting Constructor
      46         461 : FlagElementsThread::FlagElementsThread(FlagElementsThread & x, Threads::split split)
      47             :   : ThreadedElementLoop<ConstElemRange>(x, split),
      48         461 :     _fe_problem(x._fe_problem),
      49         461 :     _displaced_problem(x._displaced_problem),
      50         461 :     _aux_sys(x._aux_sys),
      51         461 :     _system_number(x._system_number),
      52         461 :     _adaptivity(x._adaptivity),
      53         461 :     _field_var(x._field_var),
      54         461 :     _field_var_number(x._field_var_number),
      55         461 :     _serialized_solution(x._serialized_solution),
      56         461 :     _max_h_level(x._max_h_level),
      57         461 :     _is_serialized_solution(x._is_serialized_solution)
      58             : {
      59         461 : }
      60             : 
      61             : void
      62     1608716 : FlagElementsThread::onElement(const Elem * elem)
      63             : {
      64             :   mooseAssert(elem->active(), "This thread should only act on active elements");
      65             : 
      66             :   // By default do nothing, and only grab the marker from the solution if the current variable is
      67             :   // active
      68             :   // on the element subdomain.
      69     1608716 :   Marker::MarkerValue marker_value = Marker::DO_NOTHING;
      70     1608716 :   if (_field_var.activeOnSubdomain(elem->subdomain_id()))
      71             :   {
      72     1606379 :     dof_id_type dof_number = elem->dof_number(_system_number, _field_var_number, 0);
      73             : 
      74     1606379 :     Number dof_value = 0.;
      75             :     // If solution is serialized in the caller,
      76             :     // we use the serialized solution
      77     1606379 :     if (_is_serialized_solution)
      78     1469132 :       dof_value = _serialized_solution[dof_number];
      79             :     else // Otherwise, we look at the ghosted local solution
      80             :     {
      81             :       // Local ghosted solution
      82      137247 :       auto & current_local_solution = *_aux_sys.currentSolution();
      83             :       // Libesh will convert a global dof number to a local one,
      84             :       // then return the corresponding entry value
      85      137247 :       dof_value = current_local_solution(dof_number);
      86             :     }
      87             : 
      88             :     // round() is a C99 function, it is not located in the std:: namespace.
      89     1606379 :     marker_value = static_cast<Marker::MarkerValue>(round(dof_value));
      90             : 
      91             :     // Make sure we aren't masking an issue in the Marker system by rounding its values.
      92     1606379 :     if (std::abs(marker_value - dof_value) > TOLERANCE * TOLERANCE)
      93           0 :       mooseError("Invalid Marker value detected: ", dof_value);
      94             :   }
      95             : 
      96             :   // If no Markers cared about what happened to this element let's just leave it alone
      97     1608716 :   if (marker_value == Marker::DONT_MARK)
      98      557712 :     marker_value = Marker::DO_NOTHING;
      99             : 
     100             :   // Don't refine past the max level
     101     1608716 :   if (_max_h_level && marker_value == Marker::REFINE && elem->level() >= _max_h_level)
     102      343380 :     marker_value = Marker::DO_NOTHING;
     103             : 
     104     1608716 :   const_cast<Elem *>(elem)->set_refinement_flag((Elem::RefinementState)marker_value);
     105             : 
     106     1608716 :   if (_displaced_problem)
     107      324710 :     _displaced_problem->mesh()
     108      324710 :         .elemPtr(elem->id())
     109      324710 :         ->set_refinement_flag((Elem::RefinementState)marker_value);
     110     1608716 : }
     111             : 
     112             : void
     113         461 : FlagElementsThread::join(const FlagElementsThread & /*y*/)
     114             : {
     115         461 : }

Generated by: LCOV version 1.14