cosapp 1.4.0
CoSApp, the Collaborative System Approach.
License: Apache-2.0
Requires Python: >=3.9
Keywords: cosapp, system simulation, system design

# CoSApp - Collaborative System Approach

The primary goal of **CoSApp** is to help technical departments in the design of complex systems.
To do so, the framework allows the simulation of various systems representing the different parts of the final product in a common environment.
The benefit is the ability for each subsystem team to carry out design study with a direct feedback at product level.

The main features are:

### Butterfly effect

Couple your simulation models with CoSApp to get immediate impact on main product variables and iterate to converge on a better design.

### Design guidance

All systems can share design parameters associated with an acceptable range.
You can take advantage of those limited degrees of freedom without fear of breaking your collaborators' work.

### Flexible simulation workflows

CoSApp solvers can be combined into versatile, customized workflows that fit specific simulation intents.

Have a look at the [introduction](https://cosapp.readthedocs.io/en/stable/tutorials/00-Introduction.html#), containing many tutorials!

This code is the property of Safran SA.
It uses code coming from various open-source projects (see [LICENSE](https://gitlab.com/cosapp/cosapp/blob/master/LICENSE.rst) file).

# Citing

If you use CoSApp, please cite us!

Lac *et al.* (2024), [CoSApp: a Python library to create, simulate and design complex systems](https://doi.org/10.21105/joss.06292), Journal of Open Source Software 9(94), 6292. 

BibTeX entry:

```bibtex
@article{Lac.etal:joss2024,
    author={Étienne Lac and Guy {De Spiegeleer} and Adrien Delsalle and Frédéric Collonval and Duc-Trung Lê and Mathias Malandain},
    title={CoSApp: a Python library to create, simulate and design complex systems},
    journal={Journal of Open Source Software},
    year={2024},
    volume={9},
    number={94},
    pages={6292},
    doi={10.21105/joss.06292},
    publisher={The Open Journal}
}
```

# Try it now!

Run a Jupyter Lab instance with binder to try out CoSApp features through examples.

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/cosapp%2Fcosapp/master?urlpath=lab/tree/docs/tutorials)
[![lite-badge](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)]( https://cosapp.gitlab.io/cosapp/)

# History


## 1.4.0 (2025-12-14)

### New features & API changes

- Add the possibility to declare unknowns and equations in implicit time drivers (MR [#447](https://gitlab.com/cosapp/cosapp/-/merge_requests/447)).
- Simplify `System.add_inward` and `add_outward` (MR [#448](https://gitlab.com/cosapp/cosapp/-/merge_requests/448)).

### Bug fixes & Code improvements

- Fix `WeakSet` pickling for Python 3.14 (MR [#451](https://gitlab.com/cosapp/cosapp/-/merge_requests/451)).
- Fix minor bugs in tests on dynamic systems (MR [#450](https://gitlab.com/cosapp/cosapp/-/merge_requests/450)).
- Fix bugs with implicit time drivers (MR [#449](https://gitlab.com/cosapp/cosapp/-/merge_requests/449)).
- Fix bug with nested solvers (MR [#443](https://gitlab.com/cosapp/cosapp/-/merge_requests/443)).

### Documentation & Maintenance

- New `Docker` container serving `JupyterLite` image (MR [#444](https://gitlab.com/cosapp/cosapp/-/merge_requests/444)).
- Update CI script (MR [#442](https://gitlab.com/cosapp/cosapp/-/merge_requests/442)).


## 1.3.0 (2025-09-18)

### New features & API changes

- Deprecation of methods `NonLinearSolver.extend` and `RunSingleCase.extend`, replaced by new methods `add_problem` (MR [#430](https://gitlab.com/cosapp/cosapp/-/merge_requests/430)).
- Declaring integer-valued `numpy` arrays no longer raises a warning (MR [#428](https://gitlab.com/cosapp/cosapp/-/merge_requests/428)).
- Harmonize solver option "history" between `NonLinearSolver` and `Optimizer` (MR [#432](https://gitlab.com/cosapp/cosapp/-/merge_requests/432)).
  `Optimizer` option "monitored" is now deprecated, in favour of "history".
  Moreover, option "history" can now be set at recorder creation:

  ```python
  solver = system.add_solver(NonLinearSolver("solver"))

  solver.add_recorder(DataFrameRecorder(...), history=True)
  ```

### Bug fixes & Code improvements

- Add missing initial data in solver convergence path (MR [#431](https://gitlab.com/cosapp/cosapp/-/merge_requests/431)).
- Handle zero-sized `numpy` arrays in mathematical algorithms (MR [#433](https://gitlab.com/cosapp/cosapp/-/merge_requests/433)).
- Fix bugs with multidimensional arrays as unknowns or transient variables (MR [#434](https://gitlab.com/cosapp/cosapp/-/merge_requests/434)).
- Fix bug on targets during mathematical problem extension (MR [#435](https://gitlab.com/cosapp/cosapp/-/merge_requests/435)).
- Fix bug on target detection during system problem assembly (MR [#436](https://gitlab.com/cosapp/cosapp/-/merge_requests/436)).
- Fix target initialization issue in implicit time drivers (MR [#437](https://gitlab.com/cosapp/cosapp/-/merge_requests/437)).
- New deprecation decorator (MR [#429](https://gitlab.com/cosapp/cosapp/-/merge_requests/429)).
- Improved type hints and general refactoring pass (MR [#438](https://gitlab.com/cosapp/cosapp/-/merge_requests/438)).

### Documentation

- Updated tutorial on targets (MR [#440](https://gitlab.com/cosapp/cosapp/-/merge_requests/440)).


## 1.2.0 (2025-06-13)

### New features & API changes

- New function `cosapp.systems.batch_run` and support class `BatchRunner` to obtain the response surface of a system over a set of test points, with multiprocessing support (MRs [#423](https://gitlab.com/cosapp/cosapp/-/merge_requests/423), [#424](https://gitlab.com/cosapp/cosapp/-/merge_requests/424)).
- Support of multiprocessing for `System.make_surrogate` (MR [#422](https://gitlab.com/cosapp/cosapp/-/merge_requests/422)).
- Removed deprecated property `data` for recorders (MR [#421](https://gitlab.com/cosapp/cosapp/-/merge_requests/421)).
- New method `System.get_variable` to obtain a variable object (containing unit, description and so on) from its contextual name in a system (MR [#417](https://gitlab.com/cosapp/cosapp/-/merge_requests/417)).
- Deprecation of function `BasePort.get_details`, replaced by methods `get_variable` and `variable_dict` (MR [#420](https://gitlab.com/cosapp/cosapp/-/merge_requests/420)).
- Expose protected property `System.problem` in the scope of method `setup_run` (MR [#419](https://gitlab.com/cosapp/cosapp/-/merge_requests/419)).

### Bug fixes & Code improvements

- Modified call sequence in `System.call_setup_run`, to make sure that the system tree is setup before drivers are (MR [#418](https://gitlab.com/cosapp/cosapp/-/merge_requests/418)).
- Improved type hints and general refactoring pass (MR [#425](https://gitlab.com/cosapp/cosapp/-/merge_requests/425)).

### Documentation

- Updated tutorial on multi-point design (MR [#426](https://gitlab.com/cosapp/cosapp/-/merge_requests/426)).


## 1.1.0 (2025-04-28)

### New features & API changes

- New implicit time drivers: backward Euler and order 1-4 Backward Difference Formula (BDF) integrators (MRs [#405](https://gitlab.com/cosapp/cosapp/-/merge_requests/405), [#415](https://gitlab.com/cosapp/cosapp/-/merge_requests/415)).
- Add new signal `system_update_signal` for all time drivers, emitted at each time step (MR [#406](https://gitlab.com/cosapp/cosapp/-/merge_requests/406)).
- Improvement of driver `MonteCarlo` (MR [#409](https://gitlab.com/cosapp/cosapp/-/merge_requests/409)).
- Expose exception `EventError` in module `cosapp.multimode` (MR [#407](https://gitlab.com/cosapp/cosapp/-/merge_requests/407)).

### Bug fixes & Code improvements

- Improved type hints and general refactoring pass (MRs [#400](https://gitlab.com/cosapp/cosapp/-/merge_requests/400), [#408](https://gitlab.com/cosapp/cosapp/-/merge_requests/408), [#410](https://gitlab.com/cosapp/cosapp/-/merge_requests/410), [#416](https://gitlab.com/cosapp/cosapp/-/merge_requests/416)).
- Support for polynomials with multi-dimensional coefficients in `TwoPointCubicPolynomial` (MR [#404](https://gitlab.com/cosapp/cosapp/-/merge_requests/404)).

### Documentation

- Updated section on "Tips & Tricks" (MR [#412](https://gitlab.com/cosapp/cosapp/-/merge_requests/412)).
- Updated tutorial on time drivers (MR [#415](https://gitlab.com/cosapp/cosapp/-/merge_requests/415)).

### Dependency management

- Update of the `JupyterLite` image (MRs [#401](https://gitlab.com/cosapp/cosapp/-/merge_requests/401), [#402](https://gitlab.com/cosapp/cosapp/-/merge_requests/402), [#403](https://gitlab.com/cosapp/cosapp/-/merge_requests/403), [#411](https://gitlab.com/cosapp/cosapp/-/merge_requests/411), [#413](https://gitlab.com/cosapp/cosapp/-/merge_requests/413)).


## 1.0.1 (2025-03-24)

### Bug fixes & Improvements

- New transient variables dynamically added during transitions are now accounted for in time drivers (MRs [#394](https://gitlab.com/cosapp/cosapp/-/merge_requests/394), [#396](https://gitlab.com/cosapp/cosapp/-/merge_requests/396)).
- Bug fixes in `CrankNicolson` (MRs [#395](https://gitlab.com/cosapp/cosapp/-/merge_requests/395), [#397](https://gitlab.com/cosapp/cosapp/-/merge_requests/397)).
- Refactoring of `state_io` functions (MR [#398](https://gitlab.com/cosapp/cosapp/-/merge_requests/398)).


## 1.0.0 (2025-03-12)

### New feature: Parallel execution of drivers

The parallelization of certain drivers was implemented by [Adrien Delsalle](https://gitlab.com/adriendelsalle) and [Gaétan Laurens](https://gitlab.com/GtnLrs) (MRs [#330](https://gitlab.com/cosapp/cosapp/-/merge_requests/330), [#332](https://gitlab.com/cosapp/cosapp/-/merge_requests/332), [#334](https://gitlab.com/cosapp/cosapp/-/merge_requests/334), [#335](https://gitlab.com/cosapp/cosapp/-/merge_requests/335), [#339](https://gitlab.com/cosapp/cosapp/-/merge_requests/339), [#341](https://gitlab.com/cosapp/cosapp/-/merge_requests/341), [#345](https://gitlab.com/cosapp/cosapp/-/merge_requests/345), [#348](https://gitlab.com/cosapp/cosapp/-/merge_requests/348), [#353](https://gitlab.com/cosapp/cosapp/-/merge_requests/353), [#357](https://gitlab.com/cosapp/cosapp/-/merge_requests/357), [#365](https://gitlab.com/cosapp/cosapp/-/merge_requests/365), [#374](https://gitlab.com/cosapp/cosapp/-/merge_requests/374), [#390](https://gitlab.com/cosapp/cosapp/-/merge_requests/390)):
- `LinearDoE` and `MonteCarlo`;
- `NonLinearSolver` (computation of the Jacobian matrix in parallel).

This major feature relies on a robust serialization of systems, drivers and recorders, using either `pickle` or `json`.
The serialization of all drivers, in particular, allows for the parallel execution of the drivers listed above, even when they contain sub-drivers.

#### Example

In the example below, using the `Ballistics` system from the advanced time driver tutorial, we compute the initial velocity leading to a targetted end point, after an imposed flight time of two seconds.
This design case implies a `RungeKutta` time driver, embedded into a `NonLinearSolver` driver.
For the latter, we request a parallel computation of the Jacobian matrix by forward finite differences, using three workers.

```python
from cosapp.drivers import NonLinearSolver, RungeKutta
from cosapp.core.numerics.solve import FfdJacobianEvaluation
from cosapp.utils.execution import ExecutionPolicy, ExecutionType

# Set test case
point = Ballistics("point")
ncpus = 3  # compute the Jacobian matrix using 3 workers

solver = point.add_driver(
    NonLinearSolver(
        "solver",
        jac=FfdJacobianEvaluation(
            execution_policy=ExecutionPolicy(ncpus, ExecutionType.MULTI_PROCESSING)
        ),
    )
)
driver = solver.add_child(RungeKutta(time_interval=(0, 2), dt=0.1, order=3))

# Set design problem: compute initial velocity that leads to a target point
solver.add_unknown("v0").add_equation("x == [10, 0, 0]")

# Define a time simulation scenario
driver.set_scenario(
    init={"x": [0, 0, 0], "v": "v0"},
    values={"point.mass": 1.5, "point.k": 0.9},
)

# Set initial guess & solve
point.v0 = np.ones(3)
point.run_drivers()
```

### Other new features & API changes

- Implementation of second-order, implicit time driver `CrankNicolson` (MRs [#377](https://gitlab.com/cosapp/cosapp/-/merge_requests/377)).
  This driver essentially works like a nonlinear solver, solving for both transient variables and intrinsic unknowns of the system of interest.
  Therefore, it is highly recommended for dynamic systems containing algebraic loops or intrinsic constraints, instead of nesting a nonlinear solver inside an explicit time driver.
- Detect the occurrence of multiple primary events at the same time (MR [#376](https://gitlab.com/cosapp/cosapp/-/merge_requests/376)).
- Add the possibility to filter events with a Boolean expression evaluated in a specific context, other than that of the event owner (MR [#375](https://gitlab.com/cosapp/cosapp/-/merge_requests/375)).
- Add `numpy.where` and `logspace` to the scope of evaluable expressions, used in equations and boundary conditions, *e.g.* (MR [#382](https://gitlab.com/cosapp/cosapp/-/merge_requests/382)).

### Bug fixes and code improvements

- Bug fix in `EvalString` serialization (MR [#383](https://gitlab.com/cosapp/cosapp/-/merge_requests/383)).
- Bug fix in the serialization of events (MR [#386](https://gitlab.com/cosapp/cosapp/-/merge_requests/386)).
- Bug fix in `MonteCarlo` with a time subdriver (MRs [#378](https://gitlab.com/cosapp/cosapp/-/merge_requests/378), [#392](https://gitlab.com/cosapp/cosapp/-/merge_requests/392)).
- Prevent name clashes for ports and sub-systems (MR [#381](https://gitlab.com/cosapp/cosapp/-/merge_requests/381)).
- Other bug fixes (MRs [#379](https://gitlab.com/cosapp/cosapp/-/merge_requests/379), [#380](https://gitlab.com/cosapp/cosapp/-/merge_requests/380), [#389](https://gitlab.com/cosapp/cosapp/-/merge_requests/389)).

### Documentation

- Add Crank-Nicolson driver in time driver tutorial (MR [#385](https://gitlab.com/cosapp/cosapp/-/merge_requests/385)).
- New tutorial on multiprocessing (MR [#391](https://gitlab.com/cosapp/cosapp/-/merge_requests/391)).

### Dependency management

- Compatibility with `numpy` 2, with retrocompatibility with version 1 (MRs [#309](https://gitlab.com/cosapp/cosapp/-/merge_requests/309), [#387](https://gitlab.com/cosapp/cosapp/-/merge_requests/387)).
- Compatibility with `pytest` 8.3 was restored (MR [#388](https://gitlab.com/cosapp/cosapp/-/merge_requests/388)).
- The code is no longer compatible with Python 3.8, as it now contains type hints of the kind `list[str]` or `dict[str, float]` (instead of `typing.List` and `typing.Dict`), introduced in Python 3.9.


## 0.19.2 (2025-01-23)

### Bug fixes and code improvements

- Improve the system transition mechanism (MR [#370](https://gitlab.com/cosapp/cosapp/-/merge_requests/370)).
- Fix bug in event cascade resolution (MRs [#371](https://gitlab.com/cosapp/cosapp/-/merge_requests/371) & [#372](https://gitlab.com/cosapp/cosapp/-/merge_requests/372)).

### Maintenance and code quality

- Improve type hints (MR [#369](https://gitlab.com/cosapp/cosapp/-/merge_requests/369)).


## 0.19.1 (2025-01-07)

### Bug fixes and code quality

- Fix dealiasing bug for custom objects (MR [#362](https://gitlab.com/cosapp/cosapp/-/merge_requests/362)).
- Fix bug in `ExplicitTimeDriver.set_scenario` (MR [#363](https://gitlab.com/cosapp/cosapp/-/merge_requests/363)).
- Fix bug with array transients (MR [#364](https://gitlab.com/cosapp/cosapp/-/merge_requests/364)).
- Suppress unnecessary exception in `PeriodicEvent.tick` (MR [#366](https://gitlab.com/cosapp/cosapp/-/merge_requests/366)).
- Improve the handling of timed events (MR [#367](https://gitlab.com/cosapp/cosapp/-/merge_requests/367)).


## 0.19.0 (2024-12-04)

### New features & API changes

- Improve the performance of unknowns and residues (MRs [#350](https://gitlab.com/cosapp/cosapp/-/merge_requests/350), [#352](https://gitlab.com/cosapp/cosapp/-/merge_requests/352), by [Gaétan Laurens](https://gitlab.com/GtnLrs)).
  In particular, this version introduces the possiblity to declare as unknown any settable attribute of an input object (that is an object contained in an input port), which until now was only possible for input port variables.
  Example:

  ```python
  from cosapp.base import System
  from cosapp.drivers import NonLinearSolver
  from dataclasses import dataclass

  @dataclass
  class Foo:
    a: float
    x: float

  class SomeSystem(System):
      def setup(self):
          self.add_inward("foo", Foo(a=1.0, x=1.0))
          self.add_outward("y", 0.0)

      def compute(self):
          self.y = self.foo.a - self.foo.x**3
  
  system = SomeSystem("system")
  solver = system.add_driver(NonLinearSolver("solver"))

  solver.add_unknown("foo.x")   # attribute `x` can now be manipulated by the solver
  solver.add_equation("y == 0")

  system.foo.a = -2.0
  system.run_drivers()

  import pytest, math
  assert system.foo.x == pytest.approx(math.cbrt(system.foo.a))
  ```

- Fix bug in `TwoPointCubicInterpolator` with multidimensional arrays (MR [#355](https://gitlab.com/cosapp/cosapp/-/merge_requests/355)).
- Allow filtered events in merged events (MR [#356](https://gitlab.com/cosapp/cosapp/-/merge_requests/356)):

  ```python
  system.event.trigger = Event.merge(
      event_a,
      event_b.filter("x > 0"),
  )
  ```

- Introduction of periodic events (MR [#360](https://gitlab.com/cosapp/cosapp/-/merge_requests/360)):

  ```python
  from cosapp.multimode import PeriodicTrigger

  system.event_a.trigger = PeriodicTrigger(period=2.3)
  system.event_b.trigger = PeriodicTrigger(period=0.25, t0=0.33)
  ```

### Documentation

- Add instructions on how to perform benchmarks with `asv_runner` in main README file (MR [#358](https://gitlab.com/cosapp/cosapp/-/merge_requests/358)).

### Maintenance and code quality

- Fix import error in JupyterLite (MR [#351](https://gitlab.com/cosapp/cosapp/-/merge_requests/351)).
- Minor code refactoring (MR [#354](https://gitlab.com/cosapp/cosapp/-/merge_requests/354)).
- Use public runners for all CI jobs (MR [#359](https://gitlab.com/cosapp/cosapp/-/merge_requests/359)).


## 0.18.0 (2024-10-24)

### New features & API changes

- Improved data recording mechanism for `NonLinearSolver`, to facilitate convergence path analysis (MR [#312](https://gitlab.com/cosapp/cosapp/-/merge_requests/312)).
- New driver `FixedPointSolver`, solving algebraic loops by fixed-point iterations (MRs [#315](https://gitlab.com/cosapp/cosapp/-/merge_requests/315) & [#322](https://gitlab.com/cosapp/cosapp/-/merge_requests/322)).
- New method `Driver.available_options`, returning the list of options available for a particular driver (MR [#316](https://gitlab.com/cosapp/cosapp/-/merge_requests/316)).
- New method `System.pull_design_method`, to promote sub-system design methods at parent level easily (MR [#314](https://gitlab.com/cosapp/cosapp/-/merge_requests/314)).
- Bug fix in FMU exporter (MR [#324](https://gitlab.com/cosapp/cosapp/-/merge_requests/324)).
- Bug fixes in system transition logic (MR [#338](https://gitlab.com/cosapp/cosapp/-/merge_requests/338)).
- New method `System.init_mode` called before each time simulation, for mode initialization (MR [#347](https://gitlab.com/cosapp/cosapp/-/merge_requests/347)).

### Documentation

- Fix bad rendering of tutorial notebooks on time simulations (MR [#321](https://gitlab.com/cosapp/cosapp/-/merge_requests/321)).
- Fix bad rendering of mermaid graph in logger documentation (MR [#326](https://gitlab.com/cosapp/cosapp/-/merge_requests/326)).
- Updated tutorial on advanced time simulations and on design methods (MR [#343](https://gitlab.com/cosapp/cosapp/-/merge_requests/343)).
- Add a section on `FixedPointSolver` in the driver tutorial (MR [#346](https://gitlab.com/cosapp/cosapp/-/merge_requests/346)).

### Maintenance and code quality

- Improved type hints for drivers (MR [#318](https://gitlab.com/cosapp/cosapp/-/merge_requests/318)).
- Updated JupyterLite image (MR [#313](https://gitlab.com/cosapp/cosapp/-/merge_requests/313)).
- Add new test on `swap_system` (MR [#342](https://gitlab.com/cosapp/cosapp/-/merge_requests/342)).
- Various updates of CI/CD settings (MRs [#317](https://gitlab.com/cosapp/cosapp/-/merge_requests/317), [#319](https://gitlab.com/cosapp/cosapp/-/merge_requests/319) [#320](https://gitlab.com/cosapp/cosapp/-/merge_requests/320), [#336](https://gitlab.com/cosapp/cosapp/-/merge_requests/336), [#337](https://gitlab.com/cosapp/cosapp/-/merge_requests/337)).
- Various test improvements (MRs [#340](https://gitlab.com/cosapp/cosapp/-/merge_requests/340), [#342](https://gitlab.com/cosapp/cosapp/-/merge_requests/342)).


## 0.17.0 (2024-06-18)

### New features & API changes

- A JupyterLite image including CoSApp is now available in the main README file (MR [#300](https://gitlab.com/cosapp/cosapp/-/merge_requests/300)).
- Fix a bug with primary event initialization (MR [#293](https://gitlab.com/cosapp/cosapp/-/merge_requests/293)).
- Improved API for partial connections: name mappings can now be given as lists mixing variable names and dictionaries, which is convenient when most variable names are identical, and only a few differ (MRs [#294](https://gitlab.com/cosapp/cosapp/-/merge_requests/294), [#295](https://gitlab.com/cosapp/cosapp/-/merge_requests/295) & [#306](https://gitlab.com/cosapp/cosapp/-/merge_requests/306)).
  Example:

  ```python
  from cosapp.base import System
  
  class SomeSystem(System):
      def setup(self):
          foo = self.add_child(Foo('foo'), pulling=['a', 'b', {'c': 'c_foo'}])
          bar = self.add_child(Bar('bar'))

          self.connect(foo, bar, ['x', 'y', {'z': 'v'}])
  ```
  
- New utility function `cosapp.tools.views.show_tree` displaying the hierarchical tree of a system similar to a folder tree in a filesystem (MRs [#296](https://gitlab.com/cosapp/cosapp/-/merge_requests/296)-[#298](https://gitlab.com/cosapp/cosapp/-/merge_requests/298)).

### Bug fixes and code quality

- New attribute `Residue.variables` providing the names of the variables involved in the residue (MR [#299](https://gitlab.com/cosapp/cosapp/-/merge_requests/299)).
- Minor bug fix in Newton-Raphson algorithm (MR [#303](https://gitlab.com/cosapp/cosapp/-/merge_requests/303)).
- Fix bad markdown rendering of systems (MR [#292](https://gitlab.com/cosapp/cosapp/-/merge_requests/292)).
- Improved type hints throughout the code (MR [#307](https://gitlab.com/cosapp/cosapp/-/merge_requests/307)).
- Other improvements (MRs [#291](https://gitlab.com/cosapp/cosapp/-/merge_requests/291), [#301](https://gitlab.com/cosapp/cosapp/-/merge_requests/301), [#302](https://gitlab.com/cosapp/cosapp/-/merge_requests/302), [#304](https://gitlab.com/cosapp/cosapp/-/merge_requests/304), [#305](https://gitlab.com/cosapp/cosapp/-/merge_requests/305), [#307](https://gitlab.com/cosapp/cosapp/-/merge_requests/307), [#308](https://gitlab.com/cosapp/cosapp/-/merge_requests/308)).

### Maintenance

- Pin dependency to `numpy` v1, until full migration to v2 (MR [#310](https://gitlab.com/cosapp/cosapp/-/merge_requests/310)).


## 0.16.0 (2024-04-18)

### Bug fixes and code quality

- Primary events triggered within the same time step are now correctly captured (MR [#287](https://gitlab.com/cosapp/cosapp/-/merge_requests/287)).
  A bug persists when several primary events occur at the exact same time, though, as only one will be retained.
- Fix bug preventing events from occurring during the first time step of a simulation (MR [#288](https://gitlab.com/cosapp/cosapp/-/merge_requests/288)).
- Fix a bug causing recorders to crash when inspecting ports with properties (MR [#282](https://gitlab.com/cosapp/cosapp/-/merge_requests/282)).
- Algebraic and time-dependent problems are now dissociated (MR [#284](https://gitlab.com/cosapp/cosapp/-/merge_requests/284)). As a consequence, invoking `self.problem.clear()` during transitions, for instance, no longer affects time-dependent unknowns such as transients.
- Fix ambiguous warning message raised by `RunSingleCase` (MR [#279](https://gitlab.com/cosapp/cosapp/-/merge_requests/279)).
- Various refactoring passes (MRs [#283](https://gitlab.com/cosapp/cosapp/-/merge_requests/283) and [#286](https://gitlab.com/cosapp/cosapp/-/merge_requests/286)).

### Maintenance

- Updated description inside the conda recipe (MR [#276](https://gitlab.com/cosapp/cosapp/-/merge_requests/276)).
- Pin `pytest` version due to a bug in version 8.1 (MR [#280](https://gitlab.com/cosapp/cosapp/-/merge_requests/280)).
- Add a "Citing" section in the main README file (MR [#281](https://gitlab.com/cosapp/cosapp/-/merge_requests/281)).
- The module parser was updated (MR [#285](https://gitlab.com/cosapp/cosapp/-/merge_requests/285)).
- Force `sphinx` < 7.3 in the documentation building environment, owing to an incompatibility with `sphinx-mdinclude` (MR [#289](https://gitlab.com/cosapp/cosapp/-/merge_requests/289)). This is a temporary patch until root cause is fixed.


## 0.15.4 (2024-02-28)

### Bug fixes and code quality

- Fix bug raised in `NonLinearSolver` for systems with rates (MR [#268](https://gitlab.com/cosapp/cosapp/-/merge_requests/268)).
- Minor refactoring pass (MR [#274](https://gitlab.com/cosapp/cosapp/-/merge_requests/274)).

### Maintenance

- Drop Python 3.8 support and add Python 3.11 test pipeline (MR [#270](https://gitlab.com/cosapp/cosapp/-/merge_requests/270)).
- Update installation and contribution guidelines (MR [#270](https://gitlab.com/cosapp/cosapp/-/merge_requests/270)).
- Update dependency list (MRs [#269](https://gitlab.com/cosapp/cosapp/-/merge_requests/269) and [#270](https://gitlab.com/cosapp/cosapp/-/merge_requests/270)).

### JOSS article

Publication of an article on CoSApp in the [Journal of Open-Source Software](https://joss.theoj.org/), referenced to version 0.15.4 (MR [#271](https://gitlab.com/cosapp/cosapp/-/merge_requests/271)).


## 0.15.3 (2023-12-19)

### Bug fixes and code quality

- Fix minor bug in `NonLinearSolver` (MR [#261](https://gitlab.com/cosapp/cosapp/-/merge_requests/261)).
- Fix incorrect return type hints in `System` (MR [#259](https://gitlab.com/cosapp/cosapp/-/merge_requests/259)).
- Improve support for read-only properties in system getters and setters (MR [#264](https://gitlab.com/cosapp/cosapp/-/merge_requests/264)).

### Maintenance

- Remove deprecated dependency for compatibility with Python 3.12 (MR [#258](https://gitlab.com/cosapp/cosapp/-/merge_requests/258)).
- Force `pythonfmu` < 0.6.3 in dependency list, to prevent a crash during tests (MR [#262](https://gitlab.com/cosapp/cosapp/-/merge_requests/262)). Temporary fix until root cause is identified.


## 0.15.2 (2023-10-14)

### Bug fixes

- Fix crash with `VisJs` rendering of sub-systems (MR [#252](https://gitlab.com/cosapp/cosapp/-/merge_requests/252)).
- Fix minor bug in `EvalString` (MR [#253](https://gitlab.com/cosapp/cosapp/-/merge_requests/253)).
- Fix bad synchronization of mode variables during transitions (MR [#254](https://gitlab.com/cosapp/cosapp/-/merge_requests/254)).
- Improve error message when pulling variables with different roles (MR [#255](https://gitlab.com/cosapp/cosapp/-/merge_requests/255)).
- Fix `TypeError` when passing `pulling` argument as a tuple in `System.add_child` (MR [#256](https://gitlab.com/cosapp/cosapp/-/merge_requests/256)).


## 0.15.1 (2023-09-18)

### New features & API changes

- The representation of `MathematicalProblem` objects now indicates the number of unknowns and equations, for a better readability (MR [#249](https://gitlab.com/cosapp/cosapp/-/merge_requests/249)).
- Optional argument `execution_index` in `System.add_child` and `Driver.add_child` can now take a negative value, with a behaviour following that of `list.insert` (MR [#250](https://gitlab.com/cosapp/cosapp/-/merge_requests/250)).

### Bug fixes and code quality

- Add missing field "time" in `ExplicitTimeRecorder.event_data`, when no recorder is set (MR [#245](https://gitlab.com/cosapp/cosapp/-/merge_requests/245)).
- Fix bug with recorders inspecting systems with iterators (MRs [#246](https://gitlab.com/cosapp/cosapp/-/merge_requests/246) and [#247](https://gitlab.com/cosapp/cosapp/-/merge_requests/247)).
- Fix bug with `NonLinearSolver` with NumPy array residues (MR [#248](https://gitlab.com/cosapp/cosapp/-/merge_requests/248)).
- Fix initialization bug of targets involving expressions (MR [#249](https://gitlab.com/cosapp/cosapp/-/merge_requests/249)).


## 0.15.0 (2023-07-20)

### New features & API changes

- Suppression of default `RunSingleCase` subdriver `runner` in `NonLinearSolver` drivers (MR [#239](https://gitlab.com/cosapp/cosapp/-/merge_requests/239)).
- Enable target initialization in multi-point design problems (MR [#233](https://gitlab.com/cosapp/cosapp/-/merge_requests/233)).
- New utility function `swap_system` to replace on the fly a subsystem by another `System` instance (MR [#238](https://gitlab.com/cosapp/cosapp/-/merge_requests/238)).

### Bug fixes and code quality

- Refactor driver `Optimizer` (MR [#240](https://gitlab.com/cosapp/cosapp/-/merge_requests/240)).
- Various bug fixes (MRs [#234](https://gitlab.com/cosapp/cosapp/-/merge_requests/234), [#235](https://gitlab.com/cosapp/cosapp/-/merge_requests/235), [#241](https://gitlab.com/cosapp/cosapp/-/merge_requests/241)).

### Documentation

- New tutorial on `swap_system` (MR [#243](https://gitlab.com/cosapp/cosapp/-/merge_requests/243)).
- General update of tutorials (MRs [#232](https://gitlab.com/cosapp/cosapp/-/merge_requests/232) and [#242](https://gitlab.com/cosapp/cosapp/-/merge_requests/242)).


## 0.14.1 (2023-06-08)

### Bug fixes and code quality

- Fix incorrect output file name in `cosapp.tools.parse_module` (MR [#229](https://gitlab.com/cosapp/cosapp/-/merge_requests/229)).
- Refactoring pass (MR [#230](https://gitlab.com/cosapp/cosapp/-/merge_requests/230)).

### Documentation

- Upgrade documentation build stack (MRs [#224](https://gitlab.com/cosapp/cosapp/-/merge_requests/224) and [#226](https://gitlab.com/cosapp/cosapp/-/merge_requests/226)).
- Fix bad rendering of ports and systems (MRs [#227](https://gitlab.com/cosapp/cosapp/-/merge_requests/227) and [#228](https://gitlab.com/cosapp/cosapp/-/merge_requests/228)).


## 0.14.0 (2023-05-17)

### New features & API changes

* Improved performance, through a revised clean/dirty mechanism (MR [#215](https://gitlab.com/cosapp/cosapp/-/merge_requests/215)).
* Possibility to add a contextual description to sub-systems and ports of a system, as well as sub-drivers (MR [#216](https://gitlab.com/cosapp/cosapp/-/merge_requests/216)). This feature is useful for automatic documentation tools, and has been included in the Markdown representation of systems (also used in function `cosapp.tools.display_doc`). Example:
  
  ```python
  from cosapp.base import System
  from my_module import FlowPort
  
  class MySystem(System):
      def setup(self):
          self.add_input(FlowPort, "fl_in1", desc="Primary inlet flow port")
          self.add_input(FlowPort, "fl_in2", desc="Secondary inlet flow port")
  
          self.add_output(FlowPort, "fl_out")
  ```
  
* New hook function `_parse_module_config`, returning pre-defined settings for `cosapp.tools.parse_module` (MR [#218](https://gitlab.com/cosapp/cosapp/-/merge_requests/218)). This allows module maintainers to simply call
  
  ```python
  from cosapp.tools import parse_module
  import my_module
  
  parse_module(my_module)
  ```

  instead of, *e.g.*,

  ```python
  parse_module(
      my_module,
      ctor_config={
          "ComplexSystem1": [
              dict(n=1, foo=0.5),
              dict(n=2, foo=0.1),
          ],
          "ComplexSystem2": [
              dict(xi=0.0, __alias__="ComplexSystem2_a"),
              dict(xi=1.0, __alias__="ComplexSystem2_b"),
          ],
      },
      excludes=["Foo*", "*Bar?"],
  )
  ```

  provided `my_module._parse_module_config()` returns a dictionary specifying the values of `ctor_config`, `excludes`, *etc.*

* Make `SolverResults` a `dataclass`, for easier handling of `NonLinearSolver.results`, *e.g.* (MR [#220](https://gitlab.com/cosapp/cosapp/-/merge_requests/220)).
* Expose attribute `problem` in system setup (MR [#221](https://gitlab.com/cosapp/cosapp/-/merge_requests/221)). Previously, `problem` was only exposed in method `System.transition`.

### Bug fixes and code quality

* Fix bug in `NonLinearSolver` log message (MR [#214](https://gitlab.com/cosapp/cosapp/-/merge_requests/214)).
* Add missing JSON file in PyPI and conda packages, preventing the use of `cosapp.tools.parse_module` (MR [#219](https://gitlab.com/cosapp/cosapp/-/merge_requests/219)).

### Documentation

* Illustrate port and sub-system description in tutorials (MR [#215](https://gitlab.com/cosapp/cosapp/-/merge_requests/215)).


## 0.13.1 (2023-04-03)

### Bug fixes and code quality

* Update test baseline to pass in a Python 3.11 environment (MR [#200](https://gitlab.com/cosapp/cosapp/-/merge_requests/200)).
* Creation of a dummy system factory, mostly for tests (MR [#201](https://gitlab.com/cosapp/cosapp/-/merge_requests/201)).
* Improve clean/dirty mechanism (MR [#202](https://gitlab.com/cosapp/cosapp/-/merge_requests/202)) and fix incorrect clean/dirty status with surrogate models (MR [#205](https://gitlab.com/cosapp/cosapp/-/merge_requests/205)).
* Fix bug in function `cosapp.tools.display_doc` for classes with setup arguments (MR [#208](https://gitlab.com/cosapp/cosapp/-/merge_requests/208)).
* Various code quality improvements (MRs [#211](https://gitlab.com/cosapp/cosapp/-/merge_requests/211), [#212](https://gitlab.com/cosapp/cosapp/-/merge_requests/212)).

### Documentation

Note: extensive use of self-documenting f-strings (introduced in Python 3.8) has made tutorials incompatible with Python 3.7.

* Updated tutorials (MRs [#203](https://gitlab.com/cosapp/cosapp/-/merge_requests/203), [#206](https://gitlab.com/cosapp/cosapp/-/merge_requests/206), [#207](https://gitlab.com/cosapp/cosapp/-/merge_requests/207), [#210](https://gitlab.com/cosapp/cosapp/-/merge_requests/210)).
* The image used in binder is now based on Python 3.10 (MR [#204](https://gitlab.com/cosapp/cosapp/-/merge_requests/204)).

### Module parser

* New function `parse_module` in `cosapp.tools` collecting all system and port classes within a Python module. This parser, generating a JSON file containing the description of all CoSApp symbols, is primarily meant to be used for constructional GUI applications, developed separately (MRs [#192](https://gitlab.com/cosapp/cosapp/-/merge_requests/192) & [#209](https://gitlab.com/cosapp/cosapp/-/merge_requests/209)).


## 0.13.0 (2023-02-09)

### Python 3.10 support

The code is now tested for Python 3.8, 3.9 and 3.10.
Support of Python 3.7 is thus officially dropped, although no version-specific Python code was introduced in this version of CoSApp.

### New features & API changes

* Module `connectors` moved from `cosapp.core` to `cosapp.ports` (MR [#189](https://gitlab.com/cosapp/cosapp/-/merge_requests/189)).
* New "direct" (with no unit conversion) connector classes `PlainConnector`, `CopyConnector` and `DeepCopyConnector`, in `cosapp.ports.connectors` (MR [#188](https://gitlab.com/cosapp/cosapp/-/merge_requests/188)).
* New method `MathematicalProblem.is_empty()`, equivalent to `shape == (0, 0)` (MR [#186](https://gitlab.com/cosapp/cosapp/-/merge_requests/186)).
* Improved VisJs graph rendering, by limiting node size for long system names (MR [#184](https://gitlab.com/cosapp/cosapp/-/merge_requests/184)).
* New utility functions `get_state` and `set_state` in `cosapp.utils`, for quick system data recovery (MR [#193](https://gitlab.com/cosapp/cosapp/-/merge_requests/193)):

  ```python
  from cosapp.utils import get_state, set_state
  
  s = SomeSystem('s')
  # ... many design steps, say
  
  # Save state in local object
  designed = get_state(s)
  
  s.drivers.clear()
  s.add_driver(SomeDriver('driver'))
  
  try:
      s.run_drivers()
  except:
      # Recover previous state
      set_state(s, designed)
  ```

* Functions `radians`, `degrees` and `arctan2`/`atan2` have been added to the scope of `EvalString` objects, and can therefore be used in equations, *e.g.* (MR [#178](https://gitlab.com/cosapp/cosapp/-/merge_requests/178)).
* Recorders can now record constant properties (MR [#181](https://gitlab.com/cosapp/cosapp/-/merge_requests/181)).
* Deprecation of `System.get_unsolved_problem` in favour of new method `assembled_problem` (MR [#174](https://gitlab.com/cosapp/cosapp/-/merge_requests/174)).
* Inner off-design problem of systems is now exposed as attribute `problem`, but only within the `transition` method (MR [#174](https://gitlab.com/cosapp/cosapp/-/merge_requests/174)). This allows users to add or remove off-design constraints during event-driven transitions, while keeping this property inaccessible the rest of the time.

  ```python
  from cosapp.base import System
  from math import sin, cos
  
  class SomeSystem(System):
      def setup(self):
          self.add_inward('x', 0.0)
          self.add_inward('y', 0.0)
          self.add_outward('z', 0.0)
          a = self.add_event('event_a', trigger='x > y')
          b = self.add_event('event_b', trigger='x < y')
      
      def compute(self):
          self.z = cos(self.x) * sin(self.y)
  
      def transition(self):
          offdesign = self.problem
          if self.event_a.present:
              offdesign.clear()
              offdesign.add_equation('z == 0.5').add_unknown('x')
          if self.event_b.present:
              offdesign.clear()
  ```

### Bug fixes and code quality

* Fix serialization bugs for systems with setup parameters (MR [#180](https://gitlab.com/cosapp/cosapp/-/merge_requests/180)) and `None` variables (MR [#172](https://gitlab.com/cosapp/cosapp/-/merge_requests/172)).
* Bug fix on event time calculation involving array transients (MR [#177](https://gitlab.com/cosapp/cosapp/-/merge_requests/177)).
* Bug fix on possible name conflicts in connector storage (MR [#173](https://gitlab.com/cosapp/cosapp/-/merge_requests/173)).
* Fix inconsistent behaviour of `System.add_child` when a `pulling` error is raised (MR [#197](https://gitlab.com/cosapp/cosapp/-/merge_requests/197)).
* Various code quality improvements (MRs [#175](https://gitlab.com/cosapp/cosapp/-/merge_requests/175), [#185](https://gitlab.com/cosapp/cosapp/-/merge_requests/185), [#186](https://gitlab.com/cosapp/cosapp/-/merge_requests/186), [#187](https://gitlab.com/cosapp/cosapp/-/merge_requests/187), [#190](https://gitlab.com/cosapp/cosapp/-/merge_requests/190), [#191](https://gitlab.com/cosapp/cosapp/-/merge_requests/191), [#194](https://gitlab.com/cosapp/cosapp/-/merge_requests/194)).

### Documentation

* Updated time driver tutorial (MR [#182](https://gitlab.com/cosapp/cosapp/-/merge_requests/182)).
* Updated Tips & Tricks (MR [#196](https://gitlab.com/cosapp/cosapp/-/merge_requests/196)).
* Other updates (MRs [#176](https://gitlab.com/cosapp/cosapp/-/merge_requests/176), [#195](https://gitlab.com/cosapp/cosapp/-/merge_requests/195), [#198](https://gitlab.com/cosapp/cosapp/-/merge_requests/198)).

## 0.12.3 (2022-09-21)

### New features & API changes

* Improved user experience:
  * Auto-completion for dynamically added attributes of systems (ports, subsystems, inwards, outwards, events...) and drivers (sub-drivers) (MRs [#164](https://gitlab.com/cosapp/cosapp/-/merge_requests/164) and [#166](https://gitlab.com/cosapp/cosapp/-/merge_requests/166));
  * Improved representation of mathematical problems, in particular for loop equations and multi-point design problems (MRs [#159](https://gitlab.com/cosapp/cosapp/-/merge_requests/159), [#160](https://gitlab.com/cosapp/cosapp/-/merge_requests/160) and [#163](https://gitlab.com/cosapp/cosapp/-/merge_requests/163)).
* New method `System.new_problem` to facilitate the creation of dynamic design methods, *e.g.* (MR [#162](https://gitlab.com/cosapp/cosapp/-