Skip to content

Implement operation gradient in Generic module#398

Open
vidulejs wants to merge 4 commits intodevelopfrom
gradient-operation
Open

Implement operation gradient in Generic module#398
vidulejs wants to merge 4 commits intodevelopfrom
gradient-operation

Conversation

@vidulejs
Copy link
Collaborator

@vidulejs vidulejs commented Feb 26, 2026

Implemented operation gradient; for volume & surface scalar fields in the new Generic module. The code closely follows PressureGradientFull.C. The gradient operation on a scalar field will result in a vector field. Therefore, when operation == 'gradient', the dataType_ will become vector. The user has to make sure it's also the case in the preCICE config.

For that reason I implemented a new check in Interface::addCouplingDataWriter, where it will find if there's a vector/scalar data mismatch between the preCICE config and the adapter. If the user configured operation gradient, they will get a more specific error:

Error in the preCICE adapter: 
Data dimension mismatch for field "PressureGradient". The field is defined as
scalar data in the preCICE configuration, but the data is vector in the adapter.
Please check your preCICE configuration. If you are trying to couple the gradient
of a scalar field, make sure the data is defined vector in preCICE config.

Previously the error would be thrown by preCICE and say that the number of vertices is incorrect.

TODO list:

  • I updated the documentation in docs/
  • I added a changelog entry in changelog-entries/ (create directory if missing)

…calar fields (like PressureGradientFull). Gradient operation will change dataType_ from scalar to vector.
Comment on lines +47 to +52
if (fieldConfig_.operation == "gradient")
{
// Calculate the full gradient (volVectorField)
// Temporary field discarded afterwards
Foam::tmp<volVectorField> tmpObject(fvc::grad(*scalarField_));
const volVectorField& gradScalarField = tmpObject(); // dereference
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Unlike PressureGradientFull, I don't store the resulting volVectorField as a member variable. I'm using Foam::tmp<volVectorField> to temporarily allocate it and automatically deallocate it once it's out of scope. Would this be a performance problem - allocating and deallocating memory for each write? Alternatively, we could create a shared buffer to store the scalar field gradients if configured.

Copy link
Member

Choose a reason for hiding this comment

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

Discussed in a meeting: This should indeed have performance implications, better allocate in the constructor and reuse.

@vidulejs vidulejs requested a review from MakisH February 27, 2026 12:55
Copy link
Member

@MakisH MakisH left a comment

Choose a reason for hiding this comment

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

Looks good overall, I have not tested it.

Comment on lines +47 to +52
if (fieldConfig_.operation == "gradient")
{
// Calculate the full gradient (volVectorField)
// Temporary field discarded afterwards
Foam::tmp<volVectorField> tmpObject(fvc::grad(*scalarField_));
const volVectorField& gradScalarField = tmpObject(); // dereference
Copy link
Member

Choose a reason for hiding this comment

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

Discussed in a meeting: This should indeed have performance implications, better allocate in the constructor and reuse.

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.

2 participants