/*
 * battery_pack_6s2p.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 15 2026, 11:10 by COMSOL 6.4.0.421. */
public class battery_pack_6s2p {

  public static Model run() {
    Model model = ModelUtil.create("Model");

//    From the File menu, choose New.
//    In the New window, click Model Wizard.
//    Start with adding a 3D space dimension along with a Heat Transfer in Fluids and a Battery Pack interface.
//    In the Model Wizard window, click 3D.
//    In the Select Physics tree, select Electrochemistry > Batteries > Battery Pack (bp).
//    Click Add.
//    In the Select Physics tree, select Heat Transfer > Heat Transfer in Fluids (ht).
//    Click Add.
//    Click Study.
//    In the Select Study tree, select General Studies > Time Dependent.
//    Click Done.

    model.component().create("comp1", true);

    model.component("comp1").geom().create("geom1", 3);
    model.component("comp1").geom("geom1").geomRep("comsol");

    model.component("comp1").mesh().create("mesh1");
    model.component("comp1").mesh("mesh1").contribute("geom/detail", true);

    model.component("comp1").physics().create("bp", "BatteryPack", "geom1");
    model.component("comp1").physics().create("ht", "HeatTransferInFluids", "geom1");

    model.study().create("std1");
    model.study("std1").create("time", "Transient");

//    Add an analytical function to account for the temperature dependent activation energy using the Arrhenius relation.
//    In the Definitions toolbar, click Analytic.

    model.component("comp1").func().create("an1", "Analytic");

//    In the Settings window for Analytic, type Arrh in the Function name text field.

    model.component("comp1").func("an1").set("funcname", "Arrh");

//    Locate the Definition section.
//    In the Expression text field, type exp(Ea/R_const*(1/Temp-1/T0)).

    model.component("comp1").func("an1").set("expr", "exp(Ea/R_const*(1/Temp-1/T0))");

//    In the Arguments text field, type Ea, Temp.

    model.component("comp1").func("an1").set("args", "Ea, Temp");

//    Locate the Units section.
//    In the table, enter the following settings:

    model.component("comp1").func("an1").setIndex("argunit", "J/mol", 0);
    model.component("comp1").func("an1").setIndex("argunit", "K", 1);

//    In the Function text field, type 1.

    model.component("comp1").func("an1").set("fununit", "1");

//    Next add interpolation functions to define the SOC dependent equilibrium potential and its temperature dependence.
//    In the Definitions toolbar, click Interpolation.

    model.component("comp1").func().create("int1", "Interpolation");

//    In the Settings window for Interpolation, type E_OCP in the Label text field.

    model.component("comp1").func("int1").label("E_OCP");

//    Locate the Definition section.
//    From the Data source list, select File.

    model.component("comp1").func("int1").set("source", "file");

//    In the Filename text field, type battery_pack_6s2p_E_OCP_data.txt.

    model.component("comp1").func("int1").set("filename", "battery_pack_6s2p_E_OCP_data.txt");

//    Click Import.

    model.component("comp1").func("int1").importData();

//    Locate the Units section.
//    In the Argument table, enter the following settings:

    model.component("comp1").func("int1").setIndex("argunit", 1, 0);
    model.component("comp1").func("int1").setIndex("fununit", "V", 0);

//    In the Function table, enter the following settings:
//    In the Definitions toolbar, click Interpolation.

    model.component("comp1").func().create("int2", "Interpolation");

//    In the Settings window for Interpolation, type dEdT in the Label text field.

    model.component("comp1").func("int2").label("dEdT");

//    Locate the Definition section.
//    From the Data source list, select File.

    model.component("comp1").func("int2").set("source", "file");

//    In the Filename text field, type battery_pack_6s2p_dEdT_data.txt.

    model.component("comp1").func("int2").set("filename", "battery_pack_6s2p_dEdT_data.txt");

//    Click Import.

    model.component("comp1").func("int2").importData();

//    Locate the Units section.
//    In the Argument table, enter the following settings:

    model.component("comp1").func("int2").setIndex("argunit", 1, 0);
    model.component("comp1").func("int2").setIndex("fununit", "V/K", 0);

//    In the Function table, enter the following settings:
//    In the Geometry toolbar, click Insert Sequence and choose Insert Sequence.

    model.component("comp1").geom("geom1").insertFile("battery_pack_6s2p_geom_sequence.mph", "geom1");

//    Browse to the model's Application Library folder and double-click the file battery_pack_6s2p_geom_sequence.mph.
//    In the Geometry toolbar, click Build All.

    model.component("comp1").geom("geom1").run("boxsel1");

//    Click the Transparency button in the Graphics toolbar.

    model.component("comp1").view("view1").set("transparency", true);

//    Disable the analysis of the geometry as the remaining small geometric details can be kept.
//    In the Model Builder window, click Geometry 1.
//    In the Settings window for Geometry, locate the Cleanup section.
//    Clear the Automatic detection of small details checkbox.
//    Click the Zoom Extents button in the Graphics toolbar.
//    In the Model Builder window, under Global Definitions, click Parameters 1.
//    In the Settings window for Parameters, type Geometry Parameters in the Label text field.

    model.param().label("Geometry Parameters");

//    Add the parameter file required for setting up the physics of the lumped battery and heat transfer interfaces.
//    In the Home toolbar, click Parameters and choose Add > Parameters.

    model.param().create("par2");

//    In the Settings window for Parameters, type Battery Parameters in the Label text field.

    model.param("par2").label("Battery Parameters");

//    Locate the Parameters section.
//    Click Load from File.
//    Browse to the model's Application Library folder and double-click the file battery_pack_6s2p_parameters.txt.
//    To import content from file, use:
//    model.param("par2").loadFile("FILENAME");
    model.param("par2").set("C_rate", "4", "C rate");
    model.param("par2").set("Q_cell", "4[A*h]", "Battery cell capacity");
    model.param("par2").set("I_1C", "Q_cell/1[h]", "1C current");
    model.param("par2").set("kT_batt_il", "30[W/m/K]", "In-layer thermal conductivity");
    model.param("par2").set("kT_batt_tl", "1[W/m/K]", "Through-layer thermal conductivity");
    model.param("par2").set("Ea_eta1C", "24[kJ/mol]", "Activation energy");
    model.param("par2").set("Ea_J0", "-59[kJ/mol]", "Activation energy");
    model.param("par2").set("Ea_Tau", "24[kJ/mol]", "Activation energy");
    model.param("par2").set("T0", "20[degC]", "Reference temperature");
    model.param("par2").set("J0_0", "0.85", "J0 at reference temperature");
    model.param("par2").set("tau_0", "1000[s]", "tau at reference temperature");
    model.param("par2").set("eta_1C", "4.5[mV]", "eta_1C at reference temperature");
    model.param("par2").set("rho_batt", "2000[kg/m^3]", "Battery density");
    model.param("par2").set("Cp_batt", "1400[J/(kg*K)]", "Battery heat capacity");
    model.param("par2").set("ht", "30[W/m^2/K]", "Heat transfer coefficient");
    model.param("par2").set("T_init", "20[degC]", "Initial/external temperature");

//    Next, add and define the materials in the different domains: air to the region surrounding the batteries and aluminum to the current collectors.
//    In the Materials toolbar, click Add Material to open the Add Material window.
//    In the tree, select Built-in > Air.
//    Click Add to Component in the window toolbar.

    model.component("comp1").material().create("mat1", "Common");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("eta", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("Cp", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("rho", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("k", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("cs", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("an1", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("an2", "Analytic");
    model.component("comp1").material("mat1").propertyGroup()
         .create("RefractiveIndex", "RefractiveIndex", "Refractive index");
    model.component("comp1").material("mat1").propertyGroup()
         .create("NonlinearModel", "NonlinearModel", "Nonlinear model");
    model.component("comp1").material("mat1").propertyGroup().create("idealGas", "idealGas", "Ideal gas");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func().create("Cp", "Piecewise");
    model.component("comp1").material("mat1").label("Air");
    model.component("comp1").material("mat1").set("family", "air");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta")
         .set("pieces", new String[][]{{"200.0", "1600.0", "-8.38278E-7+8.35717342E-8*T^1-7.69429583E-11*T^2+4.6437266E-14*T^3-1.06585607E-17*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("fununit", "Pa*s");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp")
         .set("pieces", new String[][]{{"200.0", "1600.0", "1047.63657-0.372589265*T^1+9.45304214E-4*T^2-6.02409443E-7*T^3+1.2858961E-10*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("fununit", "J/(kg*K)");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("expr", "pA*0.02897/R_const[K*mol/J]/T");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho").set("args", new String[]{"pA", "T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho").set("fununit", "kg/m^3");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("argunit", new String[]{"Pa", "K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotaxis", new String[]{"off", "on"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotfixedvalue", new String[]{"101325", "273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotargs", new String[][]{{"pA", "101325", "101325"}, {"T", "273.15", "293.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("k")
         .set("pieces", new String[][]{{"200.0", "1600.0", "-0.00227583562+1.15480022E-4*T^1-7.90252856E-8*T^2+4.11702505E-11*T^3-7.43864331E-15*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("fununit", "W/(m*K)");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("expr", "sqrt(1.4*R_const[K*mol/J]/0.02897*T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("args", new String[]{"T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("fununit", "m/s");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("argunit", new String[]{"K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("plotfixedvalue", new String[]{"273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("plotargs", new String[][]{{"T", "273.15", "373.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("funcname", "alpha_p");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("expr", "-1/rho(pA,T)*d(rho(pA,T),T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("args", new String[]{"pA", "T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("fununit", "1/K");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("argunit", new String[]{"Pa", "K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotaxis", new String[]{"off", "on"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotfixedvalue", new String[]{"101325", "273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotargs", new String[][]{{"pA", "101325", "101325"}, {"T", "273.15", "373.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("funcname", "muB");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("expr", "0.6*eta(T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("args", new String[]{"T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("fununit", "Pa*s");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("argunit", new String[]{"K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2")
         .set("plotfixedvalue", new String[]{"200"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2")
         .set("plotargs", new String[][]{{"T", "200", "1600"}});
    model.component("comp1").material("mat1").propertyGroup("def").set("thermalexpansioncoefficient", "");
    model.component("comp1").material("mat1").propertyGroup("def").set("molarmass", "");
    model.component("comp1").material("mat1").propertyGroup("def").set("bulkviscosity", "");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("thermalexpansioncoefficient", new String[]{"alpha_p(pA,T)", "0", "0", "0", "alpha_p(pA,T)", "0", "0", "0", "alpha_p(pA,T)"});
    model.component("comp1").material("mat1").propertyGroup("def").set("molarmass", "0.02897[kg/mol]");
    model.component("comp1").material("mat1").propertyGroup("def").set("bulkviscosity", "muB(T)");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("relpermeability", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("relpermittivity", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("def").set("dynamicviscosity", "eta(T)");
    model.component("comp1").material("mat1").propertyGroup("def").set("ratioofspecificheat", "1.4");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("electricconductivity", new String[]{"0[S/m]", "0", "0", "0", "0[S/m]", "0", "0", "0", "0[S/m]"});
    model.component("comp1").material("mat1").propertyGroup("def").set("heatcapacity", "Cp(T)");
    model.component("comp1").material("mat1").propertyGroup("def").set("density", "rho(pA,T)");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("thermalconductivity", new String[]{"k(T)", "0", "0", "0", "k(T)", "0", "0", "0", "k(T)"});
    model.component("comp1").material("mat1").propertyGroup("def").set("soundspeed", "cs(T)");
    model.component("comp1").material("mat1").propertyGroup("def").addInput("temperature");
    model.component("comp1").material("mat1").propertyGroup("def").addInput("pressure");
    model.component("comp1").material("mat1").propertyGroup("RefractiveIndex")
         .set("n", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("NonlinearModel").set("BA", "def.gamma-1");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").label("Piecewise 2");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp")
         .set("pieces", new String[][]{{"200.0", "1600.0", "1047.63657-0.372589265*T^1+9.45304214E-4*T^2-6.02409443E-7*T^3+1.2858961E-10*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("fununit", "J/(kg*K)");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("Rs", "R_const/Mn");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("heatcapacity", "Cp(T)");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("ratioofspecificheat", "1.4");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("molarmass", "0.02897[kg/mol]");
    model.component("comp1").material("mat1").propertyGroup("idealGas").addInput("temperature");
    model.component("comp1").material("mat1").propertyGroup("idealGas").addInput("pressure");
    model.component("comp1").material("mat1").materialType("nonSolid");

//    In the tree, select Built-in > Aluminum.
//    Click Add to Component in the window toolbar.

    model.component("comp1").material().create("mat2", "Common");
    model.component("comp1").material("mat2").propertyGroup()
         .create("Enu", "Enu", "Young's modulus and Poisson's ratio");
    model.component("comp1").material("mat2").propertyGroup().create("Murnaghan", "Murnaghan", "Murnaghan");
    model.component("comp1").material("mat2").label("Aluminum");
    model.component("comp1").material("mat2").set("family", "aluminum");
    model.component("comp1").material("mat2").propertyGroup("def")
         .set("relpermeability", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat2").propertyGroup("def").set("heatcapacity", "900[J/(kg*K)]");
    model.component("comp1").material("mat2").propertyGroup("def")
         .set("thermalconductivity", new String[]{"238[W/(m*K)]", "0", "0", "0", "238[W/(m*K)]", "0", "0", "0", "238[W/(m*K)]"});
    model.component("comp1").material("mat2").propertyGroup("def")
         .set("electricconductivity", new String[]{"3.774e7[S/m]", "0", "0", "0", "3.774e7[S/m]", "0", "0", "0", "3.774e7[S/m]"});
    model.component("comp1").material("mat2").propertyGroup("def")
         .set("relpermittivity", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat2").propertyGroup("def")
         .set("thermalexpansioncoefficient", new String[]{"23e-6[1/K]", "0", "0", "0", "23e-6[1/K]", "0", "0", "0", "23e-6[1/K]"});
    model.component("comp1").material("mat2").propertyGroup("def").set("density", "2700[kg/m^3]");
    model.component("comp1").material("mat2").propertyGroup("Enu").set("E", "70[GPa]");
    model.component("comp1").material("mat2").propertyGroup("Enu").set("nu", "0.33");
    model.component("comp1").material("mat2").propertyGroup("Murnaghan").set("l", "-250[GPa]");
    model.component("comp1").material("mat2").propertyGroup("Murnaghan").set("m", "-330[GPa]");
    model.component("comp1").material("mat2").propertyGroup("Murnaghan").set("n", "-350[GPa]");

//    In the Materials toolbar, click Add Material to close the Add Material window.
//    In the Settings window for Material, locate the Geometric Entity Selection section.
//    From the Selection list, select Air Domain.

    model.component("comp1").material("mat1").selection().named("geom1_sel4");

//    In the Model Builder window, click Aluminum (mat2).
//    In the Settings window for Material, locate the Geometric Entity Selection section.
//    From the Selection list, select Conductors.

    model.component("comp1").material("mat2").selection().named("geom1_comsel1");

//    Now define the batteries of the pack.
//    In the Model Builder window, under Component 1 (comp1), click Battery Pack (bp).
//    In the Settings window for Battery Pack, locate the Domain Selection section.
//    From the Selection list, select Batteries and Conductors.

    model.component("comp1").physics("bp").selection().named("geom1_unisel2");

//    In the Model Builder window, under Component 1 (comp1) > Battery Pack (bp), click Batteries.
//    In the Settings window for Batteries, locate the Domain Selection section.
//    From the Selection list, select Batteries.

    model.component("comp1").physics("bp").feature("batt").selection().named("geom1_unisel1");

//    Locate the Initial Capacity section.
//    In the \[Q_\textrm{cell,0}\] text field, type Q_cell.

    model.component("comp1").physics("bp").feature("batt").set("Q_cell0", "Q_cell");

//    Locate the Initial Cell Charge Distribution section.
//    In the \[\textrm{SOC}_\textrm{cell,0}\] text field, type 1.

    model.component("comp1").physics("bp").feature("batt").set("SOC_pack0", 1);

//    In the Model Builder window, click Cell Equilibrium Potential 1.
//    In the Settings window for Cell Equilibrium Potential, locate the Open Circuit Voltage section.
//    From the Open circuit voltage input list, select From definitions.

    model.component("comp1").physics("bp").feature("batt").feature("cep1").set("OpenCircuitVoltageInput", "fromdef");

//    From the \[E_\textrm{OCV,ref}\] list, select E_OCP (int1).

    model.component("comp1").physics("bp").feature("batt").feature("cep1").set("Eocvdef", "int1");

//    From the \[dE_\textrm{OCV}/dT\] list, select dEdT (int2).

    model.component("comp1").physics("bp").feature("batt").feature("cep1").set("dEocvdTdef", "int2");

//    In the Model Builder window, click Voltage Losses 1.
//    In the Settings window for Voltage Losses, locate the Ohmic Overpotential section.
//    In the \[\eta_\textrm{IR,1C}\] text field, type eta_1C*Arrh(Ea_eta1C, bp.T_cell).

    model.component("comp1").physics("bp").feature("batt").feature("vl1")
         .set("eta_ir1C", "eta_1C*Arrh(Ea_eta1C, bp.T_cell)");

//    Locate the Activation Overpotential section.
//    In the \[J_0\] text field, type J0_0*Arrh(Ea_J0,bp.T_cell).

    model.component("comp1").physics("bp").feature("batt").feature("vl1").set("J0", "J0_0*Arrh(Ea_J0,bp.T_cell)");

//    Locate the Concentration Overpotential section.
//    Select the Include concentration overpotential checkbox.

    model.component("comp1").physics("bp").feature("batt").feature("vl1")
         .set("IncludeConcentrationOverpotential", true);

//    In the \[\tau\] text field, type tau_0*Arrh(Ea_Tau,bp.T_cell).

    model.component("comp1").physics("bp").feature("batt").feature("vl1").set("tau", "tau_0*Arrh(Ea_Tau,bp.T_cell)");

//    In the Model Builder window, under Component 1 (comp1) > Battery Pack (bp), click Current Conductors.
//    In the Settings window for Current Conductors, locate the Domain Selection section.
//    From the Selection list, select Conductors.

    model.component("comp1").physics("bp").feature("ccnd").selection().named("geom1_comsel1");

//    In the Physics toolbar, click Attributes and choose Ground.

    model.component("comp1").physics("bp").feature("ccnd").create("egnd1", "ElectricGround", 2);

//    Select Boundary 1.

    model.component("comp1").physics("bp").feature("ccnd").feature("egnd1").selection().set(1);

//    In the Model Builder window, click Current Conductors.
//    In the Physics toolbar, click Attributes and choose Current.

    model.component("comp1").physics("bp").feature("ccnd").create("ec1", "ElectrodeCurrent", 2);

//    Select Boundary 167.

    model.component("comp1").physics("bp").feature("ccnd").feature("ec1").selection().set(167);

//    In the Settings window for Current, locate the Electrode Current section.
//    In the \[I_{\textrm{s,total}}\] text field, type -I_1C*C_rate.

    model.component("comp1").physics("bp").feature("ccnd").feature("ec1").set("Its", "-I_1C*C_rate");

//    In the Model Builder window, under Component 1 (comp1) > Battery Pack (bp), click Negative Connectors.
//    Select Boundaries 34, 79, 128.

    model.component("comp1").physics("bp").feature("nc").selection().set(34, 79, 128);

//    In the Model Builder window, click Positive Connectors.
//    Select Boundaries 31, 82, 125.

    model.component("comp1").physics("bp").feature("pc").selection().set(31, 82, 125);

//    Now define the heat transfer in the battery pack.
//    In the Model Builder window, under Component 1 (comp1) > Heat Transfer in Fluids (ht), click Initial Values 1.
//    In the Settings window for Initial Values, locate the Initial Values section.
//    In the \[T\] text field, type T_init.

    model.component("comp1").physics("ht").feature("init1").set("Tinit", "T_init");

//    In the Physics toolbar, click Boundaries and choose Heat Flux.

    model.component("comp1").physics("ht").create("hf1", "HeatFluxBoundary", 2);

//    In the Settings window for Heat Flux, locate the Boundary Selection section.
//    From the Selection list, select Heat Flux Boundaries.

    model.component("comp1").physics("ht").feature("hf1").selection().named("geom1_sel5");

//    Locate the Heat Flux section.
//    From the Flux type list, select Convective heat flux.

    model.component("comp1").physics("ht").feature("hf1").set("HeatFluxType", "ConvectiveHeatFlux");

//    In the \[h\] text field, type ht.

    model.component("comp1").physics("ht").feature("hf1").set("h", "ht");

//    In the \[T_{\textrm{ext}}\] text field, type T_init.

    model.component("comp1").physics("ht").feature("hf1").set("Text", "T_init");

//    In the Physics toolbar, click Domains and choose Battery Layers.

    model.component("comp1").physics("ht").create("bl1", "BatteryLayers", 3);

//    In the Settings window for Battery Layers, locate the Domain Selection section.
//    From the Selection list, select Batteries.

    model.component("comp1").physics("ht").feature("bl1").selection().named("geom1_unisel1");

//    Due to the winding of the layers, the thermal conductivities in the battery domains exhibit anisotropic properties, with higher conductivity values in the in-layer direction compared to the through-layer (radial) direction.
//    Locate the Battery Layers section.
//    From the Layer configuration list, select Spirally wound (cylindrical).

    model.component("comp1").physics("ht").feature("bl1").set("LayerConfiguration", "SpirallyWound");

//    In the \[k_\textrm{tl}\] text field, type kT_batt_tl.

    model.component("comp1").physics("ht").feature("bl1").set("ThroughLayerConductivity", "kT_batt_tl");

//    In the \[k_\textrm{il}\] text field, type kT_batt_il.

    model.component("comp1").physics("ht").feature("bl1").set("InLayerConductivity", "kT_batt_il");

//    In the \[\rho_\textrm{eff}\] text field, type rho_batt.

    model.component("comp1").physics("ht").feature("bl1").set("Density", "rho_batt");

//    In the \[C_{p,\textrm{eff}}\] text field, type Cp_batt.

    model.component("comp1").physics("ht").feature("bl1").set("HeatCapacity", "Cp_batt");

//    In the Physics toolbar, click Domains and choose Solid.

    model.component("comp1").physics("ht").create("solid1", "SolidHeatTransferModel", 3);

//    In the Settings window for Solid, locate the Domain Selection section.
//    From the Selection list, select Conductors.

    model.component("comp1").physics("ht").feature("solid1").selection().named("geom1_comsel1");

//    Add a two-way coupling between the <l>Battery Pack</l> and the <l>Heat Transfer</l> interfaces for the heat sources and the temperature by adding an <l>Electrochemical Heating</l> multiphysics node.
//    In the Physics toolbar, click Multiphysics Couplings and choose Domain > Electrochemical Heating.

    model.component("comp1").multiphysics().create("ech1", "ElectrochemicalHeating", 3);

//    In the Mesh toolbar, click Swept.

    model.component("comp1").mesh("mesh1").create("swe1", "Sweep");

//    In the Settings window for Swept, locate the Domain Selection section.
//    From the Geometric entity level list, select Domain.

    model.component("comp1").mesh("mesh1").feature("swe1").selection().geom("geom1", 3);

//    From the Selection list, select Mesh Sweep Domains.

    model.component("comp1").mesh("mesh1").feature("swe1").selection().named("geom1_boxsel1");

//    Locate the Mesh Generation section.
//    From the Elements list, select Prisms.

    model.component("comp1").mesh("mesh1").feature("swe1").set("element", "prism");

//    In the Mesh toolbar, click Free Tetrahedral.

    model.component("comp1").mesh("mesh1").create("ftet1", "FreeTet");

//    In the Model Builder window, right-click Mesh 1 and choose Build All.

    model.component("comp1").mesh("mesh1").run();

//    Adding probes for temperatures and cell potentials allows for visualizing results while solving. The <l>Battery Pack</l> interface defines cell potential variables named <c>bp.E_cell_X</c> and <c>bp.T_cell_X</c> for the individual cell voltages and volume-averaged cell temperatures, where <c>X</c> represents the cell number. Add probes for these variables as follows:
//    In the Definitions toolbar, click Probes and choose Global Variable Probe.

    model.component("comp1").probe().create("var1", "GlobalVariable");

//    In the Settings window for Global Variable Probe, type Temp1 in the Variable name text field.

    model.component("comp1").probe("var1").set("probename", "Temp1");

//    In the Label text field, type Temperature Cell 1.

    model.component("comp1").probe("var1").label("Temperature Cell 1");

//    Locate the Expression section.
//    In the Expression text field, type bp.T_cell_1.

    model.component("comp1").probe("var1").set("expr", "bp.T_cell_1");

//    In the Table and plot unit field, type degC.

    model.component("comp1").probe("var1").set("unit", "degC");

//    Select the Description checkbox.

    model.component("comp1").probe("var1").set("descractive", true);

//    In the associated text field, type Cell 1.

    model.component("comp1").probe("var1").set("descr", "Cell 1");

//    Click to expand the Table and Window Settings section.
//    Click Add Table.

    model.result().table().create("tbl1", "Table");

    model.component("comp1").probe("var1").set("table", "tbl1");

//    From the Plot window list, select New window.

    model.component("comp1").probe("var1").set("window", "new");

//    Click Add Plot Window.

    model.component("comp1").probe("var1").set("window", "window1");
    model.component("comp1").probe("var1").set("windowtitle", "Probe Plot 1");

//    Right-click Temperature Cell 1 and choose Duplicate.

    model.component("comp1").probe().duplicate("var2", "var1");

//    In the Settings window for Global Variable Probe, type Temperature Cell 2 in the Label text field.

    model.component("comp1").probe("var2").label("Temperature Cell 2");

//    In the Variable name text field, type Temp2.

    model.component("comp1").probe("var2").set("probename", "Temp2");

//    Locate the Expression section.
//    In the Expression text field, type bp.T_cell_2.

    model.component("comp1").probe("var2").set("expr", "bp.T_cell_2");

//    In the Description text field, type Cell 2.

    model.component("comp1").probe("var2").set("descr", "Cell 2");

//    Right-click Temperature Cell 2 and choose Duplicate.

    model.component("comp1").probe().duplicate("var3", "var2");

//    In the Settings window for Global Variable Probe, type Temperature Cell 3 in the Label text field.

    model.component("comp1").probe("var3").label("Temperature Cell 3");

    return model;
  }

  public static Model run2(Model model) {

//    In the Variable name text field, type Temp3.

    model.component("comp1").probe("var3").set("probename", "Temp3");

//    Locate the Expression section.
//    In the Expression text field, type bp.T_cell_3.

    model.component("comp1").probe("var3").set("expr", "bp.T_cell_3");

//    In the Description text field, type Cell 3.

    model.component("comp1").probe("var3").set("descr", "Cell 3");

//    Right-click Temperature Cell 3 and choose Duplicate.

    model.component("comp1").probe().duplicate("var4", "var3");

//    In the Settings window for Global Variable Probe, type Cell Potential 1 in the Label text field.

    model.component("comp1").probe("var4").label("Cell Potential 1");

//    In the Variable name text field, type Ecell1.

    model.component("comp1").probe("var4").set("probename", "Ecell1");

//    Locate the Expression section.
//    In the Expression text field, type bp.E_cell_1.

    model.component("comp1").probe("var4").set("expr", "bp.E_cell_1");

//    In the Description text field, type Cell 1.

    model.component("comp1").probe("var4").set("descr", "Cell 1");

//    Locate the Table and Window Settings section.
//    Click Add Table.

    model.result().table().create("tbl2", "Table");

    model.component("comp1").probe("var4").set("table", "tbl2");

//    From the Plot window list, select New window.

    model.component("comp1").probe("var4").set("window", "new");

//    Click Add Plot Window.

    model.component("comp1").probe("var4").set("window", "window2");
    model.component("comp1").probe("var4").set("windowtitle", "Probe Plot 2");

//    Right-click Cell Potential 1 and choose Duplicate.

    model.component("comp1").probe().duplicate("var5", "var4");

//    In the Settings window for Global Variable Probe, type Cell Potential 2 in the Label text field.

    model.component("comp1").probe("var5").label("Cell Potential 2");

//    In the Variable name text field, type Ecell2.

    model.component("comp1").probe("var5").set("probename", "Ecell2");

//    Locate the Expression section.
//    In the Expression text field, type bp.E_cell_2.

    model.component("comp1").probe("var5").set("expr", "bp.E_cell_2");

//    In the Description text field, type Cell 2.

    model.component("comp1").probe("var5").set("descr", "Cell 2");

//    Right-click Cell Potential 2 and choose Duplicate.

    model.component("comp1").probe().duplicate("var6", "var5");

//    In the Settings window for Global Variable Probe, type Cell Potential 3 in the Label text field.

    model.component("comp1").probe("var6").label("Cell Potential 3");

//    In the Variable name text field, type Ecell3.

    model.component("comp1").probe("var6").set("probename", "Ecell3");

//    Locate the Expression section.
//    In the Expression text field, type bp.E_cell_3.

    model.component("comp1").probe("var6").set("expr", "bp.E_cell_3");

//    In the Description text field, type Cell 3.

    model.component("comp1").probe("var6").set("descr", "Cell 3");

//    In the Model Builder window, under Study 1, click Step 1: Time Dependent.
//    In the Settings window for Time Dependent, locate the Study Settings section.
//    From the Time unit list, select h.

    model.study("std1").feature("time").set("tunit", "h");

//    In the Output times text field, type 0 0.8/C_rate.

    model.study("std1").feature("time").set("tlist", "0 0.8/C_rate");

//    In the Study toolbar, click Compute.

    model.study("std1").createAutoSequences("all");

    model.component("comp1").probe("var1").genResult("none");
    model.component("comp1").probe("var2").genResult("none");
    model.component("comp1").probe("var3").genResult("none");
    model.component("comp1").probe("var4").genResult("none");
    model.component("comp1").probe("var5").genResult("none");
    model.component("comp1").probe("var6").genResult("none");

    model.sol("sol1").runAll();

    model.result().create("pg3", "PlotGroup1D");
    model.result("pg3").set("data", "dset1");
    model.result("pg3").create("glob1", "Global");
    model.result("pg3").feature("glob1").set("unit", new String[]{"", "", ""});
    model.result("pg3").feature("glob1")
         .set("expr", new String[]{"bp.E_cell_max", "bp.E_cell_avg", "bp.E_cell_min"});
    model.result("pg3").feature("glob1").set("descr", new String[]{"Cell voltage", "Cell voltage", "Cell voltage"});
    model.result("pg3").label("Cell Voltage (bp)");
    model.result("pg3").feature("glob1").set("legendmethod", "manual");
    model.result("pg3").feature("glob1").setIndex("legends", "E<sub>max</sub>", 0);
    model.result("pg3").feature("glob1").setIndex("legends", "E<sub>avg</sub>", 1);
    model.result("pg3").feature("glob1").setIndex("legends", "E<sub>min</sub>", 2);
    model.result("pg3").create("glob2", "Global");
    model.result("pg3").feature("glob2").set("unit", new String[]{"", "", ""});
    model.result("pg3").feature("glob2").set("expr", new String[]{"bp.I_app_max", "bp.I_app_avg", "bp.I_app_min"});
    model.result("pg3").feature("glob2")
         .set("descr", new String[]{"Applied cell current", "Applied cell current", "Applied cell current"});
    model.result("pg3").feature("glob2").set("linestyle", "dashed");
    model.result("pg3").feature("glob2").set("linecolor", "cyclereset");
    model.result("pg3").feature("glob2").set("legendmethod", "manual");
    model.result("pg3").feature("glob2").setIndex("legends", "I<sub>max</sub>", 0);
    model.result("pg3").feature("glob2").setIndex("legends", "I<sub>avg</sub>", 1);
    model.result("pg3").feature("glob2").setIndex("legends", "I<sub>min</sub>", 2);
    model.result("pg3").set("twoyaxes", true);
    model.result("pg3").setIndex("plotonsecyaxis", true, 1, 1);
    model.result("pg3").set("titletype", "none");
    model.result().create("pg4", "PlotGroup1D");
    model.result("pg4").set("data", "dset1");
    model.result("pg4").create("glob1", "Global");
    model.result("pg4").feature("glob1").set("unit", new String[]{"", "", ""});
    model.result("pg4").feature("glob1").set("expr", new String[]{"bp.SOC_max", "bp.SOC_avg", "bp.SOC_min"});
    model.result("pg4").feature("glob1")
         .set("descr", new String[]{"State of charge", "State of charge", "State of charge"});
    model.result("pg4").label("State of Charge (bp)");
    model.result("pg4").feature("glob1").set("legendmethod", "manual");
    model.result("pg4").feature("glob1").setIndex("legends", "SOC<sub>max</sub>", 0);
    model.result("pg4").feature("glob1").setIndex("legends", "SOC<sub>avg</sub>", 1);
    model.result("pg4").feature("glob1").setIndex("legends", "SOC<sub>min</sub>", 2);
    model.result("pg4").create("glob2", "Global");
    model.result("pg4").feature("glob2").set("unit", new String[]{"", "", ""});
    model.result("pg4").feature("glob2").set("expr", new String[]{"bp.I_app_max", "bp.I_app_avg", "bp.I_app_min"});
    model.result("pg4").feature("glob2")
         .set("descr", new String[]{"Applied cell current", "Applied cell current", "Applied cell current"});
    model.result("pg4").feature("glob2").set("linestyle", "dashed");
    model.result("pg4").feature("glob2").set("linecolor", "cyclereset");
    model.result("pg4").feature("glob2").set("legendmethod", "manual");
    model.result("pg4").feature("glob2").setIndex("legends", "I<sub>max</sub>", 0);
    model.result("pg4").feature("glob2").setIndex("legends", "I<sub>avg</sub>", 1);
    model.result("pg4").feature("glob2").setIndex("legends", "I<sub>min</sub>", 2);
    model.result("pg4").set("twoyaxes", true);
    model.result("pg4").setIndex("plotonsecyaxis", true, 1, 1);
    model.result("pg4").set("titletype", "none");
    model.result().create("pg5", "PlotGroup3D");
    model.result("pg5").set("data", "dset1");
    model.result("pg5").label("Electric Potential (bp)");
    model.result("pg5").create("surf1", "Surface");
    model.result("pg5").feature("surf1").set("expr", new String[]{"phis"});
    model.result().create("pg6", "PlotGroup3D");
    model.result("pg6").label("Temperature (ht)");
    model.result("pg6").set("smooth", "internal");
    model.result("pg6").feature().create("vol1", "Volume");
    model.result("pg6").feature("vol1").set("solutionparams", "parent");
    model.result("pg6").feature("vol1").set("expr", "T");
    model.result("pg6").feature("vol1").set("colortable", "HeatCameraLight");
    model.result("pg6").feature("vol1").set("smooth", "internal");
    model.result("pg6").feature("vol1").set("data", "parent");
    model.result("pg3").run();

//    Add a dataset with a selection and mirror it twice in order to visualize the temperature of the full 6s2p configuration.
//    In the Results toolbar, click More Datasets and choose Solution.

    model.result().dataset().create("dset3", "Solution");

//    In the Results toolbar, click Attributes and choose Selection.
//    In the Settings window for Selection, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Domain.

    model.result().dataset("dset3").selection().geom("geom1", 3);

//    From the Selection list, select Batteries and Conductors.

    model.result().dataset("dset3").selection().named("geom1_unisel2");

//    In the Results toolbar, click More Datasets and choose Mirror 3D.

    model.result().dataset().create("mir1", "Mirror3D");

//    In the Settings window for Mirror 3D, locate the Data section.
//    From the Dataset list, select Study 1/Solution 1 (3) (sol1).

    model.result().dataset("mir1").set("data", "dset3");

//    Locate the Plane Data section.
//    In the X-coordinate text field, type 2.5*(d_batt).

    model.result().dataset("mir1").set("quickx", "2.5*(d_batt)");

//    Right-click Mirror 3D 1 and choose Duplicate.

    model.result().dataset().duplicate("mir2", "mir1");

//    In the Settings window for Mirror 3D, locate the Data section.
//    From the Dataset list, select Mirror 3D 1.

    model.result().dataset("mir2").set("data", "mir1");

//    Locate the Plane Data section.
//    From the Plane list, select zx-planes.

    model.result().dataset("mir2").set("quickplane", "zx");

//    In the y-coordinate text field, type d_batt/2.

    model.result().dataset("mir2").set("quicky", "d_batt/2");

//    Click Plot.

    model.result("pg1").set("window", "window1");
    model.result("pg1").run();

//    In the Model Builder window, expand the Results > Probe Plot Group 1 node, then click Probe Plot Group 1.
//    In the Settings window for 1D Plot Group, type Cell Temperatures vs. Time in the Label text field.

    model.result("pg1").label("Cell Temperatures vs. Time");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg1").set("xlabelactive", true);

//    Select the y-axis label checkbox.

    model.result("pg1").set("ylabelactive", true);

//    In the associated text field, type Cell Temperature (degC).

    model.result("pg1").set("ylabel", "Cell Temperature (degC)");

//    Locate the Legend section.
//    From the Position list, select Lower right.

    model.result("pg1").set("legendpos", "lowerright");

//    In the Cell Temperatures vs. Time toolbar, click Plot.

    model.result("pg1").set("window", "window1");
    model.result("pg1").run();
    model.result("pg2").set("window", "window2");
    model.result("pg2").set("windowtitle", "Probe Plot 2");
    model.result("pg2").run();

//    In the Model Builder window, under Results, click Probe Plot Group 2.
//    In the Settings window for 1D Plot Group, type Cell Potential vs. Time in the Label text field.

    model.result("pg2").label("Cell Potential vs. Time");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg2").set("xlabelactive", true);

//    Select the y-axis label checkbox.

    model.result("pg2").set("ylabelactive", true);

//    In the associated text field, type Cell Potential (V).

    model.result("pg2").set("ylabel", "Cell Potential (V)");

//    In the Cell Potential vs. Time toolbar, click Plot.

    model.result("pg2").set("window", "window2");
    model.result("pg2").set("windowtitle", "Probe Plot 2");
    model.result("pg2").run();

//    In the Results toolbar, click 3D Plot Group.

    model.result().create("pg7", "PlotGroup3D");
    model.result("pg7").run();

//    In the Settings window for 3D Plot Group, locate the Data section.
//    From the Dataset list, select Mirror 3D 2.

    model.result("pg7").set("data", "mir2");

//    In the Label text field, type Temperature.

    model.result("pg7").label("Temperature");

//    Right-click Temperature and choose Surface.

    model.result("pg7").create("surf1", "Surface");
    model.result("pg7").feature("surf1").set("evaluationsettings", "parent");

//    In the Settings window for Surface, click Replace Expression in the upper-right corner of the Expression section.
//    From the menu, choose Component 1 (comp1) > Heat Transfer in Fluids > Temperature > T - Temperature - K.

    model.result("pg7").feature("surf1").set("expr", "T");
    model.result("pg7").feature("surf1").set("descr", "Temperature");

//    Locate the Expression section.
//    In the Unit field, type degC.

    model.result("pg7").feature("surf1").set("unit", "degC");

//    Locate the Coloring and Style section.
//    From the Color table list, select HeatCameraLight.

    model.result("pg7").feature("surf1").set("colortable", "HeatCameraLight");

//    In the Temperature toolbar, click Plot.

    model.result("pg7").run();

//    Click the Zoom Extents button in the Graphics toolbar.

    model.result("pg5").run();

//    In the Model Builder window, right-click Results > Electric Potential (bp) and choose Delete.

    model.result().remove("pg5");
    model.result("pg6").run();

    model.title("Thermal Distribution in a Pack of Cylindrical Batteries");

    model
         .description("This example demonstrates how to model the temperature distribution in a battery pack during a 4C discharge.\n\nThe pack is constructed by first coupling two cylindrical batteries in parallel. Six parallel-connected pairs are then connected in series to create the full pack. (This is also called a 6s2p configuration.)\n\nThe symmetry of the problem is used twice so that only the temperature distribution for three batteries needs to be solved for.\n\nThe Battery Pack interface is used to generate the appropriate heat sources, which are then coupled to one Heat Transfer interface in a 3D geometry.");

    return model;
  }

  public static void main(String[] args) {
    Model model = run();
    run2(model);
  }

}
