Skip to content

Commit

Permalink
docs update
Browse files Browse the repository at this point in the history
  • Loading branch information
GJHSimmons committed Jan 22, 2025
1 parent fef1a0a commit a2d9eb0
Show file tree
Hide file tree
Showing 40 changed files with 1,406 additions and 146 deletions.
6 changes: 3 additions & 3 deletions docs/components/composite_ported_objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ A very simple problem which can be modelled in a composite ported object is the
\frac{1}{2}C_D \rho A v^2
$$

directed vertically upwards, where $C_D$ is the drag coefficient of the object, $\rho$ is the air denstity, $A$ is the effective surface area of the object, and $m$ is its mass.
directed vertically upwards, where $C_D$ is the drag coefficient of the object, $\rho$ is the air density, $A$ is the effective surface area of the object, and $m$ is its mass.

In `psymple`, the forces acting on the falling object can be modelled individually, and then aggregated together. Let the positive direction be downwards. For the gravitational force $F_G = mg$, applying Newton's second law gives $\frac{dv}{dt} = g$, while for the resistance force, $\frac{dv}{dt} = - \mu v^2$, where $\mu = \frac{C_D \rho A}{2m}$.

Expand Down Expand Up @@ -60,7 +60,7 @@ To create the falling object model from these components, `psymple` needs to kno

!!! info "Referencing a child port"

The port of a child object is referenced by the string `"name.port_name"` where `name = child.name` is the attritube specified when instantiating that child object. This *does not* need to be the same as the `python` identifier.
The port of a child object is referenced by the string `"name.port_name"` where `name = child.name` is the attribute specified when instantiating that child object. This *does not* need to be the same as the `python` identifier.

These are all accomplished inside this composite ported object:

Expand Down Expand Up @@ -147,7 +147,7 @@ Similarly, there are two syntaxes for specifying variable wires. The following a
When `psymple` builds the `model` composite ported object, it:

1. Creates the input ports and variable ports specified.
2. Builds a [`DirectedWire`][psymple.build.wires.DirectedWire] instance for each itme in the argument list `directed_wires`. In doing so, it checks that all the ports exist and are of the correct type (source ports must be input ports of `model`, or output ports/variable ports of its children, and destination ports must be input ports of children, or output ports of `model`).
2. Builds a [`DirectedWire`][psymple.build.wires.DirectedWire] instance for each item in the argument list `directed_wires`. In doing so, it checks that all the ports exist and are of the correct type (source ports must be input ports of `model`, or output ports/variable ports of its children, and destination ports must be input ports of children, or output ports of `model`).
3. Builds a [`VariableAggregationWiring`][psymple.build.wires.VariableAggregationWiring] instance for each item in the argument list `variable_wires`. In doing so, it checks all the ports exist and are variable ports.

## Next steps
Expand Down
2 changes: 1 addition & 1 deletion docs/components/variable_ported_objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ The automatic creation of input ports can be overridden: see the documentation o

In practice, there are only two reasons to specify ports:

1. In the case where not every variable needs to be exposed. This is useful when, for example, a second-order differential equation is being modelled by a system of first-order equations. For example, the pendulum equation $ \ddot y = - \frac{g}{l} sin(y) $ can be written as the two first-order equations $ \dot y = x $ and $ \dot x = - \frac{g}{l} sin(y) $. In this case, we only need to expose the variable `y`. This can be done as follows:
1. In the case where not every variable needs to be exposed. This is useful when, for example, a second-order differential equation is being modelled by a system of first-order equations. For example, the pendulum equation $\ddot y = - \frac{g}{l} sin(y)$ can be written as the two first-order equations $\dot y = x$ and $\dot x = - \frac{g}{l} sin(y)$. In this case, we only need to expose the variable `y`. This can be done as follows:

``` py title="second-order ODE model"
from psymple.build import VariablePortedObject
Expand Down
35 changes: 35 additions & 0 deletions docs/development/community_guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Community Guidelines

## Contributing to `psymple`

There are many ways you can be involved in contributing to the development and maintenance of `psymple`.

- Help to find bugs or other issues, by adding a bug report to the [issues](https://github.com/casasglobal-org/psymple/issues) page.
- Help to edit and maintain the [documentation](https://casasglobal-org.github.io/psymple/) using issues or [pull requests](https://github.com/casasglobal-org/psymple/pulls).
- Develop new features, examples, documentation or bug fixes by creating pull requests.
- Get involved by helping to review open issues and pull requests.
- Report something you've done using `psymple`, discuss any big ideas, or simply let us know what you think using our [discussion board](https://github.com/casasglobal-org/psymple/discussions).

!!! tip "Credit where it is due"

Anyone who makes consistent and positive contributions, either directly or indirectly, will be offered an entry on our [Development Team](development_team.md) page.


## Code of conduct

`psymple` is an open-source project which we aim to turn into a community-driven modelling platform. We welcome anyone from all backgrounds and expertise levels to get involved with `psymple` to create a diverse, welcoming and productive space. We expect anyone contributing to our community to help us do this by following the following simple guidelines:

1. **Open by default**. As an open-source and open-access project, we also implement an open-by-default approach to questions, issues, discussions and contributions to promote productivity, efficiency and accuracy.
2. **Collaborative by nature**. The best solutions are found by engaging with those outside of your usual circles and comfort zone. We ask that you both listen to, and engage with, people with different backgrounds or views to your own to come up with the best outcomes.
3. **Think big and small**. This project has big ambitions to create impact for as many people as possible, but this requires both an eye for detail for components that make up this project. We ask that every change or addition to the codebase is done with both an eye for excellence and with a holistic view of the whole.
4. **Respect for all**. People will all levels of experience and knowledge use this project. Treat everyone with respect, empathy and sympathy, and assume that everyone has good intentions. Do not shy away from being critical, but back up everything with evidence, and never make it personal.

!!! failure "We will never tolerate:"

- Violent threats or language directed against another person.
- Sexist, racist, or otherwise discriminatory jokes, insults, material and language.
- Posting (or threatening to post) other people’s personally identifying information (“doxing”).
- Sharing private content, such as emails sent privately or non-publicly, or unlogged forums, such as IRC channel history, without the sender’s consent.
- Excessive profanity. In the context of modelling, there may be examples dealing with profane or sensitive content. This is never a reason to use associated language out of context. Never use swear words.
- Repeated harassment of others. For the avoidance of doubt, if someone asks you to stop, then stop.
- Advocating for, or encouraging, any of the above behaviour.
20 changes: 20 additions & 0 deletions docs/development/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Development

`psymple` is an open-source and open-access project which welcomes all contributions from all third parties. More information about how to contribute to `psymple` can be found on the [Community Guidelines](community_guidelines.md) page.

## Governance and steering

The package `psymple` is currently being produced under a collaboration between [CASAS Global](https://www.casasglobal.org/) and [IDEMS International](https://www.idems.international/). Members of both organisations form the current core governance and steering team. In addition to being involved in the day-to-day community of `psymple`, this team maintains a collective responsibility for the development, maintenance and direction of `psymple` and are able to:

- Make decisions about the overall scope, vision and direction of the project.
- Make decisions about strategic collaborations with other organizations or individuals.
- Make decisions about specific technical issues, features, bugs and pull requests. They are the primary mechanism of guiding the code review process and merging pull requests.
- Update policy documents such as this one.
- Make decisions when regular community discussion doesn’t produce consensus on an issue in a reasonable time frame.

More information about this team and their contributions an expertise can be found on the [Development Team](development_team.md) page.

## Code of conduct

Our current Code of conduct can be found [here](community_guidelines.md#code-of-conduct).

28 changes: 28 additions & 0 deletions docs/development/development_team.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Development team

`psymple` has been developed using a broad range of expertise and contributions. This page recognises all consistent and positive contributions, both directly to the codebase and indirectly to the scope, direction and suitability of the package.

## Core governance and steering team

This is the current team who maintain a collective responsibility for the development, maintenance and direction of `psymple`, in alphabetical order of surname.

| Name | Organisation(s) | Contribution(s) | Years active |
| -------------------- | -------------------- | -------------------- | ------ |
| [Chiara Facciolà](https://github.com/fagiothree) | Mathematical Scientist, [IDEMS International](https://www.idems.international/) | <ul><li>Applied mathematical modelling</li><li>Examples of complex systems modelling</li></ul> | 2024 + |
| [Andrew Gutierrez](https://github.com/AndrewPGutierrez) | <ul><li>Professor Emeritus of Ecosystem Science, [UC Berkeley](https://www.berkeley.edu/)</li><li>CEO, [CASAS Global](https://casasglobal.org/)</li></ul> | Biological and ecosystem modelling | 2023 + |
| [Georg Osang](https://github.com/geoo89) | Postdoctoral Impact Activation Fellow, [IDEMS International](https://www.idems.international/) | Code developer and maintainer | 2023 + |
| [Luigi Ponti](https://github.com/luisponti) | <ul><li>Research scientist, [ENEA](https://www.enea.it/en/)</li><li>Research fellow, [CASAS Global](https://casasglobal.org/)</li></ul> | <ul><li>Biological and ecosystem modelling</li><li>Github structures and management</li></ul> | 2023 + |
| [George Simmons](https://github.com/GJHSimmons) | Postdoctoral Impact Activation Fellow, [IDEMS International](https://www.idems.international/) | <ul><li>Code developer and maintainer</li><li>Applied category theory and collaborative modelling</li><li>Github structures and management</li></ul> | 2023 + |
| [David Stern](https://github.com/volloholic) | Director, [IDEMS International](https://www.idems.international/) | <ul><li>Applied category theory and collaborative modelling</li><li>Scalability and impact</li></ul> | 2023 + |


## Development and maintenance team

!!! info

Anyone who contributes consistently and positively to `psymple` will be offered a place here: see our [Community Guidelines](community_guidelines.md) for more information.

- [Georg Osang](https://github.com/geoo89) - Code developer and maintainer
- [Luigi Ponti](https://github.com/luisponti) - Github structures and management
- [George Simmons](https://github.com/GJHSimmons) - Code developer and maintainer

Binary file added docs/examples/figures/logistic_equation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/malthusian_growth_bd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/malthusian_growth_r_0.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/malthusian_growth_r_0.2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/pred-prey-decaying.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/pred-prey-simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/pred-prey-tritrophic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/projectile_planar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/projectile_planar_pos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/projectile_vertical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/figures/three_body_problem.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions docs/examples/mixing_problems/mixing_problems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Mixing problems

These examples show how to model _mixing problems_ in `psymple`. A mixing problem seeks to understand the evolution of a quantity of solvent in a solute, for example a chemical being mixed in a tank of water. These problems can be highly varied, for example solution can enter a tank at variable concentration or rate, or leave the tank at variable rate. Alternatively, several tanks can be connected together, with their solutions being pumped into each other.

These examples first consider the problem for a single tank, and then the problem for many arbitrarily linked tanks.

In all examples, the core assumption is that tanks are _well-mixed_, that is, the concentration of the solute is the same throughout the tank at any moment in time.

<div class="grid cards" markdown>

- :material-roman-numeral-1:{ .lg .middle } __Single tank__

---

Modelling concentrations in a single tank.

[:octicons-arrow-right-24: Get started](single_tank.md)

- :material-roman-numeral-2:{ .lg .middle } __Multiple tanks__

---

Modelling concentrations in multiple tanks with arbitrary links.

[:octicons-arrow-right-24: Get started](multiple_tanks.md)

</div>

52 changes: 36 additions & 16 deletions docs/examples/mixing_problems/multiple_tanks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
In the previous example, we considered a mixing problem with a single tank, which had an external flow in and an external flow out. Now we consider a mixing problem consisting of two or more tanks, each of which can have external flows in and out in the same manner as for the single tank, and which furthermore can have flows to and from other tanks in the system.
# Multiple tanks mixing problem

It will help to first specify the system data. In this case, we will create a system with \( n > 1 \) tanks, such that every tank has a flow in and flow out, plus a flow to and from every other tank. The following data can be freely altered to reduce the external flows and connections, if desired.
The previous example modelled a mixing problem with a single tank, which had an external flow in and an external flow out. This example considers a mixing problem consisting of two or more tanks, each of which can have external flows in and out, and which furthermore can have flows to and from other tanks in the system.

## System data

It will help to first specify the system data. The following data specifies a system of $2$ tanks which are fully interconnected, and each have external flows both in and out. This data can be freely altered to reflect different configurations and all the code in this example will automatically run.

```py title="system data"
# Number of tanks
Expand All @@ -24,9 +28,11 @@ pipes_in_id = [1, 2]
pipes_out_id = [1, 2]
```

If you followed through the single tank example, the following lists of pipes in and out are created in exactly the same way as there. We create pipes in for every tank in `pipes_in_id` and pipes out for every tank in `pipes_out_id`.
## Defining the flow components

```py
As for the [single tank example](single_tank.md#modelling-flows-in-psymple), a tank is defined as the aggregation of multiple variables representing inflows and outflows. The following lists of pipes in and out are created in exactly the same way for the single tank example, with pipes in for every tank in `pipes_in_id` and pipes out for every tank in `pipes_out_id`.

```py title="external pipes"
from psymple.build import VariablePortedObject

pipes_in = [
Expand All @@ -52,17 +58,17 @@ pipes_out = [
]
```

Next, we need to define connector pipes. These have four variables:
To connect two tanks, a connector pipe is required. These have four variables:

- `Q_in`, the amount of salt entering the pipe from a tank,
- `Q_out`, the amount of salt flowing into the next tank. Note that this has the same concentration
as for `Q_in`,
- `V_in`, the volume of water entering the pipe from the tank,
- `V_out`, the volume of water exiting the pipe into the next tank.

We create a connector pipe for every pair in `link_pipes_id`.
A connector pipe is defined for every pair in `link_pipes_id`.

```py
```py title="connector pipes"
connectors = [
VariablePortedObject(
name=f"pipe_{i}_{j}",
Expand All @@ -77,11 +83,9 @@ connectors = [
]
```

Now we just need to define our system of tanks. Compared to the single tank example, the children, variable ports and input ports are exactly the same (just one for each tank, if it was specified), except for aditionally the specification of the flow rates `rate_i_j` of the connector pipes as additional input ports.

The directed wires simply connect the rates at the input ports to the correct pipes.
## Defining the system

The only thing which becomes more complicated is the aggregation of the variables. Each tank `i`, and therefore each variable `Q_i` (and `V_i`), can have:
The system is defined by variables `Q_1`,...,`Q_n` and `V_1`,...,`V_n` representing the mass and volume in each of the $n$ tanks. This is done in an analogous way to the single tank example, where the only thing which becomes more complicated is the aggregation of the variables. Each tank `i`, and therefore each variable `Q_i` (and `V_i`), can have:

- External in-flows if `i in pipes_in_id`,
- External out-flows if `i in pipes_out_id`,
Expand Down Expand Up @@ -134,6 +138,14 @@ tanks = CompositePortedObject(

And that's it!

## Simulating the system

The following code sets up a simulation in which for $t<50$>, there are flows of $10\text{l/s}$ (from tank 2) and $4 \text{l/s}$ (external) into tank 1 and flows of $3\text{l/s}$ (to tank 2) and $11\text{l/s}$ (external) out. Similarly, tank 2 has flows in of $3\text{l/s}$ (from tank 1) and $7\text{l/s}$ (external) and flows out of $10\text{l/s}$ (to tank 1).

The external concentration of the fluid entering tank 1 is $0.5\text{g/l}$ and for tank 2 only pure water is added.

The total amount of solution in each tank will remain constant for $t<50$. At $t=50$ the external supply to tank 1 is turned off so that the volume of tank 1 will start to drain.

```py
S = System(tanks)
S.compile()
Expand All @@ -144,18 +156,26 @@ S.set_parameters(
"rate_2_1": 10,
"rate_in_1": "Piecewise((4, T<50), (0, True))",
"rate_in_2": 7,
"conc_in_1": 1 / 2,
"conc_in_1": 0.5,
"conc_in_2": 0,
"rate_out_1": 11,
#"rate_out_2": 0
"rate_out_2": 0,
}
)

print(S)

sym = S.create_simulation(solver="cts", initial_values={"Q_1": 20, "Q_2": 80, "V_1": 800, "V_2": 1000})
sym = S.create_simulation(
initial_values={"Q_1": 20, "Q_2": 80, "V_1": 800, "V_2": 1000}
)

sym.simulate(100, n_steps=100)
sym.simulate(t_end=250)

sym.plot_solution()
```
```

The following plot shows the result of the simulation until tank 1 is empty after $250\text{s}$.

![Multiple tank mixing problem](../figures/multi_tank_mixing_expt_1.png)

The figure shows that the concentrations in the two tanks decreasing after $t=50$ since only fresh water is added to the system after this point.
Loading

0 comments on commit a2d9eb0

Please sign in to comment.