Skip to content

feat: add PermeabilitySpecification as an high-level FieldSpecification - #4019

Draft
kdrienCG wants to merge 45 commits into
feature/kdrienCG/nonScalarFieldSpecificationfrom
feature/kdrienCG/permeabilitySpecification
Draft

feat: add PermeabilitySpecification as an high-level FieldSpecification#4019
kdrienCG wants to merge 45 commits into
feature/kdrienCG/nonScalarFieldSpecificationfrom
feature/kdrienCG/permeabilitySpecification

Conversation

@kdrienCG

@kdrienCG kdrienCG commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

(Previously #4012)
(Discussion: #4092)

This PR proposes to add an easy way to add higher-level components that create FieldSpecifications without the boilerplate.

The goal of this component, along with future specialized field specifications (temperature, porosity, etc.), is to improve the experience for both the users and developers.

Compared to the standard FieldSpecification, these components would:

  • Expose only relevant XML attributes, with documentation tailored for its specific fieldName. It would also benefit from auto-generated documentation (see feat: add limits to input attributes #4063 that can even show value limits and enable automatic validation).
  • Establish a standard way to document user-facing fields. As of now, when a developer adds a field he must not forget to document if it is usable by the user. We want to provide a standard way to do so.
  • Provide specialized validation directly in the data, limiting the user to entering only coherent values (via postInputInitialization() for example).
  • Hide GEOS implementation details from users. For example, each specialized specification already knows whether it targets cells, nodes, edges, or faces. When multiple targets are valid, the choice can be exposed as an enum-string instead of requiring users to learn some implementation details to use it.

The Group system supports all of this: it gives developers a single place to document, validate, and optionally process user input. That is why this architecture is built on Group.

Hiding application data behind an interface is a common pattern that:

  • improves stability of input files when the implementation changes,
  • reduces the risk of users silently breaking a simulation, and
  • avoids teaching internal details such as "do not use the initialPressure fieldname, it is auto-filled by the pressure field; use pressure with initialCondition=1" or "do not touch deltaPressure it is internal."

The flexibility offered by FieldSpecification is not affected. The goal is not to remove it, but to provide a safer default alternative for common use cases, while still keeping FieldSpecification available for advanced user, scenarios that require explicit data access and testing cases. Specialized components are built on top of it to ensure testing and support.

More specialized field specifications will follow. For example, component fractions with constraints such as sum = 1.0, implemented by creating multiple FieldSpecification entries under the hood.


As an example, to define the permeability you have to specify 3 differents FieldSpecifications.
One for the x-axis, a second for the y-axis, and a last one for the z-axis.
There is also some implementation details that could be hidden, like the component XML attribute for example.

<FieldSpecifications>
  <FieldSpecification
      name="permx"
      component="0"
      initialCondition="1"
      setNames="{ all }"
      objectPath="ElementRegions/reservoir"
      fieldName="rockPerm_permeability"
      functionName="permxFunc"
      scale="9.869233e-16"/>

  <FieldSpecification
      name="permy"
      component="1"
      initialCondition="1"
      setNames="{ all }"
      objectPath="ElementRegions/reservoir"
      fieldName="rockPerm_permeability"
      functionName="permyFunc"
      scale="9.869233e-16"/>

  <FieldSpecification
      name="permz"
      component="2"
      initialCondition="1"
      setNames="{ all }"
      objectPath="ElementRegions/reservoir"
      fieldName="rockPerm_permeability"
      functionName="permzFunc"
      scale="9.869233e-16"/>
</FieldSpecifications>

With this PR, their would be a PermeabilitySpecification component that would create behind the scene those three FieldSpecifications to keep full compatibility with other parts that rely on FieldSpecificationBase. One could think of PermeabilitySpecification as a blueprint or recipe to create FieldSpecificationBase objects.

Here is how it looks like for PermeabilitySpecification:

<FieldSpecifications>
    <PermeabilitySpecification
      name="perm"
      setNames="{ all }"
      regionNames="{ reservoir }"
      permeabilityModelName="rockPerm"
      functionNames="permFunc"
      scales="{9.869233e-16, 9.869233e-16, 9.869233e-16}"/>
</FieldSpecifications>

The following architecture is proposed:

ps_processors_architecture_1

@kdrienCG kdrienCG self-assigned this Apr 7, 2026
@kdrienCG kdrienCG added type: feature New feature or request type: new A new issue has been created and requires attention labels Apr 7, 2026
@rrsettgast

Copy link
Copy Markdown
Contributor

Hi @kdrienCG
This is something we have been meaning to get to for a while. But not just for perm. Can you implement a generalization to allow for processing and application of arbitrary tensor inputs? There are many things that this would be useful for besides permeability. I think we could read in a "scale" as any array type, and apply appropriately. Then this could be used for stresses, displacements, or any other non-scalar field without multiple FieldSpecificaiton blocks.

@kdrienCG

Copy link
Copy Markdown
Contributor Author

Hi @kdrienCG This is something we have been meaning to get to for a while. But not just for perm. Can you implement a generalization to allow for processing and application of arbitrary tensor inputs? There are many things that this would be useful for besides permeability. I think we could read in a "scale" as any array type, and apply appropriately. Then this could be used for stresses, displacements, or any other non-scalar field without multiple FieldSpecificaiton blocks.

Hi @rrsettgast , and thanks for the suggestion
I agree there should be a generalized way to do this, beyond permeability.

I propose doing that in a follow-up PR so we can keep this one focused on specialized components and easier to review.

I've also put together a prototype to test the generalized approach, I can open a separate PR so we can agree on what its interface should be.

@kdrienCG kdrienCG added ci: run CUDA builds Allows to triggers (costly) CUDA jobs ci: run integrated tests Allows to run the integrated tests in GEOS CI labels Apr 13, 2026
@kdrienCG
kdrienCG marked this pull request as ready for review April 13, 2026 08:48
@kdrienCG kdrienCG added the flag: no rebaseline Does not require rebaseline label Apr 14, 2026
Modify the specification parameter name in PermeabilitySpecificationFactory to match the parent class method definition (FieldSpecificationFactory)
@kdrienCG kdrienCG removed the ci: run CUDA builds Allows to triggers (costly) CUDA jobs label Apr 14, 2026
@kdrienCG
kdrienCG changed the base branch from develop to feature/kdrienCG/nonScalarFieldSpecification July 15, 2026 15:21
Comment thread src/coreComponents/fieldSpecification/FieldSpecificationABC.hpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.hpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.cpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.cpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.cpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.cpp Outdated
Comment thread src/coreComponents/fieldSpecification/PermeabilitySpecification.cpp Outdated
kdrienCG and others added 5 commits July 29, 2026 14:08
Co-authored-by: MelReyCG <122801580+MelReyCG@users.noreply.github.com>
Removes fieldName attribute as fieldKey is always "permeability" but introduces a new attribute "permeabilityModelName" for the constitutive model, as a complete fieldName for permeability is "constitutive_fieldkey"
Comment on lines +140 to +149
/**
* @brief Validate that a certain permeability model name exists in the domain
* @param domain The domain
* @param permeabilityModelName The name of the permeability model to validated
* @param permSpec Reference to the current object to print its DataContext
* @note Throws if the permeability model doesn't exists
*/
void expectValidPermeabilityModel( DomainPartition const & domain,
string const & modelName,
PermeabilitySpecification const & permSpec )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✌️

Comment on lines +53 to +54
// @copydoc FieldSpecificationABC::SetErrorMode
using SetErrorMode = FieldSpecificationABC::SetErrorMode;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

dead code

Comment on lines +46 to +49
registerWrapper( viewKeyStruct::permeabilityModelNameString(), &m_permeabilityModelName ).
setRTTypeName( rtTypes::CustomTypes::groupNameRef ).
setInputFlag( InputFlags::REQUIRED ).
setDescription( "Name of the constitutive permeability model." );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📝Optional, ConstitutiveBase::makeFieldName won't be called if leaved empty.

Comment on lines +104 to +108
virtual string const & getFieldName() const override
{
static string const fieldName = fields::permeability::permeability::key();
return fieldName;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
virtual string const & getFieldName() const override
{
static string const fieldName = fields::permeability::permeability::key();
return fieldName;
}
virtual string_view getFieldName() const override
{ return fields::permeability::permeability::key(); }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A lot of call sites expect a string const &, it will be a subject for another PR if you agree.

Comment on lines +104 to +107
void expectValidCellRegion( DomainPartition const & domain,
string const & fullRegionName,
PermeabilitySpecification const & permSpec )
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we can propose that as a standard method in the ABC + it has some sense to be a member function for the context retrieval.

Suggested change
void expectValidCellRegion( DomainPartition const & domain,
string const & fullRegionName,
PermeabilitySpecification const & permSpec )
{
template< typename ELEMENT_REGION_T >
void FieldSpecificationABC::expectValidCellRegion( DomainPartition const & domain,
string_view fullRegionName ) const
{

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci: run code coverage enables running of the code coverage CI jobs ci: run integrated tests Allows to run the integrated tests in GEOS CI flag: no rebaseline Does not require rebaseline type: feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants