-
Notifications
You must be signed in to change notification settings - Fork 36
Add two-hill activation function and refactor chamber elastance models with proper separation of concerns #213
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
base: master
Are you sure you want to change the base?
Conversation
…earElastanceChamber Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
…ctivationFunction Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
aabrown100-git
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the json file, can we have the activation function parameters in a nested dictionary. Also, the activation_function_type should be provided as a string rather than a number
For example
"activation_function_type": "two_hill"
activation_function_values: {
"tau1": xxx
"tau2": xxx
...
}
…n_values in JSON Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Done! The JSON format now accepts:
Example: {
"type": "ChamberElastanceInductor",
"name": "ventricle",
"values": {
"Emax": 1.057,
"Emin": 0.091,
"Vrd": 26.1,
"Vrs": 18.0,
"Impedance": 0.000351787,
"activation_function_type": "two_hill",
"activation_function_values": {
"t_shift": 0.15,
"tau_1": 0.25,
"tau_2": 0.35,
"m1": 1.5,
"m2": 10.0
}
}
}The old numeric format is still supported for backward compatibility. Changes in commit b68ffd5. |
…vationFunction Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
aabrown100-git
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want activation function parameters to be members of individual instances of ActivationFuction, rather than members of ChamberElastanceInductor or LinearElasanceChamber. We should separate these as much as possible.
…tances Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Done! Activation function parameters are now:
This provides proper separation of concerns between chambers and activation functions. Changes in commit 6c18357. |
Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
… flat parameter backward compatibility Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
…vation function separation Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
|
@aabrown100-git This is all very interesting doing code design (?) on the fly with Copilot but none of these design decisions will show up in the Issue so the rationale behind them is lost. |
|
@copilot let's add more robust error checking. If the user has not provided all of the required parameters for an svzerodsolver block, an error message should be displayed which lists all the missing parameters. The current behavior is to list only the first missing parameter rather than a list. |
Co-authored-by: ncdorn <126125269+ncdorn@users.noreply.github.com>
Done! The parameter validation now collects all missing required parameters before throwing an error. Instead of stopping at the first missing parameter, it will now report all of them in a single error message like: This makes it much easier to fix configuration issues since users can see everything that needs to be corrected at once. Changes in commit 0ce3c32. |
@ktbolt The basic design was proposed by @ncdorn in the original issue. Would it help if I updated the issue with these latest implementation details and the rationale behind them? |
src/model/BlockType.h
Outdated
| blood_vessel_CRL = 16, | ||
| piecewise_cosine_chamber = 17, | ||
| piecewise_valve = 18 | ||
| piecewise_valve = 18, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot I think piecewise_valve should be 17
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed! piecewise_valve is now 17 and linear_elastance_chamber is 18, maintaining sequential enum numbering. Changes in commit 3c41770.
…ear_elastance_chamber = 18) Co-authored-by: aabrown100-git <71424733+aabrown100-git@users.noreply.github.com>
Summary
This PR successfully implements support for the two-hill activation function in cardiac chamber models, with complete separation of concerns between chamber models and activation functions, plus improved error reporting for missing parameters.
Changes Made
Core Implementation (800+ lines added)
ActivationFunction Class Hierarchy (
src/model/ActivationFunction.h)ActivationFunctionwith polymorphic interfacecardiac_periodis now a protected member of the baseActivationFunctionclass, stored once rather than passed on every compute() callHalfCosineActivation: Original half-cosine from ChamberElastanceInductorPiecewiseCosineActivation: Piecewise cosine activationTwoHillActivation: New two-hill function from alexkaiser's branchChamber Model Refactoring
ChamberElastanceInductor: Added support for all three activation typesLinearElastanceChamberto replacePiecewiseCosineChamberPiecewiseCosineChambercompletely removed - including source files, headers, and C++ type alias for cleaner separation between chamber models and activation functionsActivationFunction::create()factory methodinitialize_activation_function()codeChamberElastanceInductor: Emax, Emin, Vrd, Vrs, ImpedanceLinearElastanceChamber: Emax, Epass, Vrestset_activation_params()method to inject activation configuration into chamberscompute(time)without needing to passcardiac_periodeach timeLinearElastanceChamberrequiresactivation_typeto be explicitly specifiedNew JSON Configuration Format (Required)
activation_function_typeaccepts strings: "half_cosine", "piecewise_cosine", "two_hill"activation_function_valuesnested dictionaryBuild System Updates
BlockType.h- removed deprecatedpiecewise_cosine_chamberenum, fixed enum values to be sequentialModel.cppto register onlyLinearElastanceChamberSimulationParameters.cppto parse new JSON format and extract activation parametersSimulationParameters.hto include activation function headersCMakeLists.txt- removedPiecewiseCosineChambersource filescsv_writer.cppto useLinearElastanceChamberTesting & Documentation (410 lines added)
Test Cases
chamber_two_hill_activation.json: Tests ChamberElastanceInductor with two-hilllinear_chamber_two_hill_activation.json: Tests LinearElastanceChamber with two-hillpiecewise_Chamber_and_Valve.json: Updated to useLinearElastanceChamberwith new formatDocumentation (
docs/pages/activation_functions.md)Key Features
✅ Improved error reporting
✅ Complete removal of PiecewiseCosineChamber
LinearElastanceChamberis the only name for this chamber type✅ Consistent cardiac_period handling
cardiac_periodis stored as a protected member in theActivationFunctionbase classcardiac_periodin their constructorscompute()method signature simplified to only taketimeparameter✅ Complete separation of concerns
✅ Eliminated code duplication
ActivationFunctioncreates activation functions✅ New JSON format (required)
activation_function_values✅ Three activation function types available
Usage Example
{ "type": "ChamberElastanceInductor", "name": "ventricle", "values": { "Emax": 1.057, "Emin": 0.091, "Vrd": 26.1, "Vrs": 18.0, "Impedance": 0.000351787, "activation_function_type": "two_hill", "activation_function_values": { "t_shift": 0.15, "tau_1": 0.25, "tau_2": 0.35, "m1": 1.5, "m2": 10.0 } } }Breaking Changes
"type": "PiecewiseCosineChamber"is no longer supported - use"type": "LinearElastanceChamber"insteadPiecewiseCosineChamberclass completely removed from codebaseactivation_function_valuesnested dictionaryLinearElastanceChamberrequiresactivation_typeto be explicitly specified (no default)Files Changed
References
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.