/*
 * porous_absorber.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 15 2026, 10:25 by COMSOL 6.4.0.421. */
public class porous_absorber {

  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 Acoustics > Pressure Acoustics > Pressure Acoustics, Frequency Domain (acpr).
//    Click Add.
//    Click Study.
//    In the Select Study tree, select General Studies > Frequency Domain.
//    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("acpr", "PressureAcoustics", "geom1");

    model.study().create("std1");
    model.study("std1").create("freq", "Frequency");

//    Load the parameters for the model. The list of parameters include geometry definitions, definitions used in the mesh, and material parameters for the melamine foam.
//    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 porous_absorber_parameters.txt.
//    To import content from file, use:
//    model.param().loadFile("FILENAME");
    model.param().set("f_max", "10[kHz]", "Maximal frequency in the model");
    model.param().set("lambda_min", "343[m/s]/f_max", "Minimal wavelength");
    model.param().set("theta0", "0[deg]", "Incident wave angle");
    model.param().set("W", "20[cm]", "Domain width");
    model.param().set("H", "40[cm]", "Air domain height");
    model.param().set("Hp", "10[cm]", "Porous layer height");
    model.param().set("a", "2.5[cm]", "Inclusion radius");
    model.param().set("Hpml", "20[cm]", "PML Domain Height");
    model.param().set("mu0", "1.8e-5[Pa*s]", "Dynamic viscosity of air");
    model.param().set("epsilonP0", "0.995", "Melamine foam porosity");
    model.param().set("Rf0", "10.5e3[Pa*s/m^2]", "Flow resistivity");
    model.param().set("tau0", "1.0059", "Tortuosity");
    model.param().set("Lv0", "240[um]", "Viscous characteristic length");
    model.param().set("Lth0", "470[um]", "Thermal characteristic length");

//    In the Geometry toolbar, click Rectangle.

    model.component("comp1").geom("geom1").create("r1", "Rectangle");

//    In the Settings window for Rectangle, locate the Size and Shape section.
//    In the Width text field, type W.

    model.component("comp1").geom("geom1").feature("r1").set("size", new String[]{"W", "1"});

//    In the Height text field, type H+Hp.

    model.component("comp1").geom("geom1").feature("r1").set("size", new String[]{"W", "H+Hp"});

//    Locate the Position section.
//    In the y text field, type 0.
//    In the y text field, type -Hp.

    model.component("comp1").geom("geom1").feature("r1").set("pos", new String[]{"0", "-Hp"});

//    Click to expand the Layers section.
//    In the table, enter the following settings:

    model.component("comp1").geom("geom1").feature("r1").setIndex("layer", "Hp", 0);

//    In the Geometry toolbar, click Circle.

    model.component("comp1").geom("geom1").run("r1");
    model.component("comp1").geom("geom1").create("c1", "Circle");

//    In the Settings window for Circle, locate the Size and Shape section.
//    In the Radius text field, type a.

    model.component("comp1").geom("geom1").feature("c1").set("r", "a");

//    Locate the Position section.
//    In the x text field, type W/2.

    model.component("comp1").geom("geom1").feature("c1").set("pos", new String[]{"W/2", "0"});

//    In the y text field, type -Hp/2.

    model.component("comp1").geom("geom1").feature("c1").set("pos", new String[]{"W/2", "-Hp/2"});

//    In the Geometry toolbar, click Booleans and Partitions and choose Difference.

    model.component("comp1").geom("geom1").run("c1");
    model.component("comp1").geom("geom1").create("dif1", "Difference");

//    Select the object r1.

    model.component("comp1").geom("geom1").feature("dif1").selection("input").set("r1");

//    In the Settings window for Difference, locate the Difference section.
//    Select the Activate Selection toggle button for Objects to subtract.
//    Select the object c1.

    model.component("comp1").geom("geom1").feature("dif1").selection("input2").set("c1");

//    Click Build All Objects.

    model.component("comp1").geom("geom1").runPre("fin");

//    Click the Zoom Extents button in the Graphics toolbar.
//    The geometry should look like that in the figure below.
//    In the Definitions toolbar, click Local Variables.

    model.component("comp1").variable().create("var1");

    model.component("comp1").geom("geom1").run();

//    In the Settings window for Variables, type Variables 1 - Z and alpha in the Label text field.

    model.component("comp1").variable("var1").label("Variables 1 - Z and alpha");

//    Locate the Variables section.
//    Click Load from File.
//    Browse to the model's Application Library folder and double-click the file porous_absorber_variables.txt.
//    To import content from file, use:
//    model.component("comp1").variable("var1").loadFile("FILENAME");
    model.component("comp1").variable("var1").set("kx_e", "sin(theta0)", "Plane wave direction, x");
    model.component("comp1").variable("var1").set("ky_e", "-cos(theta0)", "Plane wave direction, y");
    model.component("comp1").variable("var1").set("k0", "intop2(acpr.k)", "Free-field wave number");
    model.component("comp1").variable("var1").set("kx", "k0*kx_e", "Incident plane wave k_x");
    model.component("comp1").variable("var1").set("ky", "k0*ky_e", "Incident plane wave k_y");
    model.component("comp1").variable("var1")
         .set("Z", "aveop2(acpr.p_t/(-nx*up(acpr.vx)-ny*up(acpr.vy)))/intop2(acpr.rho*acpr.c)", "Specific surface normal impedance");
    model.component("comp1").variable("var1")
         .set("R", "aveop1(acpr.pport1.p_out/acpr.pport1.p_in)", "Reflection coefficient (averaged)");
    model.component("comp1").variable("var1").set("alpha_R", "1-abs(R)^2", "Absorption coefficient (based on R)");
    model.component("comp1").variable("var1").set("Pin", "acpr.pport1.P_in", "Incident power");
    model.component("comp1").variable("var1").set("Pout", "acpr.pport1.P_out_tot", "Outgoing power");
    model.component("comp1").variable("var1").set("alpha", "1-Pout/Pin", "Absorption coefficient");

//    In the Definitions toolbar, click Local Variables.

    model.component("comp1").variable().create("var2");

//    In the Settings window for Variables, type Variables 2 - Analytical in the Label text field.

    model.component("comp1").variable("var2").label("Variables 2 - Analytical");

//    Locate the Variables section.
//    Click Load from File.
//    Browse to the model's Application Library folder and double-click the file porous_absorber_analytical.txt.
//    To import content from file, use:
//    model.component("comp1").variable("var2").loadFile("FILENAME");
    model.component("comp1").variable("var2")
         .set("Z_ana", "aveop1(-i*intop1(acpr.Z)*intop1(acpr.k)/kx_ana*cot(kx_ana*Hp))/intop2(acpr.rho*acpr.c)", "Specific surface normal impedance (analytical)");
    model.component("comp1").variable("var2").set("ky_ana", "intop2(acpr.k)*sin(theta0)");
    model.component("comp1").variable("var2").set("kx_ana", "sqrt(intop1(acpr.k)^2-ky_ana^2)");
    model.component("comp1").variable("var2")
         .set("R_ana", "(Z_ana*cos(theta0)-1)/(Z_ana*cos(theta0)+1)", "Reflection coefficient (analytical)");
    model.component("comp1").variable("var2")
         .set("alpha_ana", "1-abs(R_ana)^2", "Absorption coefficient (analytical)");

//    Define two nonlocal integration couplings that act on points in the geometry. You will use them later to map (or probe) values from these points. One in the porous domain and one in the air domain.
//    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 1.

    model.component("comp1").cpl("intop1").selection().set(1);

//    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 3.

    model.component("comp1").cpl("intop2").selection().set(3);

//    Define an average and integration coupling on the periodic port and one on the porous-air interface. They will help compute the average reflection coefficient as well as incident and reflected powers.
//    In the Definitions toolbar, click Nonlocal Couplings and choose Average.

    model.component("comp1").cpl().create("aveop1", "Average");
    model.component("comp1").cpl("aveop1").set("axisym", true);

//    In the Settings window for Average, locate the Source Selection section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp1").cpl("aveop1").selection().geom("geom1", 1);

//    Select Boundary 5.

    model.component("comp1").cpl("aveop1").selection().set(5);

//    In the Definitions toolbar, click Nonlocal Couplings and choose Average.

    model.component("comp1").cpl().create("aveop2", "Average");
    model.component("comp1").cpl("aveop2").set("axisym", true);

//    In the Settings window for Average, locate the Source Selection section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp1").cpl("aveop2").selection().geom("geom1", 1);

//    Select Boundary 4.

    model.component("comp1").cpl("aveop2").selection().set(4);

//    Now proceed to set up the material properties. Add air as the default domain material and create a new material to define the melamine foam porosity.
//    In the Materials toolbar, click Add Material to open the Add Material window.
//    In the tree, select Built-in > Air.
//    Click Add to Component in the window toolbar.

    model.component("comp1").material().create("mat1", "Common");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("eta", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("Cp", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("rho", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("k", "Piecewise");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("cs", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("an1", "Analytic");
    model.component("comp1").material("mat1").propertyGroup("def").func().create("an2", "Analytic");
    model.component("comp1").material("mat1").propertyGroup()
         .create("RefractiveIndex", "RefractiveIndex", "Refractive index");
    model.component("comp1").material("mat1").propertyGroup()
         .create("NonlinearModel", "NonlinearModel", "Nonlinear model");
    model.component("comp1").material("mat1").propertyGroup().create("idealGas", "idealGas", "Ideal gas");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func().create("Cp", "Piecewise");
    model.component("comp1").material("mat1").label("Air");
    model.component("comp1").material("mat1").set("family", "air");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta")
         .set("pieces", new String[][]{{"200.0", "1600.0", "-8.38278E-7+8.35717342E-8*T^1-7.69429583E-11*T^2+4.6437266E-14*T^3-1.06585607E-17*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("eta").set("fununit", "Pa*s");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp")
         .set("pieces", new String[][]{{"200.0", "1600.0", "1047.63657-0.372589265*T^1+9.45304214E-4*T^2-6.02409443E-7*T^3+1.2858961E-10*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("Cp").set("fununit", "J/(kg*K)");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("expr", "pA*0.02897/R_const[K*mol/J]/T");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho").set("args", new String[]{"pA", "T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho").set("fununit", "kg/m^3");
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("argunit", new String[]{"Pa", "K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotaxis", new String[]{"off", "on"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotfixedvalue", new String[]{"101325", "273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("rho")
         .set("plotargs", new String[][]{{"pA", "101325", "101325"}, {"T", "273.15", "293.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("def").func("k")
         .set("pieces", new String[][]{{"200.0", "1600.0", "-0.00227583562+1.15480022E-4*T^1-7.90252856E-8*T^2+4.11702505E-11*T^3-7.43864331E-15*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("def").func("k").set("fununit", "W/(m*K)");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("expr", "sqrt(1.4*R_const[K*mol/J]/0.02897*T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("args", new String[]{"T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("fununit", "m/s");
    model.component("comp1").material("mat1").propertyGroup("def").func("cs").set("argunit", new String[]{"K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("plotfixedvalue", new String[]{"273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("cs")
         .set("plotargs", new String[][]{{"T", "273.15", "373.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("funcname", "alpha_p");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("expr", "-1/rho(pA,T)*d(rho(pA,T),T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("args", new String[]{"pA", "T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1").set("fununit", "1/K");
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("argunit", new String[]{"Pa", "K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotaxis", new String[]{"off", "on"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotfixedvalue", new String[]{"101325", "273.15"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an1")
         .set("plotargs", new String[][]{{"pA", "101325", "101325"}, {"T", "273.15", "373.15"}});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("funcname", "muB");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("expr", "0.6*eta(T)");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("args", new String[]{"T"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("fununit", "Pa*s");
    model.component("comp1").material("mat1").propertyGroup("def").func("an2").set("argunit", new String[]{"K"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2")
         .set("plotfixedvalue", new String[]{"200"});
    model.component("comp1").material("mat1").propertyGroup("def").func("an2")
         .set("plotargs", new String[][]{{"T", "200", "1600"}});
    model.component("comp1").material("mat1").propertyGroup("def").set("thermalexpansioncoefficient", "");
    model.component("comp1").material("mat1").propertyGroup("def").set("molarmass", "");
    model.component("comp1").material("mat1").propertyGroup("def").set("bulkviscosity", "");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("thermalexpansioncoefficient", new String[]{"alpha_p(pA,T)", "0", "0", "0", "alpha_p(pA,T)", "0", "0", "0", "alpha_p(pA,T)"});
    model.component("comp1").material("mat1").propertyGroup("def").set("molarmass", "0.02897[kg/mol]");
    model.component("comp1").material("mat1").propertyGroup("def").set("bulkviscosity", "muB(T)");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("relpermeability", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("relpermittivity", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("def").set("dynamicviscosity", "eta(T)");
    model.component("comp1").material("mat1").propertyGroup("def").set("ratioofspecificheat", "1.4");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("electricconductivity", new String[]{"0[S/m]", "0", "0", "0", "0[S/m]", "0", "0", "0", "0[S/m]"});
    model.component("comp1").material("mat1").propertyGroup("def").set("heatcapacity", "Cp(T)");
    model.component("comp1").material("mat1").propertyGroup("def").set("density", "rho(pA,T)");
    model.component("comp1").material("mat1").propertyGroup("def")
         .set("thermalconductivity", new String[]{"k(T)", "0", "0", "0", "k(T)", "0", "0", "0", "k(T)"});
    model.component("comp1").material("mat1").propertyGroup("def").set("soundspeed", "cs(T)");
    model.component("comp1").material("mat1").propertyGroup("def").addInput("temperature");
    model.component("comp1").material("mat1").propertyGroup("def").addInput("pressure");
    model.component("comp1").material("mat1").propertyGroup("RefractiveIndex")
         .set("n", new String[]{"1", "0", "0", "0", "1", "0", "0", "0", "1"});
    model.component("comp1").material("mat1").propertyGroup("NonlinearModel").set("BA", "def.gamma-1");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").label("Piecewise 2");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("arg", "T");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp")
         .set("pieces", new String[][]{{"200.0", "1600.0", "1047.63657-0.372589265*T^1+9.45304214E-4*T^2-6.02409443E-7*T^3+1.2858961E-10*T^4"}});
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("argunit", "K");
    model.component("comp1").material("mat1").propertyGroup("idealGas").func("Cp").set("fununit", "J/(kg*K)");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("Rs", "R_const/Mn");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("heatcapacity", "Cp(T)");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("ratioofspecificheat", "1.4");
    model.component("comp1").material("mat1").propertyGroup("idealGas").set("molarmass", "0.02897[kg/mol]");
    model.component("comp1").material("mat1").propertyGroup("idealGas").addInput("temperature");
    model.component("comp1").material("mat1").propertyGroup("idealGas").addInput("pressure");
    model.component("comp1").material("mat1").materialType("nonSolid");

//    In the Materials toolbar, click Add Material to close the Add Material window.
//    In the Model Builder window, right-click Component 1 (comp1) > Materials and choose Blank Material.

    model.component("comp1").material().create("mat2", "Common");

//    In the Settings window for Material, type Melamine Foam in the Label text field.

    model.component("comp1").material("mat2").label("Melamine Foam");

//    Select Domain 1.

    model.component("comp1").material("mat2").selection().set(1);

//    Click to expand the Material Properties section.
//    In the Material properties tree, select Basic Properties > Porosity.
//    Click Add to Material.

    model.component("comp1").material("mat2").propertyGroup("def").set("porosity", "");

//    Locate the Material Contents section.
//    In the table, enter the following settings:

    model.component("comp1").material("mat2").propertyGroup("def").set("porosity", new String[]{"epsilonP0"});

//    Locate the Material Properties section.
//    In the Material properties tree, select Acoustics > Poroacoustics Model > Thermal characteristic length (Lth).
//    Click Add to Material.

    model.component("comp1").material("mat2").propertyGroup()
         .create("PoroacousticsModel", "PoroacousticsModel", "Poroacoustics_model");

//    Locate the Material Contents section.
//    In the table, enter the following settings:

    model.component("comp1").material("mat2").propertyGroup("PoroacousticsModel").set("Rf", new String[]{"Rf0"});
    model.component("comp1").material("mat2").propertyGroup("PoroacousticsModel").set("Lth", new String[]{"Lth0"});
    model.component("comp1").material("mat2").propertyGroup("PoroacousticsModel").set("Lv", new String[]{"Lv0"});
    model.component("comp1").material("mat2").propertyGroup("PoroacousticsModel").set("tau", new String[]{"tau0"});

//    Notice that the parameter for the tortuosity is called tau0, not to be confused with the material property of the static viscous tortuosity.
//    Now set up the physics and the boundary conditions.
//    In the Physics toolbar, click Domains and choose Poroacoustics.

    model.component("comp1").physics("acpr").create("pom1", "PoroacousticsModel", 2);

//    Select Domain 1.

    model.component("comp1").physics("acpr").feature("pom1").selection().set(1);

//    In the Settings window for Poroacoustics, locate the Poroacoustics Model section.
//    From the Poroacoustics model list, select Johnson–Champoux–Allard (JCA).

    model.component("comp1").physics("acpr").feature("pom1").set("FluidModel", "JohnsonChampouxAllard");

//    Locate the Fluid Properties section.
//    From the Fluid material list, select Air (mat1).

    model.component("comp1").physics("acpr").feature("pom1").set("FluidMaterial", "mat1");

//    In the Physics toolbar, click Boundaries and choose Periodic Condition.

    model.component("comp1").physics("acpr").create("pc1", "PeriodicCondition", 1);

//    Select Boundaries 1, 3, 6, 7.

    model.component("comp1").physics("acpr").feature("pc1").selection().set(1, 3, 6, 7);

//    In the Settings window for Periodic Condition, locate the Periodicity Settings section.
//    From the Type of periodicity list, select Floquet periodicity.

    model.component("comp1").physics("acpr").feature("pc1").set("PeriodicType", "Floquet");

//    Come back and select the k-vector from the <l>Periodic Port</l> after defining it.
//    In the Physics toolbar, click Boundaries and choose Periodic Port.

    model.component("comp1").physics("acpr").create("pport1", "PeriodicPort", 1);

//    Select Boundary 5.

    model.component("comp1").physics("acpr").feature("pport1").selection().set(5);

//    In the Settings window for Periodic Port, locate the Port Mode Settings section.
//    In the \[A_\textrm{p}^\textrm{in}\] text field, type 1.

    model.component("comp1").physics("acpr").feature("pport1").set("pamp", 1);

//    In the \[\theta_{\textrm{in}}\] text field, type theta0.

    model.component("comp1").physics("acpr").feature("pport1").set("thetai", "theta0");

//    Proceed and add the necessary number of <l>Diffraction Order Port</l> subfeatures. In this model the diffraction orders m from -10 to 6 are needed. This is discussed in the model documentation.
//    In the Physics toolbar, click Attributes and choose Diffraction Order Port.

    model.component("comp1").physics("acpr").feature("pport1").create("dport1", "DiffractionOrderPort", 1);

//    In the Settings window for Diffraction Order Port, locate the Diffraction Order Port section.
//    In the \[m\] text field, type -1.

    model.component("comp1").physics("acpr").feature("pport1").feature("dport1").setIndex("m", -1, 0);

//    In the Model Builder window, click Periodic Port 1.
//    In the Physics toolbar, click Attributes and choose Diffraction Order Port.

    model.component("comp1").physics("acpr").feature("pport1").create("dport2", "DiffractionOrderPort", 1);

//    In the Settings window for Diffraction Order Port, locate the Diffraction Order Port section.
//    In the \[m\] text field, type -2.

    model.component("comp1").physics("acpr").feature("pport1").feature("dport2").setIndex("m", -2, 0);

//    Repeat this step for the remaining diffraction orders m, such that all from -10 to 6 are included.

    model.component("comp1").physics("acpr").feature("pport1").create("dport3", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport3").setIndex("m", -3, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport4", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport4").setIndex("m", -4, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport5", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport5").setIndex("m", -5, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport6", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport6").setIndex("m", -6, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport7", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport7").setIndex("m", -7, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport8", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport8").setIndex("m", -8, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport9", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport9").setIndex("m", -9, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport10", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport10").setIndex("m", -10, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport11", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport11").setIndex("m", 1, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport12", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport12").setIndex("m", 2, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport13", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport13").setIndex("m", 3, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport14", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport14").setIndex("m", 4, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport15", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport15").setIndex("m", 5, 0);
    model.component("comp1").physics("acpr").feature("pport1").create("dport16", "DiffractionOrderPort", 1);
    model.component("comp1").physics("acpr").feature("pport1").feature("dport16").setIndex("m", 6, 0);

//    Now all the necessary diffraction orders are included to get the full expansion at the periodic port. Make the final setting on the periodic condition.
//    In the Model Builder window, under Component 1 (comp1) > Pressure Acoustics, Frequency Domain (acpr), click Periodic Condition 1.
//    In the Settings window for Periodic Condition, locate the Periodicity Settings section.
//    From the \[\mathbf{k}_{\textrm{F}}\] list, select Periodic port Floquet wave number vector (acpr/pport1).

    model.component("comp1").physics("acpr").feature("pc1").set("kFloquet_src", "root.comp1.acpr.pport1.kitx");

//    In the Mesh toolbar, click More Attributes and choose Identical Mesh.

    model.component("comp1").mesh("mesh1").create("id1", "IdenticalMesh");

//    Select Boundary 1.

    model.component("comp1").mesh("mesh1").feature("id1").selection("group1").set(1);

//    In the Settings window for Identical Mesh, locate the Second Entity Group section.
//    Select the Activate Selection toggle button.
//    Select Boundary 6.

    model.component("comp1").mesh("mesh1").feature("id1").selection("group2").set(6);

//    In the Mesh toolbar, click Free Triangular.

    model.component("comp1").mesh("mesh1").create("ftri1", "FreeTri");

//    In the Settings window for Free Triangular, locate the Domain Selection section.
//    From the Geometric entity level list, select Domain.

    model.component("comp1").mesh("mesh1").feature("ftri1").selection().geom("geom1", 2);

//    Select Domain 1.

    model.component("comp1").mesh("mesh1").feature("ftri1").selection().set(1);

//    In the Model Builder window, click Size.
//    In the Settings window for Size, locate the Element Size section.
//    Click the Custom button.

    model.component("comp1").mesh("mesh1").feature("size").set("custom", true);

//    Locate the Element Size Parameters section.
//    In the Maximum element size text field, type lambda_min/5.

    model.component("comp1").mesh("mesh1").feature("size").set("hmax", "lambda_min/5");

//    This mesh resolves the smallest wavelength of the study <c>lambda_min</c> with 5 elements.
//    In the Mesh toolbar, click Mapped.

    model.component("comp1").mesh("mesh1").create("map1", "Map");

//    In the Settings window for Mapped, click Build All.

    model.component("comp1").mesh("mesh1").run();

//    In the Model Builder window, click Mesh 1.
//    In the Model Builder window, under Study 1, click Step 1: Frequency Domain.
//    In the Settings window for Frequency Domain, locate the Study Settings section.
//    Click Range.
//    In the Range dialog, choose ISO preferred frequencies from the Entry method list.
//    In the Start frequency text field, type 10.
//    In the Stop frequency text field, type 800.
//    From the Interval list, select 1/3 octave.
//    Click Replace.

    model.study("std1").feature("freq")
         .set("plist", "{10, 12.5, 16, 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800}");

//    In the Settings window for Frequency Domain, locate the Study Settings section.
//    Click Range.

    return model;
  }

  public static Model run2(Model model) {
//    In the Range dialog, type 825 in the Start frequency text field.
//    In the Stop frequency text field, type 10000.
//    From the Interval list, select 1/24 octave.
//    Click Add.

    model.study("std1").feature("freq")
         .set("plist", "{10, 12.5, 16, 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800} {825, 850, 875, 900, 925, 950, 975, 1e3, 1.03e3, 1.06e3, 1.09e3, 1.12e3, 1.15e3, 1.18e3, 1.22e3, 1.25e3, 1.28e3, 1.32e3, 1.36e3, 1.4e3, 1.45e3, 1.5e3, 1.55e3, 1.6e3, 1.65e3, 1.7e3, 1.75e3, 1.8e3, 1.85e3, 1.9e3, 1.95e3, 2e3, 2.06e3, 2.12e3, 2.18e3, 2.24e3, 2.3e3, 2.36e3, 2.43e3, 2.5e3, 2.58e3, 2.65e3, 2.72e3, 2.8e3, 2.9e3, 3e3, 3.07e3, 3.15e3, 3.25e3, 3.35e3, 3.45e3, 3.55e3, 3.65e3, 3.75e3, 3.87e3, 4e3, 4.12e3, 4.25e3, 4.37e3, 4.5e3, 4.62e3, 4.75e3, 4.87e3, 5e3, 5.15e3, 5.3e3, 5.45e3, 5.6e3, 5.8e3, 6e3, 6.15e3, 6.3e3, 6.5e3, 6.7e3, 6.9e3, 7.1e3, 7.3e3, 7.5e3, 7.75e3, 8e3, 8.25e3, 8.5e3, 8.75e3, 9e3, 9.25e3, 9.5e3, 9.75e3, 1e4}");

//    This frequency request uses ISO preferred sequences with a third octave spacing for low frequencies and a 24th octave spacing at higher frequencies. Add a parametric sweep over the incidence angle <c>theta0</c> for the values \[0^o\] and \[45^o\].
//    In the Study toolbar, click Parametric Sweep.

    model.study("std1").create("param", "Parametric");

//    In the Settings window for Parametric Sweep, locate the Study Settings section.
//    Click Add.

    model.study("std1").feature("param").setIndex("pname", "f_max", 0);
    model.study("std1").feature("param").setIndex("plistarr", "", 0);
    model.study("std1").feature("param").setIndex("punit", "Hz", 0);
    model.study("std1").feature("param").setIndex("pname", "f_max", 0);
    model.study("std1").feature("param").setIndex("plistarr", "", 0);
    model.study("std1").feature("param").setIndex("punit", "Hz", 0);

//    In the table, enter the following settings:

    model.study("std1").feature("param").setIndex("pname", "theta0", 0);
    model.study("std1").feature("param").setIndex("plistarr", "0[deg] 45[deg]", 0);
    model.study("std1").feature("param").setIndex("punit", "deg", 0);

//    In the Study toolbar, click Compute.

    model.study("std1").createAutoSequences("all");

    model.sol().create("sol2");
    model.sol("sol2").study("std1");
    model.sol("sol2").label("Parametric Solutions 1");

    model.batch("p1").feature("so1").set("psol", "sol2");
    model.batch("p1").run("compute");

    model.result().create("pg1", "PlotGroup2D");
    model.result("pg1").set("data", "dset2");
    model.result("pg1").setIndex("looplevel", 108, 0);
    model.result("pg1").setIndex("looplevel", 2, 1);
    model.result("pg1").create("surf1", "Surface");
    model.result("pg1").feature("surf1").set("expr", new String[]{"acpr.p_t"});
    model.result("pg1").feature("surf1").set("colortable", "Wave");
    model.result("pg1").feature("surf1").set("colorscalemode", "linearsymmetric");
    model.result("pg1").set("showlegendsunit", true);
    model.result("pg1").label("Acoustic Pressure (acpr)");
    model.result().create("pg2", "PlotGroup2D");
    model.result("pg2").set("data", "dset2");
    model.result("pg2").setIndex("looplevel", 108, 0);
    model.result("pg2").setIndex("looplevel", 2, 1);
    model.result("pg2").create("surf1", "Surface");
    model.result("pg2").feature("surf1").set("expr", new String[]{"acpr.Lp_t"});
    model.result("pg2").feature("surf1").set("colortable", "Rainbow");
    model.result("pg2").feature("surf1").set("colorscalemode", "linear");
    model.result("pg2").set("showlegendsunit", true);
    model.result("pg2").label("Sound Pressure Level (acpr)");
    model.result("pg1").run();

//    Create an array dataset that will help you plot the Floquet periodic solution on several unit cells.
//    In the Results toolbar, click More Datasets and choose Array 2D.

    model.result().dataset().create("arr1", "Array2D");

//    In the Settings window for Array 2D, locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result().dataset("arr1").set("data", "dset2");

//    Locate the Array Size section.
//    In the X size text field, type 4.

    model.result().dataset("arr1").set("fullsize", new int[]{4, 1});

//    Enable <l>Floquet-Bloch periodicity</l> and enter the <l>Wave vector</l> to visualize the periodic solution.
//    Click to expand the Advanced section.
//    Select the Floquet–Bloch periodicity checkbox.

    model.result().dataset("arr1").set("floquetper", true);

//    Find the Wave vector subsection.
//    In the X text field, type kx.

    model.result().dataset("arr1").set("wavevector", new String[]{"kx", "0"});

//    In the Y text field, type ky.

    model.result().dataset("arr1").set("wavevector", new String[]{"kx", "ky"});
    model.result("pg1").run();

//    In the Model Builder window, under Results, click Acoustic Pressure (acpr).
//    In the Settings window for 2D Plot Group, type Acoustic Pressure in the Label text field.

    model.result("pg1").label("Acoustic Pressure");

//    Locate the Data section.
//    From the Dataset list, select Array 2D 1.

    model.result("pg1").set("data", "arr1");
    model.result("pg1").run();

//    In the Model Builder window, expand the Acoustic Pressure node, then click Surface 1.
//    In the Acoustic Pressure toolbar, click Plot.

    model.result("pg1").run();

//    Click the Zoom Extents button in the Graphics toolbar.
//    Now change the incidence angle from \[45^o\] to \[0^o\].

    model.result("pg1").run();

//    In the Model Builder window, click Acoustic Pressure.
//    In the Settings window for 2D Plot Group, locate the Data section.
//    From the Parameter value (theta0 (deg)) list, select 0.

    model.result("pg1").setIndex("looplevel", 1, 1);

//    In the Acoustic Pressure toolbar, click Plot.

    model.result("pg1").run();

//    Click the Zoom Extents button in the Graphics toolbar.
//    The result should look like that in the following figure.

    model.result("pg2").run();

//    In the Model Builder window, under Results, click Sound Pressure Level (acpr).
//    In the Settings window for 2D Plot Group, type Sound Pressure Level in the Label text field.

    model.result("pg2").label("Sound Pressure Level");

//    Locate the Data section.
//    From the Dataset list, select Array 2D 1.

    model.result("pg2").set("data", "arr1");

//    Next, create 1D plots to depict the absorption properties of the melamine absorber.
//    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 Point Pressure in the Label text field.

    model.result("pg3").label("Point Pressure");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result("pg3").set("data", "dset2");

//    Click to expand the Title section.
//    From the Title type list, select Label.

    model.result("pg3").set("titletype", "label");

//    Right-click Point Pressure and choose Point Graph.

    model.result("pg3").create("ptgr1", "PointGraph");
    model.result("pg3").feature("ptgr1").set("markerpos", "datapoints");
    model.result("pg3").feature("ptgr1").set("linewidth", "preference");

//    Select Point 2.

    model.result("pg3").feature("ptgr1").selection().set(2);

//    In the Settings window for Point Graph, click to expand the Legends section.
//    Select the Show legends checkbox.

    model.result("pg3").feature("ptgr1").set("legend", true);

//    In the Point Pressure toolbar, click Plot.

    model.result("pg3").run();

//    Click the x-Axis Log Scale button in the Graphics toolbar.

    model.result("pg3").set("xlog", true);

//    In the Results toolbar, click 1D Plot Group.

    model.result().create("pg4", "PlotGroup1D");
    model.result("pg4").run();

//    In the Settings window for 1D Plot Group, type Normal Impedance in the Label text field.

    model.result("pg4").label("Normal Impedance");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result("pg4").set("data", "dset2");

//    Locate the Title section.
//    From the Title type list, select Label.

    model.result("pg4").set("titletype", "label");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg4").set("xlabelactive", true);

//    In the associated text field, type f (Hz).

    model.result("pg4").set("xlabel", "f (Hz)");

//    Select the y-axis label checkbox.

    model.result("pg4").set("ylabelactive", true);

//    In the associated text field, type Z/(rho*c) (1).

    model.result("pg4").set("ylabel", "Z/(rho*c) (1)");

//    Locate the Legend section.
//    From the Position list, select Upper right.
//    Right-click Normal Impedance and choose Global.

    model.result("pg4").create("glob1", "Global");
    model.result("pg4").feature("glob1").set("markerpos", "datapoints");
    model.result("pg4").feature("glob1").set("linewidth", "preference");

//    In the Settings window for Global, locate the y-Axis Data section.
//    In the table, enter the following settings:

    model.result("pg4").feature("glob1").setIndex("expr", "Z", 0);
    model.result("pg4").feature("glob1").setIndex("expr", "Z_ana", 1);

//    Click to expand the Legends section.
//    In the Normal Impedance toolbar, click Plot.

    model.result("pg4").run();

//    Click the x-Axis Log Scale button in the Graphics toolbar.

    model.result("pg4").set("xlog", true);

//    In the Results toolbar, click 1D Plot Group.

    model.result().create("pg5", "PlotGroup1D");
    model.result("pg5").run();

//    In the Settings window for 1D Plot Group, type Absorption Coefficient in the Label text field.

    model.result("pg5").label("Absorption Coefficient");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result("pg5").set("data", "dset2");

//    Locate the Title section.
//    From the Title type list, select Label.

    model.result("pg5").set("titletype", "label");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg5").set("xlabelactive", true);

//    In the associated text field, type f (Hz).

    model.result("pg5").set("xlabel", "f (Hz)");

//    Select the y-axis label checkbox.

    model.result("pg5").set("ylabelactive", true);

//    In the associated text field, type \alpha (1).

    model.result("pg5").set("ylabel", "\\alpha (1)");

//    Locate the Legend section.
//    From the Position list, select Lower right.

    model.result("pg5").set("legendpos", "lowerright");

//    Right-click Absorption Coefficient and choose Global.

    model.result("pg5").create("glob1", "Global");
    model.result("pg5").feature("glob1").set("markerpos", "datapoints");
    model.result("pg5").feature("glob1").set("linewidth", "preference");

//    In the Settings window for Global, locate the y-Axis Data section.
//    In the table, enter the following settings:

    model.result("pg5").feature("glob1").setIndex("expr", "alpha", 0);
    model.result("pg5").feature("glob1").setIndex("expr", "alpha_R", 1);
    model.result("pg5").feature("glob1").setIndex("expr", "alpha_ana", 2);

//    In the Absorption Coefficient toolbar, click Plot.

    model.result("pg5").run();

//    Click the x-Axis Log Scale button in the Graphics toolbar.

    model.result("pg5").set("xlog", true);

//    In the Results toolbar, click 1D Plot Group.

    model.result().create("pg6", "PlotGroup1D");
    model.result("pg6").run();

//    In the Settings window for 1D Plot Group, type Normal Incidence Absorption in the Label text field.

    model.result("pg6").label("Normal Incidence Absorption");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result("pg6").set("data", "dset2");

//    From the Parameter selection (theta0) list, select From list.

    model.result("pg6").setIndex("looplevelinput", "manual", 1);

//    In the Parameter values (theta0 (deg)) list, select 0.

    model.result("pg6").setIndex("looplevel", new int[]{1}, 1);

//    select 0 in the Parameter values (theta0 (deg)) list.
//    Click to expand the Title section.
//    From the Title type list, select Label.

    model.result("pg6").set("titletype", "label");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg6").set("xlabelactive", true);

//    In the associated text field, type f (Hz).

    model.result("pg6").set("xlabel", "f (Hz)");

//    Select the y-axis label checkbox.

    model.result("pg6").set("ylabelactive", true);

//    In the associated text field, type \alpha (1).

    model.result("pg6").set("ylabel", "\\alpha (1)");

//    Locate the Axis section.
//    Select the x-axis log scale checkbox.

    model.result("pg6").set("xlog", true);

//    Locate the Legend section.
//    Clear the Show legends checkbox.

    model.result("pg6").set("showlegends", false);

//    In the Normal Incidence Absorption toolbar, click More Plots and choose Octave Band.

    model.result("pg6").create("oct1", "OctaveBand");
    model.result("pg6").feature("oct1").set("quantity", "bandpower");
    model.result("pg6").feature("oct1").set("markerpos", "datapoints");
    model.result("pg6").feature("oct1").set("linewidth", "preference");

//    In the Settings window for Octave Band, locate the Selection section.
//    From the Geometric entity level list, select Global.

    model.result("pg6").feature("oct1").selection().geom("geom1");

//    Locate the y-Axis Data section.
//    In the Expression text field, type alpha.

    model.result("pg6").feature("oct1").set("expr", "alpha");

//    From the Expression type list, select General (non-dB).

    model.result("pg6").feature("oct1").set("exprtype", "general");

//    Locate the Plot section.
//    From the Quantity list, select Band average power spectral density.

    model.result("pg6").feature("oct1").set("quantity", "bandaveragepsd");

//    Right-click Octave Band 1 and choose Duplicate.

    model.result("pg6").feature().duplicate("oct2", "oct1");
    model.result("pg6").run();

//    In the Settings window for Octave Band, locate the Plot section.
//    From the Band type list, select 1/3 octave.

    model.result("pg6").feature("oct2").set("bandtype", "octave3");

//    Right-click Octave Band 2 and choose Duplicate.

    model.result("pg6").feature().duplicate("oct3", "oct2");
    model.result("pg6").run();

//    In the Settings window for Octave Band, locate the Plot section.
//    From the Quantity list, select Continuous power spectral density.

    model.result("pg6").feature("oct3").set("quantity", "continuous");

//    Click to expand the Coloring and Style section.
//    From the Width list, select 2.

    model.result("pg6").feature("oct3").set("linewidth", 2);

//    In the Normal Incidence Absorption toolbar, click Plot.

    model.result("pg6").run();

//    The final two plots and evaluation group are used to assess how many diffraction order ports are needed for the given frequency range and angles of incidence.
//    In the Results toolbar, click 1D Plot Group.

    model.result().create("pg7", "PlotGroup1D");
    model.result("pg7").run();

//    In the Settings window for 1D Plot Group, type Powers of Outgoing Modes - 0 deg in the Label text field.

    model.result("pg7").label("Powers of Outgoing Modes - 0 deg");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result("pg7").set("data", "dset2");

//    From the Parameter selection (theta0) list, select First.

    model.result("pg7").setIndex("looplevelinput", "first", 1);

//    Click to expand the Title section.
//    From the Title type list, select Label.

    model.result("pg7").set("titletype", "label");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg7").set("xlabelactive", true);

//    In the associated text field, type f (Hz).

    model.result("pg7").set("xlabel", "f (Hz)");

//    Select the y-axis label checkbox.

    model.result("pg7").set("ylabelactive", true);

//    In the associated text field, type Power of outgoing mode (dB).

    model.result("pg7").set("ylabel", "Power of outgoing mode (dB)");

//    Locate the Axis section.
//    Select the x-axis log scale checkbox.

    model.result("pg7").set("xlog", true);

//    Locate the Legend section.
//    From the Layout list, select Outside graph axis area.

    model.result("pg7").set("legendlayout", "outside");

//    Right-click Powers of Outgoing Modes - 0 deg and choose Global.

    model.result("pg7").create("glob1", "Global");
    model.result("pg7").feature("glob1").set("markerpos", "datapoints");
    model.result("pg7").feature("glob1").set("linewidth", "preference");

//    In the Settings window for Global, locate the y-Axis Data section.
//    In the table, enter the following settings:

    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.P_out/acpr.Pref_SWL)", 0);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 0);
    model.result("pg7").feature("glob1").setIndex("descr", "Plane Wave", 0);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport1.P_out/acpr.Pref_SWL)", 1);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 1);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -1", 1);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport2.P_out/acpr.Pref_SWL)", 2);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 2);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -2", 2);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport3.P_out/acpr.Pref_SWL)", 3);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 3);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -3", 3);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport4.P_out/acpr.Pref_SWL)", 4);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 4);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -4", 4);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport5.P_out/acpr.Pref_SWL)", 5);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 5);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -5", 5);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport6.P_out/acpr.Pref_SWL)", 6);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 6);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -6", 6);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport7.P_out/acpr.Pref_SWL)", 7);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 7);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -7", 7);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport8.P_out/acpr.Pref_SWL)", 8);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 8);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -8", 8);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport9.P_out/acpr.Pref_SWL)", 9);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 9);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -9", 9);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport10.P_out/acpr.Pref_SWL)", 10);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 10);
    model.result("pg7").feature("glob1").setIndex("descr", "m = -10", 10);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport11.P_out/acpr.Pref_SWL)", 11);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 11);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 1", 11);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport12.P_out/acpr.Pref_SWL)", 12);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 12);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 2", 12);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport13.P_out/acpr.Pref_SWL)", 13);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 13);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 3", 13);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport14.P_out/acpr.Pref_SWL)", 14);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 14);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 4", 14);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport15.P_out/acpr.Pref_SWL)", 15);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 15);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 5", 15);
    model.result("pg7").feature("glob1").setIndex("expr", "10*log10(acpr.pport1.dport16.P_out/acpr.Pref_SWL)", 16);
    model.result("pg7").feature("glob1").setIndex("unit", "dB", 16);
    model.result("pg7").feature("glob1").setIndex("descr", "m = 6", 16);

//    Click to expand the Legends section.
//    Find the Include subsection.
//    Clear the Solution checkbox.

    model.result("pg7").feature("glob1").set("autosolution", false);

//    In the Powers of Outgoing Modes - 0 deg toolbar, click Plot.

    model.result("pg7").run();
    model.result("pg7").run();

//    In the Model Builder window, click Powers of Outgoing Modes - 0 deg.
//    In the Settings window for 1D Plot Group, locate the Axis section.
//    Select the Manual axis limits checkbox.

    model.result("pg7").set("axislimits", true);

//    In the y minimum text field, type 30.

    model.result("pg7").set("ymin", 30);

//    In the y maximum text field, type 100.

    model.result("pg7").set("ymax", 100);

//    In the Powers of Outgoing Modes - 0 deg toolbar, click Plot.

    model.result("pg7").run();

//    This plot shows the power in the different diffraction order modes at 0 deg. incidence. At frequencies above 2000 Hz several modes become important, comparable to the plane wave mode.
//    Right-click Powers of Outgoing Modes - 0 deg and choose Duplicate.

    model.result().duplicate("pg8", "pg7");
    model.result("pg8").run();

//    In the Settings window for 1D Plot Group, type Powers of Outgoing Modes - 45 deg in the Label text field.

    model.result("pg8").label("Powers of Outgoing Modes - 45 deg");

//    Locate the Data section.
//    From the Parameter selection (theta0) list, select Last.

    model.result("pg8").setIndex("looplevelinput", "last", 1);

//    In the Powers of Outgoing Modes - 45 deg toolbar, click Plot.

    model.result("pg8").run();

//    This plot shows the power in the different diffraction order modes at 45 deg. incidence. At frequencies above 1000 Hz several modes become important, comparable to the plane wave mode.
//    In the Results toolbar, click Evaluation Group.

    model.result().evaluationGroup().create("eg1", "EvaluationGroup");

//    In the Settings window for Evaluation Group, type Evaluation Group 1 - Diffraction Order in the Label text field.

    model.result().evaluationGroup("eg1").label("Evaluation Group 1 - Diffraction Order");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Parametric Solutions 1 (sol2).

    model.result().evaluationGroup("eg1").set("data", "dset2");

//    From the Parameter selection (freq) list, select Last.

    model.result().evaluationGroup("eg1").setIndex("looplevelinput", "last", 0);

//    Locate the Transformation section.
//    Select the Transpose checkbox.

    model.result().evaluationGroup("eg1").set("transpose", true);

//    Click to expand the Format section.
//    From the Include parameters list, select On.

    model.result().evaluationGroup("eg1").set("includeparameters", true);

//    Right-click Evaluation Group 1 - Diffraction Order and choose Global Evaluation.

    model.result().evaluationGroup("eg1").create("gev1", "EvalGlobal");

//    In the Settings window for Global Evaluation, locate the Expressions section.
//    In the table, enter the following settings:

    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport1.kn)", 0);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -1", 0);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport2.kn)", 1);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -2", 1);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport3.kn)", 2);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -3", 2);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport4.kn)", 3);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -4", 3);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport5.kn)", 4);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -5", 4);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport6.kn)", 5);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -6", 5);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport7.kn)", 6);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -7", 6);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport8.kn)", 7);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -8", 7);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport9.kn)", 8);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -9", 8);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport10.kn)", 9);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = -10", 9);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport11.kn)", 10);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 1", 10);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport12.kn)", 11);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 2", 11);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport13.kn)", 12);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 3", 12);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport14.kn)", 13);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 4", 13);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport15.kn)", 14);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 5", 14);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("expr", "imag(acpr.pport1.dport16.kn)", 15);
    model.result().evaluationGroup("eg1").feature("gev1").setIndex("descr", "m = 6", 15);

//    In the Evaluation Group 1 - Diffraction Order toolbar, click Evaluate.

    model.result().evaluationGroup("eg1").run();

//    This evaluation performed at the highest study frequency can be used to see when enough diffraction order ports have been added. As soon as the imaginary part of the port wave number is no longer 0, it becomes non-propagating. This happens, for the two angles if incidence combined, at m = -10 and m = 6. This analysis depends on the angle of incidence and should be done at the highest frequency.

    model.result("pg1").run();
    model.result("pg1").setIndex("looplevel", 2, 1);
    model.result("pg1").run();

    model.title("Porous Absorber");

    model
         .description("This is a 2D model of a porous sound-absorbing wall-lining material. The absorption coefficient alpha and specific surface impedance Z are determined as functions of frequency for two different incidence angles. The example uses Periodic Floquet boundary conditions.");

    return model;
  }

  public static void main(String[] args) {
    Model model = run();
    run2(model);
  }

}
