From ab040fae39740cf32ba06357e6da32a3d1cde848 Mon Sep 17 00:00:00 2001 From: Kyle Gamble Date: Wed, 14 Nov 2018 08:07:39 -0700 Subject: [PATCH] Add new layer_bounding_block parameter in LayeredBase to allow NodalUserObjects executed on a boundary to be used with layers defined by a block. Closes #12479. --- framework/include/userobject/LayeredBase.h | 2 +- framework/src/userobject/LayeredBase.C | 22 ++- .../src/userobject/LayeredSideIntegral.C | 4 + .../block_restricted_num_layers.i | 98 ------------- .../gold/layered_average_bounding_block_out.e | Bin 0 -> 35440 bytes .../layered_average_bounding_block.e | Bin 0 -> 3592 bytes .../layered_average_bounding_block.i | 129 ++++++++++++++++++ test/tests/userobjects/layered_average/tests | 9 ++ .../userobjects/layered_side_integral/tests | 13 ++ 9 files changed, 171 insertions(+), 106 deletions(-) delete mode 100644 test/tests/userobjects/layered_average/block_restricted_num_layers.i create mode 100644 test/tests/userobjects/layered_average/gold/layered_average_bounding_block_out.e create mode 100644 test/tests/userobjects/layered_average/layered_average_bounding_block.e create mode 100644 test/tests/userobjects/layered_average/layered_average_bounding_block.i diff --git a/framework/include/userobject/LayeredBase.h b/framework/include/userobject/LayeredBase.h index fd6f701c7c33..954369ed53e1 100644 --- a/framework/include/userobject/LayeredBase.h +++ b/framework/include/userobject/LayeredBase.h @@ -133,7 +133,7 @@ class LayeredBase : private Restartable bool _cumulative; /// List of SubdomainIDs, if given - std::vector _blocks; + std::vector _layer_bounding_blocks; }; #endif diff --git a/framework/src/userobject/LayeredBase.C b/framework/src/userobject/LayeredBase.C index 897b0e4847f2..38982c11e0f5 100644 --- a/framework/src/userobject/LayeredBase.C +++ b/framework/src/userobject/LayeredBase.C @@ -54,6 +54,12 @@ validParams() params.addParam>( "block", "The list of block ids (SubdomainID) that this object will be applied"); + params.addParam>("layer_bounding_block", + "List of block ids (SubdomainID) that are used to " + "determine the upper and lower geometric bounds for " + "all layers. If this is not specified, the ids " + "specified in 'block' are used for this purpose."); + return params; } @@ -73,7 +79,7 @@ LayeredBase::LayeredBase(const InputParameters & parameters) _layer_has_value(declareRestartableData>("layer_has_value")), _layered_base_subproblem(*parameters.getCheckedPointerParam("_subproblem")), _cumulative(parameters.get("cumulative")), - _blocks() + _layer_bounding_blocks() { if (_layered_base_params.isParamValid("num_layers") && _layered_base_params.isParamValid("bounds")) @@ -101,8 +107,11 @@ LayeredBase::LayeredBase(const InputParameters & parameters) if (!_interval_based && _sample_type == 1) mooseError("'sample_type = interpolate' not supported with 'bounds' in ", _layered_base_name); - if (_layered_base_params.isParamValid("block")) - _blocks = _layered_base_subproblem.mesh().getSubdomainIDs( + if (_layered_base_params.isParamValid("layer_bounding_block")) + _layer_bounding_blocks = _layered_base_subproblem.mesh().getSubdomainIDs( + _layered_base_params.get>("layer_bounding_block")); + else if (_layered_base_params.isParamValid("block")) + _layer_bounding_blocks = _layered_base_subproblem.mesh().getSubdomainIDs( _layered_base_params.get>("block")); _layer_values.resize(_num_layers); @@ -234,9 +243,7 @@ void LayeredBase::initialize() { if (_using_displaced_mesh) - { getBounds(); - } for (unsigned int i = 0; i < _layer_values.size(); i++) { @@ -322,7 +329,7 @@ LayeredBase::setLayerValue(unsigned int layer, Real value) void LayeredBase::getBounds() { - if (_blocks.size() == 0) + if (_layer_bounding_blocks.size() == 0) { BoundingBox bounding_box = MeshTools::create_bounding_box(_layered_base_subproblem.mesh()); _direction_min = bounding_box.min()(_direction); @@ -339,7 +346,8 @@ LayeredBase::getBounds() { auto subdomain_id = elem_ptr->subdomain_id(); - if (std::find(_blocks.begin(), _blocks.end(), subdomain_id) == _blocks.end()) + if (std::find(_layer_bounding_blocks.begin(), _layer_bounding_blocks.end(), subdomain_id) == + _layer_bounding_blocks.end()) continue; for (auto & node : elem_ptr->node_ref_range()) diff --git a/framework/src/userobject/LayeredSideIntegral.C b/framework/src/userobject/LayeredSideIntegral.C index 3c1187483aec..3bc93dbbcf67 100644 --- a/framework/src/userobject/LayeredSideIntegral.C +++ b/framework/src/userobject/LayeredSideIntegral.C @@ -23,6 +23,10 @@ validParams() LayeredSideIntegral::LayeredSideIntegral(const InputParameters & parameters) : SideIntegralVariableUserObject(parameters), LayeredBase(parameters) { + if (parameters.isParamValid("block") && parameters.isParamValid("boundary")) + mooseError("Both block and boundary cannot be specified in LayeredSideIntegral. If you want to " + "define the geometric bounds of the layers from a specified block set " + "layer_bounding_block instead."); } void diff --git a/test/tests/userobjects/layered_average/block_restricted_num_layers.i b/test/tests/userobjects/layered_average/block_restricted_num_layers.i deleted file mode 100644 index 8bea536fa592..000000000000 --- a/test/tests/userobjects/layered_average/block_restricted_num_layers.i +++ /dev/null @@ -1,98 +0,0 @@ -[Mesh] - type = GeneratedMesh - nx = 10 - ny = 10 - dim = 2 -[] - -[Variables] - [u] - [] -[] - -[AuxVariables] - [master_app_var] - order = CONSTANT - family = MONOMIAL - block = '1' - [] -[] - -[AuxKernels] - [layered_aux] - type = SpatialUserObjectAux - variable = master_app_var - execute_on = 'timestep_end' - user_object = master_uo - block = '1' - [] -[] - -[UserObjects] - [master_uo] - type = LayeredAverage - direction = x - variable = 'u' - block = '1' - num_layers = 2 - [] -[] - -[Kernels] - [diff] - type = Diffusion - variable = u - [] -[] - -[BCs] - [left] - type = DirichletBC - variable = u - boundary = 'left' - value = 0 - [] - [right] - type = DirichletBC - variable = u - boundary = 'right' - value = 100 - [] -[] - -[Executioner] - type = Transient - nl_abs_tol = 1e-10 - nl_rel_tol = 1e-10 - petsc_options_iname = '-pc_type -pc_hypre_type' - num_steps = 1 - petsc_options_value = 'hypre boomeramg' - l_tol = 1e-8 -[] - -[Postprocessors] - [u_avg] - type = ElementAverageValue - variable = 'u' - execute_on = 'initial timestep_end' - [] - [final_avg] - type = ElementAverageValue - variable = 'master_app_var' - execute_on = 'initial timestep_end' - block = '1' - [] -[] - -[Outputs] - exodus = true -[] - -[MeshModifiers] - [middle] - type = SubdomainBoundingBox - block_id = 1 - top_right = '0.6 0.6 0' - bottom_left = '0.4 0.4 0' - [] -[] diff --git a/test/tests/userobjects/layered_average/gold/layered_average_bounding_block_out.e b/test/tests/userobjects/layered_average/gold/layered_average_bounding_block_out.e new file mode 100644 index 0000000000000000000000000000000000000000..96ab8bb7c5ef6d98398c5f3bf6be1354125ccbcc GIT binary patch literal 35440 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 literal 0 HcmV?d00001 diff --git a/test/tests/userobjects/layered_average/layered_average_bounding_block.i b/test/tests/userobjects/layered_average/layered_average_bounding_block.i new file mode 100644 index 000000000000..5c93d37e6d4d --- /dev/null +++ b/test/tests/userobjects/layered_average/layered_average_bounding_block.i @@ -0,0 +1,129 @@ +# +# The mesh consists of two blocks. Block 1 has a height and width of 1 whereas +# block 2 has a height of 2 and width of 1. A gap of 1 exists between the two +# blocks in the x direction. Elements are 0.25 high and 1 wide. The solution +# in block 1 is u = y and block 2 is u = 4y. +# +# Two sets of LayeredAverage values are computed. In both cases, four +# layers are used. In 'bounding_block1', the LayeredAverage values are computed +# on block 1 using the bounds (dimensions of block 2). In 'bounding_block2', +# the LayeredAverage values are computed on block 2 using the bounds (dimensions +# of block 1). +# +# In 'bounding_block1', since the layers are defined by the dimensions of block +# 2 only two layers appear in block one. The values in block 1 are thus: +# 0.25 for 00.75. +# +# + +[Mesh] + file = layered_average_bounding_block.e +[] + +[Variables] + [./u] + [../] +[] + +[AuxVariables] + [./bounding_block1] + order = CONSTANT + family = MONOMIAL + [../] + [./bounding_block2] + order = CONSTANT + family = MONOMIAL + [../] +[] + +[Kernels] + [./diff] + type = Diffusion + variable = u + [../] +[] + +[AuxKernels] + [./bounding_block1] + type = SpatialUserObjectAux + block = 1 + variable = bounding_block1 + execute_on = timestep_end + user_object = bounding_block1 + [../] + [./bounding_block2] + type = SpatialUserObjectAux + block = 2 + variable = bounding_block2 + execute_on = timestep_end + user_object = bounding_block2 + [../] +[] + +[BCs] + [./ll] + type = DirichletBC + variable = u + boundary = 1 + value = 0 + [../] + [./lu] + type = DirichletBC + variable = u + boundary = 2 + value = 1 + [../] + [./ul] + type = DirichletBC + variable = u + boundary = 3 + value = 0 + [../] + [./uu] + type = DirichletBC + variable = u + boundary = 4 + value = 8 + [../] +[] + +[UserObjects] + [./bounding_block1] + type = LayeredAverage + direction = y + num_layers = 4 + variable = u + execute_on = linear + block = 1 + layer_bounding_block = 2 + [../] + [./bounding_block2] + type = LayeredAverage + direction = y + num_layers = 4 + block = 2 + layer_bounding_block = 1 + variable = u + execute_on = linear + [../] +[] + +[Executioner] + type = Transient + dt = 1 + end_time = 1 +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/userobjects/layered_average/tests b/test/tests/userobjects/layered_average/tests index 5fec6022bc80..72551329ae9b 100644 --- a/test/tests/userobjects/layered_average/tests +++ b/test/tests/userobjects/layered_average/tests @@ -100,4 +100,13 @@ design = '/LayeredAverage.md' issues = '#8835 #12152' [../] + [./block_restricted_bounding_block] + type = 'Exodiff' + input = 'layered_average_bounding_block.i' + exodiff = 'layered_average_bounding_block_out.e' + + requirement = "MOOSE shall allow bounds for layered averages when using num_layers to come from a block different than the block restriction" + design = '/LayeredAverage.md' + issues = '#12479' + [../] [] diff --git a/test/tests/userobjects/layered_side_integral/tests b/test/tests/userobjects/layered_side_integral/tests index 57025d2401dd..b9a2ad022600 100644 --- a/test/tests/userobjects/layered_side_integral/tests +++ b/test/tests/userobjects/layered_side_integral/tests @@ -1,19 +1,32 @@ [Tests] + design = '\LayeredSideIntegral.md' + issues = '#1289' [./test] type = 'Exodiff' input = 'layered_side_integral_test.i' exodiff = 'out.e' + requirement = "MOOSE shall correctly compute layered integrals along a specified boundary" [../] [./average] type = 'Exodiff' input = 'layered_side_average.i' exodiff = 'layered_side_average_out.e' + requirement = "MOOSE shall allow taking averages of variables along a coordinate axis in layers on a boundary" [../] [./flux_average] type = 'Exodiff' input = 'layered_side_flux_average.i' exodiff = 'layered_side_flux_average_out.e' + requirement = "MOOSE shall allow taking averages of the flux of variables along a coordinate axis in layers on a boundary" + [../] + + [./layered_side_average_error_check] + type = RunException + input = 'layered_side_average.i' + cli_args = 'UserObjects/layered_side_average/block=0' + expect_err = "Both block and boundary cannot be specified in LayeredSideIntegral. If you want to define the geometric bounds of the layers from a specified block set layer_bounding_block instead." + requirement = "MOOSE shall not allow both the block and boundary parameter to be specified for layered side integrals" [../] []