![]() |
VOOZH | about |
dotnet add package Softellect.OdePackInterop --version 10.0.100.29
NuGet\Install-Package Softellect.OdePackInterop -Version 10.0.100.29
<PackageReference Include="Softellect.OdePackInterop" Version="10.0.100.29" />
<PackageVersion Include="Softellect.OdePackInterop" Version="10.0.100.29" />Directory.Packages.props
<PackageReference Include="Softellect.OdePackInterop" />Project file
paket add Softellect.OdePackInterop --version 10.0.100.29
#r "nuget: Softellect.OdePackInterop, 10.0.100.29"
#:package Softellect.OdePackInterop@10.0.100.29
#addin nuget:?package=Softellect.OdePackInterop&version=10.0.100.29Install as a Cake Addin
#tool nuget:?package=Softellect.OdePackInterop&version=10.0.100.29Install as a Cake Tool
This is a simple C# / F# NET9 interop with FORTRAN ODE Solver DLSODE aimed at solving very large systems of potentially stiff ODEs (like in chemical systems) where the number of variables is or more.
An alternative could be to use SUNDIALS, which is a newer C port of various FORTRAN solvers. However, since SUNDIALS is written in C, an attempt to create a NET5 interop results in C++/CLI E0337 "Linkage specification is incompatible" error, which is a known issue but without a publicly available solution as of March 14, 2021.
Stiff chemical problems of this size pose several computational difficulties:
The purpose of this interop is to reuse existing ODE solvers, which are in public domain, while attempting to solve extremely large systems of [chemical] ODEs in a reasonable time and with a reasonable precision.
The interop includes a performance test for a large chemical-like system of ODEs. Both C# and F# versions of the test are included. F# posed an additional challenge most likely due to the absence of unsafe context.
The tests used a chemical-like system of equations based on a simple set of "reactions":
�
The number of variables was 100,001 (n = 50,000).
All forward and backward coefficients were the same:
The initial conditions set
and all other to zeros.
The system was solved from to . The system has an integral of motion: sum of all y must be constant.
Five variants were tested under two different setups. The first setup treated all negative values of y as exact zeros when calculating the derivatives and the second one just used them as is without any corrections. The tested variants were as follows:
SolutionMethod.Bdf, CorrectorIteratorMethod.ChordWithDiagonalJacobian).SolutionMethod.Adams, CorrectorIteratorMethod.ChordWithDiagonalJacobian).SolutionMethod.Bdf, CorrectorIteratorMethod.Functional).SolutionMethod.Adams, CorrectorIteratorMethod.Functional).These variants were chosen as they were the only ones, which did not require time and memory expensive Jacobian calculations. All other combinations from DLSODE solver and all other solvers from ODEPACK do require full or banded Jacobian in some form and this was ruled out due to its size. Corrector iterator method ChordWithDiagonalJacobian calculates diagonal Jacobian and this is only one extra call to the derivative function per step.
When non-negativity was used (all negative values of y were treated as zeros when calculating
the derivative) then the results are as follows (No. f-s is the number of derivative evaluations and No. J-s is the number of Jacobian evaluations):
SolutionMethod.Bdf, CorrectorIteratorMethod.ChordWithDiagonalJacobian). Integral of motion: 10.0 -> 10.301689191032535 or OVER 3% discrepancy.
No. steps = 40,104, No. f-s = 132,533, No. J-s = 37,380
Elapsed: 00:02:37.3532643
SolutionMethod.Adams, CorrectorIteratorMethod.ChordWithDiagonalJacobian). Integral of motion: 10.0 -> 10.380914193130206 or OVER 3% discrepancy.
No. steps = 39,955, No. f-s = 100,769, No. J-s = 20,207
Elapsed: 00:01:49.2829071
SolutionMethod.Bdf, CorrectorIteratorMethod.Functional). Integral of motion: 10.0 -> 9.999999999999996.
No. steps = 49,067, No. f-s = 89,820, No. J-s = 0
Elapsed: 00:01:42.9414014
SolutionMethod.Adams, CorrectorIteratorMethod.Functional). Integral of motion: 10.0 -> 9.999999999999936.
No. steps = 48,266, No. f-s = 87,707, No. J-s = 0
Elapsed: 00:01:39.7107217
The solver did not come back.
When non-negativity was turned off, then the following happened:
SolutionMethod.Bdf, CorrectorIteratorMethod.ChordWithDiagonalJacobian). Integral of motion is nearly conserved: 10.0 -> 9.994361679959828
No. steps = 18,176, No. f-s = 64,101, No. J-s = 20,098
Elapsed: 00:00:46.7831109
SolutionMethod.Adams, CorrectorIteratorMethod.ChordWithDiagonalJacobian).
Integral of motion has nearly 2% discrepancy: 10.0 -> 9.98345003326132
No. steps = 185,378, No. f-s = 649,958, No. J-s = 184,053
Elapsed: 00:08:43.6774383
SolutionMethod.Bdf, CorrectorIteratorMethod.Functional). The solver did not come back.
SolutionMethod.Adams, CorrectorIteratorMethod.Functional). The solver did not come back.
The solver did not come back.
This makes the following combinations as clear winners:
SolutionMethod.Bdf and CorrectorIteratorMethod.ChordWithDiagonalJacobian. This seems to be the fastest method with the least number of derivative function evaluations. It was at least twice faster in the test, but the integral of motion started to deviate from the expected value and this may or may not have a significant impact for real tasks.CorrectorIteratorMethod.Functional, and then use either SolutionMethod.Adams (seems to be slightly faster) or SolutionMethod.Bdf. The integral of motion was conserved with a very high precision. However, the calculation was at least twice slower than for the combination above, and the number of derivative function evaluation was about 50% larger. This may change for real tasks.FORTRAN Interoperability with NET
Exporting subroutines from a FORTRAN DLL
FORTAN compiler issue due to usage of array and scalar variable interchangeably
Discussion about positivity constraints in ODEs
Intel FORTRAN compiler was used to compile FORTRAN code. File ODEPACK\dependencies.txt contains dependencies of compiled DLL and folder DLLs contains some of them. Solution was tested only in x64 mode and Release mode is recommended as it is not possible to debug in FORTRAN code from C# interop anyway.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on Softellect.OdePackInterop:
| Package | Downloads |
|---|---|
|
Softellect.DistributedProcessing.SolverRunner
Softellect Solver Runner ... |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.100.29 | 143 | 1/13/2026 |
| 9.0.303.28 | 186 | 8/23/2025 |
| 9.0.300.27 | 277 | 5/16/2025 |
| 9.0.100.4 | 223 | 11/16/2024 |
| 8.0.400.2 | 204 | 11/10/2024 |
| 8.0.400.1 | 245 | 9/22/2024 |
| 8.0.200.1 | 256 | 4/4/2024 |
| 8.0.0.1 | 321 | 11/19/2023 |
| 7.0.5.1 | 343 | 4/17/2023 |
| 7.0.0.1 | 498 | 11/9/2022 |
| 7.0.0-preview-0001 | 367 | 9/19/2022 |
| 0.1.2 | 605 | 9/18/2022 |
| 0.1.1 | 599 | 3/27/2021 |
| 0.1.0 | 532 | 3/14/2021 |
Added methods to specify tolerance parameters.