Repository: idaholab/moose
Pull request #30104: Fix combo marker block restriction issues
Author: login: GiudGiud
Labels: name: PR: Failed but allowed
name: PR: Ready for review/merge
Created: 2025-03-16T20:56:41Z | Merged: 2025-03-20T19:47:11Z

refs #30103


Diff:
diff --git a/framework/include/markers/ComboMarker.h b/framework/include/markers/ComboMarker.h
index 6ff9ff9f264d..84c964dc1387 100644
--- a/framework/include/markers/ComboMarker.h
+++ b/framework/include/markers/ComboMarker.h
@@ -12,7 +12,7 @@
 #include "Marker.h"
 
 /**
- * Combines multiple marker fields.  The most conservative wins.
+ * Combines multiple marker fields.  The most conservative (requesting additional refinement) wins.
  */
 class ComboMarker : public Marker
 {
@@ -24,7 +24,15 @@ class ComboMarker : public Marker
 protected:
   virtual MarkerValue computeElementMarker() override;
 
-  std::vector<MarkerName> _names;
+  /// Names of the markers contributing to the combo
+  const std::vector<MarkerName> & _names;
 
+  /// Pointers to the markers contributing to the Combo marker
   std::vector<const VariableValue *> _markers;
+
+  /// Boolean to keep track of whether any marker does not have the same block restriction
+  bool _block_restriction_mismatch;
+
+  /// Pointers to the variables for the markers
+  std::vector<const MooseVariableFieldBase *> _marker_variables;
 };
diff --git a/framework/include/markers/Marker.h b/framework/include/markers/Marker.h
index 14b1ac9d1ddf..e2ad2834e73b 100644
--- a/framework/include/markers/Marker.h
+++ b/framework/include/markers/Marker.h
@@ -71,6 +71,7 @@ class Marker : public MooseObject,
    */
   static MooseEnum markerStates();
 
+  /// Computes and sets the value of the refinement flag
   virtual void computeMarker();
 
   bool isActive() const;
@@ -115,9 +116,12 @@ class Marker : public MooseObject,
 
   Assembly & _assembly;
 
+  /// Reference to this marker as a variable
   MooseVariable & _field_var;
+  /// Pointer to the current element being considered in the marker element-based loop
   const Elem * const & _current_elem;
 
+  /// Reference to the mesh, obtained from the subproblem
   MooseMesh & _mesh;
 
   /// Depend Markers
diff --git a/framework/src/markers/ComboMarker.C b/framework/src/markers/ComboMarker.C
index 469d0ad6a26b..760f5340cfaa 100644
--- a/framework/src/markers/ComboMarker.C
+++ b/framework/src/markers/ComboMarker.C
@@ -8,6 +8,7 @@
 //* https://www.gnu.org/licenses/lgpl-2.1.html
 
 #include "ComboMarker.h"
+#include "FEProblemBase.h"
 
 registerMooseObject("MooseApp", ComboMarker);
 
@@ -24,10 +25,33 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(getParam<std::vector<MarkerName>>("markers")),
+    _block_restriction_mismatch(false)
 {
   for (const auto & marker_name : _names)
     _markers.push_back(&getMarkerValue(marker_name));
+
+  std::string other_block_restricted = "";
+  for (const auto & marker_name : _names)
+  {
+    const auto var_ptr = &_subproblem.getVariable(_tid, marker_name);
+    _marker_variables.push_back(var_ptr);
+
+    // Check block restrictions
+    if (blockIDs() != var_ptr->blockIDs())
+      other_block_restricted += (other_block_restricted == "" ? "" : ", ") + marker_name;
+  }
+
+  if (other_block_restricted != "")
+  {
+    _block_restriction_mismatch = true;
+    paramInfo(
+        "markers",
+        "Combo marker and markers '" + other_block_restricted +
+            "' do not share the same block restrictions. Markers outside their block restriction "
+            "will not mark.");
+  }
 }
 
 Marker::MarkerValue
@@ -36,8 +60,14 @@ ComboMarker::computeElementMarker()
   // We start with DONT_MARK because it's -1
   MarkerValue marker_value = DONT_MARK;
 
-  for (const auto & var : _markers)
-    marker_value = std::max(marker_value, static_cast<MarkerValue>((*var)[0]));
+  // No need to check block restrictions if they all match
+  if (!_block_restriction_mismatch)
+    for (const auto & var : _markers)
+      marker_value = std::max(marker_value, static_cast<MarkerValue>((*var)[0]));
+  else
+    for (const auto i : index_range(_markers))
+      if (_marker_variables[i]->hasBlocks(_current_elem->subdomain_id()))
+        marker_value = std::max(marker_value, static_cast<MarkerValue>((*_markers[i])[0]));
 
   return marker_value;
 }
diff --git a/test/tests/markers/combo_marker/combo_marker_block_restricted.i b/test/tests/markers/combo_marker/combo_marker_block_restricted.i
new file mode 100644
index 000000000000..162cfad12ec1
--- /dev/null
+++ b/test/tests/markers/combo_marker/combo_marker_block_restricted.i
@@ -0,0 +1,90 @@
+[Mesh]
+  [base]
+    type = GeneratedMeshGenerator
+    dim = 2
+    nx = 10
+    ny = 10
+    elem_type = QUAD4
+  []
+  [subdomain_1]
+    type = SubdomainBoundingBoxGenerator
+    input = base
+    bottom_left = '0.1 0.1 0'
+    block_id = 1
+    top_right = '0.4 0.9 0'
+  []
+  [subdomain_2]
+    type = SubdomainBoundingBoxGenerator
+    input = subdomain_1
+    bottom_left = '0.1 0.1 0'
+    block_id = 2
+    top_right = '0.4 0.9 0'
+    location = OUTSIDE
+  []
+[]
+
+[Variables]
+  [u]
+    order = FIRST
+    family = LAGRANGE
+  []
+[]
+
+[Kernels]
+  [diff]
+    type = Diffusion
+    variable = u
+  []
+[]
+
+[BCs]
+  [left]
+    type = DirichletBC
+    variable = u
+    boundary = 1
+    value = 0
+  []
+  [right]
+    type = DirichletBC
+    variable = u
+    boundary = 2
+    value = 1
+  []
+[]
+
+[Executioner]
+  type = Steady
+
+  solve_type = 'PJFNK'
+[]
+
+[Adaptivity]
+  initial_marker = combo
+  initial_steps = 1
+  [Markers]
+    [box]
+      type = BoxMarker
+      bottom_left = '0.0 0. 0'
+      top_right = '1 0.5 0'
+      inside = refine
+      outside = do_nothing
+      block = '1'
+    []
+    [box2]
+      type = BoxMarker
+      bottom_left = '0.5 0.5 0'
+      top_right = '0.8 0.8 0'
+      inside = refine
+      outside = coarsen
+      block = '2'
+    []
+    [combo]
+      type = ComboMarker
+      markers = 'box box2'
+    []
+  []
+[]
+
+[Outputs]
+  exodus = true
+[]
diff --git a/test/tests/markers/combo_marker/gold/combo_marker_block_restricted_out.e b/test/tests/markers/combo_marker/gold/combo_marker_block_restricted_out.e
new file mode 100644
index 000000000000..c0c39a66f71d
Binary files /dev/null and b/test/tests/markers/combo_marker/gold/combo_marker_block_restricted_out.e differ
diff --git a/test/tests/markers/combo_marker/tests b/test/tests/markers/combo_marker/tests
index 863e8d8d42c5..08b20f93b80a 100644
--- a/test/tests/markers/combo_marker/tests
+++ b/test/tests/markers/combo_marker/tests
@@ -1,13 +1,19 @@
 [Tests]
-  issues = '#1303'
   design = 'ComboMarker.md'
 
-  [./test]
+  [test]
     type = 'Exodiff'
     input = 'combo_marker_test.i'
     exodiff = 'combo_marker_test_out.e'
     scale_refine = 2
-
     requirement = "The system shall include the ability to combine multiple mesh refinement markers into a single value."
-  [../]
+    issues = '#1303'
+  []
+  [test_block_restriction]
+    type = 'Exodiff'
+    input = 'combo_marker_block_restricted.i'
+    exodiff = 'combo_marker_block_restricted_out.e'
+    requirement = "The system shall include the ability to combine multiple mesh refinement markers into a single value even if the block restrictions of each marker do not match."
+    issues = '#30103'
+  []
 []


Reviews:
user: login: lindsayad
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-17T19:56:08Z
user: login: GiudGiud
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T20:21:22Z
user: login: lindsayad
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-17T20:51:22Z

Review comments:
diff_hunk: @@ -24,7 +24,15 @@ class ComboMarker : public Marker
 protected:
   virtual MarkerValue computeElementMarker() override;
 
-  std::vector<MarkerName> _names;
+  /// Names of the markers contributing to the combo
+  const std::vector<MarkerName> _names;
path: framework/include/markers/ComboMarker.h
user: login: lindsayad
body: ```suggestion
  const std::vector<MarkerName> & _names;
```
created_at: 2025-03-17T19:47:16Z
author_association: MEMBER
diff_hunk: @@ -24,10 +25,31 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(parameters.get<std::vector<MarkerName>>("markers")),
path: framework/src/markers/ComboMarker.C
user: login: lindsayad
body: ```suggestion
    _names(getParam<std::vector<MarkerName>>("markers")),
```
created_at: 2025-03-17T19:48:39Z
author_association: MEMBER
diff_hunk: @@ -24,10 +25,31 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(parameters.get<std::vector<MarkerName>>("markers")),
+    _block_restriction_mismatch(false)
 {
   for (const auto & marker_name : _names)
     _markers.push_back(&getMarkerValue(marker_name));
+
+  for (const auto & marker_name : _names)
+    _marker_variables.push_back(&_fe_problem.getVariable(_tid, marker_name));
+
+  // Check block restrictions
+  std::string other_block_restricted = "";
+  for (const auto & marker_name : _names)
+    if (blockIDs() != _fe_problem.getVariable(_tid, marker_name).blockIDs())
path: framework/src/markers/ComboMarker.C
user: login: lindsayad
body: Can you consolidate the two loops, only call `_subproblem.getVariable` once?
created_at: 2025-03-17T19:51:47Z
author_association: MEMBER
diff_hunk: @@ -24,10 +25,31 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(parameters.get<std::vector<MarkerName>>("markers")),
+    _block_restriction_mismatch(false)
 {
   for (const auto & marker_name : _names)
     _markers.push_back(&getMarkerValue(marker_name));
+
+  for (const auto & marker_name : _names)
+    _marker_variables.push_back(&_fe_problem.getVariable(_tid, marker_name));
path: framework/src/markers/ComboMarker.C
user: login: lindsayad
body: ```suggestion
    _marker_variables.push_back(&_subproblem.getVariable(_tid, marker_name));
```
created_at: 2025-03-17T19:52:18Z
author_association: MEMBER
diff_hunk: @@ -24,10 +25,31 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(parameters.get<std::vector<MarkerName>>("markers")),
+    _block_restriction_mismatch(false)
 {
   for (const auto & marker_name : _names)
     _markers.push_back(&getMarkerValue(marker_name));
+
+  for (const auto & marker_name : _names)
+    _marker_variables.push_back(&_fe_problem.getVariable(_tid, marker_name));
path: framework/src/markers/ComboMarker.C
user: login: lindsayad
body: Markers may be placed on the displaced mesh vs. undisplaced
created_at: 2025-03-17T19:54:09Z
author_association: MEMBER
diff_hunk: @@ -1,13 +1,19 @@
 [Tests]
-  issues = '#1303'
   design = 'ComboMarker.md'
 
-  [./test]
+  [test]
     type = 'Exodiff'
     input = 'combo_marker_test.i'
     exodiff = 'combo_marker_test_out.e'
     scale_refine = 2
-
     requirement = "The system shall include the ability to combine multiple mesh refinement markers into a single value."
-  [../]
+    issues = '#1303'
+  []
+  [test_block_restriction]
+    type = 'Exodiff'
+    input = 'combo_marker_block_restricted.i'
+    exodiff = 'combo_marker_block_restricted_out.e'
+    requirement = "The system shall include the ability to combine multiple mesh refinement markers into a single value even if the block restriction of each marker do not match."
path: test/tests/markers/combo_marker/tests
user: login: lindsayad
body: ```suggestion
    requirement = "The system shall include the ability to combine multiple mesh refinement markers into a single value even if the block restrictions of each marker do not match."
```
created_at: 2025-03-17T19:55:58Z
author_association: MEMBER
diff_hunk: @@ -24,10 +25,31 @@ ComboMarker::validParams()
 }
 
 ComboMarker::ComboMarker(const InputParameters & parameters)
-  : Marker(parameters), _names(parameters.get<std::vector<MarkerName>>("markers"))
+  : Marker(parameters),
+    _names(parameters.get<std::vector<MarkerName>>("markers")),
+    _block_restriction_mismatch(false)
 {
   for (const auto & marker_name : _names)
     _markers.push_back(&getMarkerValue(marker_name));
+
+  for (const auto & marker_name : _names)
+    _marker_variables.push_back(&_fe_problem.getVariable(_tid, marker_name));
+
+  // Check block restrictions
+  std::string other_block_restricted = "";
+  for (const auto & marker_name : _names)
+    if (blockIDs() != _fe_problem.getVariable(_tid, marker_name).blockIDs())
path: framework/src/markers/ComboMarker.C
user: login: GiudGiud
body: done
created_at: 2025-03-17T20:21:22Z
author_association: CONTRIBUTOR

PR comments:
user: login: moosebuild
created_at: 2025-03-16T23:36:41Z
body: Job [Documentation](https://civet.inl.gov/job/2753300/), step Docs: sync website on 6998d62 wanted to post the following:

View the site [here](https://mooseframework.inl.gov/docs/PRs/30104/site)

This comment will be updated on new commits.
author_association: CONTRIBUTOR
user: login: moosebuild
created_at: 2025-03-16T23:52:43Z
body: Job [Coverage](https://civet.inl.gov/job/2753316/), step Generate coverage on 6998d62 wanted to post the following:


## Framework coverage

<table>
  <thead>
    <tr>
      <th></th>
      <th>3403d2</th>
      <th colspan=4>#30104 6998d6</th>
    </tr>
    <tr>
      <th></th>
      <th>Total</th>
      <th>Total</th>
      <th>+/-</th>
      <th>New</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><b>Rate</b></td>
      <td>85.29%</td>
      <td>85.29%</td>
      <td>+0.00%</td>
      <td>100.00%</td>
    </tr>
    <tr>
      <td><b>Hits</b></td>
      <td>109051</td>
      <td>109066</td>
      <td>+15</td>
      <td>18</td>
    </tr>
    <tr>
      <td><b>Misses</b></td>
      <td>18808</td>
      <td>18808</td>
      <td>-</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

[Diff coverage report](https://mooseframework.inl.gov/docs/PRs/30104/coverage_diff/framework)

[Full coverage report](https://mooseframework.inl.gov/docs/PRs/30104/coverage/framework)


## Modules coverage

Coverage did not change

## Full coverage reports

<details>
<summary>Reports</summary>

- [`framework`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/framework)
- [`chemical_reactions`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/chemical_reactions)
- [`combined`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/combined)
- [`contact`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/contact)
- [`electromagnetics`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/electromagnetics)
- [`external_petsc_solver`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/external_petsc_solver)
- [`fluid_properties`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/fluid_properties)
- [`fsi`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/fsi)
- [`functional_expansion_tools`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/functional_expansion_tools)
- [`geochemistry`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/geochemistry)
- [`heat_transfer`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/heat_transfer)
- [`level_set`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/level_set)
- [`misc`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/misc)
- [`navier_stokes`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/navier_stokes)
- [`optimization`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/optimization)
- [`peridynamics`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/peridynamics)
- [`phase_field`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/phase_field)
- [`porous_flow`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/porous_flow)
- [`ray_tracing`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/ray_tracing)
- [`rdg`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/rdg)
- [`reactor`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/reactor)
- [`richards`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/richards)
- [`scalar_transport`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/scalar_transport)
- [`solid_mechanics`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/solid_mechanics)
- [`solid_properties`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/solid_properties)
- [`stochastic_tools`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/stochastic_tools)
- [`subchannel`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/subchannel)
- [`thermal_hydraulics`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/thermal_hydraulics)
- [`xfem`](https://mooseframework.inl.gov/docs/PRs/30104/coverage/xfem)

</details>



This comment will be updated on new commits.
author_association: CONTRIBUTOR