/*
 * microstructured_optical_fiber.java
 */

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

/** Model exported on May 12 2026, 08:15 by COMSOL 6.4.0.418. */
public class microstructured_optical_fiber {

  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 Optics > Wave Optics > Electromagnetic Waves, Frequency Domain (ewfd).
//    Click Add.
//    Click Study.
//    In the Select Study tree, select Preset Studies for Selected Physics Interfaces > Mode Analysis.
//    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("ewfd", "ElectromagneticWavesFrequencyDomain", "geom1");

    model.study().create("std1");
    model.study("std1").create("mode", "ModeAnalysis");
    model.study("std1").feature("mode").set("ftplistmethod", "manual");
    model.study("std1").feature("mode").set("shiftactive", false);
    model.study("std1").feature("mode").set("linpsolnum", "auto");
    model.study("std1").feature("mode").set("outputmap", new String[]{});
    model.study("std1").feature("mode").set("ngenAUX", "1");
    model.study("std1").feature("mode").set("goalngenAUX", "1");
    model.study("std1").feature("mode").set("ngenAUX", "1");
    model.study("std1").feature("mode").set("goalngenAUX", "1");

//    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 microstructured_optical_fiber_parameters.txt.
//    To import content from file, use:
//    model.param().loadFile("FILENAME");
    model.param().set("d", "5[um]", "Hole diameter");
    model.param().set("Delta", "6.75[um]", "Hole separation");
    model.param().set("rb", "10[um]", "Radius for calculation domain");
    model.param().set("nbg", "1.45", "Background refractive index");
    model.param().set("nair", "1", "Air refractive index");
    model.param().set("wl", "1.45[um]", "Wavelength");
    model.param().set("neffMax", "1.4454", "Maximum expected effective index,");
    model.param().set("neffMin", "1.429", "Minimum expected effective index,");
    model.param().set("wlr", "wl/sqrt(nbg^2-neffMax^2)", "Wavelength in the radial direction");

//    The parameter <c>wlr</c>, the in-plane wavelength, will be used in the definition of the perfectly matched layer (PML).
//    Start building the geometry. Add a circle for the computation domain and then a smaller circle that represents the air holes. The air-hole circle is rotated in steps of 60 degrees. In total, six air holes will be added.
//    In the Geometry toolbar, click Circle.

    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 rb+wlr.

    model.component("comp1").geom("geom1").feature("c1").set("r", "rb+wlr");

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

    model.component("comp1").geom("geom1").feature("c1").setIndex("layername", "Layer 1", 0);
    model.component("comp1").geom("geom1").feature("c1").setIndex("layer", "wlr", 0);

//    In the Geometry toolbar, click Circle.

    model.component("comp1").geom("geom1").run("c1");
    model.component("comp1").geom("geom1").create("c2", "Circle");

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

    model.component("comp1").geom("geom1").feature("c2").set("r", "d/2");

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

    model.component("comp1").geom("geom1").feature("c2").set("pos", new String[]{"0", "-Delta"});

//    Now, give the selection a name that can be referred to later.
//    Locate the Selections of Resulting Entities section.
//    Find the Cumulative selection subsection.
//    Click New.
//    In the New Cumulative Selection dialog, type Air Holes in the Name text field.
//    Click OK.

    model.component("comp1").geom("geom1").selection().create("csel1", "CumulativeSelection");
    model.component("comp1").geom("geom1").selection("csel1").label("Air Holes");
    model.component("comp1").geom("geom1").feature("c2").set("contributeto", "csel1");

//    In the Geometry toolbar, click Transforms and choose Rotate.

    model.component("comp1").geom("geom1").run("c2");
    model.component("comp1").geom("geom1").create("rot1", "Rotate");

//    Select the object c2.

    model.component("comp1").geom("geom1").feature("rot1").selection("input").set("c2");

//    In the Settings window for Rotate, locate the Rotation section.
//    In the Angle text field, type range(0,60,300).

    model.component("comp1").geom("geom1").feature("rot1").set("rot", "range(0,60,300)");

//    Locate the Selections of Resulting Entities section.
//    Find the Cumulative selection subsection.
//    From the Contribute to list, select Air Holes.

    model.component("comp1").geom("geom1").feature("rot1").set("contributeto", "csel1");

//    Click Build All Objects.

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

//    Add a selection for the air hole boundaries. This selection will be used later, when setting up the plots.
//    In the Definitions toolbar, click Adjacent.

    model.component("comp1").selection().create("adj1", "Adjacent");

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

//    In the Settings window for Adjacent, type Air Hole Boundaries in the Label text field.

    model.component("comp1").selection("adj1").label("Air Hole Boundaries");

//    Locate the Input Entities section.
//    Under Input selections, click Add.
//    In the Add dialog, select Air Holes in the Input selections list.
//    Click OK.

    model.component("comp1").selection("adj1").set("input", new String[]{"geom1_csel1_dom"});

//    Now, add the materials.
//    In the Model Builder window, right-click Component 1 (comp1) > Materials and choose Blank Material.

    model.component("comp1").material().create("mat1", "Common");

//    In the Settings window for Material, type Silica in the Label text field.

    model.component("comp1").material("mat1").label("Silica");

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

    model.component("comp1").material("mat1").propertyGroup()
         .create("RefractiveIndex", "RefractiveIndex", "Refractive_index");
    model.component("comp1").material("mat1").propertyGroup("RefractiveIndex").set("n", new String[]{"nbg"});
    model.component("comp1").material("mat1").propertyGroup("RefractiveIndex").set("ki", new String[]{"0"});

//    Right-click Materials and choose Blank Material.

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

//    In the Settings window for Material, type Air in the Label text field.

    model.component("comp1").material("mat2").label("Air");

//    Locate the Geometric Entity Selection section.
//    From the Selection list, select Air Holes.

    model.component("comp1").material("mat2").selection().named("geom1_csel1_dom");

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

    model.component("comp1").material("mat2").propertyGroup()
         .create("RefractiveIndex", "RefractiveIndex", "Refractive_index");
    model.component("comp1").material("mat2").propertyGroup("RefractiveIndex").set("n", new String[]{"nair"});
    model.component("comp1").material("mat2").propertyGroup("RefractiveIndex").set("ki", new String[]{"0"});

//    In the first part of the model, a perfectly matched layer (PML) will be used for truncating the computation domain.
//    In the Definitions toolbar, click Perfectly Matched Layer.

    model.component("comp1").coordSystem().create("pml1", "PML");

//    Select Domains 1, 2, 3, 4.

    model.component("comp1").coordSystem("pml1").selection().set(1, 2, 3, 4);

//    In the Settings window for Perfectly Matched Layer, locate the Geometry section.
//    From the Type list, select Cylindrical.

    model.component("comp1").coordSystem("pml1").set("ScalingType", "Cylindrical");

//    Locate the Scaling section.
//    From the Typical wavelength from list, select User defined.

    model.component("comp1").coordSystem("pml1").set("wavelengthSourceType", "userDefined");

//    In the Typical wavelength text field, type wlr.

    model.component("comp1").coordSystem("pml1").set("typicalWavelength", "wlr");

//    . This parameter approximates the in-plane wavelength.
//    In the Model Builder window, under Study 1, click Step 1: Mode Analysis.
//    In the Settings window for Mode Analysis, locate the Study Settings section.
//    In the Mode analysis frequency text field, type c_const/wl.

    model.study("std1").feature("mode").set("modeFreq", "c_const/wl");

//    From the Mode search method list, select Rectangle.

    model.study("std1").feature("mode").set("eigmethod", "region");

//    , as we will search for the complex effective indices in a rectangular region defined by the following parameters.
//    In the Approximate number of modes text field, type 10.

    model.study("std1").feature("mode").set("appnreigs", 10);

//    Find the Rectangle search region subsection.
//    In the Smallest real part (Effective mode index) text field, type neffMin.

    model.study("std1").feature("mode").set("eigsr", "neffMin");

//    In the Largest real part (Effective mode index) text field, type neffMax.

    model.study("std1").feature("mode").set("eiglr", "neffMax");

//    In the Smallest imaginary part (Effective mode index) text field, type -3e-5.

    model.study("std1").feature("mode").set("eigsi", "-3e-5");

//    In the Model Builder window, under Component 1 (comp1), click Mesh 1.
//    In the Settings window for Mesh, locate the Physics-Controlled Mesh section.
//    From the Element size list, select Extremely fine.

    model.component("comp1").mesh("mesh1").autoMeshSize(1);

//    Click Build All.

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

//    The mesh plot shows that the PML domains have been meshed with a mapped mesh.
//    In the Study toolbar, click Compute.

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

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

    model.result().create("pg1", "PlotGroup2D");
    model.result("pg1").set("data", "dset1");
    model.result("pg1").setIndex("looplevel", 1, 0);
    model.result("pg1").create("surf1", "Surface");
    model.result("pg1").feature("surf1").set("expr", "ewfd.normE");
    model.result("pg1").feature("surf1").set("descr", "Electric field norm");
    model.result("pg1").set("showlegendsmaxmin", true);
    model.result("pg1").feature("surf1").set("colortable", "RainbowLight");
    model.result("pg1").label("Electric Field (ewfd)");
    model.result("pg1").selection().geom("geom1", 2);
    model.result("pg1").selection().set(5, 6, 7, 8, 9, 10, 11);
    model.result("pg1").set("applyselectiontodatasetedges", true);
    model.result("pg1").run();
    model.result("pg1").set("applyselectiontodatasetedges", true);
    model.result("pg1").run();

//    In the Settings window for 2D Plot Group, locate the Color Legend section.
//    Clear the Show legends checkbox.

    model.result("pg1").set("showlegends", false);

//    , as the absolute amplitude of the mode field is not important.
//    In the Electric Field (ewfd) toolbar, click Plot.

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

//    Click the Show Grid button in the Graphics toolbar.

    model.component("comp1").view("view1").set("showgrid", false);

//    , to remove some more information that is not necessary in the plot.
//    Click the Zoom Extents button in the Graphics toolbar.
//    As seen, the mode field is localized to the central high-index region, with only a very small part of the field penetrating in between the holes.
//    The effective index is shown in the plot title. As seen, it is a complex number, where the imaginary part represents attenuation of the wave as it propagates along the fiber due to radiation leaking through the air-hole ring. Below, the effective indices for the different modes are evaluated.
//    In the Results toolbar, click Global Evaluation.

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

//    In the Settings window for Global Evaluation, click Replace Expression in the upper-right corner of the Expressions section.
//    From the menu, choose Component 1 (comp1) > Electromagnetic Waves, Frequency Domain > Global > ewfd.neff - Effective mode index - 1.

    model.result().numerical("gev1").set("expr", new String[]{"ewfd.neff"});
    model.result().numerical("gev1").set("descr", new String[]{"Effective mode index"});
    model.result().numerical("gev1").set("unit", new String[]{"1"});

//    Click Evaluate.

    model.result().table().create("tbl1", "Table");
    model.result().table("tbl1").comments("Global Evaluation 1");
    model.result().numerical("gev1").set("table", "tbl1");
    model.result().numerical("gev1").setResult();

//    Click Full Precision in the window toolbar.
//    The imaginary part of the effective index is larger for the modes with a lower real part of the effective index. Those modes have a smaller in-plane wavelength and are, thus, more loosely bound to the central high-index region.
//    Now, replace the PML with a Scattering boundary condition (SBC).
//    In the Model Builder window, under Component 1 (comp1), click Electromagnetic Waves, Frequency Domain (ewfd).
//    Select Domains 5, 6, 7, 8, 9, 10, 11.

    model.component("comp1").physics("ewfd").selection().set(5, 6, 7, 8, 9, 10, 11);

//    In the Physics toolbar, click Boundaries and choose Scattering Boundary Condition.

    model.component("comp1").physics("ewfd").create("sctr1", "Scattering", 1);

//    In the Settings window for Scattering Boundary Condition, locate the Boundary Selection section.
//    From the Selection list, select All boundaries.

    model.component("comp1").physics("ewfd").feature("sctr1").selection().all();

//    Locate the Scattering Boundary Condition section.
//    From the Scattered wave type list, select Cylindrical wave.

    model.component("comp1").physics("ewfd").feature("sctr1").set("WaveType", "CylindricalWave");

//    Click to expand the Mode Analysis section.
//    Select the Subtract propagation constant from material wave number checkbox.

    model.component("comp1").physics("ewfd").feature("sctr1").set("UseReducedWaveNumber", true);

//    , to subtract the mode propagation constant from the material wave number when calculating the wave vector component in the radial (normal) direction.
//    In the Home toolbar, click Compute.

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

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

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

//    In the Model Builder window, under Results > Derived Values, click Global Evaluation 1.
//    In the Settings window for Global Evaluation, click Evaluate.

    model.result().numerical("gev1").set("table", "tbl1");
    model.result().numerical("gev1").appendResult();

//    Comparing the effective indices from the PML and the SBC simulations, it is clear that the real parts agree up to 4–5 decimals, whereas the imaginary parts (that are much smaller in magnitude) only agree by the order of magnitude.
//    Now, add some additional plots, to make it possible to distinguish the different mode types.

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

//    In the Model Builder window, expand the Results > Electric Field (ewfd) node, then click Surface 1.
//    In the Settings window for Surface, locate the Expression section.
//    In the Expression text field, type sqrt(abs(ewfd.Ex)^2+abs(ewfd.Ey)^2).

    model.result("pg1").feature("surf1").set("expr", "sqrt(abs(ewfd.Ex)^2+abs(ewfd.Ey)^2)");

//    . This represents the norm of the tangential electric field.
//    Right-click Results > Electric Field (ewfd) > Surface 1 and choose Duplicate.

    model.result("pg1").feature().duplicate("surf2", "surf1");
    model.result("pg1").run();

//    In the Settings window for Surface, locate the Expression section.
//    In the Expression text field, type 10*abs(ewfd.Ez).

    model.result("pg1").feature("surf2").set("expr", "10*abs(ewfd.Ez)");

//    . This represents the norm of the longitudinal electric field. This component is scaled by a factor of ten, to make it visible when compared to the tangential electric field components.
//    Click to expand the Inherit Style section.
//    From the Plot list, select Surface 1.

    model.result("pg1").feature("surf2").set("inheritplot", "surf1");

//    Right-click Surface 2 and choose Transformation.

    model.result("pg1").feature("surf2").create("trn1", "Transformation");
    model.result("pg1").run();

//    In the Settings window for Transformation, locate the Transformation section.
//    In the Y text field, type -2.1*rb.

    model.result("pg1").feature("surf2").feature("trn1").set("move", new String[]{"0", "-2.1*rb"});

//    Clear the Apply to dataset edges checkbox.

    model.result("pg1").feature("surf2").feature("trn1").set("applytodatasetedges", false);

//    Click the Zoom Extents button in the Graphics toolbar.

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

//    In the Model Builder window, under Results > Electric Field (ewfd), Ctrl-click to select Surface 1, Surface 2.
//    Right-click and choose Duplicate.

    model.result("pg1").feature().duplicate("surf3", "surf1");
    model.result("pg1").feature().duplicate("surf4", "surf2");
    model.result("pg1").run();

//    In the Settings window for Surface, locate the Expression section.
//    In the Expression text field, type sqrt(abs(ewfd.Hx)^2+abs(ewfd.Hy)^2).

    model.result("pg1").feature("surf3").set("expr", "sqrt(abs(ewfd.Hx)^2+abs(ewfd.Hy)^2)");

//    . This represents the norm of the tangential magnetic field.
//    Right-click Surface 3 and choose Transformation.

    model.result("pg1").feature("surf3").create("trn1", "Transformation");
    model.result("pg1").run();

//    In the Settings window for Transformation, locate the Transformation section.
//    In the X text field, type 2.1*rb.

    model.result("pg1").feature("surf3").feature("trn1").set("move", new String[]{"2.1*rb", "0"});

//    Clear the Apply to dataset edges checkbox.

    model.result("pg1").feature("surf3").feature("trn1").set("applytodatasetedges", false);

//    Click the Zoom Extents button in the Graphics toolbar.

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

//    In the Model Builder window, expand the Results > Electric Field (ewfd) > Surface 4 node, then click Surface 4.
//    In the Settings window for Surface, locate the Expression section.
//    In the Expression text field, type 10*abs(ewfd.Hz).

    model.result("pg1").feature("surf4").set("expr", "10*abs(ewfd.Hz)");

//    . This represents the norm of the longitudinal magnetic field. Again, a scale factor of 10 is used here to make the longitudinal component visible when compared to the tangential components.
//    Locate the Inherit Style section.
//    From the Plot list, select Surface 3.

    model.result("pg1").feature("surf4").set("inheritplot", "surf3");
    model.result("pg1").run();

//    In the Model Builder window, click Transformation 1.
//    In the Settings window for Transformation, locate the Transformation section.
//    In the X text field, type 2.1*rb.

    model.result("pg1").feature("surf4").feature("trn1").set("move", new String[]{"2.1*rb", "-2.1*rb"});
    model.result("pg1").run();

//    In the Model Builder window, under Results, click Electric Field (ewfd).
//    In the Settings window for 2D Plot Group, click to expand the Title section.
//    From the Title type list, select Manual.

    model.result("pg1").set("titletype", "manual");

//    In the Title text area, type Tangential and longitudinal electric and magnetic fields.

    model.result("pg1").set("title", "Tangential and longitudinal electric and magnetic fields");

//    Add arrow plots to visualize the polarization direction.
//    Right-click Electric Field (ewfd) and choose Arrow Surface.

    model.result("pg1").create("arws1", "ArrowSurface");
    model.result("pg1").feature("arws1").set("evaluationsettings", "parent");

//    In the Settings window for Arrow Surface, locate the Coloring and Style section.
//    From the Color list, select White.

    model.result("pg1").feature("arws1").set("color", "white");

//    Right-click Arrow Surface 1 and choose Transformation.

    model.result("pg1").feature("arws1").create("trn1", "Transformation");
    model.result("pg1").run();

//    In the Settings window for Transformation, locate the Transformation section.
//    In the X text field, type 2.1*rb.

    model.result("pg1").feature("arws1").feature("trn1").set("move", new String[]{"2.1*rb", "0"});

//    Clear the Apply to dataset edges checkbox.

    model.result("pg1").feature("arws1").feature("trn1").set("applytodatasetedges", false);
    model.result("pg1").run();

//    In the Model Builder window, right-click Results > Electric Field (ewfd) > Arrow Surface 1 and choose Duplicate.

    model.result("pg1").feature().duplicate("arws2", "arws1");
    model.result("pg1").run();

//    In the Settings window for Arrow Surface, click Replace Expression in the upper-right corner of the Expression section.
//    From the menu, choose Component 1 (comp1) > Electromagnetic Waves, Frequency Domain > Electric > ewfd.Ex,ewfd.Ey - Electric field.

    model.result("pg1").feature("arws2").set("expr", new String[]{"ewfd.Ex", "ewfd.Ey"});
    model.result("pg1").feature("arws2").set("descr", "Electric field");
    model.result("pg1").run();

//    In the Model Builder window, expand the Arrow Surface 2 node.
//    Right-click Transformation 1 and choose Delete.

    model.result("pg1").feature("arws2").feature().remove("trn1");
    model.result("pg1").run();

//    To clearly see the different polarization directions for the two degenerate modes with the highest effective indices, it helps here to change the phase of the solution to 45 degrees. Another option to see the different polarization directions would be to make an animation of one harmonic period.

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

//    In the Model Builder window, click Electric Field (ewfd).
//    In the Settings window for 2D Plot Group, locate the Phase section.
//    From the Solution at angle (phase) list, select Manual.

    model.result("pg1").set("phasetype", "manual");

//    In the Phase text field, type 45.

    model.result("pg1").set("phase", 45);

//    Now, remove the black edges and then add them back using line plots. This will make the location of the air holes more visible.
//    Locate the Plot Settings section.
//    Clear the Plot dataset edges checkbox.

    model.result("pg1").set("edges", false);

//    Right-click Electric Field (ewfd) and choose Line.

    model.result("pg1").create("line1", "Line");
    model.result("pg1").feature("line1").set("evaluationsettings", "parent");

//    In the Settings window for Line, locate the Coloring and Style section.
//    From the Coloring list, select Uniform.

    model.result("pg1").feature("line1").set("coloring", "uniform");

//    From the Color list, select Black.

    model.result("pg1").feature("line1").set("color", "black");

//    Right-click Line 1 and choose Selection.

    model.result("pg1").feature("line1").create("sel1", "Selection");

//    In the Settings window for Selection, locate the Selection section.
//    From the Selection list, select Air Hole Boundaries.

    model.result("pg1").feature("line1").feature("sel1").selection().named("adj1");
    model.result("pg1").run();

//    In the Model Builder window, right-click Results > Electric Field (ewfd) > Line 1 and choose Duplicate.

    model.result("pg1").feature().duplicate("line2", "line1");
    model.result("pg1").run();

//    In the Model Builder window, right-click Line 2 and choose Transformation.

    model.result("pg1").feature("line2").create("trn1", "Transformation");
    model.result("pg1").run();

//    In the Settings window for Transformation, locate the Transformation section.
//    In the X text field, type 2.1*rb.

    model.result("pg1").feature("line2").feature("trn1").set("move", new String[]{"2.1*rb", "0"});
    model.result("pg1").run();

//    In the Model Builder window, under Results > Electric Field (ewfd), Ctrl-click to select Line 1, Line 2.
//    Right-click and choose Duplicate.

    model.result("pg1").feature().duplicate("line3", "line1");
    model.result("pg1").feature().duplicate("line4", "line2");
    model.result("pg1").run();

//    In the Model Builder window, right-click Line 3 and choose Transformation.

    model.result("pg1").feature("line3").create("trn1", "Transformation");
    model.result("pg1").run();

//    In the Settings window for Transformation, locate the Transformation section.
//    In the Y text field, type -2.1*rb.

    model.result("pg1").feature("line3").feature("trn1").set("move", new String[]{"0", "-2.1*rb"});
    model.result("pg1").run();

//    In the Model Builder window, expand the Results > Electric Field (ewfd) > Line 4 node, then click Transformation 1.
//    In the Settings window for Transformation, locate the Transformation section.
//    In the Y text field, type -2.1*rb.

    model.result("pg1").feature("line4").feature("trn1").set("move", new String[]{"2.1*rb", "-2.1*rb"});
    model.result("pg1").run();

//    Finally, add some informative annotations.
//    In the Model Builder window, right-click Electric Field (ewfd) and choose Annotation.

    model.result("pg1").create("ann1", "Annotation");

//    In the Settings window for Annotation, locate the Annotation section.
//    In the Text text field, type Electric fields.

    model.result("pg1").feature("ann1").set("text", "Electric fields");

//    Locate the Position section.
//    In the Y text field, type 1.2*rb.

    model.result("pg1").feature("ann1").set("posyexpr", "1.2*rb");

//    Locate the Coloring and Style section.
//    Clear the Show point checkbox.

    model.result("pg1").feature("ann1").set("showpoint", false);

//    From the Anchor point list, select Center.

    model.result("pg1").feature("ann1").set("anchorpoint", "center");

//    Click the Zoom Extents button in the Graphics toolbar.
//    Right-click Annotation 1 and choose Duplicate.

    model.result("pg1").feature().duplicate("ann2", "ann1");
    model.result("pg1").run();

//    In the Settings window for Annotation, locate the Annotation section.
//    In the Text text field, type Magnetic fields.

    model.result("pg1").feature("ann2").set("text", "Magnetic fields");

//    Locate the Position section.
//    In the X text field, type 2.1*rb.

    model.result("pg1").feature("ann2").set("posxexpr", "2.1*rb");
    model.result("pg1").run();

//    In the Model Builder window, right-click Results > Electric Field (ewfd) > Annotation 1 and choose Duplicate.

    model.result("pg1").feature().duplicate("ann3", "ann1");
    model.result("pg1").run();

//    In the Settings window for Annotation, locate the Annotation section.
//    In the Text text field, type Tangential.

    model.result("pg1").feature("ann3").set("text", "Tangential");

//    Locate the Position section.
//    In the X text field, type -1.1*rb.

    model.result("pg1").feature("ann3").set("posxexpr", "-1.1*rb");

//    In the Y text field, type 0.

    model.result("pg1").feature("ann3").set("posyexpr", 0);

//    Locate the Coloring and Style section.
//    From the Anchor point list, select Middle right.

    model.result("pg1").feature("ann3").set("anchorpoint", "middleright");

//    Click the Zoom Extents button in the Graphics toolbar.
//    Right-click Annotation 3 and choose Duplicate.

    model.result("pg1").feature().duplicate("ann4", "ann3");
    model.result("pg1").run();

//    In the Settings window for Annotation, locate the Annotation section.
//    In the Text text field, type Longitudinal.

    model.result("pg1").feature("ann4").set("text", "Longitudinal");

//    Locate the Position section.
//    In the Y text field, type -2.1*rb.

    model.result("pg1").feature("ann4").set("posyexpr", "-2.1*rb");
    model.result("pg1").run();

//    In the Model Builder window, click Electric Field (ewfd).
//    In the Settings window for 2D Plot Group, locate the Title section.
//    In the Parameter indicator text field, type Effective mode index=eval(ewfd.neff).

    model.result("pg1").set("paramindicator", "Effective mode index=eval(ewfd.neff)");

//    , to update the effective index in the title.
//    Now it is time to analyze the mode types, by stepping through the modes, starting with the mode with the largest effective index.
//    Click Plot Last.

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

//    This is the first HE<sub>11</sub>-like mode. These modes are degenerate with a degeneracy of two. This mixed mode has both longitudinal electric and magnetic field components.
//    Click Plot Previous.

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

//    This is the second degenerate HE<sub>11</sub>-like mode. The polarization is of course orthogonal to the first HE<sub>11</sub>-like mode.
//    Click Plot Previous.

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

//    This is a TE<sub>01</sub>-like mode, where the field is almost rotationally invariant and polarized in the φ direction. As seen, the longitudinal electric field is very small, whereas the longitudinal magnetic field is nonnegligible.
//    Click Plot Previous.

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

//    This is the first degenerate HE<sub>21</sub>-like mode.
//    Click Plot Previous.

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

//    This is the second degenerate HE<sub>21</sub>-like mode.
//    Click Plot Previous.

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

//    This is a TM<sub>01</sub>-like mode, where the field is almost rotationally invariant and polarized in the radial direction. As seen, the longitudinal magnetic field is very small, whereas the longitudinal electric field is nonnegligible.
//    Click Plot Previous.

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

//    This is the first HE<sub>31</sub>-like mode.
//    Click Plot Previous.

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

//    This is the first degenerate EH<sub>11</sub>-like mode.
//    Click Plot Previous.

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

//    This is the second degenerate EH<sub>11</sub>-like mode.
//    Click Plot Previous.

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

//    Finally, this is the second HE<sub>31</sub>-like mode.

    model.title("Leaky Modes in a Microstructured Optical Fiber");

    model
         .description("This model use a mode analysis study to find the complex effective indices of a microstructured optical fiber (MOF), consisting of air holes in a silica host. As the effective index is smaller than the refractive index of the silica background material, the modes are leaky.\n\nThe model demonstrates both the use of a perfectly matched layer (PML) and the use of the Scattering boundary condition to truncate the simulation domain.\n\nThe real and imaginary parts of the effective index compare well to values from a published paper.");

    return model;
  }

  public static void main(String[] args) {
    run();
  }

}
