/*
 * geoelectrics.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 15 2026, 12:21 by COMSOL 6.4.0.421. */
public class geoelectrics {

  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 AC/DC > Electric Fields and Currents > Electric Currents (ec).
//    Click Add.
//    Click Study.
//    In the Select Study tree, select General Studies > Stationary.
//    Click Done.

    model.component().create("comp1", true);

    model.component("comp1").geom().create("geom1", 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("ec", "ConductiveMedia", "geom1");

    model.study().create("std1");
    model.study("std1").create("stat", "Stationary");

//    Add parameters that are useful for defining physical and geometric quantities.
//    In the Model Builder window, under Global Definitions, click Parameters 1.
//    In the Settings window for Parameters, locate the Parameters section.
//    In the table, enter the following settings:

    model.param().set("L", "50[m]");
    model.param().descr("L", "Domain length");
    model.param().set("W", "50[m]");
    model.param().descr("W", "Domain width");
    model.param().set("H", "20[m]");
    model.param().descr("H", "Domain height");
    model.param().set("WI", "4[m]");
    model.param().descr("WI", "Infinite layer thickness");
    model.param().set("N", "25");
    model.param().descr("N", "Number of electrodes");
    model.param().set("a", "1[m]");
    model.param().descr("a", "Electrode separation");
    model.param().set("x0", "L/2-N/2*a");
    model.param().descr("x0", "First electrode x-position");
    model.param().set("y0", "W/2");
    model.param().descr("y0", "First electrode y-position");
    model.param().set("rho0", "100[m/S]");
    model.param().descr("rho0", "Resistivity");

//    Add two extra parameters which are going to be useful for sweeping among excitations applied to different entities. For further details, look at coming comments in these instructions, where the parameters are used.
//    In the table, enter the following settings:

    model.param().set("dom_C1", "39");
    model.param().descr("dom_C1", "Positive electrode domain number");
    model.param().set("dom_C2", "44");
    model.param().descr("dom_C2", "Negative electrode domain number");

//    In the Geometry toolbar, click Block.

    model.component("comp1").geom("geom1").create("blk1", "Block");

//    In the Settings window for Block, locate the Size and Shape section.
//    In the Width text field, type L.

    model.component("comp1").geom("geom1").feature("blk1").set("size", new String[]{"L", "1", "1"});

//    In the Depth text field, type W.

    model.component("comp1").geom("geom1").feature("blk1").set("size", new String[]{"L", "W", "1"});

//    In the Height text field, type H.

    model.component("comp1").geom("geom1").feature("blk1").set("size", new String[]{"L", "W", "H"});

//    Locate the Position section.
//    In the z text field, type -H.

    model.component("comp1").geom("geom1").feature("blk1").set("pos", new String[]{"0", "0", "-H"});

//    Click to expand the Layers section.
//    In the table, enter the following settings:

    model.component("comp1").geom("geom1").feature("blk1").setIndex("layer", "WI", 0);

//    Find the Layer position subsection.
//    Select the Left checkbox.

    model.component("comp1").geom("geom1").feature("blk1").set("layerleft", true);

//    Select the Right checkbox.

    model.component("comp1").geom("geom1").feature("blk1").set("layerright", true);

//    Select the Front checkbox.

    model.component("comp1").geom("geom1").feature("blk1").set("layerfront", true);

//    Select the Back checkbox.

    model.component("comp1").geom("geom1").feature("blk1").set("layerback", true);

//    Click Build Selected.

    model.component("comp1").geom("geom1").run("blk1");

//    In the Geometry toolbar, click More Primitives and choose Polygon.

    model.component("comp1").geom("geom1").create("pol1", "Polygon");
    model.component("comp1").geom("geom1").feature("pol1").set("source", "table");

//    In the Settings window for Polygon, locate the Coordinates section.
//    From the Data source list, select Vectors.

    model.component("comp1").geom("geom1").feature("pol1").set("source", "vectors");

//    In the x text field, type range(x0,a,x0+N*a).

    model.component("comp1").geom("geom1").feature("pol1").set("x", "range(x0,a,x0+N*a)");

//    In the y text field, type y0+0*range(0,1,N).

    model.component("comp1").geom("geom1").feature("pol1").set("y", "y0+0*range(0,1,N)");

//    In the z text field, type 0*range(0,1,N).

    model.component("comp1").geom("geom1").feature("pol1").set("z", "0*range(0,1,N)");

//    Click Build Selected.

    model.component("comp1").geom("geom1").run("pol1");

//    In the Geometry toolbar, click Block.

    model.component("comp1").geom("geom1").create("blk2", "Block");

//    In the Settings window for Block, locate the Size and Shape section.
//    In the Width text field, type (N+4)*a.

    model.component("comp1").geom("geom1").feature("blk2").set("size", new String[]{"(N+4)*a", "1", "1"});

//    In the Depth text field, type (N+4)*a.

    model.component("comp1").geom("geom1").feature("blk2").set("size", new String[]{"(N+4)*a", "(N+4)*a", "1"});

//    In the Height text field, type N*a/3.

    model.component("comp1").geom("geom1").feature("blk2").setIndex("size", "N*a/3", 2);

//    Locate the Position section.
//    In the x text field, type x0-2*a.

    model.component("comp1").geom("geom1").feature("blk2").set("pos", new String[]{"x0-2*a", "0", "0"});

//    In the y text field, type y0-(N+4)*a/2.

    model.component("comp1").geom("geom1").feature("blk2").set("pos", new String[]{"x0-2*a", "y0-(N+4)*a/2", "0"});

//    In the z text field, type -N*a/3.

    model.component("comp1").geom("geom1").feature("blk2").setIndex("pos", "-N*a/3", 2);

//    Click Build Selected.

    model.component("comp1").geom("geom1").run("blk2");

//    In the Model Builder window, click Form Union (fin).
//    In the Settings window for Form Union/Assembly, click Build Selected.

    model.component("comp1").geom("geom1").run("fin");

//    Click the Go to Default View button in the Graphics toolbar.
//    Click the Transparency button in the Graphics toolbar.

    model.component("comp1").view("view1").set("transparency", true);

//     to see the interior of the geometry.
//    Click the Transparency button in the Graphics toolbar.

    model.component("comp1").view("view1").set("transparency", false);

//     to return to the default state.
//    In the Definitions toolbar, click Analytic.

    model.component("comp1").func().create("an1", "Analytic");

//    In the Settings window for Analytic, type V_ref in the Function name text field.

    model.component("comp1").func("an1").set("funcname", "V_ref");

//    Locate the Definition section.
//    In the Expression text field, type 1[A]*rho0/(2*pi)*(1/abs(x-x1)-1/abs(x-x2)).

    model.component("comp1").func("an1").set("expr", "1[A]*rho0/(2*pi)*(1/abs(x-x1)-1/abs(x-x2))");

//    In the Arguments text field, type x, x1, x2.

    model.component("comp1").func("an1").set("args", "x, x1, x2");

//    The analytical solution given by <c>V_ref</c> will be used to validate the computed solution.
//    In the Definitions toolbar, click Explicit.

    model.component("comp1").selection().create("sel1", "Explicit");

//    In the Settings window for Explicit, locate the Input Entities section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp1").selection("sel1").geom(2);

//    Select all the exterior boundaries located in the ground. This operation can be performed quickly by selecting the <l>Group by continuous tangent</l> checkbox, then clicking on one boundary from each of the sides and the bottom of the box.

    model.component("comp1").selection("sel1")
         .set(1, 2, 3, 4, 5, 8, 10, 11, 15, 17, 18, 22, 23, 25, 26, 28, 33, 40, 45, 46, 54, 55, 57, 62, 69, 74, 75, 76, 77, 78, 79, 80, 81);

//    In the Label text field, type Ground Boundaries.

    model.component("comp1").selection("sel1").label("Ground Boundaries");

//    In the Definitions toolbar, click Explicit.

    model.component("comp1").selection().create("sel2", "Explicit");

//    Select Domains 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19.

    model.component("comp1").selection("sel2").set(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19);

//    In the Settings window for Explicit, type Infinite Element Domains in the Label text field.

    model.component("comp1").selection("sel2").label("Infinite Element Domains");

//    In the Definitions toolbar, click Explicit.

    model.component("comp1").selection().create("sel3", "Explicit");

//    Select Domains 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19.

    model.component("comp1").selection("sel3").set(1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19);

//    In the Settings window for Explicit, locate the Output Entities section.
//    From the Output entities list, select Adjacent boundaries.

    model.component("comp1").selection("sel3").geom("geom1", 3, 2, new String[]{"exterior"});
    model.component("comp1").selection("sel3").set(1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19);

//    Select the Interior boundaries checkbox.

    model.component("comp1").selection("sel3").geom("geom1", 3, 2, new String[]{"exterior", "interior"});
    model.component("comp1").selection("sel3").set(1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19);

//    In the Label text field, type Infinite Elements Boundaries.

    model.component("comp1").selection("sel3").label("Infinite Elements Boundaries");

//    In the Definitions toolbar, click Infinite Element Domain.

    model.component("comp1").coordSystem().create("ie1", "InfiniteElement");

//    In the Settings window for Infinite Element Domain, locate the Domain Selection section.
//    From the Selection list, select Infinite Element Domains.

    model.component("comp1").coordSystem("ie1").selection().named("sel2");

//    Set the physical size of the infinite elements domain to be 100 times the size of the geometry. Larger sizes can give even more accurate results but will require a more refined mesh to be resolved.
//    Locate the Scaling section.
//    In the Physical width text field, type 1e2*dGeomChar.

    model.component("comp1").coordSystem("ie1").set("width", "1e2*dGeomChar");

//    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, locate the Material Contents section.
//    In the table, enter the following settings:

    model.component("comp1").material("mat1").propertyGroup("def")
         .set("electricconductivity", new String[]{"1/rho0"});
    model.component("comp1").material("mat1").propertyGroup("def").set("relpermittivity", new String[]{"1"});

//    In the Label text field, type 100 Ohmm Homogeneous.

    model.component("comp1").material("mat1").label("100 Ohmm Homogeneous");

//    In the Physics toolbar, click Points and choose Point Current Source.

    model.component("comp1").physics("ec").create("pcs1", "PointCurrentSource", 0);

//    Select Points 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.

    model.component("comp1").physics("ec").feature("pcs1").selection()
         .set(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);

//    In the Settings window for Point Current Source, locate the Point Current Source section.
//    In the \[Q_\textrm{j,p}\] text field, type 1*(dom==dom_C1)-1*(dom==dom_C2).

    model.component("comp1").physics("ec").feature("pcs1").set("Qjp", "1*(dom==dom_C1)-1*(dom==dom_C2)");

//    The <c>dom</c> variable is a built-in variable that represents the domain number. It uniquely identifies each entity within the specified dimension. In this model, it is used to select different points, since on point 1 it has a value of 1, on point 2 it has a value of 2, and so on. The <c>==</c> operator, together with a sweep over a parameter, allows for scanning over different sources, identifying them by their domain number. Point number <c>dom_C1</c> injects a unit charge. Point number <c>dom_C2</c> extracts a unit charge. See the <em>COMSOL Multiphysics Reference Manual</em> for more information about built-in variables and operators.
//    Locate the Point Selection section.
//    Click Create Selection.
//    In the Create Selection dialog, type Point sources in the Selection name text field.
//    Click OK.

    model.component("comp1").selection().create("sel4", "Explicit");
    model.component("comp1").selection("sel4").geom(0);
    model.component("comp1").selection("sel4").label("Point sources");
    model.component("comp1").selection("sel4")
         .set(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);

    model.component("comp1").physics("ec").feature("pcs1").selection().named("sel4");

//    In the Physics toolbar, click Boundaries and choose Ground.

    model.component("comp1").physics("ec").create("gnd1", "Ground", 2);

//    In the Settings window for Ground, locate the Boundary Selection section.
//    From the Selection list, select Ground Boundaries.

    model.component("comp1").physics("ec").feature("gnd1").selection().named("sel1");

//    In the Model Builder window, right-click Component 1 (comp1) > Mesh 1 and choose Edit Physics-Induced Sequence.

    model.component("comp1").mesh("mesh1").automatic(false);

//    In the Model Builder window, right-click Free Tetrahedral 1 and choose Size.

    model.component("comp1").mesh("mesh1").feature("ftet1").create("size1", "Size");

//    In the Settings window for Size, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Edge.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size1").selection().geom("geom1", 1);

//    Select Edges 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size1").selection()
         .set(67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91);

//    Locate the Element Size section.
//    Click the Custom button.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size1").set("custom", true);

//    Locate the Element Size Parameters section.
//    Select the Maximum element size checkbox.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size1").set("hmaxactive", true);

//    In the associated text field, type 0.05.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size1").set("hmax", 0.05);

//    Right-click Free Tetrahedral 1 and choose Size.

    model.component("comp1").mesh("mesh1").feature("ftet1").create("size2", "Size");

//    Select Domain 13.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size2").selection().set(13);

//    In the Settings window for Size, locate the Element Size section.
//    Click the Custom button.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size2").set("custom", true);

//    Locate the Element Size Parameters section.
//    Select the Maximum element size checkbox.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size2").set("hmaxactive", true);

//    In the associated text field, type 2.

    model.component("comp1").mesh("mesh1").feature("ftet1").feature("size2").set("hmax", 2);

//    Click Build All.

    model.component("comp1").mesh("mesh1").run();

//    In the Model Builder window, under Study 1, click Step 1: Stationary.
//    In the Settings window for Stationary, click to expand the Study Extensions section.
//    Add a parametric sweep on the charge source and sink. It can be seen that only one Jacobian is going to be computed, making the solution time for subsequent parameters after the first one faster. A further time improvement can be achieved by forcing a direct solver, as the whole LU decomposition of first step would be reused in that case. This improved solution time comes at the cost of a larger memory usage.
//    Select the Auxiliary sweep checkbox.

    model.study("std1").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std1").feature("stat").setIndex("pname", "L", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "", 0);
    model.study("std1").feature("stat").setIndex("punit", "m", 0);
    model.study("std1").feature("stat").setIndex("pname", "L", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "", 0);
    model.study("std1").feature("stat").setIndex("punit", "m", 0);

//    In the table, enter the following settings:

    model.study("std1").feature("stat").setIndex("pname", "dom_C1", 0);
    model.study("std1").feature("stat").setIndex("plistarr", "34 39", 0);

//    Click Add.

    model.study("std1").feature("stat").setIndex("pname", "L", 1);
    model.study("std1").feature("stat").setIndex("plistarr", "", 1);
    model.study("std1").feature("stat").setIndex("punit", "m", 1);
    model.study("std1").feature("stat").setIndex("pname", "L", 1);
    model.study("std1").feature("stat").setIndex("plistarr", "", 1);
    model.study("std1").feature("stat").setIndex("punit", "m", 1);

//    In the table, enter the following settings:

    model.study("std1").feature("stat").setIndex("pname", "dom_C2", 1);
    model.study("std1").feature("stat").setIndex("plistarr", "49 44", 1);

//    The continuation solver is not needed for this sweep.
//    From the Run continuation for list, select No parameter.

    model.study("std1").feature("stat").set("pcontinuationmode", "no");

//    In the Study toolbar, click Compute.

    model.study("std1").createAutoSequences("all");

    model.sol("sol1").runAll();

    model.result().create("pg1", "PlotGroup3D");
    model.result("pg1").label("Electric Potential (ec)");
    model.result("pg1").set("frametype", "spatial");
    model.result("pg1").set("showlegendsmaxmin", true);
    model.result("pg1").feature().create("vol1", "Volume");
    model.result("pg1").feature("vol1").set("solutionparams", "parent");
    model.result("pg1").feature("vol1").set("colortable", "Dipole");
    model.result("pg1").feature("vol1").set("evaluationsettings", "parent");
    model.result("pg1").feature("vol1").set("data", "parent");
    model.result().create("pg2", "PlotGroup3D");
    model.result("pg2").label("Electric Field (ec)");
    model.result("pg2").set("frametype", "spatial");
    model.result("pg2").set("showlegendsmaxmin", true);
    model.result("pg2").feature().create("mslc1", "Multislice");
    model.result("pg2").feature("mslc1").set("solutionparams", "parent");
    model.result("pg2").feature("mslc1").set("expr", "ec.normE");
    model.result("pg2").feature("mslc1").set("multiplanexmethod", "coord");
    model.result("pg2").feature("mslc1").set("xcoord", "ec.CPx");
    model.result("pg2").feature("mslc1").set("multiplaneymethod", "coord");
    model.result("pg2").feature("mslc1").set("ycoord", "ec.CPy");
    model.result("pg2").feature("mslc1").set("multiplanezmethod", "coord");
    model.result("pg2").feature("mslc1").set("zcoord", "ec.CPz");
    model.result("pg2").feature("mslc1").set("colortable", "Prism");
    model.result("pg2").feature("mslc1").set("colortabletrans", "nonlinear");
    model.result("pg2").feature("mslc1").set("colorcalibration", -0.8);
    model.result("pg2").feature("mslc1").set("evaluationsettings", "parent");
    model.result("pg2").feature("mslc1").set("data", "parent");
    model.result("pg2").feature().create("strmsl1", "StreamlineMultislice");
    model.result("pg2").feature("strmsl1").set("solutionparams", "parent");
    model.result("pg2").feature("strmsl1").set("expr", new String[]{"ec.Ex", "ec.Ey", "ec.Ez"});
    model.result("pg2").feature("strmsl1").set("multiplanexmethod", "coord");
    model.result("pg2").feature("strmsl1").set("xcoord", "ec.CPx");
    model.result("pg2").feature("strmsl1").set("multiplaneymethod", "coord");
    model.result("pg2").feature("strmsl1").set("ycoord", "ec.CPy");
    model.result("pg2").feature("strmsl1").set("multiplanezmethod", "coord");
    model.result("pg2").feature("strmsl1").set("zcoord", "ec.CPz");
    model.result("pg2").feature("strmsl1").set("titletype", "none");
    model.result("pg2").feature("strmsl1").set("posmethod", "uniform");
    model.result("pg2").feature("strmsl1").set("udensity", 8);
    model.result("pg2").feature("strmsl1").set("color", "black");
    model.result("pg2").feature("strmsl1").set("evaluationsettings", "parent");
    model.result("pg2").feature("strmsl1").set("maxlen", 0.4);
    model.result("pg2").feature("strmsl1").set("maxtime", Double.POSITIVE_INFINITY);
    model.result("pg2").feature("strmsl1").set("inheritcolor", false);
    model.result("pg2").feature("strmsl1").set("maxtime", Double.POSITIVE_INFINITY);
    model.result("pg2").feature("strmsl1").set("data", "parent");
    model.result("pg2").feature("strmsl1").set("inheritplot", "mslc1");
    model.result("pg2").feature("strmsl1").feature().create("tran1", "Transparency");
    model.result("pg2").feature("strmsl1").feature("tran1").set("transparency", 0.9);
    model.result("pg2").feature("strmsl1").feature().create("filt1", "Filter");
    model.result("pg2").feature("strmsl1").feature("filt1").set("expr", "!isScalingSystemDomain");
    model.result("pg1").run();

//    The default volume plot of the electric potential is useful when checking for general modeling errors. To adapt the plot for this application, modify it as follows:

    model.result("pg1").run();

//    In the Model Builder window, expand the Electric Potential (ec) node.
//    Right-click Volume 1 and choose Delete.

    model.result("pg1").feature().remove("vol1");
    model.result("pg1").run();

//    In the Electric Potential (ec) toolbar, click More Plots and choose Multislice.

    model.result("pg1").create("mslc1", "Multislice");
    model.result("pg1").feature("mslc1").set("evaluationsettings", "parent");

//    In the Settings window for Multislice, locate the Multiplane Data section.
//    Find the x-planes subsection.
//    In the Planes text field, type 3.

    model.result("pg1").feature("mslc1").set("xnumber", "3");

//    Find the y-planes subsection.
//    In the Planes text field, type 2.

    model.result("pg1").feature("mslc1").set("ynumber", "2");

//    Locate the Coloring and Style section.
//    From the Color table list, select Dipole.

    model.result("pg1").feature("mslc1").set("colortable", "Dipole");

//    In the Electric Potential (ec) toolbar, click Plot.

    model.result("pg1").run();

//    Follow the instructions below to create tailored plots for this application.
//    In the Model Builder window, right-click View 1 and choose Hide for Physics.

    model.component("comp1").view("view1").hideEntities().create("hide1");

//    In the Settings window for Hide for Physics, locate the Geometric Entity Selection section.
//    From the Selection list, select Infinite Element Domains.

    model.component("comp1").view("view1").hideEntities("hide1").named("sel2");

//    Right-click View 1 and choose Hide for Physics.

    model.component("comp1").view("view1").hideEntities().create("hide2");

//    In the Settings window for Hide for Physics, locate the Geometric Entity Selection section.
//    From the Geometric entity level list, select Boundary.

    model.component("comp1").view("view1").hideEntities("hide2").geom("geom1", 2);

//    From the Selection list, select Infinite Elements Boundaries.

    model.component("comp1").view("view1").hideEntities("hide2").named("sel3");

//    In the Results toolbar, click 3D Plot Group.

    model.result().create("pg3", "PlotGroup3D");
    model.result("pg3").run();

//    Right-click 3D Plot Group 3 and choose Slice.

    model.result("pg3").create("slc1", "Slice");
    model.result("pg3").feature("slc1").set("evaluationsettings", "parent");

//    In the Settings window for Slice, locate the Expression section.
//    In the Expression text field, type with(1,ec.Jx)*with(2,ec.Jx)+with(1,ec.Jy)*with(2,ec.Jy)+with(1,ec.Jz)*with(2,ec.Jz).

    model.result("pg3").feature("slc1")
         .set("expr", "with(1,ec.Jx)*with(2,ec.Jx)+with(1,ec.Jy)*with(2,ec.Jy)+with(1,ec.Jz)*with(2,ec.Jz)");

//    Locate the Plane Data section.
//    From the Plane list, select zx-planes.

    model.result("pg3").feature("slc1").set("quickplane", "zx");

//    From the Entry method list, select Coordinates.

    model.result("pg3").feature("slc1").set("quickymethod", "coord");

//    In the y-coordinates text field, type 25 27 29.

    model.result("pg3").feature("slc1").set("quicky", "25 27 29");

//    Click to expand the Range section.
//    Select the Manual color range checkbox.

    model.result("pg3").feature("slc1").set("rangecoloractive", true);

//    In the Minimum text field, type -1E-4.

    model.result("pg3").feature("slc1").set("rangecolormin", "-1E-4");

//    In the Maximum text field, type 1E-4.

    model.result("pg3").feature("slc1").set("rangecolormax", "1E-4");

//    Locate the Coloring and Style section.
//    From the Color table list, select Dipole.

    model.result("pg3").feature("slc1").set("colortable", "Dipole");

//    In the 3D Plot Group 3 toolbar, click Plot.

    model.result("pg3").run();
    model.result("pg3").run();

//    In the Model Builder window, click 3D Plot Group 3.
//    In the Settings window for 3D Plot Group, click to expand the Title section.
//    From the Title type list, select Manual.

    model.result("pg3").set("titletype", "manual");

//    In the Title text area, type Sensitivity plot.

    model.result("pg3").set("title", "Sensitivity plot");

//    In the Label text field, type Sensitivity.

    model.result("pg3").label("Sensitivity");

//    Next, plot the electric potential on the surface.
//    In the Model Builder window, expand the Results > Datasets node.
//    Right-click Results > Datasets > Study 1/Solution 1 (sol1) and choose Duplicate.

    model.result().dataset().duplicate("dset2", "dset1");

//    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("dset2").selection().geom("geom1", 2);

//    Select Boundaries 37, 50.

    model.result().dataset("dset2").selection().geom("geom1", 2);
    model.result().dataset("dset2").selection().set(37, 50);

//    In the Results toolbar, click 3D Plot Group.

    model.result().create("pg4", "PlotGroup3D");
    model.result("pg4").run();

//    In the Settings window for 3D Plot Group, type Electric Potential at the Surface in the Label text field.

    model.result("pg4").label("Electric Potential at the Surface");

//    Locate the Data section.
//    From the Dataset list, select Study 1/Solution 1 (2) (sol1).

    model.result("pg4").set("data", "dset2");

//    Right-click Electric Potential at the Surface and choose Surface.

    model.result("pg4").create("surf1", "Surface");
    model.result("pg4").feature("surf1").set("evaluationsettings", "parent");

//    In the Settings window for Surface, click to expand the Range section.
//    Select the Manual color range checkbox.

    model.result("pg4").feature("surf1").set("rangecoloractive", true);

//    In the Minimum text field, type -10.

    model.result("pg4").feature("surf1").set("rangecolormin", -10);

//    In the Maximum text field, type 10.

    model.result("pg4").feature("surf1").set("rangecolormax", 10);

//    Locate the Coloring and Style section.
//    From the Color table list, select Dipole.

    model.result("pg4").feature("surf1").set("colortable", "Dipole");
    model.result("pg4").run();

//    In the Model Builder window, right-click Electric Potential at the Surface and choose Contour.

    model.result("pg4").create("con1", "Contour");
    model.result("pg4").feature("con1").set("evaluationsettings", "parent");

//    In the Settings window for Contour, locate the Levels section.
//    From the Entry method list, select Levels.

    model.result("pg4").feature("con1").set("levelmethod", "levels");

//    In the Levels text field, type -10^(range(0,-0.2,-3)) 10^(range(-3,0.2,0)).

    model.result("pg4").feature("con1").set("levels", "-10^(range(0,-0.2,-3)) 10^(range(-3,0.2,0))");

//    Locate the Coloring and Style section.
//    From the Coloring list, select Uniform.

    model.result("pg4").feature("con1").set("coloring", "uniform");

//    From the Color list, select Black.

    model.result("pg4").feature("con1").set("color", "black");

//    Clear the Color legend checkbox.

    model.result("pg4").feature("con1").set("colorlegend", false);

//    In the Electric Potential at the Surface toolbar, click Plot.

    model.result("pg4").run();

//    Click the Go to Default View button in the Graphics toolbar.
//    In the Results toolbar, click Cut Plane.

    model.result().dataset().create("cpl1", "CutPlane");

//    In the Settings window for Cut Plane, locate the Plane Data section.
//    From the Plane list, select zx-planes.

    model.result().dataset("cpl1").set("quickplane", "zx");

//    In the y-coordinate text field, type y0.

    model.result().dataset("cpl1").set("quicky", "y0");

//    In the Results toolbar, click 3D Plot Group.

    model.result().create("pg5", "PlotGroup3D");
    model.result("pg5").run();

//    In the Settings window for 3D Plot Group, type Electric Potential, Slice in the Label text field.

    model.result("pg5").label("Electric Potential, Slice");

//    Locate the Data section.
//    From the Dataset list, select Cut Plane 1.

    model.result("pg5").set("data", "cpl1");

//    From the Parameter value (dom_C1,dom_C2) list, select 1: dom_C1=34, dom_C2=49.

    model.result("pg5").setIndex("looplevel", 1, 0);

//    Right-click Electric Potential, Slice and choose Surface.

    model.result("pg5").create("surf1", "Surface");
    model.result("pg5").feature("surf1").set("evaluationsettings", "parent");

//    In the Settings window for Surface, locate the Range section.
//    Select the Manual color range checkbox.

    model.result("pg5").feature("surf1").set("rangecoloractive", true);

//    In the Minimum text field, type -10.

    model.result("pg5").feature("surf1").set("rangecolormin", -10);

//    In the Maximum text field, type 10.

    model.result("pg5").feature("surf1").set("rangecolormax", 10);

//    Locate the Coloring and Style section.
//    From the Color table list, select Dipole.

    model.result("pg5").feature("surf1").set("colortable", "Dipole");
    model.result("pg5").run();

//    In the Model Builder window, right-click Electric Potential, Slice and choose Contour.

    model.result("pg5").create("con1", "Contour");
    model.result("pg5").feature("con1").set("evaluationsettings", "parent");

//    In the Settings window for Contour, locate the Levels section.
//    From the Entry method list, select Levels.

    model.result("pg5").feature("con1").set("levelmethod", "levels");

//    In the Levels text field, type -10^(range(0.4,-0.2,-3)) 10^(range(-3,0.2,0.4)).

    return model;
  }

  public static Model run2(Model model) {

    model.result("pg5").feature("con1").set("levels", "-10^(range(0.4,-0.2,-3)) 10^(range(-3,0.2,0.4))");

//    Locate the Coloring and Style section.
//    From the Coloring list, select Uniform.

    model.result("pg5").feature("con1").set("coloring", "uniform");

//    From the Color list, select Black.

    model.result("pg5").feature("con1").set("color", "black");

//    Clear the Color legend checkbox.

    model.result("pg5").feature("con1").set("colorlegend", false);

//    In the Electric Potential, Slice toolbar, click Plot.

    model.result("pg5").run();
    model.result("pg5").run();

//    In the Model Builder window, click Electric Potential, Slice.
//    In the Settings window for 3D Plot Group, locate the Data section.
//    From the Parameter value (dom_C1,dom_C2) list, select 2: dom_C1=39, dom_C2=44.

    model.result("pg5").setIndex("looplevel", 2, 0);

//    In the Electric Potential, Slice toolbar, click Plot.

    model.result("pg5").run();

//    In the Results toolbar, click More Datasets and choose Grid > Grid 1D.

    model.result().dataset().create("grid1", "Grid1D");
    model.result().dataset("grid1").set("source", "data");

//    In the Settings window for Grid 1D, locate the Data section.
//    From the Source list, select Function.

    model.result().dataset("grid1").set("source", "function");

//    From the Function list, select Analytic 1 (V_ref).

    model.result().dataset("grid1").set("function", "an1");

//    Locate the Parameter Bounds section.
//    In the Minimum text field, type 10.

    model.result().dataset("grid1").set("parmin1", 10);

//    In the Maximum text field, type 40.

    model.result().dataset("grid1").set("parmax1", 40);

//    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 Result Comparison in the Label text field.

    model.result("pg6").label("Result Comparison");

//    Click to expand the Title section.
//    From the Title type list, select Manual.

    model.result("pg6").set("titletype", "manual");

//    In the Title text area, type Comparison between analytical (lines) and modeled (markers) results.

    model.result("pg6").set("title", "Comparison between analytical (lines) and modeled (markers) results");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg6").set("xlabelactive", true);

//    In the associated text field, type Position (m).

    model.result("pg6").set("xlabel", "Position (m)");

//    Select the y-axis label checkbox.

    model.result("pg6").set("ylabelactive", true);

//    In the associated text field, type Voltage (V).

    model.result("pg6").set("ylabel", "Voltage (V)");

//    Right-click Result Comparison and choose Point Graph.

    model.result("pg6").create("ptgr1", "PointGraph");
    model.result("pg6").feature("ptgr1").set("markerpos", "datapoints");
    model.result("pg6").feature("ptgr1").set("linewidth", "preference");

//    In the Settings window for Point Graph, locate the Data section.
//    From the Dataset list, select Study 1/Solution 1 (1) (sol1).

    model.result("pg6").feature("ptgr1").set("data", "dset1");

//    From the Parameter selection (dom_C1, dom_C2) list, select First.

    model.result("pg6").feature("ptgr1").setIndex("looplevelinput", "first", 0);

//    Locate the Selection section.
//    From the Selection list, select Point sources.

    model.result("pg6").feature("ptgr1").selection().named("sel4");

//    Locate the y-Axis Data section.
//    In the Expression text field, type abs(V).

    model.result("pg6").feature("ptgr1").set("expr", "abs(V)");

//    Locate the x-Axis Data section.
//    From the Parameter list, select Expression.

    model.result("pg6").feature("ptgr1").set("xdata", "expr");

//    In the Expression text field, type x.

    model.result("pg6").feature("ptgr1").set("xdataexpr", "x");

//    Click to expand the Coloring and Style section.
//    From the Color list, select Blue.

    model.result("pg6").feature("ptgr1").set("linecolor", "blue");

//    Click to expand the Legends section.
//    Right-click Point Graph 1 and choose Duplicate.

    model.result("pg6").feature().duplicate("ptgr2", "ptgr1");
    model.result("pg6").run();

//    In the Settings window for Point Graph, locate the Data section.
//    From the Parameter selection (dom_C1, dom_C2) list, select Last.

    model.result("pg6").feature("ptgr2").setIndex("looplevelinput", "last", 0);

//    Locate the Coloring and Style section.
//    From the Color list, select Green.

    model.result("pg6").feature("ptgr2").set("linecolor", "green");
    model.result("pg6").run();

//    In the Model Builder window, right-click Result Comparison and choose Line Graph.

    model.result("pg6").create("lngr1", "LineGraph");
    model.result("pg6").feature("lngr1").set("markerpos", "datapoints");
    model.result("pg6").feature("lngr1").set("linewidth", "preference");
    model.result("pg6").feature("lngr1").set("evaluationsettings", "parent");

//    In the Settings window for Line Graph, locate the Data section.
//    From the Dataset list, select Grid 1D 1.

    model.result("pg6").feature("lngr1").set("data", "grid1");

//    Locate the y-Axis Data section.
//    In the Expression text field, type abs(V_ref(x,17.5,32.5)).

    model.result("pg6").feature("lngr1").set("expr", "abs(V_ref(x,17.5,32.5))");

//    Locate the x-Axis Data section.
//    From the Parameter list, select Expression.

    model.result("pg6").feature("lngr1").set("xdata", "expr");

//    In the Expression text field, type x.

    model.result("pg6").feature("lngr1").set("xdataexpr", "x");

//    Click to expand the Coloring and Style section.
//    From the Color list, select Blue.

    model.result("pg6").feature("lngr1").set("linecolor", "blue");

//    Right-click Line Graph 1 and choose Duplicate.

    model.result("pg6").feature().duplicate("lngr2", "lngr1");
    model.result("pg6").run();

//    In the Settings window for Line Graph, locate the y-Axis Data section.
//    In the Expression text field, type abs(V_ref(x,22.5,27.5)).

    model.result("pg6").feature("lngr2").set("expr", "abs(V_ref(x,22.5,27.5))");

//    Locate the Coloring and Style section.
//    From the Color list, select Green.

    model.result("pg6").feature("lngr2").set("linecolor", "green");

//    In the Result Comparison toolbar, click Plot.

    model.result("pg6").run();

//    Change to log scale.
//    Click the y-Axis Log Scale button in the Graphics toolbar.

    model.result("pg6").set("ylog", true);

//    In the Result Comparison toolbar, click Plot.

    model.result("pg6").run();

//    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 Relative Error in the Label text field.

    model.result("pg7").label("Relative Error");

//    Locate the Title section.
//    From the Title type list, select Manual.

    model.result("pg7").set("titletype", "manual");

//    In the Title text area, type Relative error between modeled and analytical potential.

    model.result("pg7").set("title", "Relative error between modeled and analytical potential");

//    Locate the Plot Settings section.
//    Select the x-axis label checkbox.

    model.result("pg7").set("xlabelactive", true);

//    In the associated text field, type Position (m).

    model.result("pg7").set("xlabel", "Position (m)");

//    Select the y-axis label checkbox.

    model.result("pg7").set("ylabelactive", true);

//    In the associated text field, type Relative error.

    model.result("pg7").set("ylabel", "Relative error");

//    Locate the Axis section.
//    Select the Manual axis limits checkbox.

    model.result("pg7").set("axislimits", true);

//    Select the y-axis log scale checkbox.

    model.result("pg7").set("ylog", true);

//    In the x minimum text field, type 12.25.

    model.result("pg7").set("xmin", 12.25);

//    In the x maximum text field, type 37.75.

    model.result("pg7").set("xmax", 37.75);

//    In the y minimum text field, type 1e-7.

    model.result("pg7").set("ymin", "1e-7");

//    Right-click Relative Error and choose Line Graph.

    model.result("pg7").create("lngr1", "LineGraph");
    model.result("pg7").feature("lngr1").set("markerpos", "datapoints");
    model.result("pg7").feature("lngr1").set("linewidth", "preference");
    model.result("pg7").feature("lngr1").set("evaluationsettings", "parent");

//    In the Settings window for Line Graph, locate the Data section.
//    From the Dataset list, select Study 1/Solution 1 (1) (sol1).

    model.result("pg7").feature("lngr1").set("data", "dset1");

//    From the Parameter selection (dom_C1, dom_C2) list, select First.

    model.result("pg7").feature("lngr1").setIndex("looplevelinput", "first", 0);

//    Locate the y-Axis Data section.
//    In the Expression text field, type abs(V-V_ref(x,17.5,32.5))/abs(V).

    model.result("pg7").feature("lngr1").set("expr", "abs(V-V_ref(x,17.5,32.5))/abs(V)");

//    Select Edges 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91.

    model.result("pg7").feature("lngr1").selection()
         .set(67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91);

//    Locate the x-Axis Data section.
//    From the Parameter list, select Expression.

    model.result("pg7").feature("lngr1").set("xdata", "expr");

//    In the Expression text field, type x.

    model.result("pg7").feature("lngr1").set("xdataexpr", "x");

//    Right-click Line Graph 1 and choose Duplicate.

    model.result("pg7").feature().duplicate("lngr2", "lngr1");
    model.result("pg7").run();

//    In the Settings window for Line Graph, locate the Data section.
//    From the Parameter selection (dom_C1, dom_C2) list, select Last.

    model.result("pg7").feature("lngr2").setIndex("looplevelinput", "last", 0);

//    Locate the y-Axis Data section.
//    In the Expression text field, type abs(V-V_ref(x,22.5,27.5))/abs(V).

    model.result("pg7").feature("lngr2").set("expr", "abs(V-V_ref(x,22.5,27.5))/abs(V)");

//    In the Relative Error toolbar, click Plot.

    model.result("pg7").run();
    model.result("pg4").run();

    model.title("A Geoelectrical Forward Problem");

    model
         .description("The classical forward problem in the field of geoelectrics \u2014 which includes electrical resistivity tomography, ERT, and vertical electric sounding, VES \u2014 is the calculation of the electric potential at a given set of electrodes when electric currents are injected into the ground at other electrodes. This example describes the 3D ERT forward problem for 25\u00a0electrodes in a homogeneous ground of 100\u00a0ohmmeters and compares it to the analytical solution.");

    return model;
  }

  public static void main(String[] args) {
    Model model = run();
    run2(model);
  }

}
