Repository navigation
MATLAB Unit Test - Solver parameterization #101
Description
MATLAB tests that iterate Tests over different Solvers can be paramaterized.
Currently, the different test cases are organized in a struct and run sequentially for each Test.
openstream/tests/integration/SolverIntegrationTest.m
Lines 120 to 149 in f65f6ff
| % Define the test cases. | |
| % | |
| % Each structure contains: | |
| % Number Numerical identifier used by the test class. | |
| % ModelID Physical-model input-set identifier. | |
| % OptionsID Numerical-option input-set identifier. | |
| % GeometryID Geometry input-set identifier. | |
| % BoundaryCondition Boundary-condition filename without the .inp extension. | |
| % Constructor Function handle to the corresponding solver constructor. | |
| % MixtureCase Index of the mixture solver used for initialization. A value of zero indicates that no existing mixture solver is supplied. | |
| cases = [ | |
| struct( ... | |
| Number = 1, ... | |
| ModelID = "TUTORIAL1", ... | |
| OptionsID = "DEFAULT", ... | |
| GeometryID = "TUTORIAL1", ... | |
| BoundaryCondition = "tutorial1", ... | |
| Constructor = @MixtureSolver, ... | |
| MixtureCase = 0); | |
| struct( ... | |
| Number = 2, ... | |
| ModelID = "TUTORIAL1", ... | |
| OptionsID = "DEFAULT", ... | |
| GeometryID = "TUTORIAL1", ... | |
| BoundaryCondition = "tutorial1", ... | |
| Constructor = @TwoFluidSolver, ... | |
| MixtureCase = 1); | |
The benefit of this approach is not having to re-solve the MixtureSolver results the other Solvers depend on. The issue is that if a subsequent Solver fails, say the TwoFluid Solver, the entire test class will fail to solve. For example, a artificial error is thrown during the TwoFluid solver construction for demonstration:
% Call abstract class constructor
twfSolver = twfSolver@Solvers.AbstractSolver(inputSet);
% Store mixSolver handle
twfSolver.mixSolver = mixSolver;
% Attempt to solve mixSolver if it is unsolved
if twfSolver.mixSolver.STATE == Solvers.SolverState.UNSOLVED
twfSolver.mixSolver.solve();
end
% Initialize solver parameters
twfSolver.initializeSolver();
% Artificial bug to demonstrate caveat of using a bundled testing scheme
error('Artificial bug')
then,
As a result, all SolverIntegrationTest tests failed and did not run to completion.
---------
Error ID:
---------
''
--------------
Error Details:
--------------
Error using Solvers.TwoFluid.TwoFluidSolver
Artificial bug
Error in SolverIntegrationTest/constructAndSolveTestCases (line 220)
testCase.solvers{caseIndex} =
cases(caseIndex).Constructor(testCase.inputSets{caseIndex},mixtureSolver);
================================================================================
Done setting up SolverIntegrationTest in 3.6666 seconds
Tearing down SolverIntegrationTest
Evaluating addTeardown function: teardownAppliedFixture
Done tearing down SolverIntegrationTest in 0.054539 seconds
and
Failure Summary:
Name Failed Incomplete Reason(s)
====================================================================================
SolverIntegrationTest/solverStates X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/mixtureBoundaryConditions X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/mixtureEnergyBalance X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/mixtureInitializationTransfer X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/fieldMassFlowRates X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/fieldVelocities X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/fieldEnthalpies X X Errored.
------------------------------------------------------------------------------------
SolverIntegrationTest/saveLoadRoundTrip X X Errored.
One solution is to implement the different solvers as ClassSetupParameters as in commit cd3eca0
openstream/tests/integration/SolverIntegrationTest.m
Lines 46 to 76 in cd3eca0
| properties (ClassSetupParameter) | |
| % Define the test cases. | |
| % | |
| % Each structure contains: | |
| % Number Numerical identifier used by the test class. | |
| % ModelID Physical-model input-set identifier. | |
| % OptionsID Numerical-option input-set identifier. | |
| % GeometryID Geometry input-set identifier. | |
| % BoundaryCondition Boundary-condition filename without the .inp extension. | |
| % Constructor Function handle to the corresponding solver constructor. | |
| % MixtureCase Index of the mixture solver used for initialization. A value of zero indicates that no existing mixture solver is supplied. | |
| case_option = struct( ... | |
| Mixture = ... | |
| struct( ... | |
| Number = 1, ... | |
| ModelID = "TUTORIAL1", ... | |
| OptionsID = "DEFAULT", ... | |
| GeometryID = "TUTORIAL1", ... | |
| BoundaryCondition = "tutorial1", ... | |
| Constructor = @Solvers.Mixture.MixtureSolver, ... | |
| MixtureCase = 0), ... | |
| TwoFluid = ... | |
| struct( ... | |
| Number = 2, ... | |
| ModelID = "TUTORIAL1", ... | |
| OptionsID = "DEFAULT", ... | |
| GeometryID = "TUTORIAL1", ... | |
| BoundaryCondition = "tutorial1", ... | |
| Constructor = @Solvers.TwoFluid.TwoFluidSolver, ... | |
| MixtureCase = 1), ... |
This works well, but for some reason can siginificantly increase execution time - more than the time it requires to rerun the MixtureSolver three times.
Activity
lecorrejm commentedon Sep 13, 2026
That seems to work and I did not notice any significant increase in execution time on my side.
I have cleaned up the file, see commit
71377ea05e4e190534e8da448611ffde17093824.The problem I see though is that the mixture-specific tests (mixtureBoundaryConditions, mixtureEnergyBalance, mixtureInitializationTransfer) are repeated for every solver. This is probably unnecessary.