Skip to content

Volume tagging#98

Draft
piyushkarki wants to merge 32 commits intopiyush/thomas/dockerfrom
piyush/volume-tagging
Draft

Volume tagging#98
piyushkarki wants to merge 32 commits intopiyush/thomas/dockerfrom
piyush/volume-tagging

Conversation

@piyushkarki
Copy link
Copy Markdown
Collaborator

@piyushkarki piyushkarki commented Mar 15, 2026

Closes Issue: N/A

Summary:

This PR introduces volume tagging support, allowing material properties to be assigned regionally based on integer tags defined in the mesh (physical groups in Gmsh). The element tags are parsed, preserved during MPI parallel mesh partitioning, and exposed directly to Lua configuration scripts, enabling region-aware material property functions for Elasticity and Poisson operators.

Description: Changes

  • Mesh & Geometry: Captured element tags during mesh parsing in GlobalSimplexMeshBuilder (addElement). Introduced VolumeData (inheriting from MeshData) to handle the storage and MPI redistribution (via AllToAllV) of these tags across partitions. Extended Curvilinear to store and provide access to these tags via getVolumeTag(elNo).

  • Lua Scripting Integration: Extended LuaLib with getMemberFunctionTagged and functional_t_region to allow Lua material functions to accept an additional tag argument alongside spatial coordinates.

  • Form & Operators: Updated DGCurvilinearCommon::make_volume_functional to evaluate material functions by passing both the quadrature coordinates and the element's volume tag. ElasticityScenario, PoissonScenario, and SeasScenario were updated to use functional_t_region for material properties (mu, lam, rho, K). These can all be unified under a single functional_t once facet tagging comes in.

  • CI/Tests: Updated GitHub Actions to fetch test data from the volume-tagging-test branch of tandem_test_data. Refactored existing Python parallel consistency tests to be reusable and added a new volume tagging consistency test.

Tests

  • Unit tests:

    • VolumeData round-trip: Verified that volume tags are correctly packed, redistributed across MPI ranks using AllToAllV, and unpacked identically.
    • Out-of-range lids: Verified that redistribution safely assigns a default tag of -1 for out-of-range local IDs.
    • make_volume_functional: Created a 2-triangle mesh with tags 1 and 2, evaluated a mock material function that switches on the tag, and verified the resulting quadrature matrix exactly matches the expected branch values.
  • Integration tests:

    • Parallel Consistency: Added test_parallel_consistency_volume_tagging.py to ensure that VTU outputs produced by multi-rank partitioned runs with volume tags are strictly consistent with single-rank runs.

Additional Info

If a mesh is loaded that does not provide volume tags (or an older builder is used), the system safely defaults to assigning a tag of -1 to all elements and prints a warning to std::cerr.

tldr:

Volume tags from the mesh are now passed to Lua scripts. You can define region-specific materials in your TOML/Lua config like this:

function mu(x, y, tag) 
  if tag == 1 then 
    return 30.0 
  else 
    return 40.0 
  end 
end

@piyushkarki piyushkarki changed the title Piyush/volume tagging Volume tagging Mar 15, 2026
@piyushkarki piyushkarki self-assigned this Mar 17, 2026
@piyushkarki piyushkarki force-pushed the piyush/volume-tagging branch 2 times, most recently from 44956eb to b190d6c Compare March 26, 2026 22:53
Copy link
Copy Markdown
Collaborator

@Thomas-Ulrich Thomas-Ulrich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (as far as I can understand). See minor comments nevertheless.


MeshSize{ PointsOf{Surface{:};} } = res;

//Physical Curve(1) = { 1, 8, 9, 11, 12, 6, 7, 4 }; // exterior
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented lines?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.



function VolumeTagging:mu(x, y, tag)
local _tag = math.floor(tag)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need to use math.floor?
In any case, if you want to avoid floor(3.99999999) = 3
you may want to try:
local _tag = math.floor(tag + 0.5)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something I inherited from an old PR. Here: #39

We will not have this issue since it's always long int. I will remove the floor. Thanks!

NumberingConvention convention_;
};

class VolumeData : public MeshData {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling it VolumeTagData would avoid confusion, as VolumeData are generally stored as ElementalData

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this. Was also iffy about the name. Thanks! Reminds me of this.

@baroryan
Copy link
Copy Markdown
Collaborator

baroryan commented Apr 3, 2026

I am able to compile and run, thanks for implementing this feature!

Maybe one thing to consider is to add an example to show users how to use the feature:
for example change mu function in examples/2d/bp3.lua with (and call the new lua bp3_voltag.lua)

function BP3:mu(x, y,tag)
        local rho
        if tag == 1 then
                rho=self.rho0/2
        else
                rho=self.rho0
        end
    return self.cs^2 * rho
end

and then another bp3_voltag.toml that refers to the new bp3_voltag.lua

@baroryan
Copy link
Copy Markdown
Collaborator

baroryan commented Apr 3, 2026

also one quick question when I use this:

function BP3:mu(x, y,tag)
        local rho
        if tag == 1 then
                print(tag)
                rho=self.rho0/2
        else
                rho=self.rho0
                print(tag)
        end
    return self.cs^2 * rho
end

I am getting a lot nil results from the lua (though I should only get 1/2 as defined in the mesh )

for example:

2
2
2
nil
nil
nil
nil

--- Is Tandem calling this function for fault elements where tag is not defined ? Could this cause some ill defined scenarios on the lua end ?

@piyushkarki
Copy link
Copy Markdown
Collaborator Author

@baroryan thank you for taking a look!

  1. I will add a BP3 copy with modified function signatures for mu and lambda.

  2. For the ````nil``` cases: My guess is, you get this because you are probably calling mu from other lua functions as well, such as lambda, where you might be calling mu without a tag in which case this is expected (please let me know if that is not the case). So, you could add tag to lambda as well but then you need to propagate this tag into your mu call too. Now I am thinking if there are functions which require mu but are never fed with a tag. Would be nice to know. It's only mu, rho and lambda for this PR since "volume" tags only apply to these bulk quantities. For the fault tagging PR, you can see almost all functions are fed with a tag so this won't be an issue.

@baroryan
Copy link
Copy Markdown
Collaborator

baroryan commented Apr 7, 2026

Thanks Piyush! You were right about 2, my bad : )

Copy link
Copy Markdown
Collaborator

@Thomas-Ulrich Thomas-Ulrich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now. See also new comments.

- **mesh_file**: Mesh file.
- **lib**: Lua file containing material & frictional paramters.
- **scenario**: Name of the specific scenario defined in the Lua library.
- **Lua material functions**: When volume tagging is used, `mu`, `lam`, and `rho` Lua functions also receive the volume tag as the last argument.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about:
Note that the mu, lam, and rho Lua functions receive the volume tag as the last function argument. If region IDs are not set in the mesh, a value of -1 is assumed.


function VolumeTagging:mu(x, y, tag)
local _tag = math.floor(tag)
local _tag = tag
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the end you don't need _tag its seems, you could use directly tag?

@piyushkarki piyushkarki force-pushed the piyush/volume-tagging branch from 8b8df34 to 021c95c Compare April 11, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants