/*
 * sheet_metal_forming.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 12 2026, 11:56 by COMSOL 6.4.0.418. */
public class sheet_metal_forming {

  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 2D.
//    In the Select Physics tree, select Structural Mechanics > Solid Mechanics (solid).
//    Click Add.
//    Click Study.
//    In the Select Study tree, select General Studies > Stationary.
//    Click Done.

    model.component().create("comp1", true);

    model.component("comp1").geom().create("geom1", 2);

    model.component("comp1").mesh().create("mesh1");

    model.component("comp1").physics().create("solid", "SolidMechanics", "geom1");

    model.study().create("std1");
    model.study("std1").create("stat", "Stationary");

//    Load all model parameters from a file containing parameters for the geometry and some material properties.
//    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 sheet_metal_forming_parameters.txt.
//    To import content from file, use:
//    model.param().loadFile("FILENAME");
    model.param().set("R1", "23.5[mm]", "Punch radius");
    model.param().set("R2", "25[mm]", "Die radius");
    model.param().set("R3", "4[mm]", "Die shoulder");
    model.param().set("L", "60[mm]", "Sheet length");
    model.param().set("th", "1[mm]", "Sheet thickness");
    model.param().set("w_sheet", "30[mm]", "Sheet width");
    model.param().set("w_tools", "50[mm]", "Tools width");
    model.param().set("para", "0", "Punch displacement parameter");
    model.param().set("punch_max", "28.5", "Punch stroke");
    model.param().set("K", "550.4[MPa]", "Hollomon hardening parameter");
    model.param().set("n", "0.223", "Strain hardening exponent");
    model.param().set("sigma0", "194[MPa]", "Initial yield stress");
    model.param().set("eps0", "3e-2", "Smoothing function strain parameter");

//    In the Model Builder window, right-click Global Definitions and choose Geometry Parts > 2D Part.

    model.geom().create("part1", "Part", 2);

//    Now build a 2D section of the model geometry, starting with the blank geometry.
//    In the Geometry toolbar, click Rectangle.

    model.geom("part1").create("r1", "Rectangle");

//    In the Settings window for Rectangle, locate the Size and Shape section.
//    In the Width text field, type L.

    model.geom("part1").feature("r1").set("size", new String[]{"L", "1"});

//    In the Height text field, type th.

    model.geom("part1").feature("r1").set("size", new String[]{"L", "th"});

//    Add an extra domain to get better mesh control in the blank.
//    Click to expand the Layers section.
//    In the table, enter the following settings:

    model.geom("part1").feature("r1").setIndex("layername", "Layer 1", 0);
    model.geom("part1").feature("r1").setIndex("layer", "40[mm]", 0);

//    Select the Layers to the left checkbox.

    model.geom("part1").feature("r1").set("layerleft", true);

//    Clear the Layers on bottom checkbox.

    model.geom("part1").feature("r1").set("layerbottom", false);

//    Click Build Selected.

    model.geom("part1").run("r1");

//    Continue with the punch geometry.
//    In the Geometry toolbar, click Circle.

    model.geom("part1").create("c1", "Circle");

//    In the Settings window for Circle, locate the Size and Shape section.
//    In the Radius text field, type R1.

    model.geom("part1").feature("c1").set("r", "R1");

//    In the Sector angle text field, type 90.

    model.geom("part1").feature("c1").set("angle", 90);

//    Locate the Position section.
//    In the y text field, type R1+th.

    model.geom("part1").feature("c1").set("pos", new String[]{"0", "R1+th"});

//    Locate the Rotation Angle section.
//    In the Rotation text field, type -90.

    model.geom("part1").feature("c1").set("rot", -90);

//    Click to expand the Layers section.
//    In the table, enter the following settings:

    model.geom("part1").feature("c1").setIndex("layername", "Layer 1", 0);
    model.geom("part1").feature("c1").setIndex("layer", "th", 0);

//    Click Build Selected.

    model.geom("part1").run("c1");

//    Finally, draw the die geometry.
//    In the Geometry toolbar, click Circle.

    model.geom("part1").create("c2", "Circle");

//    In the Settings window for Circle, locate the Size and Shape section.
//    In the Radius text field, type R2+th.

    model.geom("part1").feature("c2").set("r", "R2+th");

//    In the Sector angle text field, type 90.

    model.geom("part1").feature("c2").set("angle", 90);

//    Locate the Position section.
//    In the y text field, type -R3.

    model.geom("part1").feature("c2").set("pos", new String[]{"0", "-R3"});

//    Locate the Rotation Angle section.
//    In the Rotation text field, type -90.

    model.geom("part1").feature("c2").set("rot", -90);

//    Locate the Layers section.
//    In the table, enter the following settings:

    model.geom("part1").feature("c2").setIndex("layername", "Layer 1", 0);
    model.geom("part1").feature("c2").setIndex("layer", "th", 0);

//    Click Build Selected.

    model.geom("part1").run("c2");

//    In the Geometry toolbar, click Circle.

    model.geom("part1").create("c3", "Circle");

//    In the Settings window for Circle, locate the Size and Shape section.
//    In the Radius text field, type R3.

    model.geom("part1").feature("c3").set("r", "R3");

//    In the Sector angle text field, type 90.

    model.geom("part1").feature("c3").set("angle", 90);

//    Locate the Position section.
//    In the x text field, type R2+R3.

    model.geom("part1").feature("c3").set("pos", new String[]{"R2+R3", "0"});

//    In the y text field, type -R3.

    model.geom("part1").feature("c3").set("pos", new String[]{"R2+R3", "-R3"});

//    Locate the Rotation Angle section.
//    In the Rotation text field, type 90.

    model.geom("part1").feature("c3").set("rot", 90);

//    Locate the Layers section.
//    In the table, enter the following settings:

    model.geom("part1").feature("c3").setIndex("layername", "Layer 1", 0);
    model.geom("part1").feature("c3").setIndex("layer", "th", 0);

//    Click Build Selected.

    model.geom("part1").run("c3");

//    In the Geometry toolbar, click Rectangle.

    model.geom("part1").create("r2", "Rectangle");

//    In the Settings window for Rectangle, locate the Size and Shape section.
//    In the Width text field, type 1[cm].

    model.geom("part1").feature("r2").set("size", new String[]{"1[cm]", "1"});

//    In the Height text field, type th.

    model.geom("part1").feature("r2").set("size", new String[]{"1[cm]", "th"});

//    Locate the Position section.
//    In the x text field, type R2+R3.

    model.geom("part1").feature("r2").set("pos", new String[]{"R2+R3", "0"});

//    In the y text field, type -th.

    model.geom("part1").feature("r2").set("pos", new String[]{"R2+R3", "-th"});

//    Click Build Selected.

    model.geom("part1").run("r2");

//    In the Model Builder window, right-click Part 1 and choose Delete Entities.

    model.geom("part1").create("del1", "Delete");

//    In the Settings window for Delete Entities, locate the Entities or Objects to Delete section.
//    From the Geometric entity level list, select Domain.

    model.geom("part1").feature("del1").selection("input").init(2);

//    On the object c1, select Domain 1.

    model.geom("part1").feature("del1").selection("input").set("c1", 1);
    model.geom("part1").feature("del1").selection("input").set("c2", 1);
    model.geom("part1").feature("del1").selection("input").set("c3", 1);

//    On the object c2, select Domain 1.
//    On the object c3, select Domain 1.
//    Click Build Selected.

    model.geom("part1").run("del1");

//    In the Geometry toolbar, click Booleans and Partitions and choose Union.

    model.geom("part1").create("uni1", "Union");

//    Select the objects del1(2), del1(3), r2.

    model.geom("part1").feature("uni1").selection("input").set("del1(2)", "del1(3)", "r2");

//    In the Geometry toolbar, click Part Instance and choose Part 1.

    model.component("comp1").geom("geom1").create("pi1", "PartInstance");
    model.component("comp1").geom("geom1").feature("pi1").set("selkeepnoncontr", false);
    model.component("comp1").geom("geom1").feature("pi1").set("part", "part1");

//    In the Settings window for Part Instance, click Build Selected.

    model.component("comp1").geom("geom1").run("pi1");

//    In the Model Builder window, under Component 1 (comp1) > Geometry 1, click Form Union (fin).
//    In the Settings window for Form Union/Assembly, locate the Form Union/Assembly section.
//    From the Action list, select Form an assembly.

    model.component("comp1").geom("geom1").feature("fin").set("action", "assembly");

//    Clear the Create pairs checkbox.

    model.component("comp1").geom("geom1").feature("fin").set("createpairs", false);

//    Click Build Selected.

    model.component("comp1").geom("geom1").run("fin");

//    You can now add contact pairs to define on which boundary you expect the contact to happen.
//    In the Definitions toolbar, click Pairs and choose Contact Pair.

    model.component("comp1").pair().create("p1", "Contact");

//    Select Boundary 20.

    model.component("comp1").pair("p1").source().set(20);

//    In the Settings window for Pair, locate the Destination Boundaries section.
//    Select the Activate Selection toggle button.
//    Select Boundary 13.

    model.component("comp1").pair("p1").destination().set(13);

//    In the Definitions toolbar, click Pairs and choose Contact Pair.

    model.component("comp1").pair().create("p2", "Contact");

//    Select Boundaries 5, 8, 9.

    model.component("comp1").pair("p2").source().set(5, 8, 9);

//    In the Settings window for Pair, locate the Destination Boundaries section.
//    Select the Activate Selection toggle button.
//    Select Boundary 12.

    model.component("comp1").pair("p2").destination().set(12);

//    To define the punch displacement for the loading and the unloading stages, use an interpolation function that makes the displacement a function of a monotonic parameter.
//    In the Home toolbar, click Functions and choose Global > Interpolation.

    model.func().create("int1", "Interpolation");

//    In the Settings window for Interpolation, locate the Definition section.
//    In the Function name text field, type punch.

    model.func("int1").set("funcname", "punch");

//    In the table, enter the following settings:

    model.func("int1").setIndex("table", 0, 0, 0);
    model.func("int1").setIndex("table", 0, 0, 1);
    model.func("int1").setIndex("table", 0.98, 1, 0);
    model.func("int1").setIndex("table", "-punch_max", 1, 1);
    model.func("int1").setIndex("table", 1, 2, 0);
    model.func("int1").setIndex("table", "-punch_max", 2, 1);
    model.func("int1").setIndex("table", 2, 3, 0);
    model.func("int1").setIndex("table", 0, 3, 1);
    model.func("int1").setIndex("fununit", "mm", 0);

//    Locate the Units section.
//    In the Function table, enter the following settings:

    model.func("int1").setIndex("argunit", 1, 0);

//    In the Argument table, enter the following settings:
//    In the Materials toolbar, click Add Material to open the Add Material window.
//    In the tree, select Built-in > Structural steel.
//    Right-click and choose Add to Global Materials.

    model.material().create("mat1", "Common", "");
    model.material("mat1").propertyGroup().create("Enu", "Enu", "Young's modulus and Poisson's ratio");
    model.material("mat1").propertyGroup("Enu").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup("Enu").func().create("int2", "Interpolation");
    model.material("mat1").propertyGroup().create("Murnaghan", "Murnaghan", "Murnaghan");
    model.material("mat1").propertyGroup()
         .create("ElastoplasticModel", "ElastoplasticModel", "Elastoplastic material model");
    model.material("mat1").propertyGroup("ElastoplasticModel").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup().create("Ludwik", "Ludwik", "Ludwik");
    model.material("mat1").propertyGroup("Ludwik").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup().create("JohnsonCook", "JohnsonCook", "Johnson-Cook");
    model.material("mat1").propertyGroup().create("Swift", "Swift", "Swift");
    model.material("mat1").propertyGroup().create("Voce", "Voce", "Voce");
    model.material("mat1").propertyGroup("Voce").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup().create("HockettSherby", "HockettSherby", "Hockett-Sherby");
    model.material("mat1").propertyGroup("HockettSherby").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup().create("ArmstrongFrederick", "ArmstrongFrederick", "Armstrong-Frederick");
    model.material("mat1").propertyGroup("ArmstrongFrederick").func().create("int1", "Interpolation");
    model.material("mat1").propertyGroup().create("Norton", "Norton", "Norton");
    model.material("mat1").propertyGroup().create("Garofalo", "Garofalo", "Garofalo (hyperbolic sine)");
    model.material("mat1").propertyGroup()
         .create("ChabocheViscoplasticity", "ChabocheViscoplasticity", "Chaboche viscoplasticity");
    model.material("mat1").label("Structural steel");
    model.material("mat1").set("family", "custom");
    model.material("mat1")
         .set("customspecular", new double[]{0.7843137254901961, 0.7843137254901961, 0.7843137254901961});
    model.material("mat1").set("diffuse", "custom");
    model.material("mat1")
         .set("customdiffuse", new double[]{0.6666666666666666, 0.6666666666666666, 0.6666666666666666});
    model.material("mat1").set("ambient", "custom");
    model.material("mat1")
         .set("customambient", new double[]{0.6666666666666666, 0.6666666666666666, 0.6666666666666666});
    model.material("mat1").set("noise", true);
    model.material("mat1").set("fresnel", 0.9);
    model.material("mat1").set("roughness", 0.3);
    model.material("mat1").set("diffusewrap", 0);
    model.material("mat1").set("reflectance", 0);
    model.material("mat1").propertyGroup("def").set("lossfactor", "0.02");
    model.material("mat1").propertyGroup("def")
         .set("relpermeability", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.material("mat1").propertyGroup("def").set("heatcapacity", "475[J/(kg*K)]");
    model.material("mat1").propertyGroup("def")
         .set("thermalconductivity", new String[]{"44.5[W/(m*K)]", "0", "0", "0", "44.5[W/(m*K)]", "0", "0", "0", "44.5[W/(m*K)]"});
    model.material("mat1").propertyGroup("def")
         .set("electricconductivity", new String[]{"4.032e6[S/m]", "0", "0", "0", "4.032e6[S/m]", "0", "0", "0", "4.032e6[S/m]"});
    model.material("mat1").propertyGroup("def")
         .set("relpermittivity", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.material("mat1").propertyGroup("def")
         .set("thermalexpansioncoefficient", new String[]{"12.3e-6[1/K]", "0", "0", "0", "12.3e-6[1/K]", "0", "0", "0", "12.3e-6[1/K]"});
    model.material("mat1").propertyGroup("def").set("density", "7850[kg/m^3]");
    model.material("mat1").propertyGroup("Enu").func("int1").set("funcname", "E");
    model.material("mat1").propertyGroup("Enu").func("int1")
         .set("table", new String[][]{{"293.15", "200e9"}, {"793.15", "166.6e9"}});
    model.material("mat1").propertyGroup("Enu").func("int1").set("extrap", "linear");
    model.material("mat1").propertyGroup("Enu").func("int1").set("fununit", new String[]{"Pa"});
    model.material("mat1").propertyGroup("Enu").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("Enu").func("int2").set("funcname", "nu");
    model.material("mat1").propertyGroup("Enu").func("int2")
         .set("table", new String[][]{{"293.15", "0.30"}, {"793.15", "0.315"}});
    model.material("mat1").propertyGroup("Enu").func("int2").set("extrap", "linear");
    model.material("mat1").propertyGroup("Enu").func("int2").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("Enu").func("int2").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("Enu").set("E", "E(T)");
    model.material("mat1").propertyGroup("Enu").set("nu", "nu(T)");
    model.material("mat1").propertyGroup("Enu").addInput("temperature");
    model.material("mat1").propertyGroup("Murnaghan").set("l", "-3.0e11[Pa]");
    model.material("mat1").propertyGroup("Murnaghan").set("m", "-6.2e11[Pa]");
    model.material("mat1").propertyGroup("Murnaghan").set("n", "-7.2e11[Pa]");
    model.material("mat1").propertyGroup("ElastoplasticModel").func("int1").set("funcname", "a");
    model.material("mat1").propertyGroup("ElastoplasticModel").func("int1")
         .set("table", new String[][]{{"600", "1"}, {"1100", "0.1"}, {"1643", "0"}});
    model.material("mat1").propertyGroup("ElastoplasticModel").func("int1").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("ElastoplasticModel").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("ElastoplasticModel").set("sigmags", "350[MPa]*a(T)");
    model.material("mat1").propertyGroup("ElastoplasticModel").set("Et", "1.045[GPa]*a(T)");
    model.material("mat1").propertyGroup("ElastoplasticModel").set("Ek", "1.045[GPa]*a(T)");
    model.material("mat1").propertyGroup("ElastoplasticModel").set("sigmagh", "1.050[GPa]*epe*a(T)");
    model.material("mat1").propertyGroup("ElastoplasticModel")
         .set("Hillcoefficients", new String[]{"0[m^2*s^4/kg^2]", "0[m^2*s^4/kg^2]", "0[m^2*s^4/kg^2]", "0[m^2*s^4/kg^2]", "0[m^2*s^4/kg^2]", "0[m^2*s^4/kg^2]"});
    model.material("mat1").propertyGroup("ElastoplasticModel")
         .set("ys", new String[]{"0[N/m^2]", "0[N/m^2]", "0[N/m^2]", "0[N/m^2]", "0[N/m^2]", "0[N/m^2]"});
    model.material("mat1").propertyGroup("ElastoplasticModel").addInput("temperature");
    model.material("mat1").propertyGroup("ElastoplasticModel").addInput("effectiveplasticstrain");
    model.material("mat1").propertyGroup("Ludwik").func("int1").set("funcname", "a");
    model.material("mat1").propertyGroup("Ludwik").func("int1")
         .set("table", new String[][]{{"600", "1"}, {"1100", "0.1"}, {"1643", "0"}});
    model.material("mat1").propertyGroup("Ludwik").func("int1").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("Ludwik").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("Ludwik").set("k_lud", "560[MPa]*a(T)");
    model.material("mat1").propertyGroup("Ludwik").set("n_lud", "0.61");
    model.material("mat1").propertyGroup("Ludwik").addInput("temperature");
    model.material("mat1").propertyGroup("JohnsonCook").label("Johnson-Cook");
    model.material("mat1").propertyGroup("JohnsonCook").set("k_jcook", "560[MPa]");
    model.material("mat1").propertyGroup("JohnsonCook").set("n_jcook", "0.61");
    model.material("mat1").propertyGroup("JohnsonCook").set("C_jcook", "0.12");
    model.material("mat1").propertyGroup("JohnsonCook").set("epet0_jcook", "1[1/s]");
    model.material("mat1").propertyGroup("JohnsonCook").set("m_jcook", "0.6");
    model.material("mat1").propertyGroup("Swift").set("e0_swi", "0.021");
    model.material("mat1").propertyGroup("Swift").set("n_swi", "0.2");
    model.material("mat1").propertyGroup("Voce").func("int1").set("funcname", "a");
    model.material("mat1").propertyGroup("Voce").func("int1")
         .set("table", new String[][]{{"600", "1"}, {"1100", "0.1"}, {"1643", "0"}});
    model.material("mat1").propertyGroup("Voce").func("int1").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("Voce").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("Voce").set("sigma_voc", "249[MPa]*a(T)");
    model.material("mat1").propertyGroup("Voce").set("beta_voc", "9.3");
    model.material("mat1").propertyGroup("Voce").addInput("temperature");
    model.material("mat1").propertyGroup("HockettSherby").label("Hockett-Sherby");
    model.material("mat1").propertyGroup("HockettSherby").func("int1").set("funcname", "a");
    model.material("mat1").propertyGroup("HockettSherby").func("int1")
         .set("table", new String[][]{{"600", "1"}, {"1100", "0.1"}, {"1643", "0"}});
    model.material("mat1").propertyGroup("HockettSherby").func("int1").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("HockettSherby").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("HockettSherby").set("sigma_hoc", "684[MPa]*a(T)");
    model.material("mat1").propertyGroup("HockettSherby").set("m_hoc", "3.9");
    model.material("mat1").propertyGroup("HockettSherby").set("n_hoc", "0.85");
    model.material("mat1").propertyGroup("HockettSherby").addInput("temperature");
    model.material("mat1").propertyGroup("ArmstrongFrederick").label("Armstrong-Frederick");
    model.material("mat1").propertyGroup("ArmstrongFrederick").func("int1").set("funcname", "a");
    model.material("mat1").propertyGroup("ArmstrongFrederick").func("int1")
         .set("table", new String[][]{{"600", "1"}, {"1100", "0.1"}, {"1643", "0"}});
    model.material("mat1").propertyGroup("ArmstrongFrederick").func("int1").set("fununit", new String[]{"1"});
    model.material("mat1").propertyGroup("ArmstrongFrederick").func("int1").set("argunit", new String[]{"K"});
    model.material("mat1").propertyGroup("ArmstrongFrederick").set("Ck", "2.070[GPa]*a(T)");
    model.material("mat1").propertyGroup("ArmstrongFrederick").set("gammak", "8.0");
    model.material("mat1").propertyGroup("ArmstrongFrederick").addInput("temperature");
    model.material("mat1").propertyGroup("Norton").set("A_nor", "1.2e-15[1/s]");
    model.material("mat1").propertyGroup("Norton").set("sigRef_nor", "1[MPa]");
    model.material("mat1").propertyGroup("Norton").set("n_nor", "4.5");
    model.material("mat1").propertyGroup("Garofalo").set("A_gar", "1e-6[1/s]");
    model.material("mat1").propertyGroup("Garofalo").set("sigRef_gar", "100[MPa]");
    model.material("mat1").propertyGroup("Garofalo").set("n_gar", "4.6");
    model.material("mat1").propertyGroup("ChabocheViscoplasticity").set("A_cha", "1[1/s]");
    model.material("mat1").propertyGroup("ChabocheViscoplasticity").set("sigRef_cha", "490[MPa]");
    model.material("mat1").propertyGroup("ChabocheViscoplasticity").set("n_cha", "9");

//    In the Materials toolbar, click Add Material to close the Add Material window.
//    In the Model Builder window, right-click Global Definitions > Materials and choose Blank Material.

    model.material().create("mat2", "Common", "");

//    In the Model Builder window, right-click Component 1 (comp1) > Materials and choose More Materials > Material Link.

    model.component("comp1").material().create("matlnk1", "Link");

//    Right-click Materials and choose More Materials > Material Link.

    model.component("comp1").material().create("matlnk2", "Link");

//    Select Domains 4, 5.

    model.component("comp1").material("matlnk2").selection().set(4, 5);

//    In the Settings window for Material Link, locate the Link Settings section.
//    From the Material list, select Material 2 (mat2).

    model.component("comp1").material("matlnk2").set("link", "mat2");

//    In the Model Builder window, under Global Definitions > Materials, click Material 2 (mat2).
//    In the Settings window for Material, locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat2").propertyGroup().create("Enu", "Enu", "Young's_modulus_and_Poisson's_ratio");
    model.material("mat2").propertyGroup("Enu").set("E", new String[]{"70.5[kN/mm^2]"});
    model.material("mat2").propertyGroup("Enu").set("nu", new String[]{"0.342"});
    model.material("mat2").propertyGroup("def").set("density", new String[]{"2700[kg/m^3]"});

//    Click to expand the Material Properties section.
//    In the Material properties tree, select Solid Mechanics > Elastoplastic Material > Elastoplastic Material Model > Initial yield stress (sigmags).
//    Click Add to Material.

    model.material("mat2").propertyGroup()
         .create("ElastoplasticModel", "ElastoplasticModel", "Elastoplastic_material_model");

//    Locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat2").propertyGroup("ElastoplasticModel").set("sigmags", new String[]{"sigma0"});

//    Use a piecewise constant function to define the hardening function with a smooth transition. At small equivalent plastic strain (lower than 3%) use a linear function; at higher values, use the Hollomon hardening function.
//    In the Model Builder window, expand the Material 2 (mat2) node.
//    Right-click Global Definitions > Materials > Material 2 (mat2) > Elastoplastic material model (ElastoplasticModel) and choose Functions > Piecewise.

    model.material("mat2").propertyGroup("ElastoplasticModel").func().create("pw1", "Piecewise");

//    In the Settings window for Piecewise, type sigma_hard in the Function name text field.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("funcname", "sigma_hard");

//    Locate the Definition section.
//    From the Extrapolation list, select None.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("extrap", "none");

//    From the Smoothing list, select Continuous first derivative.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("smooth", "contd1");

//    Find the Intervals subsection.
//    In the table, enter the following settings:

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").setIndex("pieces", 0, 0, 0);
    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").setIndex("pieces", "eps0", 0, 1);
    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1")
         .setIndex("pieces", "(K*eps0^n-sigma0)/eps0*x", 0, 2);
    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").setIndex("pieces", "eps0", 1, 0);
    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").setIndex("pieces", 0.5, 1, 1);
    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").setIndex("pieces", "K*x^n-sigma0", 1, 2);

//    Locate the Units section.
//    In the Arguments text field, type 1.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("argunit", "1");

//    In the Function text field, type Pa.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("fununit", "Pa");

//    Locate the Definition section.
//    From the Extrapolation list, select Nearest function.

    model.material("mat2").propertyGroup("ElastoplasticModel").func("pw1").set("extrap", "interior");

//    In the Model Builder window, under Global Definitions > Materials > Material 2 (mat2), click Elastoplastic material model (ElastoplasticModel).
//    In the Settings window for Elastoplastic Material Model, locate the Model Inputs section.
//    Click Select Quantity.
//    In the Physical Quantity dialog, type plastic strain in the text field.
//    In the tree, select Solid Mechanics > Equivalent plastic strain (1).
//    Click OK.

    model.material("mat2").propertyGroup("ElastoplasticModel").addInput("effectiveplasticstrain");

//    In the Model Builder window, click Material 2 (mat2).
//    In the Settings window for Material, locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat2").propertyGroup("ElastoplasticModel").set("sigmagh", new String[]{"sigma_hard(epe)"});

//    In the Model Builder window, under Component 1 (comp1), click Solid Mechanics (solid).
//    Select Domains 4, 5, 6.

    model.component("comp1").physics("solid").selection().set(4, 5, 6);

//    In the Settings window for Solid Mechanics, locate the Thickness section.
//    In the \[d\] text field, type w_sheet.

    model.component("comp1").physics("solid").prop("d").set("d", "w_sheet");

//    In the Model Builder window, under Component 1 (comp1) > Solid Mechanics (solid), click Linear Elastic Material 1.
//    In the Physics toolbar, click Attributes and choose Plasticity.

    model.component("comp1").physics("solid").feature("lemm1").create("plsty1", "Plasticity", 2);

//    Select Domains 4, 5.

    model.component("comp1").physics("solid").feature("lemm1").feature("plsty1").selection().set(4, 5);

//    In the Settings window for Plasticity, locate the Plasticity Model section.
//    Find the Isotropic hardening model subsection.
//    From the list, select Hardening function.

    model.component("comp1").physics("solid").feature("lemm1").feature("plsty1")
         .set("IsotropicHardeningModel", "HardeningFunction");

//    In the Physics toolbar, click Boundaries and choose Symmetry.

    model.component("comp1").physics("solid").create("sym1", "SymmetrySolid", 1);

//    Select Boundaries 1, 11, 18.

    model.component("comp1").physics("solid").feature("sym1").selection().set(11, 18);

//    In the Physics toolbar, click Domains and choose Prescribed Displacement.

    model.component("comp1").physics("solid").create("disp1", "Displacement2", 2);

//    Select Domain 6.

    model.component("comp1").physics("solid").feature("disp1").selection().set(6);

//    In the Settings window for Prescribed Displacement, locate the Prescribed Displacement section.
//    From the Displacement in x direction list, select Prescribed.

    model.component("comp1").physics("solid").feature("disp1").setIndex("Direction", "prescribed", 0);

//    From the Displacement in y direction list, select Prescribed.

    model.component("comp1").physics("solid").feature("disp1").setIndex("Direction", "prescribed", 1);

//    In the \[u_{\, 0 \, y}\] text field, type punch(para).

    model.component("comp1").physics("solid").feature("disp1").setIndex("U0", "punch(para)", 1);

//    For such a problem (using continuation parameter), a constant penalty factor is preferred. Set it with a lower value than the default to improve the stability.
//    In the Model Builder window, click Contact 1.
//    In the Settings window for Contact, locate the Contact Method section.
//    From the list, select Augmented Lagrangian.

    model.component("comp1").physics("solid").feature("dcnt1").set("ContactMethodCtrl", "AugmentedLagrange");

//    Locate the Contact Pressure Penalty Factor section.
//    From the Penalty factor control list, select Manual tuning.

    model.component("comp1").physics("solid").feature("dcnt1").set("penaltyCtrlAuglag", "ManualTuning");

//    In the \[f_{\textrm{p}}\] text field, type 0.1.

    model.component("comp1").physics("solid").feature("dcnt1").set("pfm", 0.1);

//    From the Use relaxation list, select Never.

    model.component("comp1").physics("solid").feature("dcnt1").set("useRelaxation", "Never");

//    Right-click Component 1 (comp1) > Solid Mechanics (solid) > Contact 1 and choose Duplicate.

    model.component("comp1").physics("solid").feature().duplicate("dcnt2", "dcnt1");

//    In the Settings window for Contact, locate the Pair Selection section.
//    From the Pairs list, select From list.

    model.component("comp1").physics("solid").feature("dcnt2").set("pairSelection", "list");

//    Click Add.
//    In the Add dialog, select Contact Pair 2 (p2) in the Pairs list.
//    Click OK.

    model.component("comp1").physics("solid").feature("dcnt2").set("pairs", new String[]{"p2"});

//    In the Settings window for Contact, locate the Contact Pressure Penalty Factor section.
//    In the \[f_{\textrm{p}}\] text field, type 2e-2.

    model.component("comp1").physics("solid").feature("dcnt2").set("pfm", "2e-2");

//    In the Mesh toolbar, click Mapped.

    model.component("comp1").mesh("mesh1").create("map1", "Map");

//    Right-click Mapped 1 and choose Distribution.

    model.component("comp1").mesh("mesh1").feature("map1").create("dis1", "Distribution");

//    Select Boundary 13.

    return model;
  }

  public static Model run2(Model model) {

    model.component("comp1").mesh("mesh1").feature("map1").feature("dis1").selection().set(13);

//    In the Settings window for Distribution, locate the Distribution section.
//    In the Number of elements text field, type 50.

    model.component("comp1").mesh("mesh1").feature("map1").feature("dis1").set("numelem", 50);
    model.component("comp1").mesh("mesh1").feature("map1").create("dis2", "Distribution");
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis2").selection().set(1, 18);
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis2").set("numelem", 1);
    model.component("comp1").mesh("mesh1").feature("map1").create("dis3", "Distribution");
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis3").selection().set(8, 20);
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis3").set("numelem", 25);
    model.component("comp1").mesh("mesh1").feature("map1").create("dis4", "Distribution");
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis4").selection().set(11);
    model.component("comp1").mesh("mesh1").feature("map1").create("dis5", "Distribution");
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis5").selection().set(9);
    model.component("comp1").mesh("mesh1").feature("map1").feature("dis5").set("numelem", 10);
    model.component("comp1").mesh("mesh1").run();

//    Distribution 2-5
//    Proceed to add four additional distributions with the following settings:
//    Click Build All.

    model.component("comp1").mesh("mesh1").run();

//    The blank deformation angle is the slope of the line between the points (4e-2, 0) and (6e-2,0). Use integration coupling variables to evaluate the spatial coordinates at these points.
//    In the Definitions toolbar, click Nonlocal Couplings and choose Integration.

    model.component("comp1").cpl().create("intop1", "Integration");
    model.component("comp1").cpl("intop1").set("axisym", true);

//    In the Settings window for Integration, locate the Source Selection section.
//    From the Geometric entity level list, select Point.

    model.component("comp1").cpl("intop1").selection().geom("geom1", 0);

//    Select Point 11.

    model.component("comp1").cpl("intop1").selection().set(11);

//    In the Definitions toolbar, click Nonlocal Couplings and choose Integration.

    model.component("comp1").cpl().create("intop2", "Integration");
    model.component("comp1").cpl("intop2").set("axisym", true);

//    In the Settings window for Integration, locate the Source Selection section.
//    From the Geometric entity level list, select Point.

    model.component("comp1").cpl("intop2").selection().geom("geom1", 0);

//    Select Point 13.

    model.component("comp1").cpl("intop2").selection().set(13);

//    In the Definitions toolbar, click Local Variables.

    model.component("comp1").variable().create("var1");

//    In the Settings window for Variables, locate the Variables section.
//    In the table, enter the following settings:

    model.component("comp1").variable("var1").set("angle", "2*atan((intop2(x)-intop1(x))/(intop2(y)-intop1(y)))");
    model.component("comp1").variable("var1").descr("angle", "Blank deformation angle");

//    In the Model Builder window, click Study 1.
//    In the Settings window for Study, type Frictionless in the Label text field.

    model.study("std1").label("Frictionless");

//    In the Model Builder window, under Frictionless, click Step 1: Stationary.
//    In the Settings window for Stationary, click to expand the Results While Solving section.
//    Select the Plot checkbox.

    model.study("std1").feature("stat").set("plot", true);

//    Set up an auxiliary continuation sweep for the <c>para</c> parameter.
//    Click to expand the Study Extensions section.
//    Select the Auxiliary sweep checkbox.

    model.study("std1").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std1").feature("stat").setIndex("pname", "R1", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "", 0);
    model.study("std1").feature("stat").setIndex("punit", "m", 0);
    model.study("std1").feature("stat").setIndex("pname", "R1", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "", 0);
    model.study("std1").feature("stat").setIndex("punit", "m", 0);

//    In the table, enter the following settings:

    model.study("std1").feature("stat").setIndex("pname", "para", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "1e-4 range(2e-2,2e-2,1.5)", 0);

//    In the Study toolbar, click Show Default Solver.

    model.study("std1").showAutoSequences("all");

//    In the Model Builder window, expand the Solution 1 (sol1) node.
//    In the Model Builder window, expand the Frictionless > Solver Configurations > Solution 1 (sol1) > Stationary Solver 1 node, then click Parametric 1.
//    In the Settings window for Parametric, click to expand the Continuation section.
//    Select the Tuning of step size checkbox.

    model.sol("sol1").feature("s1").feature("p1").set("paramtuning", true);

//    In the Initial step size text field, type 1e-4.

    model.sol("sol1").feature("s1").feature("p1").set("pinitstep", "1e-4");

//    In the Minimum step size text field, type 1e-4.

    model.sol("sol1").feature("s1").feature("p1").set("pminstep", "1e-4");

//    In the Maximum step size text field, type 2e-2.

    model.sol("sol1").feature("s1").feature("p1").set("pmaxstep", "2e-2");

//    From the Predictor list, select Linear.

    model.sol("sol1").feature("s1").feature("p1").set("porder", "linear");

//    Right-click Frictionless > Solver Configurations > Solution 1 (sol1) > Stationary Solver 1 > Parametric 1 and choose Stop Condition.

    model.sol("sol1").feature("s1").feature("p1").create("st1", "StopCondition");

//    In the Settings window for Stop Condition, locate the Stop Expressions section.
//    Click Add.

    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);

//    In the table, enter the following settings:

    model.sol("sol1").feature("s1").feature("p1").feature("st1")
         .setIndex("stopcondarr", "min(comp1.solid.Tnmax_p1,comp1.solid.Tnmax_p2)-(para>1)", 0);
    model.sol("sol1").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "negative", 0);

//    Locate the Output at Stop section.
//    From the Add solution list, select Step after stop.

    model.sol("sol1").feature("s1").feature("p1").feature("st1").set("storestopcondsol", "stepafter");

//    Clear the Add information checkbox.

    model.sol("sol1").feature("s1").feature("p1").feature("st1").set("stopcondwarn", false);

//    Click Run.

    model.sol("sol1").runAll();

    model.result().remove("pg1");

    model.study("std1").feature("stat").set("plotgroup", "Default");

    model.result().create("pg1", "PlotGroup2D");
    model.result("pg1").set("data", "dset1");
    model.result("pg1").setIndex("looplevel", 66, 0);
    model.result("pg1").label("Stress (solid)");
    model.result("pg1").set("frametype", "spatial");
    model.result("pg1").create("surf1", "Surface");
    model.result("pg1").feature("surf1").set("expr", new String[]{"solid.misesGp"});
    model.result("pg1").feature("surf1").set("threshold", "manual");
    model.result("pg1").feature("surf1").set("thresholdvalue", 0.2);
    model.result("pg1").feature("surf1").set("colortable", "Rainbow");
    model.result("pg1").feature("surf1").set("colortabletrans", "none");
    model.result("pg1").feature("surf1").set("colorscalemode", "linear");
    model.result("pg1").feature("surf1").set("resolution", "normal");
    model.result("pg1").feature("surf1").set("refine", 2);
    model.result("pg1").feature("surf1").set("colortable", "Prism");
    model.result("pg1").feature("surf1").create("def", "Deform");
    model.result("pg1").feature("surf1").feature("def").set("scaleactive", true);
    model.result("pg1").feature("surf1").feature("def").set("scale", "1");
    model.result("pg1").feature("surf1").feature("def").set("expr", new String[]{"u", "v"});
    model.result("pg1").feature("surf1").feature("def").set("descr", "Displacement field");
    model.result("pg1").run();

//    The default plot shows the von Mises stress, equivalent plastic strain, and contact pressure after the release. For better clarity, disable the equivalent plastic strain, which will be plotted separately.
//    In the Settings window for 2D Plot Group, type Stress (Frictionless) in the Label text field.

    model.result("pg1").label("Stress (Frictionless)");

//    In the Stress (Frictionless) toolbar, click Plot.

    model.result("pg1").run();

//    In the Results toolbar, click Result Templates to open the Result Templates window.
//    In the tree, select Frictionless/Solution 1 (sol1) > Solid Mechanics > Equivalent Plastic Strain (solid).
//    Click Add Result Template in the window toolbar.

    model.result().create("pg2", "PlotGroup2D");
    model.result("pg2").set("data", "dset1");
    model.result("pg2").setIndex("looplevel", 66, 0);
    model.result("pg2").label("Equivalent Plastic Strain (solid)");
    model.result("pg2").create("surf1", "Surface");
    model.result("pg2").feature("surf1").set("expr", new String[]{"solid.epeGp"});
    model.result("pg2").feature("surf1").set("inheritplot", "none");
    model.result("pg2").feature("surf1").set("resolution", "normal");
    model.result("pg2").feature("surf1").set("refine", 2);
    model.result("pg2").feature("surf1").set("colortabletype", "discrete");
    model.result("pg2").feature("surf1").set("bandcount", 11);
    model.result("pg2").feature("surf1").set("colortable", "AuroraAustralisDark");
    model.result("pg2").feature("surf1").set("descractive", true);
    model.result("pg2").feature("surf1").set("descr", "Equivalent plastic strain");
    model.result("pg2").label("Equivalent Plastic Strain (solid)");
    model.result("pg2").run();
    model.result("pg2").run();

//    In the Model Builder window, expand the Equivalent Plastic Strain (solid) node.
//    Right-click Surface 1 and choose Deformation.

    model.result("pg2").feature("surf1").create("def1", "Deform");
    model.result("pg2").run();

//    In the Settings window for Deformation, locate the Scale section.
//    Select the Scale factor checkbox.

    model.result("pg2").feature("surf1").feature("def1").set("scaleactive", true);

//    In the associated text field, type 1.

    model.result("pg2").feature("surf1").feature("def1").set("scale", 1);

//    In the Equivalent Plastic Strain (solid) toolbar, click Plot.

    model.result("pg2").run();

//    Evaluate the forming angle and the angle after release.
//    The instruction below shows how to evaluate the forming angle and the angle after release.
//    In the Model Builder window, expand the Results > Datasets node.
//    Right-click Results > Derived Values and choose Global Evaluation.

    model.result().numerical().create("gev1", "EvalGlobal");

//    In the Settings window for Global Evaluation, type Deformation Angle (Frictionless) in the Label text field.

    model.result().numerical("gev1").label("Deformation Angle (Frictionless)");

//    Locate the Data section.
//    From the Parameter selection (para) list, select From list.

    model.result().numerical("gev1").setIndex("looplevelinput", "manual", 0);

//    In the Parameter values (para) list, select 1, 1.3.

    model.result().numerical("gev1").setIndex("looplevel", new int[]{51, 66}, 0);

//    Click Replace Expression in the upper-right corner of the Expressions section.
//    From the menu, choose Component 1 (comp1) > Definitions > Variables > angle - Blank deformation angle - rad.

    model.result().numerical("gev1").set("expr", new String[]{"angle"});
    model.result().numerical("gev1").set("descr", new String[]{"Blank deformation angle"});
    model.result().numerical("gev1").set("unit", new String[]{"rad"});

//    Locate the Expressions section.
//    In the table, enter the following settings:

    model.result().numerical("gev1").setIndex("unit", "deg", 0);
    model.result().numerical("gev1").setIndex("descr", "Blank deformation angle", 0);

//    Click Evaluate.

    model.result().table().create("tbl1", "Table");
    model.result().table("tbl1").comments("Deformation Angle (Frictionless)");
    model.result().numerical("gev1").set("table", "tbl1");
    model.result().numerical("gev1").setResult();

//    In the Model Builder window, expand the Results > Tables node, then click Table 1.
//    In the Settings window for Table, type Deformation Angle (Frictionless) in the Label text field.

    model.result().table("tbl1").label("Deformation Angle (Frictionless)");

//    In the Results toolbar, click 1D Plot Group.

    model.result().create("pg3", "PlotGroup1D");
    model.result("pg3").run();

//    In the Settings window for 1D Plot Group, type Punch Force vs. Displacement in the Label text field.

    model.result("pg3").label("Punch Force vs. Displacement");

//    Locate the Data section.
//    From the Dataset list, select None.

    model.result("pg3").set("data", "none");

//    Click to expand the Title section.
//    From the Title type list, select None.

    model.result("pg3").set("titletype", "none");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg3").set("xlabelactive", true);

//    In the associated text field, type Punch displacement (mm).

    model.result("pg3").set("xlabel", "Punch displacement (mm)");

//    Select the y-axis label checkbox.

    model.result("pg3").set("ylabelactive", true);

//    In the associated text field, type Punch force (N).

    model.result("pg3").set("ylabel", "Punch force (N)");

//    Locate the Legend section.
//    From the Position list, select Upper left.

    model.result("pg3").set("legendpos", "upperleft");

//    Right-click Punch Force vs. Displacement and choose Global.

    model.result("pg3").create("glob1", "Global");
    model.result("pg3").feature("glob1").set("markerpos", "datapoints");
    model.result("pg3").feature("glob1").set("linewidth", "preference");

//    In the Settings window for Global, locate the Data section.
//    From the Dataset list, select Frictionless/Solution 1 (sol1).

    model.result("pg3").feature("glob1").set("data", "dset1");

//    Locate the y-Axis Data section.
//    In the table, enter the following settings:

    model.result("pg3").feature("glob1").setIndex("expr", "2*solid.dcnt2.T_toty", 0);
    model.result("pg3").feature("glob1").setIndex("unit", "N", 0);
    model.result("pg3").feature("glob1").setIndex("descr", "", 0);

//    Locate the x-Axis Data section.
//    From the Parameter list, select Expression.

    model.result("pg3").feature("glob1").set("xdata", "expr");

//    In the Expression text field, type -punch(para).

    model.result("pg3").feature("glob1").set("xdataexpr", "-punch(para)");

//    From the Unit list, select mm.

    model.result("pg3").feature("glob1").set("xdataunit", "mm");

//    Click to expand the Legends section.
//    From the Legends list, select Manual.

    model.result("pg3").feature("glob1").set("legendmethod", "manual");

//    In the table, enter the following settings:

    model.result("pg3").feature("glob1").setIndex("legends", "Frictionless", 0);

//    In the Punch Force vs. Displacement toolbar, click Plot.

    model.result("pg3").run();

//    Now include friction in the problem.
//    In the Model Builder window, under Component 1 (comp1) > Solid Mechanics (solid), click Contact 1.
//    In the Physics toolbar, click Attributes and choose Friction.

    model.component("comp1").physics("solid").feature("dcnt1").create("fric1", "Friction", 1);

//    In the Settings window for Friction, locate the Friction Parameters section.
//    In the \[\mu\] text field, type 0.1342.

    model.component("comp1").physics("solid").feature("dcnt1").feature("fric1").set("mu_fric", 0.1342);

//    In the Model Builder window, under Component 1 (comp1) > Solid Mechanics (solid), click Contact 2.
//    In the Physics toolbar, click Attributes and choose Friction.

    model.component("comp1").physics("solid").feature("dcnt2").create("fric1", "Friction", 1);

//    In the Settings window for Friction, locate the Friction Parameters section.
//    In the \[\mu\] text field, type 0.1342.

    model.component("comp1").physics("solid").feature("dcnt2").feature("fric1").set("mu_fric", 0.1342);

//    In the Home toolbar, click Add Study to open the Add Study window.
//    Find the Studies subsection.
//    In the Select Study tree, select General Studies > Stationary.
//    Click Add Study in the window toolbar.

    model.study().create("std2");
    model.study("std2").create("stat", "Stationary");

//    In the Home toolbar, click Add Study to close the Add Study window.
//    In the Settings window for Study, type Friction in the Label text field.

    model.study("std2").label("Friction");

//    In the Model Builder window, under Friction, click Step 1: Stationary.
//    In the Settings window for Stationary, locate the Results While Solving section.
//    Select the Plot checkbox.

    model.study("std2").feature("stat").set("plot", true);

//    In the table, enter the following settings:

    model.study("std2").feature("stat").setIndex("plotgrouparr", "Default", 0);

//    Locate the Study Extensions section.
//    Select the Auxiliary sweep checkbox.

    model.study("std2").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std2").feature("stat").setIndex("pname", "R1", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "", 0);
    model.study("std2").feature("stat").setIndex("punit", "m", 0);
    model.study("std2").feature("stat").setIndex("pname", "R1", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "", 0);
    model.study("std2").feature("stat").setIndex("punit", "m", 0);

//    In the table, enter the following settings:

    model.study("std2").feature("stat").setIndex("pname", "para", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "1e-4 range(2e-2,2e-2,1.5)", 0);

//    In the Study toolbar, click Show Default Solver.

    model.study("std2").showAutoSequences("all");

//    In the Model Builder window, expand the Solution 2 (sol2) node.
//    In the Model Builder window, expand the Friction > Solver Configurations > Solution 2 (sol2) > Stationary Solver 1 node, then click Parametric 1.
//    In the Settings window for Parametric, locate the Continuation section.
//    Select the Tuning of step size checkbox.

    model.sol("sol2").feature("s1").feature("p1").set("paramtuning", true);

//    In the Initial step size text field, type 2e-2.

    model.sol("sol2").feature("s1").feature("p1").set("pinitstep", "2e-2");

//    In the Minimum step size text field, type 1e-5.

    model.sol("sol2").feature("s1").feature("p1").set("pminstep", "1e-5");

//    In the Maximum step size text field, type 2e-2.

    model.sol("sol2").feature("s1").feature("p1").set("pmaxstep", "2e-2");

//    From the Predictor list, select Linear.

    model.sol("sol2").feature("s1").feature("p1").set("porder", "linear");

//    Right-click Friction > Solver Configurations > Solution 2 (sol2) > Stationary Solver 1 > Parametric 1 and choose Stop Condition.

    model.sol("sol2").feature("s1").feature("p1").create("st1", "StopCondition");

//    In the Settings window for Stop Condition, locate the Stop Expressions section.
//    Click Add.

    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);

//    In the table, enter the following settings:

    model.sol("sol2").feature("s1").feature("p1").feature("st1")
         .setIndex("stopcondarr", "min(comp1.solid.Tnmax_p1,comp1.solid.Tnmax_p2)-(para>1)", 0);
    model.sol("sol2").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "negative", 0);

//    Locate the Output at Stop section.
//    From the Add solution list, select Step after stop.

    model.sol("sol2").feature("s1").feature("p1").feature("st1").set("storestopcondsol", "stepafter");

//    Clear the Add information checkbox.

    model.sol("sol2").feature("s1").feature("p1").feature("st1").set("stopcondwarn", false);

//    In the Study toolbar, click Show Default Plots.

    model.study("std2").createAutoSequences("sol");
    model.study("std2").createAutoSequences("jobs");

    model.result().create("pg4", "PlotGroup2D");
    model.result("pg4").set("data", "dset2");
    model.result("pg4").label("Stress (solid)");
    model.result("pg4").set("frametype", "spatial");
    model.result("pg4").create("surf1", "Surface");
    model.result("pg4").feature("surf1").set("expr", new String[]{"solid.misesGp"});
    model.result("pg4").feature("surf1").set("threshold", "manual");
    model.result("pg4").feature("surf1").set("thresholdvalue", 0.2);
    model.result("pg4").feature("surf1").set("colortable", "Rainbow");
    model.result("pg4").feature("surf1").set("colortabletrans", "none");
    model.result("pg4").feature("surf1").set("colorscalemode", "linear");
    model.result("pg4").feature("surf1").set("resolution", "normal");
    model.result("pg4").feature("surf1").set("refine", 2);
    model.result("pg4").feature("surf1").set("colortable", "Prism");
    model.result("pg4").feature("surf1").create("def", "Deform");
    model.result("pg4").feature("surf1").feature("def").set("scaleactive", true);
    model.result("pg4").feature("surf1").feature("def").set("scale", "1");
    model.result("pg4").feature("surf1").feature("def").set("expr", new String[]{"u", "v"});
    model.result("pg4").feature("surf1").feature("def").set("descr", "Displacement field");
    model.result("pg4").run();

//    Click Compute.

    model.study("std2").createAutoSequences("all");

    model.sol("sol2").runAll();

    model.result("pg4").run();

//    In the Settings window for 2D Plot Group, type Stress (Friction) in the Label text field.

    model.result("pg4").label("Stress (Friction)");

//    In the Stress (Friction) toolbar, click Plot.

    model.result("pg4").run();

//    In the tree, select Friction/Solution 2 (sol2) > Solid Mechanics > Equivalent Plastic Strain (solid).
//    Click Add Result Template in the window toolbar.

    model.result().create("pg5", "PlotGroup2D");
    model.result("pg5").set("data", "dset2");
    model.result("pg5").setIndex("looplevel", 73, 0);
    model.result("pg5").label("Equivalent Plastic Strain (solid) 1");
    model.result("pg5").create("surf1", "Surface");
    model.result("pg5").feature("surf1").set("expr", new String[]{"solid.epeGp"});
    model.result("pg5").feature("surf1").set("inheritplot", "none");
    model.result("pg5").feature("surf1").set("resolution", "normal");
    model.result("pg5").feature("surf1").set("refine", 2);
    model.result("pg5").feature("surf1").set("colortabletype", "discrete");
    model.result("pg5").feature("surf1").set("bandcount", 11);
    model.result("pg5").feature("surf1").set("colortable", "AuroraAustralisDark");
    model.result("pg5").feature("surf1").set("descractive", true);
    model.result("pg5").feature("surf1").set("descr", "Equivalent plastic strain");
    model.result("pg5").label("Equivalent Plastic Strain (solid) 1");
    model.result("pg5").run();
    model.result("pg5").run();

//    In the Model Builder window, expand the Equivalent Plastic Strain (solid) 1 node.
//    Right-click Surface 1 and choose Deformation.

    model.result("pg5").feature("surf1").create("def1", "Deform");
    model.result("pg5").run();

//    In the Settings window for Deformation, locate the Scale section.
//    Select the Scale factor checkbox.

    model.result("pg5").feature("surf1").feature("def1").set("scaleactive", true);

//    In the associated text field, type 1.

    model.result("pg5").feature("surf1").feature("def1").set("scale", 1);

//    In the Equivalent Plastic Strain (solid) 1 toolbar, click Plot.

    model.result("pg5").run();

//    You can now evaluate the angle at the forming and after-release stages.
//    In the Model Builder window, right-click Deformation Angle (Frictionless) and choose Duplicate.

    model.result().numerical().duplicate("gev2", "gev1");

//    In the Settings window for Global Evaluation, type Deformation Angle (Friction) in the Label text field.

    model.result().numerical("gev2").label("Deformation Angle (Friction)");

//    Locate the Data section.
//    From the Dataset list, select Friction/Solution 2 (sol2).

    model.result().numerical("gev2").set("data", "dset2");

//    In the Parameter values (para) list, select 1, 1.42.

    model.result().numerical("gev2").setIndex("looplevel", new int[]{51, 72}, 0);

//    Click ^ next to Evaluate then choose New Table.

    model.result().table().create("tbl2", "Table");
    model.result().table("tbl2").comments("Deformation Angle (Friction)");
    model.result().numerical("gev2").set("table", "tbl2");
    model.result().numerical("gev2").setResult();

//    In the Model Builder window, under Results > Tables, click Table 2.
//    In the Settings window for Table, type Deformation Angle (Friction) in the Label text field.

    model.result().table("tbl2").label("Deformation Angle (Friction)");
    model.result("pg3").run();

//    In the Model Builder window, right-click Results > Punch Force vs. Displacement > Global 1 and choose Duplicate.

    model.result("pg3").feature().duplicate("glob2", "glob1");
    model.result("pg3").run();

//    In the Settings window for Global, locate the Data section.
//    From the Dataset list, select Friction/Solution 2 (sol2).

    model.result("pg3").feature("glob2").set("data", "dset2");

//    Click to expand the Coloring and Style section.
//    Find the Line style subsection.
//    From the Line list, select Dashed.

    model.result("pg3").feature("glob2").set("linestyle", "dashed");

//    Locate the Legends section.
//    In the table, enter the following settings:

    model.result("pg3").feature("glob2").setIndex("legends", "Friction", 0);

//    In the Punch Force vs. Displacement toolbar, click Plot.

    model.result("pg3").run();

//    Add a table in which to store the benchmark experimental data.
//    In the Results toolbar, click Table.

    model.result().table().create("tbl3", "Table");

//    In the Settings window for Table, type Punch Force (Experiment) in the Label text field.

    model.result().table("tbl3").label("Punch Force (Experiment)");

//    Locate the Data section.
//    Click Import.
//    Browse to the model's Application Library folder and double-click the file sheet_metal_forming.txt.

    model.result().table("tbl3").importData("sheet_metal_forming.txt");
    model.result("pg3").run();

//    In the Model Builder window, right-click Punch Force vs. Displacement and choose Table Graph.

    model.result("pg3").create("tblp1", "Table");
    model.result("pg3").feature("tblp1").set("markerpos", "datapoints");
    model.result("pg3").feature("tblp1").set("linewidth", "preference");

//    In the Settings window for Table Graph, type Experiment in the Label text field.

    model.result("pg3").feature("tblp1").label("Experiment");

//    Locate the Data section.
//    From the Table list, select Punch Force (Experiment).

    model.result("pg3").feature("tblp1").set("table", "tbl3");

//    Locate the Coloring and Style section.
//    Find the Line style subsection.
//    From the Line list, select None.

    model.result("pg3").feature("tblp1").set("linestyle", "none");

//    From the Color list, select From theme.

    model.result("pg3").feature("tblp1").set("linecolor", "fromtheme");

//    Find the Line markers subsection.
//    From the Marker list, select Cycle.

    model.result("pg3").feature("tblp1").set("linemarker", "cycle");

//    Click to expand the Legends section.
//    Select the Show legends checkbox.

    model.result("pg3").feature("tblp1").set("legend", true);

//    From the Legends list, select Manual.

    model.result("pg3").feature("tblp1").set("legendmethod", "manual");

//    In the table, enter the following settings:

    model.result("pg3").feature("tblp1").setIndex("legends", "Experiment", 0);

//    In the Punch Force vs. Displacement toolbar, click Plot.

    model.result("pg3").run();

//    Friction is now included in the model. To compute the solution without friction in the first study again, you need to make sure that the friction nodes are disabled in the model for this specific study. This is convenient if you need to close the model and reopen it later.
//    In the Model Builder window, under Frictionless, click Step 1: Stationary.
//    In the Settings window for Stationary, locate the Physics and Variables Selection section.
//    Select the Modify model configuration for study step checkbox.

    model.study("std1").feature("stat").set("useadvanceddisable", true);

//    In the tree, select Component 1 (comp1) > Solid Mechanics (solid), Controls spatial frame > Contact 1 > Friction 1.
//    Right-click and choose Disable.

    model.study("std1").feature("stat").set("disabledphysics", new String[]{"solid/dcnt1/fric1"});

//    In the tree, select Component 1 (comp1) > Solid Mechanics (solid), Controls spatial frame > Contact 2 > Friction 1.
//    Right-click and choose Disable.

    model.study("std1").feature("stat")
         .set("disabledphysics", new String[]{"solid/dcnt1/fric1", "solid/dcnt2/fric1"});

    model.result().create("pg6", "PlotGroup2D");
    model.result("pg6").run();
    model.result("pg6").set("showlegends", false);
    model.result("pg6").set("titletype", "none");
    model.result("pg6").create("line1", "Line");
    model.result("pg6").feature("line1").set("evaluationsettings", "parent");
    model.result("pg6").feature("line1").set("data", "dset1");
    model.result("pg6").feature("line1").setIndex("looplevel", 16, 0);
    model.result("pg6").feature("line1").set("expr", "1");
    model.result("pg6").feature("line1").set("coloring", "uniform");
    model.result("pg6").feature("line1").set("color", "black");
    model.result("pg6").feature("line1").create("def1", "Deform");
    model.result("pg6").run();
    model.result("pg6").feature("line1").feature("def1").set("expr", new String[]{"u", "v-5e-2"});
    model.result("pg6").feature("line1").feature("def1").set("scaleactive", true);
    model.result("pg6").feature("line1").feature("def1").set("scale", 1);
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line2", "line1");
    model.result("pg6").run();

    return model;
  }

  public static Model run3(Model model) {
    model.result("pg6").feature("line2").setIndex("looplevel", 31, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line2").feature("def1").set("expr", new String[]{"u", "v-2*5e-2"});
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line3", "line2");
    model.result("pg6").run();
    model.result("pg6").feature("line3").setIndex("looplevel", 46, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line3").feature("def1").set("expr", new String[]{"u", "v-3*5e-2"});
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line4", "line1");
    model.result("pg6").run();
    model.result("pg6").feature("line4").setIndex("looplevel", 51, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line4").feature("def1").set("expr", new String[]{"u+6e-2", "v"});
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line5", "line4");
    model.result("pg6").run();
    model.result("pg6").feature("line5").setIndex("looplevel", 56, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line5").feature("def1").set("expr", new String[]{"u+6e-2", "v-5e-2"});
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line6", "line5");
    model.result("pg6").run();
    model.result("pg6").feature("line6").setIndex("looplevel", 61, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line6").feature("def1").set("expr", new String[]{"u+6e-2", "v-2*5e-2"});
    model.result("pg6").run();
    model.result("pg6").feature().duplicate("line7", "line6");
    model.result("pg6").run();
    model.result("pg6").feature("line7").setIndex("looplevel", 66, 0);
    model.result("pg6").run();
    model.result("pg6").feature("line7").feature("def1").set("expr", new String[]{"u+6e-2", "v-3*5e-2"});
    model.result("pg6").run();
    model.result("pg6").run();
    model.result("pg6").feature("line1").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line2").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line3").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line4").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line5").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line6").set("data", "dset2");
    model.result("pg6").run();
    model.result("pg6").feature("line7").set("data", "dset2");
    model.result("pg6").run();
    model.result().remove("pg6");

//    In the Model Builder window, right-click the root node and choose Add Component > 3D.

    model.component().create("comp2", true);

    model.component("comp2").geom().create("geom2", 3);
    model.component("comp2").geom("geom2").geomRep("comsol");

    model.component("comp2").mesh().create("mesh2");
    model.component("comp2").mesh("mesh2").contribute("geom/detail", true);

//    In the Geometry toolbar, click Work Plane.

    model.component("comp2").geom("geom2").create("wp1", "WorkPlane");
    model.component("comp2").geom("geom2").feature("wp1").set("unite", true);

//    In the Settings window for Work Plane, locate the Plane Definition section.
//    From the Plane list, select xz-plane.

    model.component("comp2").geom("geom2").feature("wp1").set("quickplane", "xz");

//    Locate the Unite Objects section.
//    Clear the Unite objects checkbox.

    model.component("comp2").geom("geom2").feature("wp1").set("unite", false);

//    In the Model Builder window, click Plane Geometry.
//    In the Work Plane toolbar, click Part Instance and choose Part 1.

    model.component("comp2").geom("geom2").feature("wp1").geom().create("pi1", "PartInstance");
    model.component("comp2").geom("geom2").feature("wp1").geom().feature("pi1").set("selkeepnoncontr", false);
    model.component("comp2").geom("geom2").feature("wp1").geom().feature("pi1").set("part", "part1");

//    In the Settings window for Part Instance, click Build Selected.

    model.component("comp2").geom("geom2").feature("wp1").geom().run("pi1");

//    Click the Zoom Extents button in the Graphics toolbar.
//    In the Model Builder window, right-click Component 2 (comp2) > Geometry 2 > Work Plane 1 (wp1) and choose Extrude.

    model.component("comp2").geom("geom2").run("wp1");
    model.component("comp2").geom("geom2").feature().create("ext1", "Extrude");
    model.component("comp2").geom("geom2").feature("ext1").set("workplane", "wp1");
    model.component("comp2").geom("geom2").feature("ext1").selection("input").set("wp1");

//    Select the object wp1.pi1(1).

    model.component("comp2").geom("geom2").feature("ext1").selection("input").set("wp1.pi1(1)");

//    In the Settings window for Extrude, locate the Distances section.
//    In the table, enter the following settings:

    model.component("comp2").geom("geom2").feature("ext1").setIndex("distance", "w_sheet/2", 0);

//    Select the Reverse direction checkbox.

    model.component("comp2").geom("geom2").feature("ext1").set("reverse", true);

//    Click Build Selected.

    model.component("comp2").geom("geom2").run("ext1");

//    In the Geometry toolbar, click Extrude.

    model.component("comp2").geom("geom2").feature().create("ext2", "Extrude");
    model.component("comp2").geom("geom2").feature("ext2").set("workplane", "wp1");
    model.component("comp2").geom("geom2").feature("ext2").selection("input").set("wp1.pi1(2)", "wp1.pi1(3)");

//    In the Settings window for Extrude, locate the Distances section.
//    In the table, enter the following settings:

    model.component("comp2").geom("geom2").feature("ext2").setIndex("distance", "w_tools/2", 0);

//    Select the Reverse direction checkbox.

    model.component("comp2").geom("geom2").feature("ext2").set("reverse", true);

//    Click Build Selected.

    model.component("comp2").geom("geom2").run("ext2");

//    In the Model Builder window, under Component 2 (comp2) > Geometry 2, click Form Union (fin).
//    In the Settings window for Form Union/Assembly, locate the Form Union/Assembly section.
//    From the Action list, select Form an assembly.

    model.component("comp2").geom("geom2").feature("fin").set("action", "assembly");

//    Clear the Create pairs checkbox.

    model.component("comp2").geom("geom2").feature("fin").set("createpairs", false);

//    In the Definitions toolbar, click Pairs and choose Contact Pair.

    model.component("comp2").pair().create("p3", "Contact");

    model.component("comp2").geom("geom2").run();

//    Select Boundary 30.

    model.component("comp2").pair("p3").source().set(30);

//    In the Settings window for Pair, locate the Destination Boundaries section.
//    Select the Activate Selection toggle button.
//    Select Boundary 19.

    model.component("comp2").pair("p3").destination().set(19);

//    In the Definitions toolbar, click Pairs and choose Contact Pair.

    model.component("comp2").pair().create("p4", "Contact");

//    Select Boundaries 4, 7, 14.

    model.component("comp2").pair("p4").source().set(4, 7, 14);

//    In the Settings window for Pair, locate the Destination Boundaries section.
//    Select the Activate Selection toggle button.
//    Select Boundary 19.

    model.component("comp2").pair("p4").destination().set(19);

//    In the Model Builder window, right-click Global Definitions > Materials > Material 2 (mat2) and choose Duplicate.

    model.material().duplicate("mat3", "mat2");
    model.material("mat3").set("sys", "none");

//    In the Settings window for Material, locate the Material Properties section.
//    In the Material properties tree, select Geometric Properties > Shell.
//    Click Add to Material.

    model.material("mat3").propertyGroup().create("shell", "shell", "Shell");

//    Locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat3").propertyGroup("ElastoplasticModel").set("Et", new String[]{});
    model.material("mat3").propertyGroup("ElastoplasticModel").set("Ek", new String[]{});
    model.material("mat3").propertyGroup("shell").set("lth", new String[]{"th"});
    model.material("mat3").propertyGroup("def").set("density", new String[]{"2700[kg/m^3]"});
    model.material("mat3").propertyGroup("Enu").set("E", new String[]{"70.5[kN/mm^2]"});
    model.material("mat3").propertyGroup("Enu").set("nu", new String[]{"0.342"});
    model.material("mat3").propertyGroup("ElastoplasticModel").set("sigmags", new String[]{"sigma0"});
    model.material("mat3").propertyGroup("ElastoplasticModel").set("sigmagh", new String[]{"sigma_hard(epe)"});
    model.material("mat3").propertyGroup("ElastoplasticModel")
         .set("Hillcoefficients", new String[]{"0", "0", "0", "0", "0", "0"});
    model.material("mat3").propertyGroup("ElastoplasticModel").set("ys", new String[]{"0", "0", "0", "0", "0", "0"});
    model.material("mat3").propertyGroup("ElastoplasticModel")
         .set("HillcoefficientsDimensionless", new String[]{"0", "0", "0", "0", "0", "0"});
    model.material("mat3").propertyGroup("shell").set("lrot", new String[]{"0.0"});
    model.material("mat3").propertyGroup("shell").set("lne", new String[]{"2"});

//    In the Model Builder window, right-click Component 2 (comp2) > Materials and choose More Materials > Material Link.

    model.component("comp2").material().create("matlnk3", "Link");

//    In the Settings window for Material Link, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp2").material("matlnk3").selection().geom("geom2", 2);

//    Select Boundary 30.

    model.component("comp2").material("matlnk3").selection().set(30);

//    In the Model Builder window, right-click Global Definitions > Materials > Material 3 (mat3) and choose Copy.
//    In the Model Builder window, right-click Component 2 (comp2) > Materials and choose Paste Material.

    model.component("comp2").material().copy("mat4", "mat3");

//    In the Settings window for Material, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp2").material("mat4").selection().geom("geom2", 2);
    model.component("comp2").material("mat4").set("bndType", "shell");

//    Select Boundaries 19, 24.

    model.component("comp2").material("mat4").selection().set(19, 24);

//    In the Home toolbar, click Add Physics to open the Add Physics window.
//    In the tree, select Structural Mechanics > Shell (shell).
//    Find the Physics interfaces in study subsection.
//    In the table, enter the following settings:
//    Click Add to Component 2 in the window toolbar.

    model.component("comp2").physics().create("shell", "Shell", "geom2");

    model.study("std1").feature("stat").setSolveFor("/physics/shell", false);
    model.study("std2").feature("stat").setSolveFor("/physics/shell", false);

//    In the Home toolbar, click Add Physics to close the Add Physics window.
//    In the Settings window for Shell, locate the Boundary Selection section.
//    Click Clear Selection.

    model.component("comp2").physics("shell").selection().set();

//    Select Boundaries 19, 24, 30.

    model.component("comp2").physics("shell").selection().set(19, 24, 30);

//    In the Model Builder window, under Component 2 (comp2) > Shell (shell), click Thickness and Offset 1.
//    In the Settings window for Thickness and Offset, locate the Thickness and Offset section.
//    In the \[d_0\] text field, type th.

    model.component("comp2").physics("shell").feature("to1").set("d", "th");

//    From the Position list, select Top surface on boundary.

    model.component("comp2").physics("shell").feature("to1").set("OffsetDefinition", "top");

//    In the Physics toolbar, click Boundaries and choose Linear Elastic Material, Layered.

    model.component("comp2").physics("shell").create("llem1", "LayeredElastic", 2);

//    Select Boundaries 19, 24.

    model.component("comp2").physics("shell").feature("llem1").selection().set(19, 24);

//    In the Model Builder window, under Component 2 (comp2) > Materials, click Material 3 (mat4).
//    In the Settings window for Material, locate the Orientation and Position section.
//    From the Coordinate system list, select Boundary System 2 (sys2).

    model.component("comp2").material("mat4").set("sys", "sys2");

//    From the Position list, select Top side on boundary.

    model.component("comp2").material("mat4").set("middlePlane", "top");

//    Click the Show More Options button in the Model Builder toolbar.
//    In the Show More Options dialog, in the tree, select the checkbox for the Physics > Advanced Physics Options node.
//    Click OK.
//    In the Model Builder window, under Component 2 (comp2) > Shell (shell), click Linear Elastic Material, Layered 1.
//    In the Settings window for Linear Elastic Material, Layered, click to expand the Out-of-Plane Strain section.
//    Select the Solve for out-of-plane strain components checkbox.

    model.component("comp2").physics("shell").feature("llem1").set("SolveForOutOfPlaneStrain", true);

//    In the Physics toolbar, click Attributes and choose Plasticity.

    model.component("comp2").physics("shell").feature("llem1").create("lplsty1", "LayeredPlasticity", 2);

//    Select Boundaries 19, 24.

    model.component("comp2").physics("shell").feature("llem1").feature("lplsty1").selection().set(19, 24);

//    In the Settings window for Plasticity, locate the Plasticity Model section.
//    Find the Isotropic hardening model subsection.
//    From the list, select Hardening function.

    model.component("comp2").physics("shell").feature("llem1").feature("lplsty1")
         .set("IsotropicHardeningModel", "HardeningFunction");

//    In the Physics toolbar, click Boundaries and choose Prescribed Displacement/Rotation.

    model.component("comp2").physics("shell").create("disp1", "Displacement2", 2);

//    Select Boundary 30.

    model.component("comp2").physics("shell").feature("disp1").selection().set(30);

//    In the Settings window for Prescribed Displacement/Rotation, locate the Prescribed Displacement section.
//    From the Displacement in x direction list, select Prescribed.

    model.component("comp2").physics("shell").feature("disp1").setIndex("Direction", "prescribed", 0);

//    From the Displacement in y direction list, select Prescribed.

    model.component("comp2").physics("shell").feature("disp1").setIndex("Direction", "prescribed", 1);

//    From the Displacement in z direction list, select Prescribed.

    model.component("comp2").physics("shell").feature("disp1").setIndex("Direction", "prescribed", 2);

//    In the \[u_{\, 0 \, z}\] text field, type punch(para).

    model.component("comp2").physics("shell").feature("disp1").setIndex("U0", "punch(para)", 2);

//    In the Physics toolbar, click Edges and choose Symmetry.

    model.component("comp2").physics("shell").create("sym1", "SymmetrySolid1", 1);

//    Select Edges 30, 31, 39.

    model.component("comp2").physics("shell").feature("sym1").selection().set(30, 31, 39);

//    In the Model Builder window, click Contact 1.
//    In the Settings window for Contact, locate the Contact Surface section.
//    From the Contact surface, destination list, select Bottom.

    model.component("comp2").physics("shell").feature("dcnt1").set("ContactSurfaceDst", "Bottom");

//    Locate the Contact Pressure Penalty Factor section.
//    From the Penalty factor control list, select Automatic, soft.

    model.component("comp2").physics("shell").feature("dcnt1").set("penaltyCtrlPenalty", "AutomaticSoft");

//    In the Physics toolbar, click Attributes and choose Friction.

    model.component("comp2").physics("shell").feature("dcnt1").create("fric1", "Friction", 2);

//    In the Settings window for Friction, locate the Friction Parameters section.
//    In the \[\mu\] text field, type 0.1342.

    model.component("comp2").physics("shell").feature("dcnt1").feature("fric1").set("mu_fric", 0.1342);

//    Locate the Friction Force Penalty Factor section.
//    From the Penalty factor control list, select From parent.

    model.component("comp2").physics("shell").feature("dcnt1").feature("fric1")
         .set("penaltyCtrlFrictionPenalty", "FromParent");

//    Right-click Contact 1 and choose Duplicate.

    model.component("comp2").physics("shell").feature().duplicate("dcnt2", "dcnt1");

//    In the Settings window for Contact, locate the Pair Selection section.
//    From the Pairs list, select From list.

    model.component("comp2").physics("shell").feature("dcnt2").set("pairSelection", "list");

//    Click Add.
//    In the Add dialog, select Contact Pair 4 (p4) in the Pairs list.
//    Click OK.

    model.component("comp2").physics("shell").feature("dcnt2").set("pairs", new String[]{"p4"});

//    In the Settings window for Contact, locate the Contact Surface section.
//    From the Contact surface, destination list, select Top.

    model.component("comp2").physics("shell").feature("dcnt2").set("ContactSurfaceDst", "Top");

//    In the Mesh toolbar, click More Generators and choose Mapped.

    model.component("comp2").mesh("mesh2").create("map1", "Map");

//    Select Boundaries 4, 7, 14, 19, 24, 30.

    model.component("comp2").mesh("mesh2").feature("map1").selection().set(4, 7, 14, 19, 24, 30);

//    Right-click Mapped 1 and choose Distribution.

    model.component("comp2").mesh("mesh2").feature("map1").create("dis1", "Distribution");

//    Select Edges 1, 4, 21, 49, 50.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis1").selection().set(1, 4, 21, 49, 50);

//    In the Settings window for Distribution, locate the Distribution section.
//    In the Number of elements text field, type 1.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis1").set("numelem", 1);

//    In the Model Builder window, right-click Mapped 1 and choose Distribution.

    model.component("comp2").mesh("mesh2").feature("map1").create("dis2", "Distribution");

//    Select Edges 5, 51.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis2").selection().set(5, 51);

//    In the Settings window for Distribution, locate the Distribution section.
//    In the Number of elements text field, type 25.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis2").set("numelem", 25);

//    Right-click Mapped 1 and choose Distribution.

    model.component("comp2").mesh("mesh2").feature("map1").create("dis3", "Distribution");

//    Select Edge 11.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis3").selection().set(11);

//    In the Settings window for Distribution, locate the Distribution section.
//    In the Number of elements text field, type 10.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis3").set("numelem", 10);

//    Right-click Mapped 1 and choose Distribution.

    model.component("comp2").mesh("mesh2").feature("map1").create("dis4", "Distribution");

//    Select Edge 31.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis4").selection().set(31);

//    In the Settings window for Distribution, locate the Distribution section.
//    In the Number of elements text field, type 50.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis4").set("numelem", 50);

//    Right-click Mapped 1 and choose Distribution.

    model.component("comp2").mesh("mesh2").feature("map1").create("dis5", "Distribution");

//    Select Edge 30.

    model.component("comp2").mesh("mesh2").feature("map1").feature("dis5").selection().set(30);

//    In the Settings window for Distribution, click Build Selected.

    model.component("comp2").mesh("mesh2").run("map1");

//    In the Definitions toolbar, click Nonlocal Couplings and choose Integration.

    model.component("comp2").cpl().create("intop3", "Integration");
    model.component("comp2").cpl("intop3").set("axisym", true);

//    In the Settings window for Integration, locate the Source Selection section.
//    From the Geometric entity level list, select Point.

    model.component("comp2").cpl("intop3").selection().geom("geom2", 0);

//    Select Point 21.

    model.component("comp2").cpl("intop3").selection().set(21);

//    In the Definitions toolbar, click Nonlocal Couplings and choose Integration.

    model.component("comp2").cpl().create("intop4", "Integration");
    model.component("comp2").cpl("intop4").set("axisym", true);

//    In the Settings window for Integration, locate the Source Selection section.
//    From the Geometric entity level list, select Point.

    model.component("comp2").cpl("intop4").selection().geom("geom2", 0);

//    Select Point 25.

    model.component("comp2").cpl("intop4").selection().set(25);

//    In the Model Builder window, right-click Definitions and choose Variables.

    model.component("comp2").variable().create("var2");

//    In the Settings window for Variables, locate the Variables section.
//    In the table, enter the following settings:

    model.component("comp2").variable("var2")
         .set("angle_shell", "2*atan((intop4(x)-intop3(x))/(intop4(z)-intop3(z)))");
    model.component("comp2").variable("var2").descr("angle_shell", "Blank deformation angle (shell)");

//    In the Home toolbar, click Add Study to open the Add Study window.
//    Find the Studies subsection.
//    In the Select Study tree, select General Studies > Stationary.
//    Find the Physics interfaces in study subsection.
//    In the table, enter the following settings:
//    Click Add Study in the window toolbar.

    model.study().create("std3");
    model.study("std3").create("stat", "Stationary");
    model.study("std3").feature("stat").setSolveFor("/physics/solid", false);

//    In the Home toolbar, click Add Study to close the Add Study window.
//    In the Settings window for Stationary, locate the Study Extensions section.
//    Select the Auxiliary sweep checkbox.

    model.study("std3").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std3").feature("stat").setIndex("pname", "R1", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "", 0);
    model.study("std3").feature("stat").setIndex("punit", "m", 0);
    model.study("std3").feature("stat").setIndex("pname", "R1", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "", 0);
    model.study("std3").feature("stat").setIndex("punit", "m", 0);

//    In the table, enter the following settings:

    model.study("std3").feature("stat").setIndex("pname", "para", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "1e-4 range(2e-2,2e-2,1.5)", 0);
    model.study("std3").feature("stat").setIndex("punit", "", 0);

//    In the Model Builder window, click Study 3.
//    In the Settings window for Study, type Friction (shell) in the Label text field.

    model.study("std3").label("Friction (shell)");

//    In the Study toolbar, click Show Default Solver.

    model.study("std3").showAutoSequences("all");

//    In the Model Builder window, expand the Solution 3 (sol3) node.
//    In the Model Builder window, expand the Friction (shell) > Solver Configurations > Solution 3 (sol3) > Stationary Solver 1 node, then click Parametric 1.
//    In the Settings window for Parametric, locate the Continuation section.
//    Select the Tuning of step size checkbox.

    model.sol("sol3").feature("s1").feature("p1").set("paramtuning", true);

//    In the Initial step size text field, type 2e-2.

    model.sol("sol3").feature("s1").feature("p1").set("pinitstep", "2e-2");

//    In the Minimum step size text field, type 1e-5.

    model.sol("sol3").feature("s1").feature("p1").set("pminstep", "1e-5");

//    In the Maximum step size text field, type 2e-2.

    model.sol("sol3").feature("s1").feature("p1").set("pmaxstep", "2e-2");

//    From the Predictor list, select Linear.

    model.sol("sol3").feature("s1").feature("p1").set("porder", "linear");

//    Right-click Friction (shell) > Solver Configurations > Solution 3 (sol3) > Stationary Solver 1 > Parametric 1 and choose Stop Condition.

    model.sol("sol3").feature("s1").feature("p1").create("st1", "StopCondition");

//    In the Settings window for Stop Condition, locate the Stop Expressions section.
//    Click Add.

    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondarr", "", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "true", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondActive", true, 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopconddesc", "Stop expression 1", 0);

//    In the table, enter the following settings:

    model.sol("sol3").feature("s1").feature("p1").feature("st1")
         .setIndex("stopcondarr", "min(comp2.shell.Tnmax_p3,comp2.shell.Tnmax_p4)-(para>1)", 0);
    model.sol("sol3").feature("s1").feature("p1").feature("st1").setIndex("stopcondterminateon", "negative", 0);

//    Locate the Output at Stop section.
//    From the Add solution list, select Step after stop.

    model.sol("sol3").feature("s1").feature("p1").feature("st1").set("storestopcondsol", "stepafter");

//    Clear the Add information checkbox.

    model.sol("sol3").feature("s1").feature("p1").feature("st1").set("stopcondwarn", false);

//    In the Study toolbar, click Show Default Plots.

    model.study("std3").createAutoSequences("sol");
    model.study("std3").createAutoSequences("jobs");

    model.result().dataset().create("dset4shellshl", "Shell");
    model.result().dataset("dset4shellshl").set("data", "dset4");
    model.result().dataset("dset4shellshl").setIndex("orientationexpr", "shell.nlX", 0);
    model.result().dataset("dset4shellshl").setIndex("displacementexpr", "arx", 0);
    model.result().dataset("dset4shellshl").setIndex("orientationexpr", "shell.nlY", 1);
    model.result().dataset("dset4shellshl").setIndex("displacementexpr", "ary", 1);
    model.result().dataset("dset4shellshl").setIndex("orientationexpr", "shell.nlZ", 2);
    model.result().dataset("dset4shellshl").setIndex("displacementexpr", "arz", 2);
    model.result().dataset("dset4shellshl").set("distanceexpr", "shell.z_pos");
    model.result().dataset("dset4shellshl").set("seplevels", false);
    model.result().dataset("dset4shellshl").set("resolution", 2);
    model.result().dataset("dset4shellshl").set("areascalefactor", "shell.ASF");
    model.result().dataset("dset4shellshl").set("linescalefactor", "shell.LSF");
    model.result().dataset().create("dset4shelllshl", "LayeredMaterial");
    model.result().dataset("dset4shelllshl").set("data", "dset4");
    model.result().create("pg6", "PlotGroup3D");
    model.result("pg6").set("data", "dset4shellshl");
    model.result("pg6").label("Stress (shell)");
    model.result("pg6").set("showlegends", true);
    model.result("pg6").set("frametype", "spatial");
    model.result("pg6").create("surf1", "Surface");
    model.result("pg6").feature("surf1").set("expr", new String[]{"shell.misesGp"});
    model.result("pg6").feature("surf1").set("threshold", "manual");
    model.result("pg6").feature("surf1").set("thresholdvalue", 0.2);
    model.result("pg6").feature("surf1").set("colortable", "Rainbow");
    model.result("pg6").feature("surf1").set("colortabletrans", "none");
    model.result("pg6").feature("surf1").set("colorscalemode", "linear");
    model.result("pg6").feature("surf1").set("descr", "von Mises stress");
    model.result("pg6").feature("surf1").set("colortable", "Prism");
    model.result("pg6").feature("surf1").create("def", "Deform");
    model.result("pg6").feature("surf1").feature("def").set("expr", new String[]{"shell.u", "shell.v", "shell.w"});
    model.result("pg6").feature("surf1").feature("def").set("scaleactive", true);
    model.result("pg6").feature("surf1").feature("def").set("scale", "1");
    model.result("pg6").create("surf2", "Surface");
    model.result("pg6").feature("surf2").set("expr", new String[]{"shell.misesGp"});
    model.result("pg6").feature("surf2").set("threshold", "manual");
    model.result("pg6").feature("surf2").set("thresholdvalue", 0.2);
    model.result("pg6").feature("surf2").set("colortable", "Rainbow");
    model.result("pg6").feature("surf2").set("colortabletrans", "none");
    model.result("pg6").feature("surf2").set("colorscalemode", "linear");
    model.result("pg6").feature("surf2").set("descr", "von Mises stress");
    model.result("pg6").feature("surf2").set("colortable", "Prism");
    model.result("pg6").feature("surf2").create("def", "Deform");
    model.result("pg6").feature("surf2").feature("def").set("expr", new String[]{"shell.u", "shell.v", "shell.w"});
    model.result("pg6").feature("surf2").feature("def").set("scaleactive", true);
    model.result("pg6").feature("surf2").feature("def").set("scale", "1");
    model.result("pg6").feature("surf2").set("inheritplot", "surf1");
    model.result("pg6").feature("surf2").set("data", "dset4shelllshl");
    model.result("pg6").feature("surf2").set("titletype", "none");
    model.result("pg6").feature("surf2").set("solutionparams", "parent");
    model.result("pg6").run();

//    In the Model Builder window, under Friction (shell), click Step 1: Stationary.
//    In the Settings window for Stationary, locate the Results While Solving section.
//    Select the Plot checkbox.

    model.study("std3").feature("stat").set("plot", true);

//    In the table, enter the following settings:

    model.study("std3").feature("stat").setIndex("plotgrouparr", "pg6", 0);

//    In the Study toolbar, click Compute.

    model.study("std3").createAutoSequences("all");

    model.sol("sol3").runAll();

    model.result("pg6").run();
    model.result("pg6").run();

//    In the Model Builder window, expand the Stress (shell) node.
//    Right-click Surface 1 and choose Delete.

    model.result("pg6").feature().remove("surf1");
    model.result("pg6").run();
    model.result("pg6").run();

//    In the Model Builder window, under Results, click Stress (shell).
//    In the Stress (shell) toolbar, click Plot.

    model.result("pg6").run();

//    In the Settings window for 3D Plot Group, locate the Data section.
//    From the Dataset list, select Friction (shell)/Solution 3 (4) (sol3).

    model.result("pg6").set("data", "dset4");

//    From the Parameter value (para) list, select 1.

    model.result("pg6").setIndex("looplevel", 51, 0);
    model.result("pg6").run();

//    In the Model Builder window, click Surface 2.
//    In the Stress (shell) toolbar, click Plot.

    model.result("pg6").run();

//    In the tree, select Friction (shell)/Solution 3 (4) (sol3) > Shell > Equivalent Plastic Strain (shell).
//    Click Add Result Template in the window toolbar.

    model.result().create("pg7", "PlotGroup3D");
    model.result("pg7").set("data", "dset4shelllshl");
    model.result("pg7").setIndex("looplevel", 73, 0);
    model.result("pg7").label("Equivalent Plastic Strain (shell)");
    model.result("pg7").create("surf1", "Surface");
    model.result("pg7").feature("surf1").set("expr", new String[]{"shell.epeGp"});
    model.result("pg7").feature("surf1").set("inheritplot", "none");
    model.result("pg7").feature("surf1").set("resolution", "normal");
    model.result("pg7").feature("surf1").set("refine", 2);
    model.result("pg7").feature("surf1").set("colortabletype", "discrete");
    model.result("pg7").feature("surf1").set("bandcount", 11);

    return model;
  }

  public static Model run4(Model model) {
    model.result("pg7").feature("surf1").set("colortable", "AuroraAustralisDark");
    model.result("pg7").feature("surf1").set("descractive", true);
    model.result("pg7").feature("surf1").set("descr", "Equivalent plastic strain");
    model.result("pg7").label("Equivalent Plastic Strain (shell)");
    model.result("pg7").run();

//    In the Results toolbar, click Result Templates to close the Result Templates window.

    model.result("pg7").run();

//    In the Model Builder window, expand the Equivalent Plastic Strain (shell) node.
//    Right-click Surface 1 and choose Deformation.

    model.result("pg7").feature("surf1").create("def1", "Deform");
    model.result("pg7").run();

//    In the Settings window for Deformation, locate the Expression section.
//    In the x-component text field, type shell.u.

    model.result("pg7").feature("surf1").feature("def1").set("expr", new String[]{"shell.u", "v2", "w2"});

//    In the y-component text field, type shell.v.

    model.result("pg7").feature("surf1").feature("def1").set("expr", new String[]{"shell.u", "shell.v", "w2"});

//    In the z-component text field, type shell.w.

    model.result("pg7").feature("surf1").feature("def1").setIndex("expr", "shell.w", 2);

//    Locate the Scale section.
//    Select the Scale factor checkbox.

    model.result("pg7").feature("surf1").feature("def1").set("scaleactive", true);

//    In the associated text field, type 1.

    model.result("pg7").feature("surf1").feature("def1").set("scale", 1);

//    In the Equivalent Plastic Strain (shell) toolbar, click Plot.

    model.result("pg7").run();

//    In the Model Builder window, right-click Deformation Angle (Friction) and choose Duplicate.

    model.result().numerical().duplicate("gev3", "gev2");

//    In the Settings window for Global Evaluation, type Deformation angle (Shell) in the Label text field.

    model.result().numerical("gev3").label("Deformation angle (Shell)");

//    Locate the Data section.
//    From the Dataset list, select Friction (shell)/Solution 3 (4) (sol3).

    model.result().numerical("gev3").set("data", "dset4");

//    In the Parameter values (para) list, select 1, 1.4.

    model.result().numerical("gev3").setIndex("looplevel", new int[]{51, 71}, 0);

//    Locate the Expressions section.
//    In the table, enter the following settings:

    model.result().numerical("gev3").setIndex("expr", "angle_shell", 0);
    model.result().numerical("gev3").setIndex("unit", "deg", 0);
    model.result().numerical("gev3").setIndex("descr", "Blank deformation angle (shell)", 0);

//    Click ^ next to Evaluate then choose New Table.

    model.result().table().create("tbl4", "Table");
    model.result().table("tbl4").comments("Deformation angle (Shell)");
    model.result().numerical("gev3").set("table", "tbl4");
    model.result().numerical("gev3").setResult();
    model.result("pg3").run();

//    In the Model Builder window, right-click Results > Punch Force vs. Displacement > Global 2 and choose Duplicate.

    model.result("pg3").feature().duplicate("glob3", "glob2");
    model.result("pg3").run();

//    In the Settings window for Global, locate the Data section.
//    From the Dataset list, select Friction (shell)/Solution 3 (4) (sol3).

    model.result("pg3").feature("glob3").set("data", "dset4");

//    Locate the y-Axis Data section.
//    In the table, enter the following settings:

    model.result("pg3").feature("glob3").setIndex("expr", "4*shell.dcnt2.T_totz", 0);
    model.result("pg3").feature("glob3").setIndex("unit", "N", 0);

//    Locate the Coloring and Style section.
//    Find the Line style subsection.
//    From the Line list, select Dash-dot.

    model.result("pg3").feature("glob3").set("linestyle", "dashdot");

//    Locate the Legends section.
//    In the table, enter the following settings:

    model.result("pg3").feature("glob3").setIndex("legends", "Shell", 0);

//    In the Punch Force vs. Displacement toolbar, click Plot.

    model.result("pg3").run();
    model.result("pg6").run();

    model.title("Sheet Metal Forming");

    model
         .description("Plastic metal forming using a rigid punch is simulated. The model computes the punch forces during forming and plate shape after unloading (\"springback\"). Solutions are computed using both a solid 2D plane strain and a 3D shell model. The results are compared with experimental data.");

    return model;
  }

  public static void main(String[] args) {
    Model model = run();
    model = run2(model);
    model = run3(model);
    run4(model);
  }

}
