Skip to content

Object-oriented refactoring of active stress#578

Merged
kko27 merged 43 commits into
SimVascular:mainfrom
michelebucelli:feature/oo-active-stress
Jul 22, 2026
Merged

Object-oriented refactoring of active stress#578
kko27 merged 43 commits into
SimVascular:mainfrom
michelebucelli:feature/oo-active-stress

Conversation

@michelebucelli

@michelebucelli michelebucelli commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Partially addresses #519.

Current situation

  1. Coupling of electrophysiology and mechanics through active stress had been removed in Object oriented refactoring of ionic models and plotting calcium #540, pending this refactoring;
  2. only one active stress model was implemented, was tightly coupled to specific ionic models, and was not accessible through the user-exposed parameters.

Release Notes

Many of the implementation choices here are modeled after the implementation of IonicModel in #540. Here, I took some further steps towards encapsulation which might be ported to IonicModel as well, although maybe in a separate PR. I'll add some comments to the code about this.

  1. The PR introduces the following hierarchy of classes for active stress models, with the idea that new active stress model can be added easily by deriving new classes from ActiveStress or ActiveStressODE.
---
config:
    class:
      hideEmptyMembersBox: true
---
classDiagram
  ActiveStress <|-- ActiveStressODE
  ActiveStressODE <|-- NashPanfilov
  ActiveStress <|-- UniformSteadyActiveStress
  ActiveStress <|-- UniformUnsteadyActiveStress
  dmnType *-- ActiveStress
  ActiveStressFactory .. ActiveStress : instantiates
  Factory~BaseClass~ <|.. ActiveStressFactory : BaseClass=ActiveStress
Loading
  1. A new abstract Factory class is introduced, by templating the IonicModelFactory; aliases are provided for both Factory<IonicModel> and Factory<ActiveStress>.

  2. The ActiveStress class and derived classes manage their own XML parameters through the abstract class ActiveStressParameters and the methods get_parameters, read_parameters, distribute_parameters, so that the addition of model parameters can be localized to the source files where the model is defined.

  3. A (shared) pointer to ActiveStress is stored in dmnType, to allow different active stress models in different domains.

  4. Time stepping of ActiveStress instances is managed by Integrator::predictor. After advancing one time step, the active tension along the three principal directions is stored in the vector CepMod::cem.Ya_{f,s,n}, whose entries are then passed on to the constitutive law routines.

  5. The XML section for a struct domain now can optionally contain the following tag:

    <ActiveStress>
      <Model>Model name (e.g. NashPanfilov, UniformSteady, ...)</Model>
    
      <Directional_distribution>
        <!-- optional, and same as currently implemented for Fiber_reinforcement_stress -->
      </Directional_distribution>
    
      <UniformSteady>
        <Value>123</Value>
      <UniformSteady>
    
      <!-- other sections for every implemented model, if needed -->
    </ActiveStress>

    If present, the tag enables active stress through the ActiveStress class. If the active stress model is calcium-based, and no electrophysiology equation is present, the calcium will be kept to zero.

Documentation

New additions are documented via Doxygen comments. Documentation for ActiveStress and ActiveStressODE also includes a brief list of steps needed to implement a new model.

Testing

Existing automatic tests pass with the new implementation, although they do not cover the newly added features.

I have tested this on a basic electromechanics example based on cases/cep/slab_domains. I attach below a preview of the simulation.
anim
I plan to turn this into an integration test (running one timestep is reasonably fast).

TODO before marking as ready

  • add test for uniform, steady active stress
  • add test for uniform, unsteady active stress
  • add test for coupled electromechanics with Nash-Panfilov model

Code of Conduct & Contributing Guidelines

Comment thread Code/Source/solver/active_stress.h
Comment thread Code/Source/solver/active_stress.h
Comment thread Code/Source/solver/active_stress_nash_panfilov.h
Comment thread Code/Source/solver/active_stress_ode.cpp Outdated
Comment thread Code/Source/solver/active_stress_uniform_steady.h
Comment thread Code/Source/solver/Parameters.h
Comment thread Code/Source/solver/post.cpp Outdated
@michelebucelli michelebucelli added the OOP Refactor Object-Oriented Programming Refactor of Code label Jun 29, 2026
@michelebucelli

Copy link
Copy Markdown
Collaborator Author

I think this PR is now ready for review and merging.

@kko27 kko27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@michelebucelli, thanks so much for working on this! Documentation was excellent and the code was very easy to follow.

I had a general comment about coding style. I noticed that in Exception.h and Parameters.cpp, many of the changes are due to indentation, whitespaces, and the position of the * and & operators. I have two questions about this. 1) Should we think about enforcing coding standards (as discussed in #96)? 2) And (more practically for me) is there a way I can review the code without looking over these minor changes?

Comment thread Code/Source/solver/active_stress.h
Comment thread Code/Source/solver/active_stress_ode.h
Comment thread Code/Source/solver/Vector.h
Comment thread Code/Source/solver/Integrator.cpp Outdated
Comment thread Code/Source/solver/Integrator.cpp
@ktbolt

ktbolt commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

@kko27 There used to an implementation document describing implementation details and a Coding Standards section; seems that that was removed.

It is standard procedure in software engineering to follow the coding style used in a project; especially that used in a file. However, most developers here don't follow this practice so new code ends up looking different from one function to the next (Parameters.cpp) or the coding in an entire file does not look like that used in any other file in the project (Core/Exception.h).

I suppose we will again enable automatically enforced coding standards. Note that this may mess up the formatting of some complex mathematical statements like those used in material models.

@michelebucelli

Copy link
Copy Markdown
Collaborator Author

@kko27 @ktbolt Sorry, I have automatic formatting enabled in VS Code. It normally only touches lines of code that I've modified, but sometimes it misfires and touches the whole file without me noticing. A nice (terminal-only) tool to filter out whitespace changes in diffs is difftastic.

Having said that, I am very much in favor of automated formatting. I've used clang-format in the past, and I think it goes a long way to making sure the code is clean, consistent and readable. I agree with your concern on long mathematical statements, but it can usually be worked around by breaking the statement into multiple smaller ones at no meaningful performance cost.

@ktbolt

ktbolt commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

@michelebucelli We used clang-format before so we will enable that. Thanks for your feedback !

@javijv4 javijv4 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for working on this @michelebucelli. Looks great. I just left a few comments and questions.

Comment thread Code/Source/solver/Integrator.cpp
Comment thread Code/Source/solver/Integrator.cpp
Comment thread tests/test_electromechanics.py Outdated
Comment thread tests/cases/electromechanics/slab/solver.xml
Comment thread tests/cases/electromechanics/slab/solver.xml

@javijv4 javijv4 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me!

@kko27 kko27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

@kko27
kko27 merged commit b5fbed0 into SimVascular:main Jul 22, 2026
8 checks passed
@ktbolt

ktbolt commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

@michelebucelli Are there any unit tests for ActiveStress ?

@ktbolt

ktbolt commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

@michelebucelli And we name class files using the class name, like ActiveStress.h.

Sorry, I missed this until now.

@michelebucelli

Copy link
Copy Markdown
Collaborator Author

@ktbolt

Are there any unit tests for ActiveStress?

No (or at least not yet). There are integration tests (one new electromechanics test using NashPanfilov, and the old active mechanics tests replacing Fiber_reinforcement_stress with UniformUnsteadyActiveStress).

And we name class files using the class name, like ActiveStress.h.

Sorry, I forgot to update this. If it's all right with you, I'll sneak this into the PR for #592. I'll also do the same for IonicModel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OOP Refactor Object-Oriented Programming Refactor of Code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants