/*
 * homogenization_non_newtonian_porous.java
 */

import com.comsol.model.*;
import com.comsol.model.util.*;

/** Model exported on May 16 2026, 21:57 by COMSOL 6.4.0.422. */
public class homogenization_non_newtonian_porous {

  public static Model run() {
    Model model = ModelUtil.create("Model");

//    Start by opening the model <c>pore_scale_flow_3d</c> from the Porous Media Flow Module Application Library. If you have not installed the Application Library you can alternatively download the model from the COMSOL website.
//    From the File menu, choose Application Libraries.
//    In the Application Libraries window, select Porous Media Flow Module > Fluid Flow > pore_scale_flow_3d in the tree.
//    Click Open.

    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("spf", "CreepingFlow", "geom1");

    model.study().create("std1");
    model.study("std1").create("stat", "Stationary");

    model.component("comp1").geom("geom1").lengthUnit("cm");

    model.component("comp1").mesh().create("gmesh1", "Geometry", "geom1");

    model.component("comp1").geometricModel("mesh/gmesh1");

    model.component("comp1").mesh("mesh1").geometricModel("mesh/gmesh1");
    model.component("comp1").mesh("mesh1").automatic(true);

    model.study("std1").feature("stat").setEntry("mesh", "geom1", "mesh1");

    model.component("comp1").mesh("gmesh1").create("imp1", "Import");
    model.component("comp1").mesh("gmesh1").feature("imp1").set("filename", "pore_scale_flow_3d.stl");
    model.component("comp1").mesh("gmesh1").feature("imp1").set("createdom", true);
    model.component("comp1").mesh("gmesh1").feature("imp1").set("facepartition", "detectfaces");
    model.component("comp1").mesh("gmesh1").feature("imp1").set("stltoltype", "absolute");
    model.component("comp1").mesh("gmesh1").feature("imp1").set("stltolabs", "1e-5");
    model.component("comp1").mesh("gmesh1").feature("imp1").set("facemaxangle", 62);
    model.component("comp1").mesh("gmesh1").feature("imp1").importData();

    model.component("comp1").view("view1").set("rendermesh", true);

    model.component("comp1").mesh("gmesh1").create("boxsel1", "BoxSelection");
    model.component("comp1").mesh("gmesh1").feature("boxsel1").label("Inlet");
    model.component("comp1").mesh("gmesh1").feature("boxsel1").set("entitydim", 2);
    model.component("comp1").mesh("gmesh1").feature("boxsel1").set("ymax", 0.01);
    model.component("comp1").mesh("gmesh1").feature("boxsel1").set("condition", "inside");
    model.component("comp1").mesh("gmesh1").run("boxsel1");
    model.component("comp1").mesh("gmesh1").create("boxsel2", "BoxSelection");
    model.component("comp1").mesh("gmesh1").feature("boxsel2").label("Outlet");
    model.component("comp1").mesh("gmesh1").feature("boxsel2").set("entitydim", 2);
    model.component("comp1").mesh("gmesh1").feature("boxsel2").set("ymin", 5.99);
    model.component("comp1").mesh("gmesh1").feature("boxsel2").set("condition", "inside");
    model.component("comp1").mesh("gmesh1").run("boxsel2");
    model.component("comp1").mesh("gmesh1").create("boxsel3", "BoxSelection");
    model.component("comp1").mesh("gmesh1").feature("boxsel3").label("Wall");
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("entitydim", 2);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("xmin", 0.01);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("xmax", 1.99);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("ymin", 0.01);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("ymax", 5.99);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("zmin", 0.01);
    model.component("comp1").mesh("gmesh1").feature("boxsel3").set("zmax", 1.99);
    model.component("comp1").mesh("gmesh1").run("boxsel3");
    model.component("comp1").mesh("gmesh1").create("comsel1", "ComplementSelection");
    model.component("comp1").mesh("gmesh1").feature("comsel1").label("Symmetry");
    model.component("comp1").mesh("gmesh1").feature("comsel1").set("entitydim", 2);
    model.component("comp1").mesh("gmesh1").feature("comsel1")
         .set("input", new String[]{"boxsel1", "boxsel2", "boxsel3"});
    model.component("comp1").mesh("gmesh1").run("comsel1");
    model.component("comp1").mesh("gmesh1").create("join1", "JoinEntities");
    model.component("comp1").mesh("gmesh1").feature("join1").selection().geom("geom1", 2);
    model.component("comp1").mesh("gmesh1").feature("join1").selection().named("boxsel3");
    model.component("comp1").mesh("gmesh1").run("join1");
    model.component("comp1").mesh("gmesh1").run("fin");

    model.param().set("rho_f", "1000[kg/m^3]");
    model.param().descr("rho_f", "Fluid density");
    model.param().set("mu_f", "1e-3[Pa*s]");
    model.param().descr("mu_f", "Fluid viscosity");
    model.param().set("u_in", "1e-4[m/s]");
    model.param().descr("u_in", "Inlet velocity");
    model.param().set("width", "2[cm]");
    model.param().descr("width", "REV width");
    model.param().set("length", "6[cm]");
    model.param().descr("length", "REV length");
    model.param().set("V_tot", "width^2*length");
    model.param().descr("V_tot", "Total REV volume");

    model.component("comp1").material().create("matlnk1", "Link");
    model.material().create("mat1", "Common", "");
    model.component("comp1").material("matlnk1").set("link", "mat1");
    model.material("mat1").propertyGroup("def").set("density", new String[]{"rho_f"});
    model.material("mat1").propertyGroup("def").set("dynamicviscosity", new String[]{"mu_f"});

    model.component("comp1").physics("spf").prop("ShapeProperty").set("order_fluid", 1);
    model.component("comp1").physics("spf").create("inl1", "InletBoundary", 2);
    model.component("comp1").physics("spf").feature("inl1").selection().named("gmesh1_boxsel1");
    model.component("comp1").physics("spf").feature("inl1").set("U0in", "u_in");
    model.component("comp1").physics("spf").create("out1", "OutletBoundary", 2);
    model.component("comp1").physics("spf").feature("out1").selection().named("gmesh1_boxsel2");
    model.component("comp1").physics("spf").feature("out1").set("NormalFlow", true);
    model.component("comp1").physics("spf").create("sym1", "Symmetry", 2);
    model.component("comp1").physics("spf").feature("sym1").selection().named("gmesh1_comsel1");

    model.component("comp1").mesh("mesh1").autoMeshSize(4);
    model.component("comp1").mesh("mesh1").run();

    model.result().dataset().create("mesh1", "Mesh");
    model.result().dataset("mesh1").set("mesh", "mesh1");
    model.result().create("pg1", "PlotGroup3D");
    model.result("pg1").label("Mesh Plot 1");
    model.result("pg1").set("data", "mesh1");
    model.result("pg1").set("inherithide", true);
    model.result("pg1").set("showlegendsmaxmin", true);
    model.result("pg1").create("mesh1", "Mesh");
    model.result("pg1").feature("mesh1").set("colortable", "TrafficFlow");
    model.result("pg1").feature("mesh1").set("colortabletrans", "nonlinear");
    model.result("pg1").feature("mesh1").set("nonlinearcolortablerev", true);
    model.result("pg1").feature("mesh1").set("meshdomain", "volume");
    model.result("pg1").run();
    model.result("pg1").feature("mesh1").set("colortable", "TrafficFlow");
    model.result("pg1").feature("mesh1").set("colortabletrans", "nonlinear");
    model.result("pg1").feature("mesh1").set("nonlinearcolortablerev", true);

    model.study("std1").setGenPlots(false);
    model.study("std1").createAutoSequences("all");

    model.sol("sol1").runAll();

    model.result().dataset().create("surf1", "Surface");
    model.result().dataset("surf1").selection().named("gmesh1_boxsel3");
    model.result().create("pg2", "PlotGroup3D");
    model.result("pg2").run();
    model.result("pg2").label("Velocity");
    model.result("pg2").set("edges", false);
    model.result("pg2").create("surf1", "Surface");
    model.result("pg2").feature("surf1").set("evaluationsettings", "parent");
    model.result("pg2").feature("surf1").set("data", "surf1");
    model.result("pg2").feature("surf1").set("expr", "1");
    model.result("pg2").feature("surf1").set("coloring", "uniform");
    model.result("pg2").feature("surf1").set("color", "gray");
    model.result("pg2").run();
    model.result("pg2").create("line1", "Line");
    model.result("pg2").feature("line1").set("evaluationsettings", "parent");
    model.result("pg2").feature("line1").set("data", "surf1");
    model.result("pg2").feature("line1").set("coloring", "uniform");
    model.result("pg2").feature("line1").set("color", "black");
    model.result("pg2").run();
    model.result("pg2").feature("line1").set("color", "custom");
    model.result("pg2").feature("line1")
         .set("customcolor", new double[]{0.4117647111415863, 0.4117647111415863, 0.4117647111415863});
    model.result("pg2").run();
    model.result("pg2").create("str1", "Streamline");
    model.result("pg2").feature("str1").set("evaluationsettings", "parent");
    model.result("pg2").feature("str1").selection().named("gmesh1_boxsel1");
    model.result("pg2").feature("str1").set("selnumber", 60);
    model.result("pg2").feature("str1").set("linetype", "tube");
    model.result("pg2").feature("str1").set("tuberadiusscaleactive", true);
    model.result("pg2").feature("str1").set("tuberadiusscale", 0.01);
    model.result("pg2").feature("str1").create("col1", "Color");
    model.result("pg2").run();
    model.result("pg2").feature("str1").feature("col1").set("colortable", "Acanthaster");

    model.component("comp1").cpl().create("intop1", "Integration");
    model.component("comp1").cpl("intop1").set("axisym", true);
    model.component("comp1").cpl("intop1").selection().all();
    model.component("comp1").cpl().create("aveop1", "Average");
    model.component("comp1").cpl("aveop1").set("axisym", true);
    model.component("comp1").cpl("aveop1").label("Average Inlet");
    model.component("comp1").cpl("aveop1").selection().geom("geom1", 2);
    model.component("comp1").cpl("aveop1").selection().named("gmesh1_boxsel1");
    model.component("comp1").cpl().create("aveop2", "Average");
    model.component("comp1").cpl("aveop2").set("axisym", true);
    model.component("comp1").cpl("aveop2").label("Average Outlet");
    model.component("comp1").cpl("aveop2").selection().geom("geom1", 2);
    model.component("comp1").cpl("aveop2").selection().named("gmesh1_boxsel2");

    model.component("comp1").variable().create("var1");
    model.component("comp1").variable("var1").set("por", "intop1(1)/V_tot");
    model.component("comp1").variable("var1").descr("por", "Porosity");
    model.component("comp1").variable("var1").set("dPdL", "-(aveop2(p)-aveop1(p))/length");
    model.component("comp1").variable("var1").descr("dPdL", "Pressure drop");
    model.component("comp1").variable("var1").set("u_out", "spf.out1.massFlowRate/rho_f/width^2");
    model.component("comp1").variable("var1").descr("u_out", "Superficial outlet velocity");
    model.component("comp1").variable("var1").set("kappa", "u_out*mu_f/dPdL");
    model.component("comp1").variable("var1").descr("kappa", "Permeability");

    model.sol("sol1").updateSolution();

    model.result("pg2").run();
    model.result().numerical().create("gev1", "EvalGlobal");
    model.result().numerical("gev1").set("expr", new String[]{"por"});
    model.result().numerical("gev1").set("descr", new String[]{"Porosity"});
    model.result().numerical("gev1").set("expr", new String[]{"por", "kappa"});
    model.result().numerical("gev1").set("descr", new String[]{"Porosity", "Permeability"});
    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();
    model.result("pg2").run();
    model.result("pg2").feature("str1").set("pointtype", "interactivearrow");
    model.result("pg2").feature("str1").set("localtimeshifts", 2000);
    model.result().export().create("anim1", "Animation");
    model.result().export("anim1").set("target", "player");
    model.result().export("anim1").set("plotgroup", "pg2");
    model.result().export("anim1").set("sweeptype", "streamline");
    model.result().export("anim1").set("maxframes", 50);
    model.result().export("anim1").run();
    model.result("pg2").run();
    model.result("pg2").run();
    model.result("pg2").feature("str1").set("localtime", 58000);

    model.title("Analyzing Porous Structures on the Microscopic Scale");

    model
         .description("Modeling flow through realistic porous structures is difficult due to the complexity of the structure itself. Resolving the flow field in detail is not feasible in real-life applications. Therefore, macroscopic approaches are used, which utilize averaged quantities of the porous structure, such as porosity and permeability. This example imports an STL file of a porous structure and analyzes the flow field at the pore scale in detail.");

    model.label("pore_scale_flow_3d.mph");

    model.result("pg2").run();
    model.result("pg2").run();

//    The model has been used to calculate the porosity and permeability of the porous structure. These values, which represent the intrinsic properties of the porous medium, now serve as inputs for the model. To utilize them throughout the whole model, create parameters based on the values provided in <l>Table 1</l> under the <l>Graphics</l> window. Additionally, add parameters for the Carreau fluid.
//    In the Model Builder window, expand the Results > Tables node, then click Global Definitions > Parameters 1.
//    In the Settings window for Parameters, locate the Parameters section.
//    In the table, enter the following settings:

    model.param().set("poro", "0.3709");
    model.param().descr("poro", "Porosity");
    model.param().set("kappa0", "3.029e-8[m^2]");
    model.param().descr("kappa0", "Permeability");
    model.param().set("muc0", "0.1[Pa*s]");
    model.param().descr("muc0", "Zero shear rate viscosity, Carreau fluid");
    model.param().set("muc_inf", "0.005[Pa*s]");
    model.param().descr("muc_inf", "Infinite shear rate viscosity");
    model.param().set("lambda", "1.5[s]");
    model.param().descr("lambda", "Relaxation time");
    model.param().set("n", "0.65");
    model.param().descr("n", "Power index");

//    In the Model Builder window, expand the Component 1 (comp1) node.
//    In the Model Builder window, expand the Component 1 (comp1) > Creeping Flow (spf) node, then click Fluid Properties 1.
//    In the Settings window for Fluid Properties, locate the Fluid Properties section.
//    Find the Constitutive relation subsection.
//    From the list, select Inelastic non-Newtonian.

    model.component("comp1").physics("spf").feature("fp1").set("Constitutiverelation", "InelasticNonNewtonian");

//    From the Inelastic model list, select Carreau.

    model.component("comp1").physics("spf").feature("fp1").set("nonNewtonianModels", "Carreau");

//    Edit the material properties using the parameters.
//    In the Model Builder window, expand the Global Definitions > Materials node, then click Material 1 (mat1).
//    In the Settings window for Material, locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat1").propertyGroup().create("Carreau", "Carreau", "Non-Newtonian_Carreau_model");
    model.material("mat1").propertyGroup("Carreau").set("mu0", new String[]{"muc0"});
    model.material("mat1").propertyGroup("Carreau").set("mu_inf", new String[]{"muc_inf"});
    model.material("mat1").propertyGroup("Carreau").set("lam_car", new String[]{"lambda"});
    model.material("mat1").propertyGroup("Carreau").set("n_car", new String[]{"n"});

//    In the Model Builder window, expand the Component 1 (comp1) > Definitions node, then click Variables 1.
//    In the Settings window for Variables, locate the Variables section.
//    In the table, enter the following settings:

    model.component("comp1").variable("var1").set("mu_app", "kappa0/u_out*dPdL");
    model.component("comp1").variable("var1").descr("mu_app", "Apparent viscosity");
    model.component("comp1").variable("var1")
         .set("gamma_app", "sqrt(((mu_app-muc_inf)/(muc0-muc_inf))^(2/(n-1))-1)/lambda");

//    In the Model Builder window, under Component 1 (comp1) > Creeping Flow (spf), click Inlet 1.
//    In the Settings window for Inlet, locate the Boundary Condition section.
//    From the list, select Pressure.

    model.component("comp1").physics("spf").feature("inl1").set("BoundaryCondition", "Pressure");

//    Locate the Pressure Conditions section.
//    Select the \[p_{\textrm{0}}\] text field.
//    Right-click and choose Create Parameter.
//    In the Create Parameter dialog, type p_in in the Name text field.
//    In the Expression text field, type 1[Pa].
//    In the Description text field, type Inlet pressure.
//    Click OK.

    model.param().set("p_in", "1[Pa]", "Inlet pressure");

    model.component("comp1").physics("spf").feature("inl1").set("p0", "p_in");

//    In the Study toolbar, click Add Study to open the Add Study window.
//    Find the Studies subsection.
//    In the Select Study tree, select General Studies > Stationary.
//    Click Add Study in the window toolbar.

    model.study().create("std2");
    model.study("std2").create("stat", "Stationary");

//    In the Study toolbar, click Add Study to close the Add Study window.
//    In the Settings window for Stationary, click to expand the Study Extensions section.
//    Select the Auxiliary sweep checkbox.

    model.study("std2").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std2").feature("stat").setIndex("pname", "rho_f", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "", 0);
    model.study("std2").feature("stat").setIndex("punit", "kg/m^3", 0);
    model.study("std2").feature("stat").setIndex("pname", "rho_f", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "", 0);
    model.study("std2").feature("stat").setIndex("punit", "kg/m^3", 0);

//    In the table, enter the following settings:

    model.study("std2").feature("stat").setIndex("pname", "p_in", 0);
    model.study("std2").feature("stat").setIndex("plistarr", "10^range(0,0.5,2)", 0);

//    In the table, click to select the cell at row number 1 and column number 3.
//    In the Model Builder window, click Study 2.
//    In the Settings window for Study, locate the Study Settings section.
//    Clear the Generate default plots checkbox.

    model.study("std2").setGenPlots(false);

//    In the Study toolbar, click Compute.

    model.study("std2").createAutoSequences("all");

    model.sol("sol2").runAll();

//    Reuse the velocity plot to visualize the viscosity. The streamlines color table currently indicates velocity magnitude, but switch it to show viscosity instead. To keep the original Velocity plot in the model, duplicate it first, then make the modifications.

    model.result("pg2").run();

//    In the Model Builder window, right-click Velocity and choose Duplicate.

    model.result().duplicate("pg3", "pg2");
    model.result("pg3").run();

//    In the Settings window for 3D Plot Group, type Viscosity in the Label text field.

    model.result("pg3").label("Viscosity");

//    Locate the Data section.
//    From the Dataset list, select Study 2/Solution 2 (sol2).

    model.result("pg3").set("data", "dset2");
    model.result("pg3").run();

//    In the Model Builder window, expand the Viscosity node, then click Streamline 1.
//    In the Settings window for Streamline, locate the Coloring and Style section.
//    Find the Point style subsection.
//    From the Type list, select None.

    model.result("pg3").feature("str1").set("pointtype", "none");

//    Locate the Streamline Positioning section.
//    In the Number text field, type 80.

    model.result("pg3").feature("str1").set("selnumber", 80);
    model.result("pg3").run();

//    In the Model Builder window, expand the Streamline 1 node, then click Color Expression 1.
//    In the Settings window for Color Expression, locate the Expression section.
//    In the Expression text field, type spf.mu.

    model.result("pg3").feature("str1").feature("col1").set("expr", "spf.mu");

//    Locate the Coloring and Style section.
//    From the Color table list, select Lichen.

    model.result("pg3").feature("str1").feature("col1").set("colortable", "Lichen");

//    In the Viscosity toolbar, click Plot.

    model.result("pg3").run();

//    Next, compute the normalized velocity, apparent shear rate, and apparent viscosity as previously defined under <l>Variables 1</l>.
//    In the Results toolbar, click Global Evaluation.

    model.result().numerical().create("gev2", "EvalGlobal");

//    In the Settings window for Global Evaluation, locate the Data section.
//    From the Dataset list, select Study 2/Solution 2 (sol2).

    model.result().numerical("gev2").set("data", "dset2");

//    Locate the Expressions section.
//    In the table, enter the following settings:

    model.result().numerical("gev2").setIndex("expr", "u_out/sqrt(poro*kappa0)", 0);
    model.result().numerical("gev2").setIndex("expr", "gamma_app", 1);
    model.result().numerical("gev2").setIndex("expr", "mu_app", 2);

//    Click ^ next to Evaluate then choose New Table.

    model.result().table().create("tbl2", "Table");
    model.result().table("tbl2").comments("Global Evaluation 2");
    model.result().numerical("gev2").set("table", "tbl2");
    model.result().numerical("gev2").setResult();

//    Click Table Graph in the window toolbar.

    model.result().create("pg4", "PlotGroup1D");
    model.result("pg4").set("data", "none");
    model.result("pg4").create("tblp1", "Table");
    model.result("pg4").feature("tblp1").set("source", "table");
    model.result("pg4").feature("tblp1").set("table", "tbl2");
    model.result("pg4").feature("tblp1").set("linewidth", "preference");
    model.result("pg4").feature("tblp1").set("markerpos", "datapoints");
    model.result("pg4").run();

//    In the Settings window for Table Graph, locate the Data section.
//    From the x-axis data list, select u_out/sqrt(poro*kappa0) (1/s).

    model.result("pg4").feature("tblp1").set("xaxisdata", 2);

//    From the Plot columns list, select Manual.

    model.result("pg4").feature("tblp1").set("plotcolumninput", "manual");

//    In the Columns list, select gamma_app (1/s).

    model.result("pg4").feature("tblp1").set("plotcolumns", new int[]{3});

//    select gamma_app (1/s) in the Columns list.

    model.result("pg4").run();

//    In the Model Builder window, under Results, click 1D Plot Group 4.
//    In the Settings window for 1D Plot Group, type Apparent Shear Rate vs. Normalized Velocity in the Label text field.

    model.result("pg4").label("Apparent Shear Rate vs. Normalized Velocity");

//    In the Apparent Shear Rate vs. Normalized Velocity toolbar, click Plot.

    model.result("pg4").run();

//    In the Home toolbar, click Functions and choose Global > Least-Squares Fit.

    model.func().create("lsq1", "LeastSquares");

//    In the Settings window for Least-Squares Fit, locate the Data section.
//    From the Data source list, select Result table.

    model.func("lsq1").set("source", "resultTable");

//    From the Result table list, select Table 2.

    model.func("lsq1").set("resultTable", "tbl2");

//    Locate the Data Column Settings section.
//    In the table, enter the following settings:

    model.func("lsq1").setEntry("columnType", "col1", "none");
    model.func("lsq1").setEntry("columnType", "col2", "arg");
    model.func("lsq1").setEntry("columnType", "col3", "value");

//    Locate the Parameters section.
//    Click Clear Table.

    model.func("lsq1").set("pname", new String[]{});
    model.func("lsq1").set("plist", new double[]{});

//    Locate the Data Column Settings section.
//    In the table, click to select the cell at row number 3 and column number 3.
//    In the Expression text field, type alpha*x1.

    model.func("lsq1").setEntry("exprs", "col3", "alpha*x1");

//    Locate the Parameters section.
//    In the table, enter the following settings:

    model.func("lsq1").setIndex("pname", "alpha", 0);
    model.func("lsq1").setIndex("plist", 0, 0);

//    Click Fit Parameters.

    model.func("lsq1").run();

//    Click Plot.
//    In the Model Builder window, right-click the root node and choose Add Component > 3D.

    model.component().create("comp2", true);

    model.component("comp2").geom().create("geom2", 3);
    model.component("comp2").geom("geom2").geomRep("comsol");

    model.component("comp2").mesh().create("mesh2");
    model.component("comp2").mesh("mesh2").contribute("geom/detail", true);

//    In the Geometry toolbar, click Block.

    model.component("comp2").geom("geom2").create("blk1", "Block");

//    In the Settings window for Block, locate the Size and Shape section.
//    In the Width text field, type 2[cm].

    model.component("comp2").geom("geom2").feature("blk1").set("size", new String[]{"2[cm]", "1", "1"});

//    In the Depth text field, type 6[cm].

    model.component("comp2").geom("geom2").feature("blk1").set("size", new String[]{"2[cm]", "6[cm]", "1"});

//    In the Height text field, type 2[cm].

    model.component("comp2").geom("geom2").feature("blk1").set("size", new String[]{"2[cm]", "6[cm]", "2[cm]"});

//    In the Physics toolbar, click Add Physics to open the Add Physics window.
//    In the tree, select Fluid Flow > Porous Media and Subsurface Flow > Brinkman Equations (br).
//    Find the Physics interfaces in study subsection.
//    In the table, enter the following settings:
//    Click Add to Component 2 in the window toolbar.

    model.component("comp2").physics().create("br", "PorousMediaFlowBrinkman", "geom2");

    model.study("std1").feature("stat").setSolveFor("/physics/br", false);
    model.study("std2").feature("stat").setSolveFor("/physics/br", false);

    model.component("comp2").geom("geom2").run();

//    In the Physics toolbar, click Add Physics to close the Add Physics window.
//    In the Settings window for Fluid, locate the Fluid Properties section.
//    From the \[\rho\] list, select User defined.

    model.component("comp2").physics("br").feature("porous1").feature("fluid1").set("rho_mat", "userdef");

//    In the associated text field, type rho_f.

    model.component("comp2").physics("br").feature("porous1").feature("fluid1").set("rho", "rho_f");

//    Find the Constitutive relation subsection.
//    From the list, select Inelastic non-Newtonian.

    model.component("comp2").physics("br").feature("porous1").feature("fluid1")
         .set("Constitutiverelation", "InelasticNonNewtonian");

//    From the Inelastic model list, select Carreau.

    model.component("comp2").physics("br").feature("porous1").feature("fluid1").set("nonNewtonianModels", "Carreau");

//    Find the Apparent shear rate subsection.
//    In the \[\alpha\] text field, type lsq1.alpha.

    model.component("comp2").physics("br").feature("porous1").feature("fluid1").set("alpha", "lsq1.alpha");

//    In the Model Builder window, right-click Component 2 (comp2) > Materials and choose More Materials > Material Link.

    model.component("comp2").material().create("matlnk2", "Link");

//    In the Settings window for Material Link, locate the Link Settings section.
//    Click Go to Material.
//    In the Model Builder window, under Global Definitions > Materials, click Material 1 (mat1).
//    In the Settings window for Material, locate the Material Contents section.
//    In the table, enter the following settings:

    model.material("mat1").propertyGroup("def").set("porosity", new String[]{"poro"});
    model.material("mat1").propertyGroup("def").set("hydraulicpermeability", new String[]{"kappa0"});

//    In the Physics toolbar, click Boundaries and choose Inlet.

    model.component("comp2").physics("br").create("inl1", "InletBoundary", 2);

//    Select Boundary 2.

    model.component("comp2").physics("br").feature("inl1").selection().set(2);

//    In the Settings window for Inlet, locate the Boundary Condition section.
//    From the list, select Pressure.

    model.component("comp2").physics("br").feature("inl1").set("BoundaryCondition", "Pressure");

//    Locate the Pressure Conditions section.
//    In the \[p_{\textrm{0}}\] text field, type p_in.

    model.component("comp2").physics("br").feature("inl1").set("p0", "p_in");

//    In the Physics toolbar, click Boundaries and choose Outlet.

    model.component("comp2").physics("br").create("out1", "OutletBoundary", 2);

//    Select Boundary 5.

    model.component("comp2").physics("br").feature("out1").selection().set(5);

//    In the Physics toolbar, click Boundaries and choose Symmetry.

    model.component("comp2").physics("br").create("sym1", "Symmetry", 2);

//    Select Boundaries 1, 3, 4, 6.

    model.component("comp2").physics("br").feature("sym1").selection().set(1, 3, 4, 6);

//    Define variables which are later used to compare the porous approach with the pore-scale modeling.
//    In the Definitions toolbar, click Nonlocal Couplings and choose Average.

    model.component("comp2").cpl().create("aveop3", "Average");
    model.component("comp2").cpl("aveop3").set("axisym", true);

//    In the Settings window for Average, locate the Source Selection section.
//    From the Selection list, select All domains.

    model.component("comp2").cpl("aveop3").selection().all();

//    In the Model Builder window, right-click Definitions and choose Variables.

    model.component("comp2").variable().create("var2");

//    In the Settings window for Variables, locate the Variables section.
//    In the table, enter the following settings:

    model.component("comp2").variable("var2")
         .set("u_out", "br.out1.massFlowRate/rho_f/width^2", "Superficial outlet velocity");
    model.component("comp2").variable("var2").descr("u_out", "Darcy velocity");
    model.component("comp2").variable("var2").set("mu_app", "aveop3(br.mu)", "Apparent viscosity");
    model.component("comp2").variable("var2").set("gamma_app", "aveop3(br.porous.fluid.gamma_app)");
    model.component("comp2").variable("var2").descr("gamma_app", "Apparent shear rate");

//    In the Study toolbar, click Add Study to open the Add Study window.
//    Find the Studies subsection.
//    In the Select Study tree, select General Studies > Stationary.
//    Find the Physics interfaces in study subsection.
//    In the table, enter the following settings:
//    Click Add Study in the window toolbar.

    model.study().create("std3");
    model.study("std3").create("stat", "Stationary");
    model.study("std3").feature("stat").setSolveFor("/physics/spf", false);

//    In the Study toolbar, click Add Study to close the Add Study window.
//    In the Settings window for Stationary, locate the Study Extensions section.
//    Select the Auxiliary sweep checkbox.

    model.study("std3").feature("stat").set("useparam", true);

//    Click Add.

    model.study("std3").feature("stat").setIndex("pname", "rho_f", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "", 0);
    model.study("std3").feature("stat").setIndex("punit", "kg/m^3", 0);
    model.study("std3").feature("stat").setIndex("pname", "rho_f", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "", 0);
    model.study("std3").feature("stat").setIndex("punit", "kg/m^3", 0);

//    In the table, enter the following settings:

    return model;
  }

  public static Model run2(Model model) {

    model.study("std3").feature("stat").setIndex("pname", "p_in", 0);
    model.study("std3").feature("stat").setIndex("plistarr", "10^range(0,0.5,2)", 0);

//    In the Model Builder window, click Study 3.
//    In the Settings window for Study, locate the Study Settings section.
//    Clear the Generate default plots checkbox.

    model.study("std3").setGenPlots(false);

//    In the Study toolbar, click Compute.

    model.study("std3").createAutoSequences("all");

    model.sol("sol3").runAll();

//    In the Model Builder window, right-click Results > Derived Values > Global Evaluation 2 and choose Duplicate.

    model.result().numerical().duplicate("gev3", "gev2");

//    In the Settings window for Global Evaluation, locate the Data section.
//    From the Dataset list, select Study 3/Solution 3 (4) (sol3).

    model.result().numerical("gev3").set("data", "dset4");

//    Click ^ next to Evaluate then choose New Table.

    model.result().table().create("tbl3", "Table");
    model.result().table("tbl3").comments("Global Evaluation 3");
    model.result().numerical("gev3").set("table", "tbl3");
    model.result().numerical("gev3").setResult();
    model.result("pg4").run();

//    In the Model Builder window, right-click Results > Apparent Shear Rate vs. Normalized Velocity > Table Graph 1 and choose Duplicate.

    model.result("pg4").feature().duplicate("tblp2", "tblp1");
    model.result("pg4").run();

//    In the Settings window for Table Graph, locate the Data section.
//    From the Table list, select Table 3.

    model.result("pg4").feature("tblp2").set("table", "tbl3");

//    In the Apparent Shear Rate vs. Normalized Velocity toolbar, click Plot.

    model.result("pg4").run();
    model.result("pg4").run();

//    In the Model Builder window, right-click Apparent Shear Rate vs. Normalized Velocity and choose Duplicate.

    model.result().duplicate("pg5", "pg4");
    model.result("pg5").run();

//    In the Settings window for 1D Plot Group, type Apparent Viscosity vs. Normalized Velocity in the Label text field.

    model.result("pg5").label("Apparent Viscosity vs. Normalized Velocity");
    model.result("pg5").run();

//    In the Model Builder window, expand the Apparent Viscosity vs. Normalized Velocity node, then click Table Graph 1.
//    In the Settings window for Table Graph, locate the Data section.
//    In the Columns list, select Apparent viscosity (Pa*s).

    model.result("pg5").feature("tblp1").set("plotcolumns", new int[]{4});

//    select Apparent viscosity (Pa*s) in the Columns list.

    model.result("pg5").run();

//    In the Model Builder window, click Table Graph 2.
//    In the Settings window for Table Graph, locate the Data section.
//    In the Columns list, select Apparent viscosity (Pa*s).

    model.result("pg5").feature("tblp2").set("plotcolumns", new int[]{4});

//    select Apparent viscosity (Pa*s) in the Columns list.
//    In the Apparent Viscosity vs. Normalized Velocity toolbar, click Plot.

    model.result("pg5").run();
    model.result("pg3").run();

    model.title("Homogenization of Non-Newtonian Porous Media Flow");

    model
         .description("Non-Newtonian fluids have complex flow characteristics that vary with shear rate, making their behavior in porous materials difficult to predict. Pore scale modeling captures these flow patterns at a microscopic level, helping to derive properties for macroscale use.\nThis model demonstrates how pore-scale modeling can determine the apparent shear rate through a least-squares fit of microporous data for macroscopic modeling. It also compares results, showing that this approach is valuable for various applications.");

    return model;
  }

  public static void main(String[] args) {
    Model model = run();
    run2(model);
  }

}
