Skip to content

[WIP] Multizone adjoints for turbomachinery #2446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from

Conversation

joshkellyjak
Copy link
Contributor

Proposed Changes

This is a cleaned up PR of the fixes needed for multizone adjoints for turbomachinery from the previous PR of @oleburghardt and I's work.

This hopefully is useable, so if you would like to test and report please feel free to contact me on Slack.

TODO:

  • Fix eddy viscosity tape issue in CNSSolver
  • Add turbomachinery objective functions + constraints
  • Include MZ testcase

Related Work

Now closed PR #2317

PR Checklist

Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.

  • [ X ] I am submitting my contribution to the develop branch.
  • My contribution generates no new compiler warnings (try with --warnlevel=3 when using meson).
  • My contribution is commented and consistent with SU2 style (https://su2code.github.io/docs_v7/Style-Guide/).
  • I used the pre-commit hook to prevent dirty commits and used pre-commit run --all to format old commits.
  • I have added a test case that demonstrates my contribution, if necessary.
  • I have updated appropriate documentation (Tutorials, Docs Page, config_template.cpp), if necessary.

Comment on lines +675 to 677
AD::EndPreacc();

/*--- Max is not differentiable, so we not register them for preacc. ---*/
Copy link
Member

Choose a reason for hiding this comment

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

What is the difference between ending the preaccumulation before or after?

}
} else if (Multizone_Problem && DiscreteAdjoint) {
SU2_MPI::Error(string("OUTPUT_WRT_FREQ cannot be specified for this solver "
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
SU2_MPI::Error(string("OUTPUT_WRT_FREQ cannot be specified for this solver "
SU2_MPI::Error("OUTPUT_WRT_FREQ cannot be specified for this solver "

Comment on lines +3425 to +3426
"(writing of restart and sensitivity files not possible for multizone discrete adjoint during runtime yet).\n"
"Please remove this option from the config file, output files will be written when solver finalizes.\n"), CURRENT_FUNCTION);
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm I'm pretty sure it is possible

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is one for @oleburghardt

Copy link
Contributor

@oleburghardt oleburghardt Mar 25, 2025

Choose a reason for hiding this comment

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

Yes and no, writing the files is fine, but the continuation of the multi-zone discrete adjoint solver is erratic. My guess is that some indices aren't cleared properly before re-recording the tape. (Writing adjoint solution variables to file only, without re-recording at all and without sensitivities, might give us some hints.)
The debug mode could eventually pin down where exactly things go wrong.

Comment on lines -222 to +229
BPressure = config->GetPressureOut_BC();
Temperature = config->GetTotalTemperatureIn_BC();

if (!reset){
AD::RegisterInput(BPressure);
AD::RegisterInput(Temperature);
}

BPressure = config->GetPressureOut_BC();
Temperature = config->GetTotalTemperatureIn_BC();

Copy link
Member

Choose a reason for hiding this comment

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

Why are these wrong but not the others that follow the same pattern?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This threw a tagging error, and if I remember correctly it's because in the other sections the variables it accesses are directly used in the solver, whereas in the Giles implementation they are not, creating a mismatch in tags.

Copy link
Member

Choose a reason for hiding this comment

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

Can we fix it in a way that keeps a clear pattern for doing this type of thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can give it a go

CGeometry::ComputeWallDistance(config, geometry);
}
geometry[iZone][MESH_0][INST_0]->InitTurboVertexAdj(geometry, config);
for (auto iZone = 0u; iZone < nZone; iZone++) {

Check notice

Code scanning / CodeQL

Declaration hides parameter Note

Local variable 'iZone' hides a
parameter of the same name
.

Copilot Autofix

AI 22 days ago

To fix the issue, we will rename the local variable iZone on line 493 to a distinct name, such as zoneIndex. This will eliminate the shadowing of the parameter iZone and make the code more readable. The change will only affect the loop declaration and any references to the local variable within the loop body.


Suggested changeset 1
SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp
--- a/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp
+++ b/SU2_CFD/src/iteration/CDiscAdjFluidIteration.cpp
@@ -492,4 +492,4 @@
       geometry[iZone][MESH_0][INST_0]->InitTurboVertexAdj(geometry, config);
-      for (auto iZone = 0u; iZone < nZone; iZone++) {
-        solver[iZone][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[iZone][INST_0][MESH_0],config[iZone]);
+      for (auto zoneIndex = 0u; zoneIndex < nZone; zoneIndex++) {
+        solver[zoneIndex][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[zoneIndex][INST_0][MESH_0],config[zoneIndex]);
       }
EOF
@@ -492,4 +492,4 @@
geometry[iZone][MESH_0][INST_0]->InitTurboVertexAdj(geometry, config);
for (auto iZone = 0u; iZone < nZone; iZone++) {
solver[iZone][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[iZone][INST_0][MESH_0],config[iZone]);
for (auto zoneIndex = 0u; zoneIndex < nZone; zoneIndex++) {
solver[zoneIndex][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[zoneIndex][INST_0][MESH_0],config[zoneIndex]);
}
Copilot is powered by AI and may make mistakes. Always verify output.
TurbomachineryStagePerformance->ComputePerformanceStage(InState, OutState, config_container[nZone-1]);

/*--- Set turbomachinery objective function value in each zone ---*/
for (auto iBlade = 0u; iBlade < nBladesRow; iBlade++) {

Check notice

Code scanning / CodeQL

Declaration hides variable Note

Variable iBlade hides another variable of the same name (on
line 72
).

Copilot Autofix

AI 22 days ago

To fix the issue, we will rename the iBlade variable declared on line 101 to a distinct name, such as bladeIndex. This will eliminate the shadowing of the iBlade variable declared on line 72. The change will be localized to the for loop on line 101 and its body, ensuring that the functionality remains unchanged while improving code clarity.


Suggested changeset 1
SU2_CFD/src/iteration/CTurboIteration.cpp

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/SU2_CFD/src/iteration/CTurboIteration.cpp b/SU2_CFD/src/iteration/CTurboIteration.cpp
--- a/SU2_CFD/src/iteration/CTurboIteration.cpp
+++ b/SU2_CFD/src/iteration/CTurboIteration.cpp
@@ -100,10 +100,10 @@
     /*--- Set turbomachinery objective function value in each zone ---*/
-    for (auto iBlade = 0u; iBlade < nBladesRow; iBlade++) {
+    for (auto bladeIndex = 0u; bladeIndex < nBladesRow; bladeIndex++) {
       // Should we set in ZONE_0 or nZone-1?
-      auto iBladePerf = TurbomachineryPerformance->GetBladesPerformances().at(iBlade).at(nSpan);
+      auto iBladePerf = TurbomachineryPerformance->GetBladesPerformances().at(bladeIndex).at(nSpan);
       InState = iBladePerf->GetInletState();
       OutState = iBladePerf->GetOutletState();
-      solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::ENTROPY_GENERATION, iBlade, TurbomachineryStagePerformance->GetNormEntropyGen()*100);
-      solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::TOTAL_PRESSURE_LOSS, iBlade, iBladePerf->GetTotalPressureLoss());
-      solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::KINETIC_ENERGY_LOSS, iBlade, iBladePerf->GetKineticEnergyLoss());
+      solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::ENTROPY_GENERATION, bladeIndex, TurbomachineryStagePerformance->GetNormEntropyGen()*100);
+      solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::TOTAL_PRESSURE_LOSS, bladeIndex, iBladePerf->GetTotalPressureLoss());
+      solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::KINETIC_ENERGY_LOSS, bladeIndex, iBladePerf->GetKineticEnergyLoss());
     }
EOF
@@ -100,10 +100,10 @@
/*--- Set turbomachinery objective function value in each zone ---*/
for (auto iBlade = 0u; iBlade < nBladesRow; iBlade++) {
for (auto bladeIndex = 0u; bladeIndex < nBladesRow; bladeIndex++) {
// Should we set in ZONE_0 or nZone-1?
auto iBladePerf = TurbomachineryPerformance->GetBladesPerformances().at(iBlade).at(nSpan);
auto iBladePerf = TurbomachineryPerformance->GetBladesPerformances().at(bladeIndex).at(nSpan);
InState = iBladePerf->GetInletState();
OutState = iBladePerf->GetOutletState();
solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::ENTROPY_GENERATION, iBlade, TurbomachineryStagePerformance->GetNormEntropyGen()*100);
solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::TOTAL_PRESSURE_LOSS, iBlade, iBladePerf->GetTotalPressureLoss());
solver[iBlade][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::KINETIC_ENERGY_LOSS, iBlade, iBladePerf->GetKineticEnergyLoss());
solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::ENTROPY_GENERATION, bladeIndex, TurbomachineryStagePerformance->GetNormEntropyGen()*100);
solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::TOTAL_PRESSURE_LOSS, bladeIndex, iBladePerf->GetTotalPressureLoss());
solver[bladeIndex][INST_0][MESH_0][FLOW_SOL]->SetTurboObjectiveFunction(ENUM_OBJECTIVE::KINETIC_ENERGY_LOSS, bladeIndex, iBladePerf->GetKineticEnergyLoss());
}
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +4760 to +4768
// case ENTROPY_GENERATION:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;
// case TOTAL_PRESSURE_LOSS:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;
// case KINETIC_ENERGY_LOSS:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

Copilot Autofix

AI 22 days ago

The best way to fix the problem is to either remove the commented-out code entirely or reinstate it if it is still relevant and functional. In this case, the commented-out code appears to be related to specific objective functions (ENTROPY_GENERATION, TOTAL_PRESSURE_LOSS, KINETIC_ENERGY_LOSS) that are currently not being used. If these cases are no longer relevant, they should be removed. If they are still relevant, they should be reinstated and properly integrated into the switch statement.

For this fix, we will remove the commented-out code since there is no indication that it is required or will be used in the future.

Suggested changeset 1
SU2_CFD/src/solvers/CEulerSolver.cpp

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp
--- a/SU2_CFD/src/solvers/CEulerSolver.cpp
+++ b/SU2_CFD/src/solvers/CEulerSolver.cpp
@@ -4759,11 +4759,3 @@
       break;
-    // case ENTROPY_GENERATION:
-    //   Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
-    //   break;
-    // case TOTAL_PRESSURE_LOSS:
-    //   Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
-    //   break;
-    // case KINETIC_ENERGY_LOSS:
-    //   Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
-    //   break;
+
     default:
EOF
@@ -4759,11 +4759,3 @@
break;
// case ENTROPY_GENERATION:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;
// case TOTAL_PRESSURE_LOSS:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;
// case KINETIC_ENERGY_LOSS:
// Total_ComboObj+=Weight_ObjFunc*GetTurboObjectiveFunction(Kind_ObjFunc, config->GetnMarker_Turbomachinery());
// break;

default:
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants