Coder Social home page Coder Social logo

bradyplanden / liibra.jl Goto Github PK

View Code? Open in Web Editor NEW
32.0 32.0 6.0 260.38 MB

Create reduced-order state-space models for lithium-ion batteries utilising realisation algorithms.

License: MIT License

Julia 100.00%
battery battery-models bms control control-systems julia lithium-ion reduced-order-models

liibra.jl's Introduction

liibra.jl's People

Contributors

bradyplanden avatar github-actions[bot] avatar katielukow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

liibra.jl's Issues

Lazy Hankel?

Hi Brady, saw your talk today.

I see you are forming the full Hankel matrix, and that is your major time sink. I think you should be able to form a lazy representation to the Hankel matrix as follows:

# https://en.wikipedia.org/wiki/Hankel_matrix
struct HankelMatrix{T,Ta} <: AbstractMatrix{T}
    a::Ta # array of elements [a1, ..., aN] 
end

# overload Base: size
# overload LinearAlgebra:  *, \, mul!, ldiv!, lmul!, rmul!, adjoint, transpose, conj
# ref https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array

function Base.getindex(H::HankelMatrix, idx)
    correct_index = # integer computation
    return H.a[correct_index]
end

function Base.setindex!(newval, H::HankelMatrix, idx)
    H.a[correct_index] = newval
end

And then you would be able to pass this to any SVD algorithm in Julia.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Charge from min SoC

When a simulation (HPPC, CC, Simulate) hits the lower limit of the $SoC$ array it can't pick up that value and charge the Cell.
With $SoC_{min}=10$ % it works:

using LiiBRA

#---------- Cell Definition -----------------#
Sₑ = 4
Sₛ = 2
Cell = Construct("LG M50")
Spatial!(Cell, Sₑ, Sₛ)
Ŝ = collect(1.0:-0.1:0.1)
SOC = 0.1
Cell.Const.T = 298.15
A,B,C,D = Realise(Cell,Ŝ);

γ = 10; # the duration of the pulse in seconds
λ = -5. # the current in Amperes
Results, tₑ = CC(Cell,Ŝ,SOC,λ,γ,A,B,C,D);
julia> Results.Cell_SOC
10×1 Matrix{Float64}:
 0.1
 0.1
 0.10026952208487283
 0.10053904416974567
 0.1008085662546185
 0.10107808833949135
 0.10134761042436416
 0.10161713250923698
 0.10188665459410984
 0.10215617667898266

But not with $SoC_{min}=0%$

julia> Results.Cell_SOC
10×1 Matrix{Float64}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

Btw, with Ŝ = collect(1.0:-0.1:0.0), SOC=0.0:

julia> A,B,C,D = Realise(Cell,Ŝ);
System has non-real eigenvalues at SOC:0.0

LFPO cell expansion

Hi,
I'm trying to simulate LFPO cells with LiiBRA but I'm getting an error on the output.
I've made a custom parameter set based on the Prada (2013) paper and PyBaMM and saved it on my local repo.
Here's my MWE:

Sₑ = 4 # Spatial points in electrolyte
Sₛ = 2 # Spatial point in solid
Cell = Construct("A123")
Spatial!(Cell, Sₑ, Sₛ)
Cell.RA.Fs = 4.0 # Modify transfer function sampling frequency
Cell.RA.SamplingT = 0.25 # Modify final system sampling period
# Cell.Neg.Ds = 2.0e-14 # Modify negative electrode diffusion constant
Cell.Const.T = 298.15 # Modify cell temperature= collect(1.0:-0.2:0) # List of SOC points for model generation

#---------- Generate & Simulate Model -----------------#
A, B, C, D = Realise(Cell, Ŝ)
Results, tₑ = HPPC(Cell, Ŝ, SoC0, 5.0, -3.0, A, B, C, D);

Fortunately, this works perfectly.
but, here's the catch:

julia> Results.Cell_V:
401×1 Matrix{Float64}:
 NaN
 NaN
 NaN
 NaN
   
 NaN
 NaN
 NaN
 NaN

which stems from:

julia> Results.ϕ_ẽ1
401×3 Matrix{Float64}:
 NaN  NaN  NaN
 NaN  NaN  NaN
 NaN  NaN  NaN
 NaN  NaN  NaN
   
 NaN  NaN  NaN
 NaN  NaN  NaN
 NaN  NaN  NaN
 NaN  NaN  NaN

julia> Results.y
401×21 Matrix{Float64}:
 0.0       0.0       0.0       0.0      NaN  NaN     0.0          0.0          0.0         0.0
 0.0       0.0       0.0       0.0      NaN  NaN      0.0          0.0          0.0         0.0
 0.0       0.0       0.0       0.0      NaN  NaN      2.39533e-5   2.50955e-5   0.0493683   0.0517224        
 3.92683  -1.17373  -2.03563  -2.51096  NaN  NaN      2.39533e-5   2.50955e-5   0.0493687   0.0517229        
                                                                                         
 1.67322  -3.23011  -6.47773  -7.00319  NaN  NaN     -2.55205e-11  5.12697e-11  1.74443e-6  1.74842e-6       
 1.70846  -3.23473  -6.4838   -7.0128   NaN  NaN     -2.54606e-11  5.11494e-11  1.75177e-6  1.75575e-6       
 1.74285  -3.23918  -6.4896   -7.02204  NaN  NaN     -2.54007e-11  5.10292e-11  1.7589e-6   1.76288e-6       
 1.77642  -3.24347  -6.49513  -7.03094  NaN  NaN    -2.5341e-11   5.09091e-11  1.76583e-6  1.76981e-6  

I've tried to check the SS matrices but I haven't found anything meaningful. Here's a screenshot of the eigen values of A
image
Needless to say that the same piece of code works with the "LG M50" cell.
Any ideas?

Simulate.jl doesn´t use t or Fs or Ts

Hi!,
I´m using LiiBRA to simulate PBROMs in the context of residential energy management systems.
Unfortunately when running some simulations I found some limitations, which I'm not sure are on my side or on the package.
First, when running Simulate() with a default model ($Fs=1Hz$ and $Ts=1s$) and a time array of t=0:900:2*3600 in secs. The results, of course, are incorrect because Cell.RA.SamplingT=1s when it should be 900s. Okay, perfect.
Btw, in Simulate(....,), t is not used for any calculation, but just appended to the Results Tuple. Somehow assuming that $\Delta t=1s$.
Anyway I go on and do:

Cell = Construct("LG M50")
Cell.RA.Fs = 1/900 # Modify transfer function sampling frequency
Cell.RA.SamplingT = 900 # Modify final system sampling period
Cell.Const.T = 298.15 # Modify cell temperature
Cell.Const.Debug = true # Modify cell temperature

But in Realise() I get the following error:

BoundsError: attempt to access 21×17 Matrix{Float64} at index [1:21, 18]

in the line

    U,S,V = fh!(𝐇,Cell.RA.H1,Cell.RA.H2,puls,Cell.RA.M,Puls_L)

so, why? Is $Fs$ to olow? Shouldn't there be a safe somewhere? Moreover, where is Cell.RA.Tlen even in the picture here?

Add docs site

Add a small docs site to repository to support useability.

  • API definition
  • References
  • Examples
  • Variable definitions
  • How to contribute

Version conflict

When implementing examples/LiiBRA_Ex.jl

using LiiBRA, Plots
Sₑ = 4
Sₛ = 2
Cell = Construct("LG M50")
Spatial!(Cell, Sₑ, Sₛ)
Ŝ = collect(1.0:-0.25:0.0)
SOC = 0.75
Cell.Const.T = 298.15
A,B,C,D = Realise(Cell,Ŝ);

I get the following error:

ERROR: UndefVarError: `Spatial!` not defined

My versioninfo()

Julia Version 1.10.0
Commit 3120989f39 (2023-12-25 18:01 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, tigerlake)
  Threads: 5 on 8 virtual cores
Environment:
  JULIA_NUM_THREADS = 4
(@v1.10) pkg> status LiiBRA
Status `C:\Users\XXXXXX\.julia\environments\v1.10\Project.toml`
  [a5b28938] LiiBRA v0.3.3

I´m guessing it has to do with the registry of the package on https://juliapackages.com/

Incorrect `Cell_SOC`

Hi!
I´m running some simple simulations with LiiBRA and I couldn´t help to notice that the $SoC$ values I´m getting don´t seem to add up.

I have a power setpoint $P_{BESS}$ I´m running through the cell.
image
Unfortunately the $SOC^+$ I´m getting from Simulate.jl (in blue) doesn´t seem to be ok:

  • The battery is delivering power through out the simulation, but the $SOC$ doesn´t drop.
  • The shape of it doesn´t seem to be an integrator of the input but a mirror of it.

Everything else checks out, for example, the terminal voltage below:
image
* the $v_t^-$ comes from my previous estimate

And when printing the transition matrix of:

using LiiBRA

#---------- Cell Definition -----------------#
Cell = Construct("LG M50")
Cell.RA.Fs = 4.0 # Modify transfer function sampling frequency
Cell.RA.SamplingT = 0.25 # Modify final system sampling period
Cell.Neg.Ds = 2.0e-14 # Modify negative electrode diffusion constant
Cell.Const.T = 298.15 # Modify cell temperature= collect(1.0:-0.1:0) # List of SOC points for model generation
SOC = 1. # Starting SOC

#---------- Generate & Simulate Model -----------------#
A, B, C, D = Realise(Cell, Ŝ);
A[1]
[5×5 Matrix{Float64}:
  0.940359     -3.89234e-16   1.29328e-16  2.85417e-16  0.0
  1.89597e-16   0.993649      7.42181e-17  3.1269e-16   0.0
 -1.78499e-16   1.68973e-16   0.998722     3.43525e-16  0.0
  2.98961e-16   1.67496e-16  -3.68353e-16  0.999933     0.0
  0.0           0.0           0.0          0.0          1.0]

clearly the integrator state is x[:,end] but when checking Simulate.jl the state used is x[:,1]:

cs_neg_avg = Results.x[i+1,1] * csegain_neg + SOC_Neg * Cell.Neg.cs_max

How do you handle pull requests and such? So I can change it and push to the repo.

Variable explanation

Hello, first of all nice work :) Currently I am looking into some simulations are a bit unsure of what all the outputs given from the function "Simulate" are. Does someone know if it is available on the github page and I have missed? If not it could be nice to include :)

Best regards

DRA not defined error

I am trying to run the code given in file LiiBRA_EX.jl in the examples folder but I keep getting the following error:
Code where I get the error:

function Realise(Cell, SList)
    A = B = C = D = tuple()
    for i in SList 
        #Arrhenius
        Cell.Const.T = 298.15
        Arr_Factor = (1/Cell.Const.T_ref-1/Cell.Const.T)/R

        #Set Cell Constants
        Cell.Const.SOC = i
        Cell.Const.κ = Cell.Const.κf(Cell.Const.ce0)*exp(Cell.Const.Ea_κ*Arr_Factor)
        Cell.RA.Nfft = Cell.RA.Nfft!(Cell.RA.Fs, Cell.RA.Tlen)
        Cell.RA.f = Cell.RA.f!(Cell.RA.Nfft)
        Cell.RA.s = Cell.RA.s!(Cell.RA.Fs,Cell.RA.Nfft,Cell.RA.f)

        #Realisation
        Aϕ, Bϕ, Cϕ, Dϕ = DRA(Cell,Cell.RA.s,Cell.RA.f)

        #Flatten output into Tuples
        A = flatten_(A,Aϕ)
        B = flatten_(B,Bϕ)
        C = flatten_(C,Cϕ)
        D = flatten_(D,Dϕ)
    end
return A, B, C, D
end

Error:

ERROR: UndefVarError: DRA not defined
Stacktrace:
 [1] Realise(Cell::LiiBRA.Params, SList::Vector{Float64})
   @ Main .\Untitled-1:24
 [2] top-level scope
   @ Untitled-1:50

Realise (generic function with 1 method)

I am using Julia 1.7.0

DRA / Sim_Model.jl Output

Sim_model output is varying with each DRA build. Issue stems from generated ss matrices varying from Ho-Kalman & SVD.

Array Interpolation

The current formation of the state-space arrays doesn't guarantee state-vector alignment. This is not an issue for single SOC/temperature realisations, as there is no need to interpolate between multiple representations; however, to form a realisation capable of multiple SOC & temperature values, the state vectors need to be aligned at creation.

To accomplish this, a transformation of the realisation needs to occur after formation, as per 10.1016/j.jpowsour.2013.12.134.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.