Commit 7fd79c1a authored by Elias Barbers's avatar Elias Barbers
Browse files

version 2.24.0

parent 39a4d256
Pipeline #407015 passed with stages
in 71 minutes and 20 seconds
......@@ -35,7 +35,7 @@ MexRelease/
compile_commands.json
.vscode/
__pycache__/
/scenariotest/standalone_test/*/*.txt
/scenariotest/standalone_test/*/*
!/scenariotest/standalone_test/*/reference/**
!/scenariotest/standalone_test/*.csv
!/scenariotest/simulink_test/reference/*/*.mat
......
Version 2.24.0
===========
- Expression object can rescale parameters and output value
- Two new aging effects for Loss of Active Material and Loss of Lithium Inventory
- Speed improvements for electrical and thermal simulation
- Simulation standalones write metadata to the file simulation.xml, including a randomly generated UUID for the simulation
- XML files can contain a hash value that can be checked with the verification standalone to see if they have been modified
- All matlab files create by the matlab filters contain the simulation UUID
- Output from the aging matlab filter contains the capacity in Ah and optionally OCV values
Version 2.23.0
===========
- The aging model is available as an S-Function for Simulink
......
......@@ -5,16 +5,19 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
cmake_policy(SET CMP0009 NEW)
set(ISEAFrameVERSION_MAJOR 2)
set(ISEAFrameVERSION_MINOR 23)
set(ISEAFrameVERSION_MINOR 24)
set(ISEAFramePATCH_LEVEL 0)
set(ISEAFrameNAME "docs")
set(ISEAFrameNAME "misc")
set(ISEAFrameVERSION
"${ISEAFrameVERSION_MAJOR}.${ISEAFrameVERSION_MINOR}.${ISEAFramePATCH_LEVEL}"
)
set(ARCH_TYPE
"64"
CACHE STRING "")
option(BUILD_SYMBOLIC "Build the symbolic version of the framework" OFF)
option(BUILD_NUMERIC "Build the numeric version of the framework" OFF)
option(BUILD_AGING "Build the classes required for the aging simulation" OFF)
option(BUILD_NUMERIC "Build the numeric version of the framework" ON)
option(BUILD_AGING "Build the classes required for the aging simulation" ON)
option(USE_DEBUG_GDB "Create everything with debug symbols" OFF)
option(CREATE_RELEASE_DIRS
"Create directories containing all files needed to run the simulation"
......@@ -22,6 +25,7 @@ option(CREATE_RELEASE_DIRS
option(BUILD_FOR_RT "Build a version for the realtime system" OFF)
option(USE_BOOST_THREADS "Use multithreading for the thermal model" OFF)
option(USE_EXCEPTIONS "Use exceptions" ON)
option(BUILD_FOR_NATIVE_ARCH "Optimize for current CPU ( -march=native )" OFF)
set(MATIRX_IMPLEMENTATION
Eigen
CACHE STRING "Choose matrix implementation")
......@@ -81,8 +85,10 @@ else()
if(${USE_DEBUG_GDB})
add_compile_options(-ggdb)
endif()
add_link_options("-Wl,-rpath=./")
add_compile_options(-fPIC)
if(${BUILD_FOR_NATIVE_ARCH})
add_compile_options(-march=native)
endif()
endif()
if(BUILD_FOR_RT)
......@@ -192,8 +198,7 @@ endfunction(copy_windows_files_to_dir)
function(add_release_files target files_to_copy)
if(CREATE_RELEASE_DIRS)
add_custom_command(
TARGET ${target}
POST_BUILD
TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${files_to_copy}
$<TARGET_PROPERTY:${target},RUNTIME_OUTPUT_DIRECTORY>)
endif()
......
......@@ -783,7 +783,7 @@ WARN_LOGFILE =
INPUT = "@CMAKE_SOURCE_DIR@/doxygen/" \
"@CMAKE_SOURCE_DIR@/src/" \
"@CMAKE_SOURCE_DIR@/benchmark/" \
"@CMAKE_SOURCE_DIR@/standalone/standalone/" \
"@CMAKE_SOURCE_DIR@/standalone/" \
"@CMAKE_SOURCE_DIR@/examples/"
# This tag can be used to specify the character encoding of the source files
......
......@@ -164,4 +164,22 @@ Voltage | Object | V | Voltage of
ActivationCoefficient | double | K | Constant E used to calculate the time constant
TauCoefficient | double | day | Constant A used to calculate the time constant
SocWhereOffsetIsZero | double | % | The overhang SOC that results in no change to the balancing. If this is not the same as the initial overhang SOC, the anode SOC is immediately changed before the simulation starts.
Soc | SOC state | | Soc object that specifies the overhang capacity and the initial overhang SOC
\ No newline at end of file
Soc | SOC state | | Soc object that specifies the overhang capacity and the initial overhang SOC
Loss of Active Material
------------------------
Loss of active material in a halfcell simulation is used by adding an element with the class attribute "LAM" to the electrode's aging element.
XML Tag | Type | Unit | Explanation
--------|--------|------------------------------|----------------------------------------------------------------------------------------
Value | Object | fraction of initial capacity | Fraction of the initial capacity that is lost through LAM. The cached variable cycles can be used to get the cell's equivalent full cycles
Loss of Lithium Inventory
-------------------------
Loss of lithium inventory in a halfcell simulation is used by adding an element with the class attribute "LLI" to the electrode's aging element.
XML Tag | Type | Unit | Explanation
--------|--------|------|----------------------------------------------------------------------------------------
Value | Object | As | Amount of lithium that is lost through LLI. The cached variable cycles can be used to get the cell's equivalent full cycles.
\ No newline at end of file
<Object class="ExpressionObj">
<Expression>Soc / 2 + T / 3</Expression>
<Rescale>
<InputRangeMinimum>10</InputRangeMinimum>
<InputRangeMaximum>60</InputRangeMaximum>
<OutputRangeMinimum>0</OutputRangeMinimum>
<OutputRangeMaximum>5</OutputRangeMaximum>
</Rescale>
<Parameters>
<Param cacheref="Soc">
<Rescale>
<InputRangeMinimum>0</InputRangeMinimum>
<InputRangeMaximum>100</InputRangeMaximum>
<OutputRangeMinimum>10</OutputRangeMinimum>
<OutputRangeMaximum>90</OutputRangeMaximum>
</Rescale>
</Param>
<Param cacheref="ThermalState" name="T">
<Rescale>
<InputRangeMinimum>0</InputRangeMinimum>
<InputRangeMaximum>30</InputRangeMaximum>
<OutputRangeMinimum>10</OutputRangeMinimum>
<OutputRangeMaximum>50</OutputRangeMaximum>
</Rescale>
</Param>
</Parameters>
</Object>
\ No newline at end of file
<div class="fragment">
<!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><b><font color="#0000FF">&lt;Object</font></b> <font color="#009900">class</font><font color="#990000">=</font><font color="#FF0000">"ExpressionObj"</font><b><font color="#0000FF">&gt;</font></b>
<b><font color="#0000FF">&lt;Expression&gt;</font></b>Soc / 2 + T / 3<b><font color="#0000FF">&lt;/Expression&gt;</font></b>
<b><font color="#0000FF">&lt;Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMinimum&gt;</font></b>10<b><font color="#0000FF">&lt;/InputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMaximum&gt;</font></b>60<b><font color="#0000FF">&lt;/InputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMinimum&gt;</font></b>0<b><font color="#0000FF">&lt;/OutputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMaximum&gt;</font></b>5<b><font color="#0000FF">&lt;/OutputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;/Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;Parameters&gt;</font></b>
<b><font color="#0000FF">&lt;Param</font></b> <font color="#009900">cacheref</font><font color="#990000">=</font><font color="#FF0000">"Soc"</font><b><font color="#0000FF">&gt;</font></b>
<b><font color="#0000FF">&lt;Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMinimum&gt;</font></b>0<b><font color="#0000FF">&lt;/InputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMaximum&gt;</font></b>100<b><font color="#0000FF">&lt;/InputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMinimum&gt;</font></b>10<b><font color="#0000FF">&lt;/OutputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMaximum&gt;</font></b>90<b><font color="#0000FF">&lt;/OutputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;/Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;/Param&gt;</font></b>
<b><font color="#0000FF">&lt;Param</font></b> <font color="#009900">cacheref</font><font color="#990000">=</font><font color="#FF0000">"ThermalState"</font> <font color="#009900">name</font><font color="#990000">=</font><font color="#FF0000">"T"</font><b><font color="#0000FF">&gt;</font></b>
<b><font color="#0000FF">&lt;Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMinimum&gt;</font></b>0<b><font color="#0000FF">&lt;/InputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;InputRangeMaximum&gt;</font></b>30<b><font color="#0000FF">&lt;/InputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMinimum&gt;</font></b>10<b><font color="#0000FF">&lt;/OutputRangeMinimum&gt;</font></b>
<b><font color="#0000FF">&lt;OutputRangeMaximum&gt;</font></b>50<b><font color="#0000FF">&lt;/OutputRangeMaximum&gt;</font></b>
<b><font color="#0000FF">&lt;/Rescale&gt;</font></b>
<b><font color="#0000FF">&lt;/Param&gt;</font></b>
<b><font color="#0000FF">&lt;/Parameters&gt;</font></b>
<b><font color="#0000FF">&lt;/Object&gt;</font></b></tt></pre>
</div>
......@@ -49,13 +49,34 @@ This object can be used to get a value from a mathematical expression.
XML Tag | Type | Explanation
------------------------|----------------------------------------|----------------------------------------------------
Expression | mathematical expression | expression that is evaluated each time the object value is needed
Rescale | rescale (see below) | rescaling of the calculated value
Parameters | list of [state objects](xmlstate.html) | list of states that are used as parameters in the expression
- Attribute name | string | variable name used in the expression. If this attribute is not set, but the attribute cacheref is used, that name is used instead
- Rescale | rescale (see below) | rescaling of the parameter before the expression is evaluated
To evaluate the expressions, the library [exprtk](https://github.com/ArashPartow/exprtk) is used. The documentation provides a list of operations that can be used in the expressions.
\htmlinclude expression_obj_color.xml
Rescaling
--------------
The input parameters as well as the calculated output value of the expression object can be rescaled by specifying an input range that is mapped to an output range. This is done by adding an element with the tag Rescale that contains the following children:
XML Tag | Type | Explanation
-------------------|--------|-------------------------------
InputRangeMinimum | double | lower end of the input range
InputRangeMaximum | double | upper end of the input range
OutputRangeMinimum | double | lower end of the output range
OutputRangeMaximum | double | upper end of the output range
The value is rescaled according to the formula
\f{eqnarray*}{
f(x) = (x - InputRangeMinimum) \frac{OutputRangeMaximum - OutputRangeMinimum}{InputRangeMaximum - InputRangeMinimum} + OutputRangeMinimum
\f}
\htmlinclude expression_obj_rescale_color.xml
Combination of objects
==========================
The values of multiple objects can be combined to produce a single value.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,10 +3,12 @@ import scipy.io
díff = ''
def errorFunction(description, *args):
global diff
diff += description.format(*args) + '\n'
def compareMatfiles(fileA, fileRef):
global diff
contentA = scipy.io.loadmat(fileA)
......@@ -17,25 +19,28 @@ def compareMatfiles(fileA, fileRef):
else:
return diff
def compareMatlab(matA, matRef, location=''):
if type(matA) != type(matRef):
errorFunction('Field {} has the wrong type.', location);
errorFunction('Field {} has the wrong type.', location)
return False
elif type(matA) == dict:
return compareDicts(matA, matRef, location)
elif type(matA) == numpy.ndarray:
return compareArrays(matA, matRef, location)
else:
errorFunction('Field {} has unknown type {}.', location, type(matA));
errorFunction('Field {} has unknown type {}.', location, type(matA))
return False
def compareDicts(dictA, dictRef, location):
if dictA.keys() == dictRef.keys():
success = True
for key in dictA:
if key.startswith('__'):
continue
success = success and compareMatlab(dictA[key], dictRef[key], location + '.' + key)
success = success and compareMatlab(
dictA[key], dictRef[key], location + '.' + key)
return success
else:
for key in dictA:
......@@ -46,21 +51,27 @@ def compareDicts(dictA, dictRef, location):
errorFunction('Missing field {} in {}.', key, location)
return False
def compareArrays(arrayA, arrayRef, location):
# test if array is a structure
if arrayA.dtype.names is not None or arrayRef.dtype.names is not None:
if arrayA.dtype.names == arrayRef.dtype.names:
success = True
for fieldname in arrayA.dtype.names:
success = success and compareMatlab(arrayA[fieldname], arrayRef[fieldname], location + '.' + fieldname)
if fieldname == "UUID":
continue
success = success and compareMatlab(
arrayA[fieldname], arrayRef[fieldname], location + '.' + fieldname)
return success
else:
for fieldname in arrayA.dtype.names:
if fieldname not in arrayRef.dtype.names:
errorFunction('Unexpected field {} in {}.', fieldname, location)
errorFunction('Unexpected field {} in {}.',
fieldname, location)
for fieldname in arrayRef.dtype.names:
if fieldname not in arrayA.dtype.names:
errorFunction('Missing field {} in {}.', fieldname, location)
errorFunction('Missing field {} in {}.',
fieldname, location)
return False
elif arrayA.dtype == object and arrayRef.dtype == object:
if arrayA.shape != arrayRef.shape:
......@@ -69,7 +80,8 @@ def compareArrays(arrayA, arrayRef, location):
else:
success = True
for i in range(arrayA.size):
success = success and compareMatlab(arrayA[i], arrayRef[i], location + '[' + str(i) + ']')
success = success and compareMatlab(
arrayA[i], arrayRef[i], location + '[' + str(i) + ']')
return success
else:
try:
......@@ -80,5 +92,5 @@ def compareArrays(arrayA, arrayRef, location):
else:
return True
except:
errorFunction('Could not compare field {}.', location)
return False
errorFunction('Could not compare field {}.', location)
return False
import os
import subprocess
import compareMatfiles, compareTextfiles
import compareMatfiles
import compareTextfiles
class ExecutableTest:
......@@ -9,6 +10,7 @@ class ExecutableTest:
self.command = command
self.textfiles = []
self.matfiles = []
self.ignoredFiles = []
self.success = True
def addTextfile(self, outputFile, referenceFile):
......@@ -17,6 +19,9 @@ class ExecutableTest:
def addMatfile(self, outputFile, referenceFile):
self.matfiles.append((outputFile, referenceFile))
def addIgnoredFile(self, outputFile, referenceFile):
self.ignoredFiles.append((outputFile, referenceFile))
def isUnexceptedFile(self, filename):
for knownFile in self.textfiles:
if filename == knownFile[0] or filename == knownFile[1]:
......@@ -24,6 +29,9 @@ class ExecutableTest:
for knownFile in self.matfiles:
if filename == knownFile[0] or filename == knownFile[1]:
return False
for knownFile in self.ignoredFiles:
if filename == knownFile[0] or filename == knownFile[1]:
return False
return True
def run(self,):
......
MyPrismaticCell of class RectangularBlock at (0.000000,0.000000,0.000000) in xml-file line 217
CellConnector1 of class RectangularBlock at (0.040000,0.017500,0.115000) in xml-file line 245
CellConnector1 of class RectangularBlock at (0.133000,0.017500,0.115000) in xml-file line 245
MyPrismaticCell of class RectangularBlock at (0.000000,0.000000,0.000000) in xml-file line 222
CellConnector1 of class RectangularBlock at (0.040000,0.017500,0.115000) in xml-file line 249
CellConnector1 of class RectangularBlock at (0.133000,0.017500,0.115000) in xml-file line 249
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment