Getting subdomain IDs and names when adding mesh generator with a custom action

247 views
Skip to first unread message

Shohei Ogawa

unread,
Oct 8, 2019, 10:26:00 AM10/8/19
to moose-users
Hello,

I am wondering how I could get subdomain information in action to add mesh generators. Before mesh generators are widely used, I was doing this with mesh modifier by having the code below:
```
void
AddSideSetsBetweenSubdomainsGeneratorCustomAction::act()
{
   auto & mesh_ptr = _app.actionWarehouse().mesh();
   auto subdomain_ids = mesh_ptr->meshSubdomains();
   for (auto subdomain_id : subdomain_ids)
   {
      auto subdomain_name = mesh_ptr->getSubdomainName(subdomain_id);
      // do something here
...
```

After I made the action using mesh generators, the code compiles without any issues and it runs. However, it seems that the subdomain information is not retrieved during the action process and no objects are added by the action.

Thank you,
Shohei 

Cody Permann

unread,
Oct 8, 2019, 10:41:48 AM10/8/19
to <moose-users@googlegroups.com>
What task is this Action associated with? Think about when this Action will execute relative to other things like when the Mesh is being built. What you are asking for is a little bit tricky. You are wanting information about the Mesh while you are building the Mesh. With the modifiers I can see why this use to work but you are having difficulty with it now. Perhaps we can come up with another solution to your problem. I imagine that if you used that specific generator, it would work fine, but you are doing something slightly different here using an Action to control something. Can you elaborate a bit more on what this Action does?

--
You received this message because you are subscribed to the Google Groups "moose-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/c6df9fa2-5baf-4a32-968c-daac96b1a736%40googlegroups.com.

Shohei Ogawa

unread,
Oct 8, 2019, 11:03:28 AM10/8/19
to moose-users
Thank you. I thought mesh information was available much earlier in the previous mesh system so the previous action code worked as expected.

What I want to do is adding `SideSetsBetweenSubdomainsGenerator`s (or `SideSetsBetweenSubdomains` mesh modifiers previously). Let's say I have a lot of subdomains: main_volume, part_volume_001, part_volume_002, part_volume_003,..., other_volume_001,..., other_volume_002. To define sidesets between some of those subdomains, I have one master domain: main_volume, and I use a C++ regular expression, e.g., `part_volume_(.*) ` to get the subdomains to be paired with the master subdomain. I will get the following pairs of subdomains where sidesets are created in between: (main_volume, part_volume_001), (main_volume, part_volume_002), (main_volume, part_volume_003),...

I also do add postprocessors for many subdomains in a similar way. In this case, if I use `FileMesh` object, would it be fine?


To unsubscribe from this group and stop receiving emails from it, send an email to moose...@googlegroups.com.

Shohei Ogawa

unread,
Oct 8, 2019, 11:40:50 AM10/8/19
to moose-users
I also want to mention that for adding side set postprocessors with a custom action, the issue is that there are not all the combinations of subdomains. If I add postprocessors with a sequence of numbers such as 001, 002,..., I might add postprocessors for not-existing sidesets that can cause an error. This is why I was using a regular expression to detect all existing pairs.

Cody Permann

unread,
Oct 8, 2019, 12:06:26 PM10/8/19
to <moose-users@googlegroups.com>
On Tue, Oct 8, 2019 at 9:03 AM Shohei Ogawa <ogawa...@gmail.com> wrote:
Thank you. I thought mesh information was available much earlier in the previous mesh system so the previous action code worked as expected.

To clarify, the "tasks" in MOOSE control the order in which things occur. You can find the master list in Moose.C. When you create an Action you register it against a task which tells it when it's going to execute. If you run your Action before the Mesh, you should expect not to have any meta-data about the mesh, if you run it after the mesh, you should expect the meta-data to be complete. It's not really about some hidden change in MOOSE. The Action system is transparent.

Again, what makes this more difficult is that there was a clear separation between reading in and setting up the mesh and then applying modifiers to it. With the generator system, we've compressed all mesh setup related actions into a tree format so one generator feeds into another. 

Here's another idea. What if you create a new generator to handle this custom logic instead of trying to do it in an Action? You'd insert this new generator in the middle of the stack of generators and have it add your sidesets. That seems much cleaner than doing it in the Action.
 
To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/1c50f613-d780-488c-ae4c-0a6e065708b0%40googlegroups.com.

Shohei Ogawa

unread,
Oct 8, 2019, 1:22:33 PM10/8/19
to moose-users
Hi Cody, thank you for the clarification.

I looked at Moose.C and I found the system is organized and systematic. I haven't pay much attention to those things yet but I should learn more sometime. Here is what I found.

https://github.com/idaholab/moose/blob/3047044065f2bc88fc30e66ddcc783ff0c986d50/framework/src/base/Moose.C#L255

 syntax.addDependencySets("(meta_action)"
                          "(dynamic_object_registration)"
                          "(common_output)"
                          "(set_global_params)"
                          "(setup_recover_file_base)"
                          "(setup_mesh)"
                          "(add_mesh_generator)"
                          "(execute_mesh_generators)"
                          "(set_mesh_base)"
                          "(check_copy_nodal_vars)"
                          "(add_partitioner)"
                          "(add_geometric_rm)"
                          "(attach_geometric_rm)"
                          "(init_mesh)"
                          "(prepare_mesh)"
                          "(add_mesh_modifier)"
...
                          "(add_postprocessor)"
                          "(add_vector_postprocessor)" 
...

`add_mesh_generator ` comes earlier than `init_mesh` (or maybe `set_mesh_base` though I didn't track the difference in detail for now). So I should not expect I get subdomain or boundary data when I add mesh generators. Using `FileMeshGenerator` doesn't work in my case as well because after it is added, there is one step delay until it is executed. Other `add_mesh_generator` tasks won't get mesh information because the `FileMeshGenerator` is added but not executed at this time. It seems that adding postprocessors as action will work with mesh information because this action happens near the end. This seems good news because I should generate postprocessors only on existing sidesets automatically using regular expressions.

I think making my mesh-generator adding action to work sequentially is the simplest way in my case because adding extra SideSetsBetweenSubdomainsGenerator won't cause any error. If two subdomains specified actually don't share a boundary, a new sideset is not just created. 

Cody Permann

unread,
Oct 8, 2019, 2:14:29 PM10/8/19
to <moose-users@googlegroups.com>
You are getting it. The task is what controls the order. One other thing to keep in mind. You can associate a single Action with several different tasks, in which case it'll run multiple times (once for each associated task). This is handy for doing things like building up a list of things to do at one stage and then using that information to do those things when the appropriate task is executed. This system is very powerful and flexible.

To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/559c6a98-bbce-49ea-a563-9ec5c862e19f%40googlegroups.com.

Shohei Ogawa

unread,
Oct 8, 2019, 3:37:46 PM10/8/19
to moose-users
Thank you for the tips. I will try to get used to the mesh generator system.

Shohei

Shohei Ogawa

unread,
Oct 9, 2019, 6:37:55 PM10/9/19
to moose-users
I decided to create a mesh generator that can find a lot of subdomain pairs by regular expression to add new sidesets but I came up with a couple of issues.

1. In `generate()` for mesh generator, we usually have `std::unique_ptr<MeshBase> mesh = std::move(_input);`. I don't find any functions to get a list of all subdomains in the mesh. If I use `_mesh` in `MooseMesh.h`, I have the `getSubdomainIDs` function. This is the same for the `getSubdomainName` function to get a subdomain name by subdomain ID. Do I really have to use two mesh pointer here?

2. I find
```
if (typeid(_input).name() == typeid(std::unique_ptr<DistributedMesh>).name())
  mooseError("[generator name] only works with ReplicatedMesh");
```
in some of the mesh generator classes. Is there any reason to use this thing instead of `mesh->is_replicated();`? I am just implementing a generator for replicated mesh only so I am wondering this.

Sebastian Schunert

unread,
Oct 9, 2019, 6:52:54 PM10/9/19
to moose...@googlegroups.com
1. I am not exactly sure I understand the questions. MeshBase and MooseMesh are not the same thing. MooseMesh owns a MeshBase object and provides convenient functions on top of things. A mesh generator has a pointer to the MooseMesh object as _mesh. You have to be very careful when subdomain id/subdomain name maps are set up. This might happen after the mesh generators ran. Maybe you can describe in more detail what you want to do?
2. Use _mesh->errorIfDistributedMesh("ClassName");


To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/5f1d7956-e08a-4b7b-8bd5-041f6e3ff9f0%40googlegroups.com.

Shohei Ogawa

unread,
Oct 9, 2019, 7:33:39 PM10/9/19
to moose-users
Thank you for your reply.

I wrote a test and I found that I wasn't able to get existing subdomain IDs with `_mesh->getSubdomainIDs()` Is there any way to do this in mesh generator? I would be able to loop over all the elements to gather the information but there could be a way to do that.

Yes, `_mesh->errorIfDistributedMesh("ClassName")` is used at a lot of places such as mesh modifiers, but it is not used in mesh generators. So I was wondering if the `typeid(_input).name() == typeid(std::unique_ptr<DistributedMesh>).name()` expression appeared in mesh geneartors to see it is distributed or not.

Sebastian Schunert

unread,
Oct 9, 2019, 7:39:40 PM10/9/19
to moose...@googlegroups.com
1. I implemented PatchSidesetGenerator (which takes a sideset and divides into n sidesets) and wanted to enable providing
name or id of a sideset. If I remember correctly, it's too early to use the MooseMesh machinery. Maybe someone who knows for sure
can chime in here. 

2. Check e.g. PatchSidesetGenerator in HeatConductionModule.

To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/3422d4ee-f59c-4a95-b864-df2a4266ab93%40googlegroups.com.

Shohei Ogawa

unread,
Oct 9, 2019, 7:53:04 PM10/9/19
to moose-users
I found that if I get all the subdomain IDs by looping over all the elements and using `elem->subdomain_id()`, I will be able to create a list of subdomain names by doing `mesh->subdomain_name(subdomain_id)` for each subdomain ID. I am not sure if this is the right way to do this an there could be a way to do easily this using existing functions.

Cody Permann

unread,
Oct 10, 2019, 10:15:26 AM10/10/19
to <moose-users@googlegroups.com>
On Wed, Oct 9, 2019 at 5:33 PM Shohei Ogawa <ogawa...@gmail.com> wrote:
Thank you for your reply.

I wrote a test and I found that I wasn't able to get existing subdomain IDs with `_mesh->getSubdomainIDs()`

Hmm, I would call this a bug. We are still fleshing out the MeshGenerator system details but in my view, each MeshGenerator should leave not only the MeshBase object that is currently being generated in a good state, but also all the meta-data that goes along with it. This is actually quite a bit trickier to accomplish than it sounds because of the design choices we've made in the relationship between the MeshBase and the MooseMesh object that is being populated. I'll raise this topic up with my colleagues and we'll finalize a design that will work
 
Is there any way to do this in mesh generator? I would be able to loop over all the elements to gather the information but there could be a way to do that.

As you've already discovered, you can loop over all elements, but that's definitly not what we should expect a developer to have to do to obtain basic information like sidesets. You mentioned that you wrote a test. Which Generator did you use to start the mesh? Can you provide your test case? I'd like to look at your test case and find a better way for you to obtain that information without having to design a solution yourself.
 

Yes, `_mesh->errorIfDistributedMesh("ClassName")` is used at a lot of places such as mesh modifiers, but it is not used in mesh generators. So I was wondering if the `typeid(_input).name() == typeid(std::unique_ptr<DistributedMesh>).name()` expression appeared in mesh geneartors to see it is distributed or not.

Please use the former. The Distributed vs Replicated attribute is fixed for the simulation and there is only one MooseMesh, which is constructed prior to running the generators. You can call that same method on the Generators as you do within the MooseMesh-derived objects themselves.

BTW - We are working on cleaning up and extending the MeshGenerator system right now so expect some of these loose ends to be tied up in the coming weeks. If you have specific test cases that we can look at, I'll update those in the ticket system. We'll also share information on enhancements/changes via our monthly newsletter.

 
To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/3422d4ee-f59c-4a95-b864-df2a4266ab93%40googlegroups.com.

Shohei Ogawa

unread,
Oct 10, 2019, 2:15:04 PM10/10/19
to moose-users
I think I was passing a file mesh generator output to my mesh generator. I might have been doing something wrong so I will make sure again. I am busy right now but I can share the code, the test file, and mesh sometime next week.

Shohei

Shohei Ogawa

unread,
Oct 15, 2019, 7:51:52 PM10/15/19
to moose-users
Here are code and test where I am trying to get existing subdomain IDs in the mesh. The expected command line output of the test should be something like 'Existing subdomain IDs: 0, 1, 5,' but it is not successful. It seems that the function for subdomain IDs returns nothing. This makes us loop over all elements in the mesh to get the existing subdomain IDs, which doesn't sound handy.

(In fact, the function I have to use was `_mesh->meshSubdomains()` instead of `_mesh->getSubdomainIDs()`. When I was writing the previous email, I got messed up but I think I was using the `_mesh->meshSubdomains()` function at that time.  The observation is the same. `_mesh->getSubdomainIDs()` gives you subdomain IDs by name so it is not suitable for our intent here.)

Cody Permann

unread,
Oct 16, 2019, 10:38:34 AM10/16/19
to <moose-users@googlegroups.com>
Thanks for the test case! I'll open a ticket and take a look when I get a chance. I definitely don't want users having to loop over elements to get information like that.

To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/8bbf1cc3-ad5b-4aaa-948c-4c37a7766a85%40googlegroups.com.

Derek Gaston

unread,
Oct 16, 2019, 7:52:33 PM10/16/19
to MOOSE
MeshBase is the raw libMesh type.  Look at the documentation for it here:


You can get the subdomain IDs and boundary info by calling functions on the MeshBase.

Derek


Shohei Ogawa

unread,
Oct 17, 2019, 2:08:22 AM10/17/19
to moose...@googlegroups.com
As far as I looked through the function list of MeshBase, I didn't find a function that returns all the subdomain IDs thus all the subdomain names, in the mesh. There are functions to convert subdomain names to IDs and vice versa.

Shohei Ogawa


You received this message because you are subscribed to a topic in the Google Groups "moose-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/moose-users/Okx-lWdfZKU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to moose-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/CAFfxPjpOHVv2wpaX-Jps-fHtFLfjeQyXG_oSsnZ5fV98wCWwmQ%40mail.gmail.com.

Andrew Slaughter

unread,
Oct 17, 2019, 9:23:19 AM10/17/19
to moose...@googlegroups.com
MeshBase has the following:
void subdomain_ids (std::set< subdomain_id_type > &ids) const

Cody Permann

unread,
Oct 17, 2019, 10:34:06 AM10/17/19
to <moose-users@googlegroups.com>
While I haven't looked into the issue, I suspect that there's a syncronization issue between MooseMesh and MeshBase or perhaps the MeshBoundaryInfo, which is what is causing Shohei's issue. Along those same lines, I'll have to look at the implication of introducing the "final" generator if they are writing information like sidesets or nodesets outside of the MeshBase object they are currently using. 

Derek Gaston

unread,
Oct 17, 2019, 10:53:31 AM10/17/19
to MOOSE
You shouldn't be using the MooseMesh at all while MeshGenerators are running.  It's simply an empty object (doesn't even have a mesh in it).

Use the MeshBase objects that are inputs to the MeshGenerator only.

Derek

Cody Permann

unread,
Oct 17, 2019, 11:08:05 AM10/17/19
to <moose-users@googlegroups.com>
Perhaps, but the API definitely doesn't prevent that from occurring right now and I would say that it's not obvious to users that you just can't use certain MooseMesh methods during MeshGeneration to query information about the mesh. I would propose that we look at methods that we know won't work at that point and update the API appropriately so that those methods trigger errors.

Derek Gaston

unread,
Oct 18, 2019, 7:30:03 PM10/18/19
to MOOSE
The thing is: the mesh is NOT in the MooseMesh at all... the mesh in the MooseMesh when the Generators are running is just empty...  Calling functions on the MooseMesh from a Generator is straight up wrong (only exception: the method to build a mesh base).

Derek

Shohei Ogawa

unread,
Oct 18, 2019, 8:24:56 PM10/18/19
to moose...@googlegroups.com
So it seems there is no API to get all the subdomain IDs out of the mesh information. Existing methods in MeshBase just convert names to IDs and vice versa.

Andrew Slaughter

unread,
Oct 18, 2019, 11:40:19 PM10/18/19
to moose...@googlegroups.com

Shohei Ogawa

unread,
Oct 19, 2019, 1:52:41 AM10/19/19
to moose...@googlegroups.com
Thank you. I am sorry for this but it turned out that I have had misunderstood the usage of this function until I read the code itself. The doc says

>Constructs a list of all subdomain identifiers in the global mesh.

so I thought this creates IDs in the mesh info to be ready to construct elements along with them instead of filling in the existing IDs. Also, the way to use argument and returned value seems different from other functions.

The interesting point for me is MeshBase doesn't actively keep track of subdomain IDs. It actually loops over all the active local elements when the information is needed.


Reply all
Reply to author
Forward
0 new messages