Skip to content

Commit

Permalink
Rework RenameBlockGenerator
Browse files Browse the repository at this point in the history
- Remove _id and _name params to the single old_block and new_block params
- Allow merging that is independent of ordering

refs idaholab#17710
  • Loading branch information
loganharbour committed Nov 15, 2021
1 parent 5bc225b commit aff54b5
Show file tree
Hide file tree
Showing 19 changed files with 928 additions and 470 deletions.
73 changes: 39 additions & 34 deletions framework/doc/content/source/meshgenerators/RenameBlockGenerator.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,60 @@

!syntax description /Mesh/RenameBlockGenerator

## Overview
## Renaming or Setting Block Names

`RenameBlockGenerator` is usually used to provide meaningful names to blocks so that input files are easier to
read. For instance
When using the `RenameBlockGenerator` to change block names, the result is independent of ordering.

```text
old_block_id = '1 2 3'
new_block_name = 'wheel engine axle'
```

Then the MOOSE input file can employ `block = wheel` rather than `block = 1`. `RenameBlockGenerator` may also
be to provide more meaningful names to mesh blocks that are already named. For instance
The following will change the name for the block "meaningless" to "inside" and will set the name for block "5" to "outside":

```text
old_block_name = 'silly meaningless crazy'
new_block_name = 'wheel engine axle'
```
[rename]
type = RenameBlockGenerator
input = some_mesh
old_block = 'meainingless 5'
new_block = 'inside outside'
[]
```

Then the MOOSE input file can employ `block = axle` rather than `block = crazy`.
## Merging Blocks

!alert warning
`RenameBlockGenerator` may also be used to merge blocks, but care must be taken.
When using the `RenameBlockGenerator` to merge blocks, the result is not necessarily independent of ordering.

For instance
For example, take the following:

```
old_block_id = '1 2 3'
new_block_id = '4 4 4'
[merge]
type = RenameBlockGenerator
input = some_mesh
old_block = '0 1 2 3'
new_block = '0_and_1 0_and_1 2_and_3 2_and_3'
[]
```

Then blocks 1, 2 and 3 will be merged together into one block that may be used in the remainder of
the input file. However, when merging blocks problems and even inconsistencies can occur.
The above will result in two blocks:

- Block "0_and_1" with ID "0" that contains the elements from the original blocks "0" and "1".
- Block "2_and_3" with ID "2" that contains the elements from the original blocks "2" and "3".

Firstly, in the example just given, what if the blocks 1, 2 and 3 were named? What should the name
of the block 4 be? The convention is that it is the name of the first old block that is given the
block ID of 4, which is the name of the old block 1 in this case. The user needs to be aware of this
convention. Similarly, if `old_block_name = 'oldA oldB'` and `new_block_name = 'new1 new1'`, then
the block ID of new1 is the block ID of oldA.
Take the first execution, "0" to "0_and_1". The `RenameBlockGenerator` will use the original block ID, which is "0". The second execution "1" to "0_and_1" will use the new ID associated with "0_and_1", which is "0", and merge "1" into it. The result is similar for the third and fourth executions.

Secondly, in the example above, what if block 4 already existed? An inconsistency could arise in the
input file, because block 4 is now given the name of the old block 1.
!alert! tip title=The use of ID is order independent
The order dependent behavior only exists when the new block provided is a name. Take the following instead:

```
[merge]
type = RenameBlockGenerator
input = some_mesh
old_block = '0 1 2 3'
new_block = '0 0 4 4'
[]
```

Thirdly, in this example `old_block_id = '1 2'` and `new_block_name = 'wheel wheel'`. What if another
block, with a different ID, already had the name "wheel"? This can lead to great confusion in the MOOSE input file.
The result is:

!alert note
Given all these potential problems, when merging blocks it is strongly recommended to use just
*one* `RenameBlock` that includes the names or IDs of *all* the blocks involved in the merging.
This will make the new block IDs and new block names unequivocally obvious.
- Block "0" that contains the elements from original blocks "0" and "1".
- Block "4" that contains the elements from original blocks "2" and "3".
!alert-end!

!syntax parameters /Mesh/RenameBlockGenerator

Expand Down
67 changes: 9 additions & 58 deletions framework/include/meshgenerators/RenameBlockGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,62 +32,13 @@ class RenameBlockGenerator : public MeshGenerator
protected:
std::unique_ptr<MeshBase> & _input;

std::vector<subdomain_id_type> _old_block_id;

std::vector<SubdomainName> _old_block_name;

std::vector<subdomain_id_type> _new_block_id;

std::vector<SubdomainName> _new_block_name;

/**
* Given a new_block_id, provide a block name, based
* on the old block names provided (or deduced from
* the old_block_ids provided).
*
* Eg, if
* old_block_name = 'block1 block2'
* new_block_id = '4 5'
* Then
* newBlockName(4) = block1
* newBlockName(5) = block2
*
* In the case of merging blocks, the *first encountered*
* block's name is used.
* Eg, if
* old_block_name = 'asdf block4 block1'
* new_block_id = '3 1 1'
* then
* newBlockName(1) = block4, because we look along
* new_block_id until we first encounter 1, and then get the corresponding name
* @param new_block_id the new block's ID number
* @return the name that will be given to that block
*/
SubdomainName newBlockName(const subdomain_id_type & new_block_id);

/**
* Given a new_block_name, provide a block ID, based
* on the old block IDs provided (or deduced from
* the old_block_names provided).
*
* Eg, if
* old_block_id = '4 5'
* new_block_name = 'block1 block2'
* Then
* newBlockID(block1) = 4
* newBlockID(block2) = 5
*
* In the case of merging blocks, the *first encountered*
* block's ID is used.
* Eg, if
* old_block_id = '3 1 1'
* new_block_name = 'asdf block4 block4'
* then
* newBlockID(block4) = 1, because we look along
* new_block_name until we first encounter block4, and then get the corresponding ID
* @param new_block_name the new block's name
* @return the ID number that will be given to that block
*/
SubdomainID newBlockID(const SubdomainName & new_block_name);
private:
/// The old blocks
std::vector<SubdomainName> _old_block;
/// The new blocks
std::vector<SubdomainName> _new_block;
/// The name of the parameter that specifies the old blocks
std::string _old_block_param_name;
/// The name of the parameter that specifies the new blocks
std::string _new_block_param_name;
};

8 changes: 8 additions & 0 deletions framework/include/utils/MooseMeshUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ getBoundaryIDs(const libMesh::MeshBase & mesh,
*/
BoundaryID getBoundaryID(const BoundaryName & boundary_name, const MeshBase & mesh);

/**
* Gets the subdomain ID associated with the given SubdomainName.
*
* This is needed because the SubdomainName can be either an ID or a name.
* If it is a name, the mesh is queried for the ID associated with said name.
*/
SubdomainID getSubdomainID(const SubdomainName & subdomain_name, const MeshBase & mesh);

std::vector<subdomain_id_type> getSubdomainIDs(const libMesh::MeshBase & mesh,
const std::vector<SubdomainName> & subdomain_name);
}
16 changes: 2 additions & 14 deletions framework/src/mesh/MooseMesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -1306,13 +1306,7 @@ MooseMesh::getSubdomainID(const SubdomainName & subdomain_name) const
if (subdomain_name == "ANY_BLOCK_ID")
mooseError("Please use getSubdomainIDs() when passing \"ANY_BLOCK_ID\"");

SubdomainID id = Moose::INVALID_BLOCK_ID;
std::istringstream ss(subdomain_name);

if (!(ss >> id) || !ss.eof())
id = getMesh().get_id_by_name(subdomain_name);

return id;
return MooseMeshUtils::getSubdomainID(subdomain_name, getMesh());
}

std::vector<SubdomainID>
Expand All @@ -1331,13 +1325,7 @@ MooseMesh::getSubdomainIDs(const std::vector<SubdomainName> & subdomain_name) co
break;
}

SubdomainID id = Moose::INVALID_BLOCK_ID;
std::istringstream ss(subdomain_name[i]);

if (!(ss >> id) || !ss.eof())
id = getMesh().get_id_by_name(subdomain_name[i]);

ids[i] = id;
ids[i] = MooseMeshUtils::getSubdomainID(subdomain_name[i], getMesh());
}

return ids;
Expand Down

0 comments on commit aff54b5

Please sign in to comment.