/*
 * cyclic_voltammetry_1d.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 15 2026, 14:16 by COMSOL 6.4.0.421. */
public class cyclic_voltammetry_1d {

  public static Model run() {
    Model model = ModelUtil.create("Model");

//    From the File menu, choose New.
//    In the New window, click Model Wizard.
//    In the Model Wizard window, click 1D.
//    In the Select Physics tree, select Electrochemistry > Electroanalysis (tcd).
//    Click Add.
//    This model will solve for the two concentrations of a redox couple, change the default concentration variable names to <c>cA</c> and <c>cB</c>.
//    In the Concentrations (mol/m³) table, enter the following settings:
//    Click Study.
//    In the Select Study tree, select Preset Studies for Selected Physics Interfaces > Cyclic Voltammetry.
//    Click Done.

    model.component().create("comp1", true);

    model.component("comp1").geom().create("geom1", 1);

    model.component("comp1").mesh().create("mesh1");

    model.component("comp1").physics().create("tcd", "TertiaryElectroanalysis", "geom1");
    model.component("comp1").physics("tcd").field("concentration").field("cA");
    model.component("comp1").physics("tcd").field("concentration").component(new String[]{"cA", "cB"});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("DH", new String[][]{{"9.3e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"9.3e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"9.3e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("DOH", new String[][]{{"5.3e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"5.3e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"5.3e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("um", new String[][]{{"1e-13[s*mol/kg]", "0", "0", "0", "1e-13[s*mol/kg]", "0", "0", "0", "1e-13[s*mol/kg]"}, 
         {"1e-13[s*mol/kg]", "0", "0", "0", "1e-13[s*mol/kg]", "0", "0", "0", "1e-13[s*mol/kg]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("umH", new String[][]{{"3.8e-12[s*mol/kg]"}, {"0"}, {"0"}, {"0"}, {"3.8e-12[s*mol/kg]"}, {"0"}, {"0"}, {"0"}, {"3.8e-12[s*mol/kg]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("umOH", new String[][]{{"2.2e-12[s*mol/kg]"}, {"0"}, {"0"}, {"0"}, {"2.2e-12[s*mol/kg]"}, {"0"}, {"0"}, {"0"}, {"2.2e-12[s*mol/kg]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("sigmal", new String[][]{{"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("epsilonr", new String[][]{{"80"}, {"0"}, {"0"}, {"0"}, {"80"}, {"0"}, {"0"}, {"0"}, {"80"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("minput_stress", new String[][]{{"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}, {"0"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("Dm_cA", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("D_cA", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("Dchem_cA", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("Dm_cB", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("D_cB", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});
    model.component("comp1").physics("tcd").feature("ice1")
         .set("Dchem_cB", new String[][]{{"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}, {"0"}, {"0"}, {"0"}, {"1e-9[m^2/s]"}});

    model.study().create("std1");
    model.study("std1").create("cyclv", "CyclicVoltammetry");
    model.study("std1").feature("cyclv").set("initialtime", "0");
    model.study("std1").feature("cyclv").set("solnum", "auto");
    model.study("std1").feature("cyclv").set("notsolnum", "auto");
    model.study("std1").feature("cyclv").set("outputmap", new String[]{});

//    Add the model parameters from a text file.
//    In the Model Builder window, under Global Definitions, click Parameters 1.
//    In the Settings window for Parameters, locate the Parameters section.
//    Click Load from File.
//    Browse to the model's Application Library folder and double-click the file cyclic_voltammetry_1d_parameters.txt.
//    To import content from file, use:
//    model.param().loadFile("FILENAME");
    model.param().set("v", "1[V/s]", "Voltammetric scan rate");
    model.param().set("c_bulk", "1[mmol/L]", "Reactant bulk concentration");
    model.param().set("DA", "1e-9[m^2/s]", "Reactant diffusion coefficient");
    model.param().set("DB", "1e-9[m^2/s]", "Product diffusion coefficient");
    model.param().set("K0", "1e10", "Reaction rate (dimensionless)");
    model.param().set("re", "10[mm]", "Electrode radius");
    model.param().set("i0ref", "9.6485e10[A/m^2]", "Reference exchange current density");
    model.param().set("Cdl", "0.2[F/m^2]", "Double layer capacitance");
    model.param().set("T", "298.15[K]", "Temperature");
    model.param().set("E_vertex1", "-0.4[V]", "Start potential");
    model.param().set("E_vertex2", "0.4[V]", "Switching potential");
    model.param().set("L", "6*sqrt(DA*2*abs(E_vertex1-E_vertex2)/v)", "Outer bound on diffusion layer");
    model.param()
         .set("cB0", "c_bulk/(1+exp(-E_vertex1*F_const/(R_const*T)))", "Initial product concentration at electrode");

//    Build the model geometry as a single interval, where the left boundary will later be defined as the electrode surface, and the right boundary will be the boundary toward the bulk.
//    In the Model Builder window, right-click Component 1 (comp1) > Geometry 1 and choose Interval.

    model.component("comp1").geom("geom1").create("i1", "Interval");

//    Set the interval length to <c>L</c>. The value of <c>L</c> is defined in the Parameters node. Note that <c>L</c> will vary with the Voltammetric scan rate parameter <c>v</c>, which is also defined in the Parameters node.
//    In the Settings window for Interval, locate the Interval section.
//    In the table, enter the following settings:

    model.component("comp1").geom("geom1").feature("i1").setIndex("coord", "L", 1);

//    In the Home toolbar, click Build All.

    model.component("comp1").geom("geom1").run("fin");

//    The completed geometry should now look like this:
//    In the Model Builder window, click Geometry 1.
//    Start defining the physics by setting the diffusion coefficients for the two species of the redox couple.
//    In the Model Builder window, under Component 1 (comp1) > Electroanalysis (tcd), click Electrolyte 1.
//    In the Settings window for Electrolyte, locate the Diffusion section.
//    In the \[D_{\textrm{cA}}\] text field, type DA.

    model.component("comp1").physics("tcd").feature("ice1")
         .set("D_cA", new String[]{"DA", "0", "0", "0", "DA", "0", "0", "0", "DA"});

//    In the \[D_{\textrm{cB}}\] text field, type DB.

    model.component("comp1").physics("tcd").feature("ice1")
         .set("D_cB", new String[]{"DB", "0", "0", "0", "DB", "0", "0", "0", "DB"});

//    Set the boundary to the right to bulk concentration values.
//    In the Physics toolbar, click Boundaries and choose Concentration.

    model.component("comp1").physics("tcd").create("conc1", "Concentration", 0);

//    Select Boundary 2.

    model.component("comp1").physics("tcd").feature("conc1").selection().set(2);

//    In the Settings window for Concentration, locate the Concentration section.
//    Select the Species cA checkbox.

    model.component("comp1").physics("tcd").feature("conc1").setIndex("species", true, 0);

//    In the \[c_{\textrm{0,{cA}}}\] text field, type c_bulk.

    model.component("comp1").physics("tcd").feature("conc1").setIndex("c0", "c_bulk", 0);

//    Select the Species cB checkbox.

    model.component("comp1").physics("tcd").feature("conc1").setIndex("species", true, 1);

//    Set up the electrode surface and the cyclic voltammetry settings on the left boundary.
//    In the Physics toolbar, click Boundaries and choose Electrode Surface.

    model.component("comp1").physics("tcd").create("es1", "ElectrodeSurface", 0);

//    Select Boundary 1.

    model.component("comp1").physics("tcd").feature("es1").selection().set(1);

//    In the Settings window for Electrode Surface, locate the Electrode Phase Potential Condition section.
//    From the Electrode phase potential condition list, select Cyclic voltammetry.

    model.component("comp1").physics("tcd").feature("es1").set("BoundaryCondition", "CyclicVoltammetry");

//    In the Linear sweep rate text field, type v.

    model.component("comp1").physics("tcd").feature("es1").set("sweeprate", "v");

//    The voltage will be cycled between the vertex potentials. When the start potential is not specified, the sweep will start at <l>Vertex potential 2</l>.
//    In the Vertex potential 1 text field, type E_vertex1.

    model.component("comp1").physics("tcd").feature("es1").set("Evertex1", "E_vertex1");

//    In the Vertex potential 2 text field, type E_vertex2.

    model.component("comp1").physics("tcd").feature("es1").set("Evertex2", "E_vertex2");

//    Specify the electrode reaction as a <l>Butler-Volmer</l> reaction, which is concentration dependent as defined by the stoichiometric coefficients.
//    In the Model Builder window, click Electrode Reaction 1.
//    In the Settings window for Electrode Reaction, locate the Stoichiometric Coefficients section.
//    In the \[\nu_{\textrm{cA}}\] text field, type 1.

    model.component("comp1").physics("tcd").feature("es1").feature("er1").setIndex("Vi0", 1, 0);

//    In the \[\nu_{\textrm{cB}}\] text field, type -1.

    model.component("comp1").physics("tcd").feature("es1").feature("er1").setIndex("Vi0", -1, 1);

//    Locate the Electrode Kinetics section.
//    In the \[i_{\textrm{0,ref}}\left(T\right)\] text field, type i0ref.

    model.component("comp1").physics("tcd").feature("es1").feature("er1").set("i0_ref", "i0ref");

//    In the Physics toolbar, click Attributes and choose Double-Layer Capacitance.

    model.component("comp1").physics("tcd").feature("es1").create("dlc1", "DoubleLayerCapacitance", 0);

//    In the Settings window for Double-Layer Capacitance, locate the Double-Layer Capacitance section.
//    In the \[C_{\textrm{dl}}\] text field, type Cdl.

    model.component("comp1").physics("tcd").feature("es1").feature("dlc1").set("Cdl", "Cdl");

//    Specify the initial concentration values. This will set the concentration values when the simulation starts at \[t = 0\].
//    In the Model Builder window, under Component 1 (comp1) > Electroanalysis (tcd), click Initial Values 1.
//    In the Settings window for Initial Values, locate the Initial Values section.
//    In the \[cA\] text field, type c_bulk-cB0*(1-x/L).

    model.component("comp1").physics("tcd").feature("init1").setIndex("initc", "c_bulk-cB0*(1-x/L)", 0);

//    In the \[cB\] text field, type cB0*(1-x/L).

    model.component("comp1").physics("tcd").feature("init1").setIndex("initc", "cB0*(1-x/L)", 1);

//    Set up the temperature value used in the entire model.
//    In the Model Builder window, under Global Definitions, click Default Model Inputs.
//    In the Settings window for Default Model Inputs, locate the Browse Model Inputs section.
//    In the tree, select General > Temperature (K) - minput.T.
//    Find the Expression for remaining selection subsection.
//    In the Temperature text field, type T.

    model.common("cminpt").set("modified", new String[][]{{"temperature", "T"}});

//    Solve the problem for various sweep rates.
//    In the Study toolbar, click Parametric Sweep.

    model.study("std1").create("param", "Parametric");

//    In the Settings window for Parametric Sweep, locate the Study Settings section.
//    Click Add.

    model.study("std1").feature("param").setIndex("pname", "v", 0);
    model.study("std1").feature("param").setIndex("plistarr", "", 0);
    model.study("std1").feature("param").setIndex("punit", "V/s", 0);
    model.study("std1").feature("param").setIndex("pname", "v", 0);
    model.study("std1").feature("param").setIndex("plistarr", "", 0);
    model.study("std1").feature("param").setIndex("punit", "V/s", 0);

//    In the table, enter the following settings:

    model.study("std1").feature("param").setIndex("plistarr", "10^range(-3,1,0)", 0);

//    In the Study toolbar, click Compute.

    model.study("std1").createAutoSequences("all");

    model.sol().create("sol2");
    model.sol("sol2").study("std1");
    model.sol("sol2").label("Parametric Solutions 1");

    model.batch("p1").feature("so1").set("psol", "sol2");
    model.batch("p1").run("compute");

    model.result().create("pg1", "PlotGroup1D");
    model.result("pg1").set("data", "dset2");
    model.result("pg1").create("glob1", "Global");
    model.result("pg1").feature("glob1").set("unit", new String[]{""});
    model.result("pg1").feature("glob1").set("expr", new String[]{"tcd.Itot_es1 "});
    model.result("pg1").feature("glob1").set("descr", new String[]{""});
    model.result("pg1").label("Cyclic Voltammograms (tcd)");
    model.result("pg1").feature("glob1").set("titletype", "none");
    model.result("pg1").feature("glob1").set("xdata", "expr");
    model.result("pg1").feature("glob1").set("xdataexpr", "root.comp1.tcd.phis_es1 ");
    model.result("pg1").feature("glob1").set("xdatadescr", "Electric Potential");
    model.result("pg1").feature("glob1").setIndex("descr", "Total Current", 0);
    model.result("pg1").feature("glob1").set("xdatasolnumtype", "level1");
    model.result().create("pg2", "PlotGroup1D");
    model.result("pg2").set("data", "dset2");
    model.result("pg2").create("glob1", "Global");
    model.result("pg2").feature("glob1").set("unit", new String[]{""});
    model.result("pg2").feature("glob1").set("expr", new String[]{"tcd.phis_es1 "});
    model.result("pg2").feature("glob1").set("descr", new String[]{""});
    model.result("pg2").label("Electrode Potential (tcd)");
    model.result("pg2").feature("glob1").setIndex("descr", "Electric Potential", 0);
    model.result("pg2").feature("glob1").set("xdatasolnumtype", "level1");
    model.result().create("pg3", "PlotGroup1D");
    model.result("pg3").set("data", "dset2");
    model.result("pg3").create("glob1", "Global");
    model.result("pg3").feature("glob1").set("unit", new String[]{""});
    model.result("pg3").feature("glob1").set("expr", new String[]{"tcd.itotavg_es1 "});
    model.result("pg3").feature("glob1").set("descr", new String[]{""});
    model.result("pg3").label("Average Current Density (tcd)");
    model.result("pg3").feature("glob1").setIndex("descr", "Current Density", 0);
    model.result("pg3").feature("glob1").set("xdatasolnumtype", "level1");
    model.result().create("pg4", "PlotGroup1D");
    model.result("pg4").set("data", "dset2");
    model.result("pg4").set("titletype", "manual");
    model.result("pg4").set("title", "Concentrations, All Species");
    model.result("pg4").label("Concentrations, All Species (tcd)");
    model.result("pg4").create("lngr1", "LineGraph");
    model.result("pg4").feature("lngr1").set("xdata", "expr");
    model.result("pg4").feature("lngr1").set("xdataexpr", "x");
    model.result("pg4").feature("lngr1").selection().geom("geom1", 1);
    model.result("pg4").feature("lngr1").selection().set(1);
    model.result("pg4").feature("lngr1").set("expr", new String[]{"cA"});
    model.result("pg4").feature("lngr1").label("Species A");
    model.result("pg4").feature("lngr1").set("legend", true);
    model.result("pg4").feature("lngr1").set("autosolution", false);
    model.result("pg4").feature("lngr1").set("autoexpr", false);
    model.result("pg4").feature("lngr1").set("autodescr", false);
    model.result("pg4").feature("lngr1").set("legendprefix", "A ");
    model.result("pg4").feature("lngr1").set("descractive", true);
    model.result("pg4").feature("lngr1").set("descr", "Concentration");
    model.result("pg4").create("lngr2", "LineGraph");
    model.result("pg4").feature("lngr2").set("xdata", "expr");
    model.result("pg4").feature("lngr2").set("xdataexpr", "x");
    model.result("pg4").feature("lngr2").selection().geom("geom1", 1);
    model.result("pg4").feature("lngr2").selection().set(1);
    model.result("pg4").feature("lngr2").set("expr", new String[]{"cB"});
    model.result("pg4").feature("lngr2").label("Species B");
    model.result("pg4").feature("lngr2").set("legend", true);
    model.result("pg4").feature("lngr2").set("autosolution", false);
    model.result("pg4").feature("lngr2").set("autoexpr", false);
    model.result("pg4").feature("lngr2").set("autodescr", false);
    model.result("pg4").feature("lngr2").set("legendprefix", "B ");
    model.result("pg4").feature("lngr2").set("descractive", true);
    model.result("pg4").feature("lngr2").set("descr", "Concentration");
    model.result().create("pg5", "PlotGroup1D");
    model.result("pg5").set("data", "dset2");
    model.result("pg5").label("Concentration, A (tcd)");
    model.result("pg5").set("titletype", "custom");
    model.result("pg5").set("prefixintitle", "");
    model.result("pg5").set("expressionintitle", false);
    model.result("pg5").set("typeintitle", false);
    model.result("pg5").create("lngr1", "LineGraph");
    model.result("pg5").feature("lngr1").set("xdata", "expr");
    model.result("pg5").feature("lngr1").set("xdataexpr", "x");
    model.result("pg5").feature("lngr1").selection().geom("geom1", 1);
    model.result("pg5").feature("lngr1").selection().set(1);
    model.result("pg5").feature("lngr1").set("expr", new String[]{"cA"});
    model.result().create("pg6", "PlotGroup1D");
    model.result("pg6").set("data", "dset2");
    model.result("pg6").label("Concentration, B (tcd)");
    model.result("pg6").set("titletype", "custom");
    model.result("pg6").set("prefixintitle", "");
    model.result("pg6").set("expressionintitle", false);
    model.result("pg6").set("typeintitle", false);
    model.result("pg6").create("lngr1", "LineGraph");
    model.result("pg6").feature("lngr1").set("xdata", "expr");
    model.result("pg6").feature("lngr1").set("xdataexpr", "x");
    model.result("pg6").feature("lngr1").selection().geom("geom1", 1);
    model.result("pg6").feature("lngr1").selection().set(1);
    model.result("pg6").feature("lngr1").set("expr", new String[]{"cB"});
    model.result("pg1").run();

//    A number of plots are created by default. The first default plot shows the voltammograms created by the <l>Cyclic Voltammetry</l> feature in the <l>Electrode Surface</l> node.
//    In the Settings window for 1D Plot Group, locate the Legend section.
//    From the Position list, select Upper left.

    model.result("pg1").set("legendpos", "upperleft");
    model.result("pg1").run();

//    In the Model Builder window, expand the Cyclic Voltammograms (tcd) node, then click Global 1.
//    In the Settings window for Global, click to expand the Legends section.
//    Find the Include subsection.
//    Clear the Description checkbox.

    model.result("pg1").feature("glob1").set("autodescr", false);

//    In the Cyclic Voltammograms (tcd) toolbar, click Plot.

    model.result("pg1").run();
    model.result("pg2").run();
    model.result("pg2").setIndex("looplevelinput", "first", 1);
    model.result("pg2").set("titletype", "none");
    model.result("pg2").run();
    model.result("pg2").feature("glob1").set("autodescr", false);
    model.result("pg2").run();
    model.result("pg3").run();
    model.result("pg3").setIndex("looplevelinput", "first", 1);
    model.result("pg4").run();
    model.result().remove("pg4");
    model.result("pg5").run();
    model.result().remove("pg5");
    model.result("pg6").run();
    model.result().remove("pg6");
    model.result("pg1").run();

    model.title("Cyclic Voltammetry at a Macroelectrode in 1D");

    model
         .description("The example models cyclic voltammetry at an electrode of mm dimensions. In this common analytical electrochemistry technique, the potential at a working electrode is swept up and down and the current is recorded. The current\u2013voltage waveform (the voltammogram) gives information about the reactivity and mass transport properties of the analyte.\n\nThis model forms the basis of an Electrochemistry Module Application Library app with the same title.");

    return model;
  }

  public static void main(String[] args) {
    run();
  }

}
