JSON input specification

The specification of the json input is provided through JSON schemas. In the Json schema, we added extra properties that are not part of the syntax but bring additional information such as a description field and references to the onthology (see BattInfo ).

The main Simulation schema contains schemas for

  • A schema for the geometry

  • A schema for the battery cell material parameters

  • A schema for the initialization of the state of the battery

  • A schema for the time stepping

  • A schema for the solver parameters

  • A schema for the output specification

Note

The different schemas may have common object. In the validation process, each schema is handled parallelly. The function mergeJsonStructs can be used to compose different json files.

For example a component (say the electolyte) has its geometrical and material properties specified in two separate schemas. Having separate schemas clarify the presentation and corresponds also to a convenient way to organize the input. We can easily switch between different geometrical models while keeping the same material properties. For that, we use the mergeJsonStructs function, see the example here.

Here, we give an Example

Simulation Schema

This is the main schema for the input json file. It uses other separate schemas which takes care of specific parameter sets.

{
  "$id": "file://./Simulation.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Input description for a Battery simulation in BattMo",
  "type": "object",
  "allOf": [
    {
      "$ref": "ModelSpecification.schema.json",
      "description": "Overall model specification. Choice of physics and component that will be included in the model"
    },
    {
      "$ref": "Battery.schema.json",
      "description": "Battery Physical Parameters"
    },
    {
      "$ref": "ControlModel.schema.json",
      "description": "Input for the control type and the corresponding parameters"
    },
    {
      "$ref": "Geometry.schema.json",
      "description": "Specification of the geometry including the discretization parameters"
    },
    {
      "$ref": "StateInitialization.schema.json",
      "description": "Input to setup the initial state of the battery"
    },
    {
      "$ref": "TimeStepping.schema.json",
      "description": "Input for the time stepping"
    },
    {
      "$ref": "Solver.schema.json",
      "description": "Options for the solver"
    },
    {
      "$ref": "Output.schema.json",
      "description": "Input for the choice of outputs the will be returned"
    }
  ]
}

The schemas are available in the directory JsonSchemas. Here is an example of the main input file where the inputs are given in separate files using the isFile key.

Material Parameters

The main schema for the material parameter is reproduced below (source). We recognize the battery model structure presented here.

{
  "$id": "file://./Battery.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A standard battery",
  "type": "object",
  "properties": {
    "NegativeElectrode": {
      "$ref": "Electrode.schema.json"
    },
    "PositiveElectrode": {
      "$ref": "Electrode.schema.json"
    },
    "Electrolyte": {
      "$ref": "Electrolyte.schema.json"
    },
    "Separator": {
      "$ref": "Separator.schema.json"
    },
    "ThermalModel": {
      "$ref": "ThermalComponent.schema.json",
      "description": "Battery Physical Parameters required for thermal modelling"
    }
  },
  "allOf": [
    {
      "required": [
        "NegativeElectrode",
        "PositiveElectrode",
        "Electrolyte",
        "Separator"
      ]
    }
  ]
}

It contains references to schemas that are written in separate files

  • Electrolyte

  • Electrode

    • Coating

      • Interface

      • Solid Diffusion

    • Current Collector

  • Separator

  • Thermal Model

See json input example.

Electrolyte

The ionic conductivity and the diffusion coefficient can be given as a function or a constant. When a function is given, the json file should contain the function name that is used. The signature of the function is given in the schema in form of a argument list. For example, below, we can read that that the ionicConductivity is a function of concentration and temperature, see examples here.

Note

At the moment, only function implemented in matlab are supported. To add a function, the user must therefore create it in matlab, with the right signature, and make sure it is in the path. We plan to add very soon a pure json interface, where a function can be given either as string (which is evaluated to obtain the value) or as a table. When given as a table, the value of the function is interpolated from the data points.

{
  "$id": "file://./Electrolyte",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "An electrolyte",
  "type": "object",
  "properties": {
    "ionicConductivity": {
      "allOf": [
        {"$ref": "Function.schema.json"},
        { "properties" : {
          "argumentlist": {"type" : "array",
                           "prefixItems": [{"const": "concentration"},
                                           {"const": "temperature"}]
                          },
          "symbol": {"const" : "kappa"}}}
        ],
      "description": "a function to determine the ionic conductivity of the electrolyte under given conditions"
    },
    "diffusionCoefficient": {
      "allOf": [
        {"$ref": "Function.schema.json"},
        { "properties" : {
          "argumentlist": {"type" : "array",
                           "prefixItems": [{"const": "concentration"},
                                           {"const": "temperature"}]
                          },
          "symbol": {"const" : "D"}}}
        ],
      "description": "a function to determine the diffusion coefficient of a molecule in the electrolyte under given conditions"
    },
    "species": {
      "type": "object",
      "description": "Property for the positive ion (Lithium). We support for the moment only binary electrolyte.",
      "properties": {
        "chargeNumber": {
          "type": "number",
          "description": "charge number"
        },
        "transferenceNumber": {
          "type": "number",
          "description": "transference number"
        },
        "nominalConcentration": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "nominal concentration used as initial concentration in a simulation, if the later is not given explicitely, see StateInitialization.schema.json"
        }}},
    "nominalEthyleneCarbonateConcentration" : {
      "$ref" : "PhysicalQuantity.schema.json",
      "description" : "Nominal Ethylene Carbonate concentration in the electrolyte. This is used as initial concentration, in case the SEI layer is included in model, see Coating.schema.json and the active_material_type property"},
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the material",
      "symbol": "rho"
    },
    "bruggemanCoefficient": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the coefficient for determining effective transport parameters in porous media",
      "symbol": "beta"
    },
    "useRegionBruggemanCoefficients" : {
      "type" : "boolean",
      "description" : "Set to true if the electrolye region for each component should get a specific Bruggeman coefficient, as given by regionBruggemanCoefficients. Default value is false"},
    "regionBruggemanCoefficients" : {
      "type" : "object",
      "description" : "Bruggeman coefficients for each region",
      "NegativeElectrode" : {
        "$ref": "PhysicalQuantity.schema.json"},
      "PositiveElectrode" : {
        "$ref": "PhysicalQuantity.schema.json"},
      "Separator" : {
        "$ref": "PhysicalQuantity.schema.json"}},
    "regionTags" :  {"type" : "array",
                     "description" : "Numerical tags that identifies each grid cell for the electrolyte. The conventions is 1 for negative electrode, 2 for positive electrodes, 3 for separator. It is used only when useRegionBruggemanCoefficients is true. This property is typically setup by the grid constructor."},
    "thermalConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the intrinsic Thermal conductivity of the active component",
      "symbol": ""
    },
    "specificHeatCapacity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the Specific Heat capacity of the active component",
      "symbol": ""
    }
  }
}

See json input example.

Electrode

The electrode input data contains essentially the input data for the coating and the current collector. The current collector is optional.

{
  "$id": "file://./Electrode.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Electrode",
  "type": "object",
  
  "properties" : {
    "Coating" : {"$ref" : "Coating.schema.json"},
    "CurrentCollector" : {"$ref" : "CurrentCollector.schema.json"},
    "use_normed_current_collector" : {"type" : "boolean",
                                    "description" : "Use special solver setup for current collector to avoid floating point error when there are very small voltage difference. It is only needed for the positive electrode. Default is true but we set it to false for the moment when we use an iterative linear solver"}
  }

}

See json input example and also here.

Coating

In the coating input data, we find input data for the active material, the binder and the conducting additive. In the case where we have a composite material (active_material_type is set to composite), then we have to provide the data for the two active materials (ActiveMaterial1 and ActiveMaterial1).

{
  "$id": "file://./Coating.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Coating",
  "type": "object",
  "allOf": [
    {
      "$ref": "./ElectronicComponent.schema.json"
    },
    {
      "properties": {
        "activeMaterialModelSetup": {
          "type" : "object",
          "properties" : {
            "composite" : {"type" : "boolean",
                           "description" : "default is false. It true, setup a composite material with two active materials, using fields ActiveMaterial1 and ActiveMaterial2"},
            "SEImodel" : {"type" : "string",
                          "enum" : ["none", "Safari", "Bolay"]}}},
        "ActiveMaterial": {
          "$ref": "ActiveMaterial.schema.json"
        },
        "ActiveMaterial1": {
          "$ref": "ActiveMaterial.schema.json"
        },
        "ActiveMaterial2": {
          "$ref": "ActiveMaterial.schema.json"
        },
        "Binder": {
          "$ref": "Binder.schema.json"
        },
        "ConductingAdditive": {
          "$ref": "ConductingAdditive.schema.json"
        },
        "effectiveDensity": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the mass density of the material (either in wet or calendared state). The density is computed with respect to the total volume (i.e. including the empty pores)",
          "symbol": "rho"
        },
        "bruggemanCoefficient": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the Bruggeman coefficient for effective transport in porous media",
          "symbol": "beta"
        },
        "volumeFraction" : {
          "type": "number",
          "description": "Volume fraction of the coating. This value is, in the default setup, computed from the other parameters (the mass fractions and the densities of the components, and the effictive density). If the value is passed here using this property, it overrides the default setup.",
          "symbol": "vf"
        },
        "volumeFractions" : {
          "type" : "array",
          "items" : {"type" : "number"},
          "minItems": 3,
          "maxItems": 3,
          "description": "Volume fractions for each of the component (active material, binder, conducting additive). As the volume fraction, this value , in the default setup, computed from the other parameters (the mass fractions and the densities of the components, and the effictive density). If the value is passed here using this property, it overrides the default setup. If none of the specific volumes of the components can be computed, then we assume that the volume fraction of the active material is equal to one."
        },
        "effectiveVolumetricHeatCapacity" : {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the effective volumetric heat capacity, which take into account the volume fraction. This value is in the default setup computed, but the value given here will overwrite the default computed value."
        },
        "effectiveThermalConductivity" : {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the effective thermal conductivity, which take into account the volume fraction and the bruggeman coefficient. This value is in the default setup computed, but the value given here will overwrite the default computed value."
        }
      }
    },
    {
      "if": {
        "properties": {
          "active_material_type": {
            "enum": ["default"]
          }
        },
        "required": ["active_material_type"]
      },
      "then": {
        "required": [
          "ActiveMaterial"
        ]
      }
    },
    {
      "if": {
        "properties": {
          "active_material_type": {
            "enum": ["composite"]
          }
        },
        "required": ["active_material_type"]
      },
      "then": {
        "required": [
          "ActiveMaterial1",
          "ActiveMaterial2"
        ]
      }
    }

  ]
}

See json input example

Active Material

The active material input data contains the conductivity, the thermal data and the input data for the interface and solid diffusion. The interface refers to the processes that occur there, i.e. the chemical reactions, see below. The property diffusionModelType is used to choose between the different diffusion model available, see also here.

Note

The model switch for the diffusion model (i.e. diffusionModelType) is provided in the model above the diffusion model itself, in this case the active material model. When we initialise a sub-model, we need to know its type. By having the model switch in the model above, we can directly choose and start the corresponding initializaton. This design choice is in fact used consistently in BattMo.

{
  "$id": "file://./ActiveMaterial.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Active Material",
  "type": "object",
  "properties": {
    "SEImodel" : {"type" : "string",
                  "enum" : ["none", "Safari", "Bolay"],
                  "description" : "The default is \"standard\" with no SEI layer model. Two SEI models are implemented Safari (2009) and Bolay et al (2022)"},
    "Interface": {
      "$ref": "Interface.schema.json"
    },
    "diffusionModelType": {
      "type": "string",
      "enum": [
        "full",
        "simple"
      ]
    },
    "electronicConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "properties": {
        "rdf_type": {
          "const": "htttp://emmo.info/UUID"
        }
      },
      "description": "the electronic conductivity of the material",
      "symbol": "sigma"
    },
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the material",
      "symbol": "rho"
    },
    "massFraction": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the mass of the material to the total mass of the phase or mixture",
      "symbol": "gamma"
    },
    "thermalConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the intrinsic Thermal conductivity of the active component",
      "symbol": ""
    },
    "specificHeatCapacity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the Specific Heat capacity of the active component",
      "symbol": ""
    }
  },
  "required": [
    "Interface",
    "SolidDiffusion"
  ],
  "anyOf": [
    {
      "if": {
        "properties": {
          "diffusionModelType": {
            "const": "full"
          }
        }
      },
      "then": {
        "properties": {
          "SolidDiffusion": {
            "$ref": "FullSolidDiffusionModel.schema.json"
          }
        }
      },
      "else": {
        "properties": {
          "SolidDiffusion": {
            "$ref": "SimplifiedSolidDiffusionModel.schema.json"
          }
        }
      }
    }
  ]
}

See json input example

Interface

The interface input data gives the specification of the chemical reaction occuring there. In particular, we find the definition of open circuit potential (openCircuitPotential). As mentioned above, we plan to include support for tabulated and string input for functions.

{
  "$id": "file://./Interface.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "interface",
  "type": "object",
  "properties": {
    "saturationConcentration": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the saturation concentration of the guest molecule in the host material",
      "symbol": "cmax"
    },
    "numberOfElectronsTransferred": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "stoichiometric number of electrons transferred in the electrochemical reaction",
      "symbol": "n"
    },
    "volumetricSurfaceArea": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "surface area of the active material - electrolyte interface per volume of electrode"
    },
    "activationEnergyOfReaction": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the activation energy of the electrochemical reaction",
      "symbol": "Eak"
    },
    "reactionRateConstant": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the reaction rate constant of the electrochemical reaction",
      "symbol": "k0"
    },
    "exchangeCurrentDensity": {
      "allOf": [
        {"$ref": "Function.schema.json"},
        { "properties" : {
          "argumentlist": {"type" : "array",
                           "prefixItems": [{"const": "soc"}]
                          },
          "symbol": {"const" : "j0"}}}
        ],
      "description": "The exchange current at the electrode-electrolyte interface under equilibrium conditions. If not given, it is computed from the reaction rate constant"
    },
    "guestStoichiometry100": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the concentration of the guest molecule to the saturation concentration of the guest molecule in a phase at a cell voltage that is defined as 100% SOC",
      "symbol": "theta100"
    },
    "guestStoichiometry0": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the concentration of the guest molecule to the saturation concentration of the guest molecule in a phase at a cell voltage that is defined as 0% SOC",
      "symbol": "theta0"
    },
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the active material",
      "symbol": "rho"
    },
    "openCircuitPotential": {
      "allOf": [
        {"$ref": "Function.schema.json"},
        { "properties" : {
          "argumentlist": {"type" : "array",
                           "prefixItems": [{"const": "concentration"},
                                           {"const": "temperature"},
                                           {"const": "cmax"}]
                          },
          "symbol": {"const" : "OCP"}}}
        ],
      "description": "a function to determine the open-circuit potential of the electrode under given conditions"
    },
    "chargeTransferCoefficient": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the charge transfer coefficient that enters in the Butler-Volmer equation",
      "symbol": "alpha"
    }
  },
"allOf": [{
  "if": {
    "properties": {
      "exchangeCurrentDensity": {
        "properties": {
          "type": {
            "const": "constant"
          }
        },
        "required": ["exchangeCurrentDensity"]
      }
    }
  },
  "then": {
    "required": [
      "reactionRateConstant"
    ]
  }
}]
}

See json input example

Solid Diffusion

The solid diffusion input data contains in particular the particle radius, the volumetric surface area and the reference diffusion coefficient. We use an Arrhenius-type of equation to compute the diffusion coefficient. In the case of the full diffusion model, we can provide a diffusion coefficient that depends on the concentration, see below.

{
    "$id": "file://./SolidDiffusionModel.schema.json",
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "description": "solid diffusion",
    "type": "object",
    "properties" : {
        "particleRadius": {
            "$ref": "PhysicalQuantity.schema.json",
            "description": "the characteristic radius of the particle",
            "symbol": "rp"
        },
        "activationEnergyOfDiffusion": {
            "$ref": "PhysicalQuantity.schema.json",
            "description": "the Arrhenius-type activation energy for diffusion",
            "symbol": "EaD"
        },
        "referenceDiffusionCoefficient": {
            "$ref": "PhysicalQuantity.schema.json",
            "description": "the pre-exponential reference diffusion coefficient in an Arrhenius-type equation",
            "symbol": "D0"
        },
        "volumetricSurfaceArea": {
            "$ref": "PhysicalQuantity.schema.json",
            "description": "surface area of the active material - electrolyte interface per volume of electrode"
         }
    }
}

See json input example

Full Solid Diffusion

We can specify the diffusion coefficient as a function of the state of charge. To compute the state of charge, we need the guest stoichiometries and the saturation concentration.

Note

The guest stoichiometries and the saturation concentration are also input data for the interface. The given values should then be the same. However, the submodels are initiated parallelly at the model level. For that reason, we use a validation mechanism that checks the consistency of the data of the submodels, when needed, see here for an example.

{
  "$id": "file://./FullSolidDiffusionModel.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "solid diffusion",
  "type": "object",
  "allOf": [
    {
      "$ref": "SolidDiffusionModel.schema.json"
    },
    {
      "properties": {
        "diffusionCoefficient": {
          "allOf": [
            {"$ref": "Function.schema.json"},
            { "properties" : {
              "argumentlist": {"type" : "array",
                               "prefixItems": [{"const": "soc"}]
                              },
              "symbol": {"const" : "D"}}}
          ],
          "description": "Function that is used to compute the diffusion coefficient. If not given, we use a constant diffusion coefficient as computed in SolidDiffusionModel."
        },
        "saturationConcentration": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the saturation concentration of the guest molecule in the host material",
          "symbol": "cmax"
        },
        "guestStoichiometry100": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the ratio of the concentration of the guest molecule to the saturation concentration of the guest molecule in a phase at a cell voltage that is defined as 100% SOC",
          "symbol": "theta100"
        },
        "guestStoichiometry0": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "the ratio of the concentration of the guest molecule to the saturation concentration of the guest molecule in a phase at a cell voltage that is defined as 0% SOC",
          "symbol": "theta0"
        }
      }
    }
  ]
}

See json input example

Binder

The conductivity of the binder and conductiving additive are used to compute the overall conductivity of the coating.

{
  "$id": "file://./Binder.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Binder",
  "type": "object",
  "properties": {
    "electronicConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the electronic conductivity of the material",
      "symbol": "sigma"
    },
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the material",
      "symbol": "rho"
    },
    "massFraction": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the mass of the material to the total mass of the phase or mixture",
      "symbol": "gamma"
    },
    "thermalConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the thermal conductivity of the component",
      "symbol": ""
    },
    "specificHeatCapacity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the specificHeatCapacity of the component",
      "symbol": ""
    }
  },
  "required": [
    "density",
    "massFraction"
  ]
}

See json input example

Conducting Additive

The conductivity of the binder and conductiving additive are used to compute the overall conductivity of the coating.

{
  "$id": "file://./ConductingAdditive.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "ConductingAdditive",
  "type": "object",
  "properties": {
    "electronicConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the electronic conductivity of the material",
      "symbol": "sigma"
    },
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the material",
      "symbol": "rho"
    },
    "massFraction": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the mass of the material to the total mass of the phase or mixture",
      "symbol": "gamma"
    },
    "thermalConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the thermal conductivity of the component",
      "symbol": ""
    },
    "specificHeatCapacity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the specificHeatCapacity of the component",
      "symbol": ""
    }   
  },
  "required": [
    "density",
    "massFraction",
    "electronicConductivity"
  ]
}

See json input example

Current Collector

{
  "$id": "file://./CurrentCollector.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A current collector",
  "type": "object",
  
  "$ref": "./ElectronicComponent.schema.json"
  
}

See json input example

Separator

The porosity of the separator gives the volume fraction of the electrolyte in that region.

{
  "$id": "./Separator.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A separator",
  "type": "object",
  "properties": {
    "porosity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the ratio of the volume free space to the total volume",
      "symbol": "varepsilon"
    },
    "density": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the mass density of the material",
      "symbol": "rho"
    },
    "bruggemanCoefficient": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "coefficient to determine effective transport parameters in porous media",
      "symbol": "beta"
    },
    "thermalConductivity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the thermal conductivity of the component",
      "symbol": ""
    },
    "specificHeatCapacity": {
      "$ref": "PhysicalQuantity.schema.json",
      "description": "the specificHeatCapacity of the component",
      "symbol": ""
    }
  }
}

See json input example

Thermal Model

The thermal parameters such as thermal capacity and conductivity are part of the material parameters. In the thermal model, we include the external temperature and the heat transfer paremeters with the exterior domain. The later depend often on the geometry, and they are in fact also included in the schema there, see below. We have included a flag to indicate if we consider wet or dry properties. This flag is not yet supported and we always consider dry properties, from which the effective wet properties are computed.

{
  "$id": "file://./ThermalComponent.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Thermal model",
  "type" : "object",
  "properties" : {
    "ThermalModel" : {
      "useWetProperties" : {
        "type" : "boolean",
        "description" : "If set to true, we use wet properties, which means that the thermal properties are measured with the electrolyte. In this case, it corresponds to the effective thermal properties. This property is NOT yet SUPPORTED. It could be set to false or ignored"},
      "externalHeatTransferCoefficient": {
        "$ref": "PhysicalQuantity.schema.json",
        "description": "the heat transfer coefficient between the external surface and surroundings. The use of this value depends on the choice of geometry. If needed, it is also specified in the Geometry schema"
      },
      "externalHeatTransferCoefficientTopFaces" :  {
        "$ref": "PhysicalQuantity.schema.json",
        "description": "the heat transfer coefficient between the top surfaces and surroundings. The use of this value depends on the choice of geometry. If needed, it is also specified in the Geometry schema"
      },
      "externalHeatTransferCoefficientSideFaces" : {
        "$ref": "PhysicalQuantity.schema.json",
        "description": "the heat transfer coefficient between the side surfaces and surroundings. The use of this value depends on the choice of geometry. If needed, it is also specified in the Geometry schema"
      },
      "externalHeatTransferCoefficientTab" : {
        "$ref": "PhysicalQuantity.schema.json",
        "description": "the heat transfer coefficient between the side surfaces and surroundings. The use of this value depends on the choice of geometry. If needed, it is also specified in the Geometry schema"
      },
      "externalTemperature": {
        "$ref": "PhysicalQuantity.schema.json",
        "description": "the temperature of the surroundings"
      }
    }
  }
}

See json input example

Geometry Setup

BattMo supports very general grid structures. However, the geometrical models must be constructed. Typically, in the manufacturing industry, this operation is done using CAD software. For batteries, there exist standard designs which can be parameterized by a small set of parameters, see the dedicated page.

For each design, the parameters are described in the schema.

{
  "$id": "file://./Geometry.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Specification of the geometry including the discretization parameters",
  "type": "object",

  "properties" : {"Geometry" : {"type" : "object",
                                "properties" : {"case" : {"type" : "string",
                                                          "enum" : ["1D", "multiLayerPouch", "2D-demo", "3D-demo", "jellyRoll", "sectorModel", "coinCell"]}}},
                  "NegativeElectrode" : { "$ref" : "#/$defs/particlediscretization"},
                  "PositiveElectrode" : { "$ref" : "#/$defs/particlediscretization"}
                 },

  "anyOf" : [{"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "1D"}}}},
              "$ref" : "#/$defs/1D"},
             {"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "multiLayerPouch"}}}},
              "$ref" : "#/$defs/multiLayerPouch"},
             {"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "2D-demo"}}}},
              "$ref" : "#/$defs/2D-demo" },
             {"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "3D-demo"}}}},
              "$ref" : "#/$defs/3D-demo" },
             {"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "jellyRoll"}}}},
              "$ref" : "#/$defs/jellyRoll" },
             {"properties" : {"Geometry" : {"properties" : {"case" : {"const" : "sectorModel"}}}},
              "$ref" : "#/$defs/sectorModel" }
            ],

  "$defs" : {

    "layerSpecs" : {
      "properties" : {
        "NegativeElectrode" : {
          "properties" : {
            "Coating" : {
              "$ref" : "#/$defs/layerSpec"},
            "CurrentCollector" : {
              "$ref" : "#/$defs/layerSpec"}}},
        "PositiveElectrode" : {
          "properties" : {
            "Coating" : {
              "$ref" : "#/$defs/layerSpec"},
            "CurrentCollector" : {
              "$ref" : "#/$defs/layerSpec"}}},
        "Separator" : {
          "$ref" : "#/$defs/layerSpec"}}},

    "layerSpec" : {
      "properties" : {
        "thickness" : {
          "$ref": "PhysicalQuantity.schema.json",
          "description" : "the thickness of the component",
          "symbol" : "t"},
        "numberOfDiscreteCells" : {
          "type" : "number",
          "description" : "discretization parameter"}}},

    "1D" : {
      "allOf" : [
        {"$ref" : "#/$defs/layerSpecs"},
        {"properties" : {
          "Geometry" : {
            "properties" : {
              "faceArea" : {
                "type" : "number",
                "description" : "area of the cross-section"}}}}}]},

    "multiLayerPouch" : {
      "allOf" : [
        {"$ref" : "#/$defs/layerSpecs"},
        {"properties" : {
          "Geometry" : {
            "properties" : {
              "nLayers" : {
                "type" : "number",
                "description" : "number of layers in the pouch cells"},
              "width" : { "type" : "number"},
              "length" : { "type" : "number"},
              "tab" : {
                "type" : "object",
                "description" : "parameters for the tabs",
                "properties" : {
                  "cap_tabs" : {"type" : "boolean",
                                "description" : "If true, the tabs are removed and the parameters are only used to set the current collector external coupling"},
                  "width" : {"type" : "number"},
                  "Nx" : {"type" : "number",
                          "description" : "Discretization parameter in the width direction"},
                  "NegativeElectrode" : {
                    "type" : "object",
                    "description" : "tab parameter for the negative electrode",
                    "properties" : {
                      "length" : {"type" : "number"},
                      "Ny" : {"type" : "number",
                              "description" : "Discretization parameter in the height direction"}
                    }
                  },
                  "PositiveElectrode" : {
                    "type" : "object",
                    "description" : "tab parameter for the negative electrode",
                    "properties" : {
                      "length" : {"type" : "number"},
                      "Ny" : {"type" : "number",
                              "description" : "Discretization parameter in the height direction"}}}}},
              "Electrolyte" : {
                "type" : "object",
                "description" : "Discretization parameter for the electrolyte in the width and height directions",
                "properties" : {
                  "Nx" : {"type" : "number"},
                  "Ny" : {"type" : "number"}}}}}}}]},

    "2D-demo" : {"$ref" : "#/$defs/layerSpecs",
                 "description" : "In this demo case the dimensions are fixed. Further parametrization should be done using the grid generator BatteryGeneratorP3D"},

    "3D-demo" : {
      "description" : "In this demo case the dimensions are fixed. Further parametrization should be done using  the grid generator BatteryGeneratorP4D",
      "allOf" : [
        {"$ref" : "#/$defs/layerSpecs"},
        {"properties" :
         {"Geometry" : {
           "properties" : {
             "width" : {"type" : "number"},
             "height" : {"type" : "number"},
             "Nw" : {"type" : "number",
                     "description" : "discretization number in the width direction"},
             "Nh" : {"type" : "number",
                     "description" : "discretization number in the height direction"}
           }},
          "NegativeElectrode" : {
            "CurrentColector" : {
              "tab" : {
                "type" : "object",
                "properties" : {
                  "width" : {"type" : "number"},
                  "height" : {"type" : "number"},
                  "Nw" : {"type" : "number",
                          "description": "discretization number in the width direction"}
                }
              }
            }
          }
         },
         "PositiveElectrode" : {
            "CurrentColector" : {
              "tab" : {
                "type" : "object",
                "properties" : {
                  "width" : {"type" : "number"},
                  "height" : {"type" : "number"},
                  "Nw" : {"type" : "number",
                          "description": "discretization number in the width direction"}
                }
              }
            }
         },
         "ThermalModel": {
           "properties" : {
             "externalHeatTransferCoefficientTab" : {
               "$ref": "PhysicalQuantity.schema.json",
               "description": "the heat transfer coefficient at the tab"
             }
           }
         }
        }


      ]

                },

    "particlediscretization" : {
      "properties" : {
        "ActiveMaterial" : {
          "anyOf" : [
            {"properties" : {
              "diffusionModelType" : {
                "const" : "full"}},
             "dependentSchemas" : {
               "SolidDiffusion" : {
                 "properties" : {
                   "N"  : {
                     "type" : "integer",
                     "description" : "discretization parameter for the particle"}}}}},
            {"not" : {
              "properties" : {
                "diffusionModelType" : {
                  "const" : "full"}}}}]}}},

    "jellyRoll" : {
      "properties" : {
        "Geometry" : {
          "properties" : {
            "outerRadius" : {
              "type" : "number",
              "description" : "outer radius"},
            "innerRadius"  : {
              "type" : "number",
              "description" : "inner radius"},
            "height" : {
              "type" : "number",
              "description" : "height of the battery"},
            "numberOfDiscreteCellsVertical" : {
              "type" : "integer",
              "description" : "discretization parameter giving the number of grid cells in the vertical direction"},
            "numberOfDiscreteCellsAngular" : {
              "type" : "integer",
              "description" : "discretisation parameter giving the number of angular sectors of the grid in the horizontal plane"}}},
        "NegativeElectrode" : {
          "properties" : {
            "CurrentCollector" : {
              "properties": {
                "tabparams" : {"$ref" : "#/$defs/tabparams"}
              }}}},
        "PositiveElectrode" : {
          "properties" : {
            "CurrentCollector" : {
              "properties": {
                "tabparams" : {"$ref" : "#/$defs/tabparams"}
              }}}}
      },
      "allOf" : [{"$ref" : "#/$defs/layerSpecs"}]},

    "sectorModel" : {
      "properties" : {
        "Geometry" : {
          "properties" : {
            "outerRadius" : {
              "type" : "number",
              "description" : "outer radius"},
            "innerRadius"  : {
              "type" : "number",
              "description" : "inner radius"},
            "height" : {
              "type" : "number",
              "description" : "height of the battery"},
            "numberOfDiscreteCellsVertical" : {
              "type" : "integer",
              "description" : "discretization parameter giving the number of grid cells in the vertical direction"},
            "numberOfDiscreteCellsAngular" : {
              "type" : "integer",
              "description" : "the angle of the sector is computed as 2*pi/nas"}}}},
      "allOf" : [{"$ref" : "#/$defs/layerSpecs"}]},

    "tabparams" : {
      "type" : "object",
      "description" : "Parameters for the tabs",
      "properties" : {
        "usetab" : {
          "type" : "boolean",
          "default" : true}},
      "dependentSchemas" : {
        "usetab" : {
          "anyOf" : [
            {"properties" : {
              "usetab" : {
                "const" : true},
              "fractions" : {
                "type" : "array",
                "items" : {"type" : "number"}},
              "width" : {
                "type" : "number"}}},
            {"properties" : {
              "usetab" : {
                "const" : false}}}]}}},

    "sectortabparams" : {
      "type" : "object",
      "description" : "Parameters for the tabs for the sector model",
      "properties" : {
        "usetab" : {
          "type" : "boolean",
          "default" : true
        }},
      "dependentSchemas" : {
        "usetab" : {
          "anyOf" : [
            {"properties" : {
              "usetab" : {
                "const" : true},
              "fractions" : {
                "type" : "array",
                "items" : {"type" : "number"}}}},
            {"properties" : {
              "usetab" : {
                "const" : false}}}]}}}}}

See json input example

Simulation Control Parameters

The control options are presented here. A description of each parameters for the various control models can be read from the schema.

{
  "$id": "file://./ControlModel.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties" : {
    "Control" : {
      "type" : "object",
      "properties" : {
        "controlPolicy": {
          "type": "string",
          "enum": ["CCDischarge",
                   "CCCharge",
                   "CC",
                   "CCCV",
                   "powerControl",
		   "timeControl"]}}
    }},
    "allOf": [
      {"if": {
        "properties": {"controlPolicy" : {"const" : "CCDischarge"}},
        "then": {
          "$ref" : "#/$defs/CCDischarge"}}},
      {"if": {
        "properties": {"controlPolicy" : {"const" : "CCCharge"}},
        "then": {
          "$ref" : "#/$defs/CCCharge"}}},
      {"if": {
        "properties": {"controlPolicy" : {"const" : "CCCV"}},
        "then":{
          "$ref" : "#/$defs/CCCV"}}},
      {"if": {
        "properties": {"controlPolicy" : {"const" : "powerControl"}},
        "then": {
          "$ref" : "#/$defs/powerControl"}}}
    ],

  "$defs" : {
    "CCDischarge" : {
      "properties" : {
        "DRate" : {
          "type" : "number",
          "description" : "discharge rate"},
        "rampupTime" : {
          "type" : "number",
          "description" : "Rampup time where the current is increased linearly from zero to target value. In this way, we can avoid convergence issues in case of high current. Default value is zero, which means no rampup time"},
        "lowerCutoffVoltage" : {
          "type" : "number"},
        "useCVswitch" : {
          "type" : "boolean",
          "description" : "Switch to control voltage when the lower cutoff voltage is reached. Default value is false, which means that the simulation stops when the lower voltage is reached."
        }}},
    "CCCharge" : {
      "properties" : {
        "CRate" : {
          "type" : "number",
          "description" : "charge rate"},
        "rampupTime" : {
        "type" : "number",
        "description" : "Rampup time where the current is increased linearly from zero to target value. In this way, we can avoid convergence issues in case of high current."},
       "upperCutoffVoltage" : {
         "type" : "number"},
       "useCVswitch" : {
         "type" : "boolean",
         "description" : "Switch to control voltage when the upper cutoff voltage is reached. Default value is true."
       }
      }
    },
    "CCCV": {
      "properties" : {
        "CRate" : {
          "type" : "number",
          "description" : "charge rate"},
        "DRate" : {
          "type" : "number",
          "description" : "discharge rate"},
        "lowerCutoffVoltage" : {
          "type" : "number"},
        "upperCutoffVoltage" : {
	  "type" : "number"},
        "dEdtLimit" : {"type" : "number"},
        "dIdtLimit" : {"type" : "number"},
        "numberOfCycles" : {"type" : "number"},
        "initialControl" : {"type" : "string",
                            "enum" : ["discharging", "charging"]},
        "switchTolerances" : {
          "type" : "object",
          "description" : "tolerances for the computation of the control switching (relative tolerances)",
          "properties" : {
            "CC_discharge1" : { "type" : "number",
                                "description" : "control corresponding to constant current discharge until lower cutoff voltage is reached, default value : 1e-2"},
            "CC_discharge2" : { "type" : "number",
                                "description" :  "control corresponding to zero current until dEdtLimit is reached. Default value : 0.9"},
            "CC_charge1" : { "type" : "number",
                             "description" :  "control corresponding to constant current charge until upper cutoff voltage is reached. Default value : 1e-2"},
            "CV_charge2" : { "type" : "number",
                             "description" :  "control corresponding to constant voltage until dIdtLimit is reached. Default value : 0.9"}
          }
        }
      }},

    "powerControl": {
      "properties" : {
        "case" : {"type" : "string",
                  "enum" : ["time limited", "voltage limited", "CPCV"]},
        "dischargingPower" : {"type" : "number"},
        "chargingPower" : {"type" : "number"}},

      "anyOf" : [
        { "properties" : {
          "powerControlCase" : {"const" : "time limited"},
          "dischargingTime" : {"type" : "number"},
          "chargingTime" : {"type" : "number"}
        }},

        { "properties" : {
          "powerControlCase" : {"const" : "voltage limited"}
        }},

        { "properties" : {
          "powerControlCase" : {"const" : "CPCV"},
          "lowerCutoffPower" : {"type" : "number"},
          "upperCutoffPower" : {"type" : "number"}
        }
        }
      ]}
  }
}

See json input example

Time Stepping Parameters

The description of the time stepping parameters can be read from the schema. Default parameters depending on the chose control model are provided.

{
  "$id": "file://./TimeStepping.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Input for the time stepping",
  "type": "object",
  "properties": {
    "TimeStepping": {
      "type": "object",
      "properties": {
        "totalTime": {
          "$ref": "PhysicalQuantity.schema.json",
          "description": "Total time. It is usually computed by the control models from their specific input. If given, it will (in general) overwrite this computed value. Check for the specific control model you are using",
          "symmbol": ""
        },
        "timeStepDuration": {
          "type": "number",
          "description" : "Length of the time step. The solution is computed for every time step."
        },
        "numberOfTimeSteps": {
          "type": "integer",
          "description": "Number of time steps. If timeStepDuration is not given, we use this number to compute it, using  total time. The default number of time step values is 100."
        },
        "useRampup": {
          "type": "boolean"
        },
        "numberOfRampupSteps": {
          "type": "number",
          "description": "if we use rampup, we use at the start time intervals that increases geometrically until we reach the time step target, see function rampupTimesteps."
        }
      }
    }
  }
}

See json input example

Solver Parameters

Default parameters for the solver are provided. There exist a json interface to modify those and the corresponding parameters are desribed in the schema. Many more options are available at the matlab level, which we do not document here .

{
  "$id": "file://./Solver.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "description" : "Setting that can be given to the solver. Only parts of those are avaible through json interface but many more options are available if you use the nonlinear solver object",

  "properties" : {
    "NonLinearSolver" : {
      "type" : "object",
      "description" : "Some of the settings for the Newton non-linear solver. There are many more options available, see battmoDir()/MRST/mrst-autodiff/ad-core/solvers/NonLinearSolver",
      "properties" : {
        "maxIterations" : {
          "type" : "number",
          "description" : "maximum number of Newton iterations. Default value is 10"},
        "maxTimestepCuts" : {
          "type" : "number",
          "description" : "When a Newton iteration fails to converge, we cut the time step. If it fails again, we cut again until we have reached a number of time equal maxTimeStepCuts. Then, we consider the simulation has failed. The default value is 6"},          
        "nonlinearTolerance" : {
          "type" : "number",
          "description" : "tolerance value for the nonlinear iteration"},
        "verbose" : {
          "type" : "boolean"},
        "LinearSolver" : {
          "type" : "object",
          "properties" : {
            "linearSolverSetup" : {
              "type" : "object",
              "$ref" : "LinearSolver.schema.json"}}}}}}}

Output Parameters

Some extra post-processed parameters can be asked for already at the json level. Otherwise, it is always possible to compute those afterwards (see function computeEnergyDensity for example).

{
  "$id": "file://./Ouput.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "Specification of the outputs the will be returned",
  "type": "object",

  "properties" : {
    
    "Output" : {
      "type" : "object",
      "properties" : {

        "variables" : {
          "type" : "array",
          "description" : "list of extra variables that we want to get in output structure",
          "items" : {
            "type" : "string",
            "enum" : ["energy", "energyDensity", "specificEnergy"]}},

        "saveOutput" : {
          "type" : "boolean",
          "description" : "True if simulation data will be saved to disk (default is false)"}},

      "dependentSchemas" : {
        "saveOutput" : {
          "anyOf" : [
            {"properties" : {
              "saveOutput" : {"const" : true},
              "saveOptions" : {
                "type" : "object",
                "description" : "part of the input for battmoDir()/MRST/mrst-autodiff/ad-core/simulators/sim_runner/packSimulationProblem which deals with the place where the data is saved",
                "properties" : {"outputDirectory" : {"type" : "string",
                                                     "description" : "name of the directory output where the output simulations will be saved"},
                                "name" : {"type" : "string",
                                          "description" : "name of the simulation. The output of the simulation will be saved in outputDirectory/name"},
                                "clearSimulation" : {"type" : "boolean",
                                                     "description" : "true if the data that has been saved in a previous run at the same location should be erased. False if it just should be loaded and used as the output of the simulation."}
                               }}}},
            {"properties" : {
              "saveOutput" : {"const" : false}}}]}}}}}