Skip to content
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

Add creating_a_problem example #487

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 194 additions & 0 deletions examples/notebooks/creating_a_problem.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "expmkveO04pw"
},
"source": [
"## Creating a Problem\n",
"\n",
"In this notebook, we create and solve a single particle model (SPM). This is achieved using a predefined parameter set introduced in Marquis et al. [[1]](https://doi.org/10.1149/1945-7111/abbce4) \n",
Copy link
Member

Choose a reason for hiding this comment

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

Needs an update to introduce the problem class and it's functionality.

"\n",
"Before we begin, we need to ensure that we have all the necessary tools. We will install PyBOP and upgrade dependencies."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "X87NUGPW04py",
"outputId": "0d785b07-7cff-4aeb-e60a-4ff5a669afbf"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Note: you may need to restart the kernel to use updated packages.\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"%pip install --upgrade pip ipywidgets -q\n",
"%pip install pybop -q\n",
"\n",
"import numpy as np\n",
"\n",
"import pybop\n",
"\n",
"pybop.PlotlyManager().pio.renderers.default = \"notebook_connected\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5XU-dMtU04p2"
},
"source": [
"### Creating a Model\n",
"\n",
"A fitting problem consists of three parts: An experimental dataset that is used for fitting, a model that the dataset should be fit to, and the parameters that should be fit. To obtain a problem we therefore first need to create a model. This has been explained in detail in the creating_a_model example. "
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"parameter_set = pybop.ParameterSet.pybamm(\"Marquis2019\")\n",
"model = pybop.lithium_ion.SPM(parameter_set=parameter_set)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, the parameters. All parameters of the problem are contained in pybop.Parameters(). Each of the variable to fit is defined as a pybop.Parameter() separated by commas inside pybop.Parameters(). In this example, we have two parameters, the positive electrode thickness and the positive particle radius:\n"
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"parameters = pybop.Parameters(\n",
" pybop.Parameter(\n",
" \"Positive electrode thickness [m]\",\n",
" prior=pybop.Gaussian(7.56e-05, 0.05e-05),\n",
" bounds=[65e-06, 10e-05],\n",
" ),\n",
" pybop.Parameter(\n",
" \"Positive particle radius [m]\",\n",
" prior=pybop.Gaussian(5.22e-06, 0.05e-06),\n",
" bounds=[2e-06, 9e-06],\n",
" ),\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The third component is the dataset. This could be an experimental dataset or a simulation. In this example, we just use simulation data by running model.predict() for a 1C discharge, similar to the creating_a_problem example. To pass it to the problem, we need to extract the voltage, time and current data from the simulation results and define it as the dataset:"
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"t_eval = np.arange(0, 3700, 1)\n",
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
"solution = model.predict([], t_eval) # No inputs i.e []\n",
"dataset = pybop.Dataset(\n",
" {\n",
" \"Time [s]\": np.arange(0, len(solution[\"Voltage [V]\"].data), 1),\n",
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
" \"Current function [A]\": solution[\"Current [A]\"].data,\n",
" \"Voltage [V]\": solution[\"Voltage [V]\"].data,\n",
" }\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setting up the problem\n",
"With all parts setup, we can now make a problem. Therefore, we use pybop.FittingProblem() to define a simple fitting problem and the model, parameters and dataset defined before as inputs."
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

Can you also expand this to include the pybop.DesignProblem? I think we can reduce the cost / optimisation side of this and focus on the two problem classes more.

]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem = pybop.FittingProblem(model, parameters, dataset)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Testing the problem\n",
"To verify our problem, we solve assign a sum of squared error cost function to it and solve it. \n",
Copy link
Member

Choose a reason for hiding this comment

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

I would first show how to use the problem.evaluate() and problem.evaluateS1 methods.

"The solution can be compared to the values in the parameter_set defined in the beginning."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(array([7.62324125e-05, 5.20703504e-06]), inf)\n",
"7.67500163945363e-05\n",
"5.310487559937693e-06\n"
]
}
],
"source": [
"cost = pybop.SumSquaredError(problem)\n",
"optim = pybop.Optimisation(cost)\n",
f-g-r-i-m-m marked this conversation as resolved.
Show resolved Hide resolved
"result = optim.run()\n",
"print(result)\n",
"print(parameter_set[\"Positive electrode thickness [m]\"])\n",
"print(parameter_set[\"Positive particle radius [m]\"])"
]
}
],
"metadata": {
Copy link
Member

Choose a reason for hiding this comment

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

It would be great to have a few concluding thoughts here. A summary of the notebook and a few points on the FittingProblem itself.

"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading