/*
 * eigenmodes_of_room.java
 */

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

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

  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 3D.
//    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 > Eigenfrequency.
//    Click Done.

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

    model.component("comp1").geom().create("geom1", 3);
    model.component("comp1").geom("geom1").geomRep("comsol");

    model.component("comp1").mesh().create("mesh1");
    model.component("comp1").mesh("mesh1").contribute("geom/detail", true);

    model.component("comp1").physics().create("acpr", "PressureAcoustics", "geom1");

    model.study().create("std1");
    model.study("std1").create("eig", "Eigenfrequency");
    model.study("std1").feature("eig").set("ftplistmethod", "manual");
    model.study("std1").feature("eig").set("chkeigregion", true);
    model.study("std1").feature("eig").set("storefact", false);
    model.study("std1").feature("eig").set("linpsolnum", "auto");
    model.study("std1").feature("eig").set("solnum", "auto");
    model.study("std1").feature("eig").set("notsolnum", "auto");
    model.study("std1").feature("eig").set("outputmap", new String[]{});
    model.study("std1").feature("eig").set("ngenAUX", "1");
    model.study("std1").feature("eig").set("goalngenAUX", "1");
    model.study("std1").feature("eig").set("ngenAUX", "1");
    model.study("std1").feature("eig").set("goalngenAUX", "1");

//    The geometry in this model can be created within COMSOL Multiphysics. Here it is imported for convenience.
//    In the Geometry toolbar, click Import.

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

//    In the Settings window for Import, locate the Source section.
//    Click Browse.
//    Browse to the model's Application Library folder and double-click the file eigenmodes_of_room.mphbin.

    model.component("comp1").geom("geom1").feature("imp1").set("filename", "eigenmodes_of_room.mphbin");

//    Click Import.

    model.component("comp1").geom("geom1").feature("imp1").importData();

//    Click the Wireframe Rendering button in the Graphics toolbar.

    model.component("comp1").view("view1").set("renderwireframe", true);

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

//    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 Air in the Label text field.

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

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

    model.component("comp1").material("mat1").propertyGroup("def").set("density", new String[]{"1.25"});
    model.component("comp1").material("mat1").propertyGroup("def").set("soundspeed", new String[]{"343"});

//    The boundary conditions are all <l>Sound Hard Boundary (Wall)</l> by default.
//    In this model, the mesh is set up manually. Proceed by directly adding the desired mesh component.
//    In the Mesh toolbar, click Free Tetrahedral.

    model.component("comp1").mesh("mesh1").create("ftet1", "FreeTet");

//    In the Model Builder window, under Study 1, click Step 1: Eigenfrequency.
//    In the Settings window for Eigenfrequency, locate the Study Settings section.
//    In the Search for eigenfrequencies around shift text field, type 90.

    model.study("std1").feature("eig").set("shift", "90");

//    This setting will get you at least six solutions with eigenfrequencies in the vicinity of 90 Hz. For this model you typically get additional eigensolutions that the eigenvalue solver finds.
//    In the Study toolbar, click Compute.

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

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

    model.result().create("pg1", "PlotGroup3D");
    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", 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("pg1").feature("surf1").set("colortable", "WaveLight");
    model.result("pg1").create("con1", "Contour");
    model.result("pg1").feature("con1").set("expr", new String[]{"acpr.p_t"});
    model.result("pg1").feature("con1").set("colortable", "Wave");
    model.result("pg1").feature("con1").set("colorscalemode", "linearsymmetric");
    model.result("pg1").feature("con1").set("colorlegend", false);
    model.result().create("pg2", "PlotGroup3D");
    model.result("pg2").set("data", "dset1");
    model.result("pg2").setIndex("looplevel", 1, 0);
    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().create("pg3", "PlotGroup3D");
    model.result("pg3").set("data", "dset1");
    model.result("pg3").setIndex("looplevel", 1, 0);
    model.result("pg3").create("iso1", "Isosurface");
    model.result("pg3").feature("iso1").set("expr", new String[]{"acpr.p_t"});
    model.result("pg3").feature("iso1").set("number", "10");
    model.result("pg3").feature("iso1").set("colortable", "Wave");
    model.result("pg3").feature("iso1").set("colorscalemode", "linearsymmetric");
    model.result("pg3").set("showlegendsunit", true);
    model.result("pg3").label("Acoustic Pressure, Isosurfaces (acpr)");
    model.result().evaluationGroup().create("std1EvgFrq", "EvaluationGroup");
    model.result().evaluationGroup("std1EvgFrq").set("data", "dset1");
    model.result().evaluationGroup("std1EvgFrq").label("Eigenfrequencies (Study 1)");
    model.result().evaluationGroup("std1EvgFrq").create("gev1", "EvalGlobal");
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("expr", "2*pi*freq", 0);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("unit", "rad/s", 0);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("descr", "Angular frequency", 0);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("expr", "imag(freq)/abs(freq)", 1);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("unit", "1", 1);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("descr", "Damping ratio", 1);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("expr", "abs(freq)/imag(freq)/2", 2);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("unit", "1", 2);
    model.result().evaluationGroup("std1EvgFrq").feature("gev1").setIndex("descr", "Quality factor", 2);
    model.result().evaluationGroup("std1EvgFrq").run();
    model.result("pg1").run();

//    The first default plot shows the pressure distribution on the exterior boundaries of the geometry. To see what goes on inside the room, you need to suppress some of the boundaries. This is most conveniently done by first selecting all boundaries and then removing a few of them (number 1, 2, and 4) from the selection.
//    In the Model Builder window, expand the Results > Datasets node, then click Study 1/Solution 1 (sol1).
//    In the Results toolbar, click Attributes and choose Selection.
//    In the Settings window for Selection, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Boundary.

    model.result().dataset("dset1").selection().geom("geom1", 2);

//    From the Selection list, select All boundaries.

    model.result().dataset("dset1").selection().geom("geom1", 2);
    model.result().dataset("dset1").selection().all();

//    Select Boundaries 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79.

    model.result().dataset("dset1").selection().geom("geom1", 2);
    model.result().dataset("dset1").selection()
         .set(3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79);
    model.result("pg1").run();

//    Click the Zoom Extents button in the Graphics toolbar.
//    In the Model Builder window, under Results, click Acoustic Pressure (acpr).
//    The first plot group now shows the distribution of the real value of the pressure for the lowest one of the eigenfrequencies, 74.9 Hz. This appears to be the (1,0,1) mode.

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

//    The third default plot shows the isosurfaces for the same frequency.

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

//    In the Model Builder window, expand the Acoustic Pressure, Isosurfaces (acpr) node, then click Isosurface 1.
//    In the Settings window for Isosurface, locate the Levels section.
//    In the Total levels text field, type 5.

    model.result("pg3").feature("iso1").set("number", 5);

//    In the Acoustic Pressure, Isosurfaces (acpr) toolbar, click Plot.

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

//    In the Model Builder window, right-click Acoustic Pressure, Isosurfaces (acpr) and choose Surface.

    model.result("pg3").create("surf1", "Surface");
    model.result("pg3").feature("surf1").set("evaluationsettings", "parent");

//    In the Settings window for Surface, locate the Coloring and Style section.
//    From the Color table list, select Wave.
//    In the Acoustic Pressure, Isosurfaces (acpr) toolbar, click Plot.

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

//    In the Model Builder window, click Isosurface 1.
//    In the Settings window for Isosurface, locate the Coloring and Style section.
//    Clear the Color legend checkbox.

    model.result("pg3").feature("iso1").set("colorlegend", false);

//    Modify the third default plot to show the isosurfaces and pressure distribution at 85 Hz; this is the (1,1,1) mode.

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

//    In the Model Builder window, click Acoustic Pressure, Isosurfaces (acpr).
//    In the Settings window for 3D Plot Group, locate the Data section.
//    From the Eigenfrequency (Hz) list, select 85.095.

    model.result("pg3").set("looplevel", new int[]{5});

//    From the Eigenfrequency (Hz) list, select 99.542.

    model.result("pg3").set("looplevel", new int[]{8});

//    In the Acoustic Pressure, Isosurfaces (acpr) toolbar, click Plot.

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

//    This mode looks a little different from what you would find in an empty room. It is focused behind the couch.

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

//    In the Results toolbar, click Result Templates to open the Result Templates window.
//    In the tree, select Study 1/Solution 1 (sol1) > Pressure Acoustics, Frequency Domain > Sound Pressure Level (acpr).
//    Click Add Result Template in the window toolbar.

    model.result().create("pg4", "PlotGroup3D");
    model.result("pg4").set("data", "dset1");
    model.result("pg4").setIndex("looplevel", 1, 0);
    model.result("pg4").create("surf1", "Surface");
    model.result("pg4").feature("surf1").set("expr", new String[]{"acpr.Lp_t"});
    model.result("pg4").feature("surf1").set("colortable", "Rainbow");
    model.result("pg4").feature("surf1").set("colorscalemode", "linear");
    model.result("pg4").set("showlegendsunit", true);
    model.result("pg4").label("Sound Pressure Level (acpr) 1");
    model.result("pg4").run();

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

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

//    In the Model Builder window, expand the Sound Pressure Level (acpr) 1 node, then click Surface 1.
//    In the Settings window for Surface, locate the Expression section.
//    Select the Description checkbox.

    model.result("pg4").feature("surf1").set("descractive", true);

//    In the associated text field, type Total SPL.

    model.result("pg4").feature("surf1").set("descr", "Total SPL");

//    In the Sound Pressure Level (acpr) 1 toolbar, click Plot.

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

    model.title("Eigenmodes of a Room");

    model
         .description("This example simulates standing acoustic waves in a room with furniture. The eigenmodes differ slightly from the exact solution for an empty room.");

    return model;
  }

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

}
