Skip to content

Commit

Permalink
Allow prescribing radial positions in AnnularMeshGenerator closes ida…
Browse files Browse the repository at this point in the history
  • Loading branch information
bwspenc committed Jul 30, 2021
1 parent 5821942 commit 5ae6e85
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 5 deletions.
Expand Up @@ -18,7 +18,9 @@ The inner radius and the outer radius must be specified. If the inner radius is

The minimum and maximum angle may also be specified. These default to zero and 360, respectively. If other values are chosen, a sector of an annulus, or a sector of a disc will be created. Both angles are measured anti-clockwise from the xx axis.

The number of elements in the radial direction and the angular direction may be specified. In addition, a growth factor on the element size in the radial direction may be chosen. The element-size (in the radial direction) is multiplied by this factor for each concentric ring of elements, moving from the inner to the outer radius. If the growth factor is positive, element thicknesses increase in the radial direction, while if the growth factor is negative, element thicknesses decrease in the radial direction.
The number of elements in the radial direction and the angular direction may be specified. By default, the mesh density is uniform in the radial direction, but the following options are available for more control over the radial meshing:
- A growth factor that controls the element size in the radial direction may be specified. In this case, the radial element size in the innermost ring is multiplied by this factor for each concentric ring of elements, moving from the inner to the outer radius. If the growth factor is positive, the element radial dimension increases with increasing radial position, while if the growth factor is negative, the element radial dimension decreases with increasing radial position.
- A list of values that define the radial positions of the rings of interior nodes can be specified. This allows for direct control of the element size for every one of the concentric rings. In this case, the number of radial elements is not specified, because it is inferred from the length of that list.

Sidesets are also created:

Expand Down
10 changes: 7 additions & 3 deletions framework/include/meshgenerators/AnnularMeshGenerator.h
Expand Up @@ -10,6 +10,7 @@
#pragma once

#include "MeshGenerator.h"
#include <vector>

// Forward declarations
class AnnularMeshGenerator;
Expand All @@ -30,9 +31,6 @@ class AnnularMeshGenerator : public MeshGenerator
std::unique_ptr<MeshBase> generate() override;

protected:
/// Number of elements in radial direction
const unsigned _nr;

/// Number of elements in angular direction
const unsigned _nt;

Expand All @@ -42,6 +40,12 @@ class AnnularMeshGenerator : public MeshGenerator
/// Maximum radius
const Real _rmax;

/// Radial positions of intermediate rings of nodes (optional)
const std::vector<Real> _radial_positions;

/// Number of elements in radial direction
const unsigned _nr;

/// Minimum angle in degrees
const Real _dmin;

Expand Down
17 changes: 16 additions & 1 deletion framework/src/meshgenerators/AnnularMeshGenerator.C
Expand Up @@ -32,6 +32,7 @@ AnnularMeshGenerator::validParams()
"rmin>=0.0",
"Inner radius. If rmin=0 then a disc mesh (with no central hole) will be created.");
params.addRequiredParam<Real>("rmax", "Outer radius");
params.addParam<std::vector<Real>>("radial_positions", "Directly prescribed positions of intermediate radial nodes");
params.addDeprecatedParam<Real>("tmin",
0.0,
"Minimum angle, measured in radians anticlockwise from x axis",
Expand Down Expand Up @@ -73,10 +74,11 @@ AnnularMeshGenerator::validParams()

AnnularMeshGenerator::AnnularMeshGenerator(const InputParameters & parameters)
: MeshGenerator(parameters),
_nr(getParam<unsigned int>("nr")),
_nt(getParam<unsigned int>("nt")),
_rmin(getParam<Real>("rmin")),
_rmax(getParam<Real>("rmax")),
_radial_positions(getParam<std::vector<Real>>("radial_positions")),
_nr(parameters.isParamSetByUser("radial_positions") ? _radial_positions.size() + 1 : getParam<unsigned int>("nr")),
_dmin(parameters.isParamSetByUser("tmin") ? getParam<Real>("tmin") / M_PI * 180.0
: getParam<Real>("dmin")),
_dmax(parameters.isParamSetByUser("tmax") ? getParam<Real>("tmax") / M_PI * 180.0
Expand All @@ -96,6 +98,17 @@ AnnularMeshGenerator::AnnularMeshGenerator(const InputParameters & parameters)
paramError("tmin",
"You specified the angles using both degrees and radians. Please use degrees.");

if (_radial_positions.size() != 0)
{
if (parameters.isParamSetByUser("nr"))
paramError("nr", "The 'nr' parameter cannot be specified together with 'radial_positions'");
if (parameters.isParamSetByUser("growth_r"))
paramError("growth_r", "The 'growth_r' parameter cannot be specified together with 'radial_positions'");
for (auto rpos : _radial_positions)
if (rpos <= _rmin || rpos >= _rmax)
paramError("radial_positions", "The following provided value is not within the bounds between 'rmin' and 'rmax': ", rpos);
}

if (_rmax <= _rmin)
paramError("rmax", "rmax must be greater than rmin");
if (_dmax <= _dmin)
Expand Down Expand Up @@ -145,6 +158,8 @@ AnnularMeshGenerator::generate()
{
if (layer_num == 1)
current_r = _rmin; // account for precision loss
else if (_radial_positions.size() > 0)
current_r = _radial_positions[layer_num - 2];
else
{
if (_growth_r > 0)
Expand Down
24 changes: 24 additions & 0 deletions test/tests/mesh/mesh_generation/tests
Expand Up @@ -77,6 +77,30 @@
expect_err = 'quad_subdomain_id must not equal tri_subdomain_id'
detail = 'shall throw an error if the quadrilateral and triangular subdomain ids are the same.'
[]
[annular_except7]
type = 'RunException'
input = 'annular_mesh_generator_radial_positions.i'
cli_args = 'Mesh/amg/nr=1'
expect_err = "The 'nr' parameter cannot be specified together with 'radial_positions'"
detail = 'shall throw an error if both radial positions and the number of radial elements are prescribed.'
issues = '#18486'
[]
[annular_except8]
type = 'RunException'
input = 'annular_mesh_generator_radial_positions.i'
cli_args = 'Mesh/amg/growth_r=1'
expect_err = "The 'growth_r' parameter cannot be specified together with 'radial_positions'"
detail = 'shall throw an error if both radial positions and the growth_r parameter are prescribed.'
issues = '#18486'
[]
[annular_except9]
type = 'RunException'
input = 'annular_mesh_generator_radial_positions.i'
cli_args = 'Mesh/amg/rmin=3'
expect_err = "The following provided value is not within the bounds between 'rmin' and 'rmax': 2"
detail = 'shall throw an error if any of the radial positions fall out of the bounds between rmin and rmax.'
issues = '#18486'
[]
[]
[annular]
issues = '#8432'
Expand Down
@@ -0,0 +1,15 @@
[Mesh]
[./amg]
type = AnnularMeshGenerator
nt = 12
rmin = 1
rmax = 5
radial_positions = '2 4'
dmin = 45
dmax = 135
[]
[]

[Outputs]
exodus = true
[]
Binary file not shown.
11 changes: 11 additions & 0 deletions test/tests/meshgenerators/annular_mesh_generator/tests
Expand Up @@ -32,4 +32,15 @@
deprecated = true
no_error_deprecated = true
[../]
[./annular_mesh_generator_radial_positions]
type = 'Exodiff'
input = 'annular_mesh_generator_radial_positions.i'
cli_args = '--mesh-only'
exodiff = 'annular_mesh_generator_radial_positions_in.e'
mesh_mode = 'REPLICATED'
recover = false
requirement = 'The system shall generate an annular mesh with prescribed radial positions of the intermediate rings of nodes'
design = 'meshgenerators/AnnularMeshGenerator.md'
issues = '#18486'
[../]
[]

0 comments on commit 5ae6e85

Please sign in to comment.