• CFD, Fluid Flow, FEA, Heat/Mass Transfer

Macros in Java for STAR-CCM+

Example Scripts to Automate Simulations

This page example functions and approach to automate simulation process partially or fully. It is not intended to created a push-button simulation example. Not all the codes have been tested in live STAR-CCM+ session and hence some bugs can be found.

The STAR-CCM+ user guide describes automation features available in STAR-CCM+ with many examples. There are some sample codes available online such as github.com/nitronayak/StarCCMAutomation

The first step in writing a JAVA macro for STAR CCM+ is to import the relevant packages. For example:

package macro;  - similar to #include "udf.h"
import java.util.*;  - similar to header files in C
import star.turbulence.*; - import turbulence model data
import star.common.*;   import star.material.*;
import star.base.neo.*; import star.vis.*;
import star.flow.*;     import star.energy.*;
import star.coupledflow.*;

// defineSim is the name of macro and the file name should be defineSim.java.
public class defineSim extends StarMacro {
  public void execute() {
    execute0();
  }
  //Get active simulation data
  Simulation getSim = getActiveSimulation();
  //Get domain named as FLUID and store it as 'cfd' - similar to Get_Domain in FLUENT UDF
  Region cfd = getSim.getRegionManager().getRegion("FLUID");
  //Set viscous model
  PhysicsContinuum pC0 = (PhysicsContinuum) cfd.getContinuumManager().getContinuum("Physics 1");
    pC0.enable(SteadyModel.class);
    pC0.enable(SingleComponentGasModel.class);
    pC0.enable(CoupledFlowModel.class);
    pC0.enable(IdealGasModel.class);
    pC0.enable(CoupledEnergyModel.class);
    pC0.enable(TurbulentModel.class);
    pC0.enable(RansTurbulenceModel.class);
    pC0.enable(KEpsilonTurbulence.class);
    pC0.enable(RkeTwoLayerTurbModel.class);
    pC0.enable(KeTwoLayerAllYplusWallTreatment.class);

  //Get boundary named INLET and velocity specification CLASS
  Boundary b1 = cfd.getBoundaryManager().getBoundary("INLET");
  VelocityProfile vP1 = b1.getValues().get(VelocityProfile.class);
  
    //Specify velocity normal to boundary with specified "MAGNITUDE and DIRECTION"
    //Note the word scalar in ConstantScalarProfileMethod.class
    b1.getConditions().get(InletVelocityOption.class).setSelected(InletVelocityOption.MAGNITUDE_DIRECTION);
    vP1.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(5.0);
  
    //Inlet velocity by its COMPONENTS, note 'vector' in ConstantVectorProfileMethod.class
    //b1.getConditions().get(InletVelocityOption.class).setSelected(InletVelocityOption.COMPONENTS);
    //vP1.getMethod(ConstantVectorProfileMethod.class).getQuantity().setComponents(5.0, 0.0, 0.0);
  
    //Set turbulence parameters - TURBULENT INTENSITY and VISCOSITY RATIO at INLET boundary
    TurbulenceIntensityProfile TI = b1.getValues().get(TurbulenceIntensityProfile.class);
    TI.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(0.02);

    TurbulentViscosityRatioProfile TVR = b1.getValues().get(TurbulentViscosityRatioProfile.class);
    TVR.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(5.0);
  
    //Specify fluid temperature in [K] at INLET
    StaticTemperatureProfile Tin = b1.getValues().get(StaticTemperatureProfile.class);
    Tin.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(323.0);
  
  //Get boundary named OUTLET and pressure boundary CLASS
  Boundary b2 = cfd.getBoundaryManager().getBoundary("OUTLET");
  StaticPressureProfile sP0 = b2.getValues().get(StaticPressureProfile.class);
    
    //Specify static pressure at OUTLET boundary
    b2.setBoundaryType(PressureBoundary.class);
    sP0.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(0.0);
  
    //Specify back flow turbulence parameters at OUTLET boundary
    TurbulenceIntensityProfile TI2 = b2.getValues().get(TurbulenceIntensityProfile.class);
    TI2.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(0.01);

    TurbulentViscosityRatioProfile TVR2 = b2.getValues().get(TurbulentViscosityRatioProfile.class);
    TVR2.getMethod(ConstantScalarProfileMethod.class).getQuantity().setValue(2.0);
  
    //Other options for reverse flow specifications
    b2.getConditions().get(BackflowDirectionOption.class)
      .setSelected(BackflowDirectionOption.EXTRAPOLATED);
    b2.getConditions().get(BackflowDirectionOption.class)
      .setSelected(BackflowDirectionOption.BOUNDARY_NORMAL);
    b2.getConditions().get(ReversedFlowPressureOption.class)
      .setSelected(ReversedFlowPressureOption.ENVIRONMENTAL);
    b2.getConditions().get(ReversedFlowPressureOption.class)
      .setSelected(ReversedFlowPressureOption.STATIC);
    b2.getConditions().get(ReferenceFrameOption.class)
      .setSelected(ReferenceFrameOption.LOCAL_FRAME);
    b2.getConditions().get(ReferenceFrameOption.class)
      .setSelected(ReferenceFrameOption.LAB_FRAME);
    b2.getConditions().get(KeTurbSpecOption.class)
      .setSelected(KeTurbSpecOption.INTENSITY_LENGTH_SCALE);
    b2.getConditions().get(KeTurbSpecOption.class)
      .setSelected(KeTurbSpecOption.INTENSITY_VISCOSITY_RATIO);
  
  //Save SIM file by specifying full path - note double backslashes
  getSim.saveState(resolvePath("C:\\STAR_CCM\\PipeFlow.sim"));
  //Close the simulation scene
  getSim.close(true);
}

Another macro recorded in STAR-CCM+ V14.x:
// STAR-CCM+ macro: Macro.java, Written by STAR-CCM+ 14.02.012
package macro; import java.util.*;
import star.common.*; import star.base.neo.*; import star.segregatedflow.*;
import star.material.*; import star.turbulence.*; import star.rsturb.*;
import star.vis.*; import star.flow.*; import star.kwturb.*;

public class Macro extends StarMacro {
 public void execute() { 
   execute0(); 
 }
 private void execute0() {
  Simulation sim_0 = getActiveSimulation();
  ImportManager IM_0 = sim_0.getImportManager();

  IM_0.importMeshFiles(new StringVector(new String[] {resolvePath("D:\\STAR\\Venturi.ccm")}), 
    NeoProperty.fromString("{\'FileOptions\': [{\'Sequence\': 42}]}"));

  FvRepresentation fvRep0 = ((FvRepresentation) 
    sim_0.getRepresentationManager().getObject("Volume Mesh"));

  Region region_0 = sim_0.getRegionManager().getRegion("fluid");
  fvRep0.generateCompactMeshReport(new NeoObjectVector(new Object[] {region_0}));

  sim_0.getSceneManager().createGeometryScene("Geometry Scene", "Outline", "Geometry", 1);
  Scene scene_0 = sim_0.getSceneManager().getScene("Geometry Scene 1");
  scene_0.initializeAndWait();

  PartDisplayer PD_0 = ((PartDisplayer) scene_0.getDisplayerManager().getDisplayer("Outline 1"));
  PD_0.initialize();

  PartDisplayer PD_1 = ((PartDisplayer) scene_0.getDisplayerManager().getDisplayer("Geometry 1"));
  PD_1.initialize();

  SceneUpdate sceneUpdate_0 = scene_0.getSceneUpdate();
  HardcopyProperties hardcopyProperties_0 = sceneUpdate_0.getHardcopyProperties();
  hardcopyProperties_0.setCurrentResolutionWidth(1600);
  hardcopyProperties_0.setCurrentResolutionHeight(900);
  scene_0.resetCamera();
  sim_0.saveState("D:\\STAR\\Venturi.sim");
 }

 private void execute1() {
  Simulation sim_0 = getActiveSimulation();

  MeshManager MM_0 = sim_0.getMeshManager();
  Region region_0 = sim_0.getRegionManager().getRegion("fluid");
  MM_0.convertTo2d(1.0E-18, new NeoObjectVector(new Object[] {region_0}), true);

  Scene scene_0 = sim_0.getSceneManager().getScene("Geometry Scene 1");
  CurrentView currentView_0 = scene_0.getCurrentView();
  currentView_0.setInput(new DoubleVector(new double[] {0.0, 0.0, 0.0}), 
    new DoubleVector(new double[] {0.0, 0.0, 1.0}), 
    new DoubleVector(new double[] {0.0, 1.0, 0.0}), 1.143640, 0, 30.0);
  scene_0.resetCamera();

  Region region_1 = sim_0.getRegionManager().getRegion("fluid 2D");
  region_1.setPresentationName("FLUID");

  Boundary BN_0 = region_1.getBoundaryManager().getBoundary("Default_Boundary_Region");
  Boundary BN_1 = region_1.getBoundaryManager().getBoundary("cyclic 2");
  MM_0.combineBoundaries(new NeoObjectVector(new Object[] {BN_0, BN_1}));
  MM_0.splitBoundariesByAngle(89.0, new NeoObjectVector(new Object[] {BN_0}));
  BN_0.setPresentationName("Axis");

  Boundary BN_2 = region_1.getBoundaryManager().getBoundary("Default_Boundary_Region 2");
  BN_2.setPresentationName("Outlet");

  Boundary BN_3 = region_1.getBoundaryManager().getBoundary("Default_Boundary_Region 3");
  BN_3.setPresentationName("Inlet");

  Boundary BN_4 = region_1.getBoundaryManager().getBoundary("Default_Boundary_Region 4");
  BN_4.setPresentationName("Wall");

  PhysicsContinuum Cm_0 = ((PhysicsContinuum) sim_0.getContinuumManager().getContinuum("Physics 1"));
  sim_0.getContinuumManager().remove(Cm_0);

  PhysicsContinuum Cm_1 = ((PhysicsContinuum) sim_0.getContinuumManager().getContinuum("Physics 1 2D"));
  Cm_1.setPresentationName("Physics 1");

  Cm_1.enable(SteadyModel.class);
  Cm_1.enable(SingleComponentLiquidModel.class);
  Cm_1.enable(SegregatedFlowModel.class);  
  Cm_1.enable(ConstantDensityModel.class);
  
  Cm_1.enable(TurbulentModel.class);
  Cm_1.enable(RansTurbulenceModel.class);
  Cm_1.enable(ReynoldsStressTurbulence.class);
  ReynoldsStressTurbulence RSM_0 = Cm_1.getModelManager().getModel(ReynoldsStressTurbulence.class);
  Cm_1.disableModel(RSM_0);

  Cm_1.enable(KOmegaTurbulence.class);
  Cm_1.enable(SstKwTurbModel.class);
  Cm_1.enable(KwAllYplusWallTreatment.class);
  
  sim_0.saveState("D:\\STAR\\Venturi.sim");
 }
}
public class CreateUserFieldFunctions extends StarMacro {
  public void execute() {
    execute0();
  }
  private void execute0() {
    Simulation sim_0 = getActiveSimulation();

  UserFieldFunction uFF_0 = simulation_0.getFieldFunctionManager().createFieldFunction();
  uFF_0.getTypeOption().setSelected(FieldFunctionTypeOption.SCALAR);
  uFF_0.setPresentationName("R1");
  uFF_0.setFunctionName("R1");
  uFF_0.setDefinition("0.50");
  
  UserFieldFunction uFF_1 = sim_0.getFieldFunctionManager().createFieldFunction();
  uFF_1.getTypeOption().setSelected(FieldFunctionTypeOption.SCALAR);
  uFF_1.setPresentationName("Radius");
  uFF_1.setFunctionName("Radius");
  x = $$Position[0]
  y = $$Position[1]
  uFF_1.setDefinition("sqrt(x*x + y*y)");
  }
}

Application Productivity Tools (APT)

These are template files containing predefined settings for the mesh, physics, and post-processing scenes to save engineering time. One such template available in STAR-CCM+ is Turbo Aerodynamics Workflow.
Store common variables for mesh generation, boundary conditions, material properties, solver settings, post-processing and report generation in separate file. The constants and variables are stored in file simVars.java and the main function and methods are stored in file named solverSettingsSTAR.java. The two files need to be compiled together: javac solverSettingsSTAR.java simVars.java
Variables to be copied into public void execute(). The variables are defined to be same as in PyFLUENT example and hence they can be use by removing the qualifier 'double' and semi-colons. The values are in default units (which is SI or MKS unless user has changed to any other such as FPS system). github.com/frkasper/MacroUtils/.../UserDeclarations.java is a good example to declare variables as per project specific requirements.
  double max_cell_quality = 0.10;
  double max_allowed_skew = 75.0;
  double max_volm_change  = 0.01;
  
  // Boundary conditions
  double[] gravity = { 0.0, -9.806, 0.0 };
  double[] v_init = { 0.1, 0.0, 0.0 };
  double radEmissivity = 0.80;
  
  // Porous resistances
  double i_res           = 2500;
  double v_res           = 50;
  
  // Solver settings
  double n_iter          = 4000;
  double t_step          = 1.0e-3;
  double duration        = 10.0;
  double iter_per_step   = 20;
  double count_t_steps   = duration / t_step;

  // Reference and limiting values
  double ref_den         = 1.225;
  double Tref            = 300;
  double t_max           = 500;
  double t_min           = 273;
  double p_min           = 100;
Alternatively, a table can be defined such as one described below and a Java macro can be used to read and assign boundary conditions.
Zone_Name   Type    Material_Name  Density   Thermal_Conductivty   Cp       RPM    LC_I    LC_V
------------------------------------------------------------------------------------------------
Tubes       Fluid   Air            1.120       0.027               1005.5     0      0      0
...
Here LC_I and LC_V is applicable to porous zones. Similar table can be created for wall boundary types.
One can define ArrayList<String> bc_list = new ArrayList<String>(Arrays.list("inlet_1", "inlet_2", "wall_htc", "wall_rot", "outlet_p")); to create a list of names to be used in various functions. The list can be name of scenes, reports, plots, derived parts, planes, zone names... where each item can be access using get(i).
Alternatively, following class/method can be used to read variables stored in a text file in the format var_name = var_value. '=' acts as delimiter. This way, one can use the data file created for other programming language such as Python. The important point to note the value decimal and integer values are interpreted. x = 300.0 - x will be classified as variable type 'double'. x = 300 - x will be categorized as variable type 'integer'. The format of data in 'input.txt' should be as var_name = var_value without any semi-colon at the end of the sentences.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class readDataFromFile {

  public static void main(String[] args) {
    String file_name = "input.txt";
    Map<String, Object> variables = readVariablesFromFile(file_name);

    // Print the variable names and their values and type
    for (Map.Entry<String, Object> entry : variables.entrySet()) {
      System.out.println(entry.getKey() + " = " + entry.getValue() + 
      " (" + entry.getValue().getClass().getSimpleName() + ")");
    }
  }
  public static Map<String, Object> readVariablesFromFile(String file_name) {
    Map<String, Object> variables = new HashMap<>();

    try (BufferedReader reader = new BufferedReader(new FileReader(file_name))) {
      String line;
      while ((line = reader.readLine()) != null) {
        // Split the string in '2' parts with separator as '='
        String[] parts = line.split("=", 2);
        if (parts.length == 2) {
          String var_name = parts[0].trim();
          String var_value = parts[1].trim();

          Object parsed_value = parseValue(var_value);
          variables.put(var_name, parsed_value);
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return variables;
  }
  private static Object parseValue(String value) {
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e1) {
      try {
        return Double.parseDouble(value);
      } catch (NumberFormatException e2) {
        // Default is string if not an integer or double
        return value; 
      }
    }
  }
}
Methods and Classes: uncomment/comment as needed.
import java.util.*;
import star.common.*;
import star.base.neo.*;
import star.motion.*;

public class starMacroTemplate extends StarMacro {
  public void execute() {
    importCad_Mesh(Simulation simX);
    generateSrfMesh(Simulation simX);
    generateVolMesh(Simulation simX);
    defineMatProps(Simulation simX);
    defineBndConds(Boundary bndry);
    solverSettings(Simulation simX);
    defineMonitors(Simulation simX);
    defineReports(Simulation simX);
    generateReports(Simulation simX);
    defineScenes(Simulation simX);
    saveReptPlots(Simulation simX);
  }
}
  private void importCad_Mesh() {
    ...
  }
  
  private void generateSrfMesh() {
    ...
  }
  private void generateVolMesh(simX) {
    ...
    
    //Check and print mesh quality
    MinReport min_cell_q = (MinReport) simX.getReportManager().getReport("minCellQuality");
    MaxReport max_skew = (MaxReport) simX.getReportManager().getReport("maxCellSkewness");
  }
Define a continuum model class,
  public static final Class<? extends Model>[] gas_models = new Class[] {
    ThreeDimensionalModel.class,
    SteadyModel.class,
    SingleComponentGasModel.class,
    CoupledFlowModel.class,
    PolynomialDensityModel.class,
    CoupledEnergyModel.class,
    TurbulentModel.class,
    RansTurbulenceModel.class,
    KEpsilonTurbulence.class,
    RkeTwoLayerTurbModel.class,
    KeTwoLayerAllYplusWallTreatment.class,
    RadiationModel.class,
    S2sModel.class,
    ViewfactorsCalculatorModel.class,
    GrayThermalRadiationModel.class
  };
Check if a model exists
  if(continuum.getModelManager().hasModel(SingleComponentGasModel.class) != null) {
    for (Class<? extends Model> model_class : gas_models) {
      if (continuum.getModelManager().hasModel(model_class) == null) {
        return false;
      }
    return true;
  }
Create continua
  public void createContinuum() {
    PhysicsContinuum continuum = physicsContinuumCondition.getSatisfyingObject();
    if (continuum != null) {
      notifyUser("Continuum \"" + continuum.getPresentationName() + "\" already created");
      return;
    }
    createContinuum(gas_models);
  }
Define required solver models:
ppublic void enableModels(PhysicsContinuum pc) {
  pc.enable(ThreeDimensionalModel.class);
  pc.enable(SingleComponentLiquidModel.class);
  pc.enable(SegregatedFlowModel.class);
  pc.enable(PolynomialDensityModel.class);
  pc.enable(GravityModel.class);
  pc.enable(CellQualityRemediationModel.class);
  pc.enable(PorousMediaModel.class);
  pc.enable(ImplicitUnsteadyModel.class);
}
  private double getZones(Simulation simX, String region_type) {
    double cell_count = 0;
    ElementCountReport el_count = simX.getReportManager()
      .create("star.base.report.ElementCountReport.class);
    Collection<Region> all_regions = simX.getRegionManager().getRegions();
    Collection<Region> fluid_regions = simX.getRegionManager().getRegions();
    Collection<Region> solid_regions = simX.getRegionManager().getRegions();
    for (Region reg : all_regions) {
      if (reg.getRegionType() instanceof FluidRegion) {
        solid_regions.remove(reg);
        if (!(reg instanceof ShellRegion)) {
          solid_regions.remove(reg);
        }
      }
      if (!(reg instanceof ShellRegion)) {
        fluid_regions.remove(reg);
      }
    }
    if(region_type == "fluid") {
      el_count.getParts().setObjects("fluid_regions");
      cell_count = el_count.getReportMonitorValue();
    }
    if(region_type == "solid") {
      el_count.getParts().setObjects("solid_regions");
      cell_count = el_count.getReportMonitorValue();
    }
    simX.getReportManager().remove(el_count);
    return cell_count;
  }
  
  private static List<String> getFluidZones(Simulation simX) {
    Collection<Region> all_regions = simX.getRegionManager().getRegions();
    // List to store the names of fluid regions
    List<String> fluid_regions = new ArrayList<>();
    
    for (Region reg : all_regions) {
      // if (reg.getPhysicsContinuum().getPresentationName().equals("Fluid")) {
      if (reg.getRegionType() instanceof FluidRegion) {
        fluid_regions.add(region.getPresentationName());
      }
    }
    return fluid_regions;
  }
  
  private void defineMatProps() {
    ...
  }
  
  private void defineBndConds() {
    //Create field functions
    final double m_dot = 2.50;
    UserFieldFunction UFF_mdot = (UserFieldFunction) simX.getFieldFunctionManager().
      .getFunction("m_dot");
    UFF_mdot.setDefinition(String.valueOf(m_dot))
  }
public class SetInletBoundary(Simulation simX, Boundary bnd_name) {
  public static void main(String[] args) {
    //Simulation sim = getActiveSimulation();
    //Region region = sim.getRegionManager().getRegion("region_name");
    //Boundary inletBoundary = region.getBoundaryManager().getBoundary("b_inlet");
    double b_inlet_v  = 5.0;  // [m/s]
    double b_inlet_p  = 500;  // [Pa]
    doulbe b_inlet_t  = 300;  // [K]
    double b_inlet_mf = 0.25; // [kg/s]
    int choice = 1;
    
    switch (choice) {
      case 1:   // Set Velocity Inlet
        InletBoundary v_mag = (InletBoundary) simX.get(ConditionTypeManager.class)
          .get(InletBoundary.class);
        bnd_name.setBoundaryType(v_mag);
        VelocityMagnitudeProfile vmag_value = bnd_name.getValues.
          .get(VelocityMangnitudeProfile.class);
        Units un_v = (Units) simX.getUnitsManager().getObject("m/s");
        vmag_value.getMethod(ConstantScalarProfileMethod.class).getquantity()
          .setValueAndUnits(b_inlet_v, un_v);  
        
        break;
      case 2:   // Set Pressure Inlet
        ...
        break;
      case 3:   // Set Mass Flow Inlet
        MassFlowBoundary b_mf = (MassFlowBoundary) simX.get(ConditionTypeManager.class)
          .get(MassFlowBoundary.class);
        bnd_name.setBoundaryType(b_mf);
        MassFlowRateProfile  b_mf_value = bnd_name.getValues().
          .get(MassFlowRateProfile.class);
        Units un_mf = (Units) simX.getUnitsManager().getObjects("kg/s");
        b_mf_value.getMethod(ConstantScalarProfileMethod.class).
          getQuantity().setValueAndUnits(b_inlet_mf, un_mf);
        break;
      default:
        System.out.println("Invalid choice!");
        break;
    }
    TurbulenceIntensityProfile b_inlet_ti = bnd_name.getValues
      .get(TurbulenceIntensityProfile.class);
    b_inlet_ti.getMethod(ConstantScalarProfileMethod.class).getQuantity()
      .setValue(2.0);
    TurbulenceViscosityRatioProfile b_inlet_tvr = bnd_name.getValues
      .get(TurbulenceViscosityRatioProfile.class);
    b_inlet_tvr.getMethod(ConstantScalarProfileMethod.class).getQuantity()
      .setValue(5.0);
    sim.saveState("Setup.sim");
  }
}
Define boundary conditions on walls:
public class SetWallBC{
  public static void main(String[] args) {
    Simulation sim = getActiveSimulation();
    Region region = sim.getRegionManager().getRegion("RegionName");
    Boundary wallBoundary = region.getBoundaryManager().getBoundary("WallBoundary");

    int choice = 1;
    switch (choice) {
      case 1:   // Set Fixed Temperature
        ...
        break;
      case 2:  // Set Known Wall Flux
        ...
        break;
      case 3:  // Set HTC
        ...
        ...
        break;
      case 4:  // Set Radiation
        ...
        break;
      default:
        System.out.println("Invalid choice!");
        break;
    }
    // Set Surface Roughness
    ...

    // Enable Shell Conduction
    ...

    sim.saveState("Setup.sim");
  }
}

Print Summary of Mesh Quality: STAR-CCM+ does not have option to print mesh quality one item at a time. That is, you cannot get skewness statistics (maximum, minimum...) alone but the full quality report can be generated by Diagnostics summary as explained here. To get the skewness of aspect ratio values, one need to use Field Function and Report.

Step-1) create maximum and/or minimum report as required: MaxReport max_rep = sim_1.getReportManager .create("star.base .report .MaxReport");

Step-2) Create skewness or aspect ratio field function: SkewnessAngleFunction skew_ff = (SkewnessAngleFunction) sim_1.getFieldFunctionManager() .getFunction("SkewnessAngle"); // Use comination of CellAspectRatioFunction and CellAspectRatio as needed

Step-3) Assign field function to the report: max_rep.setFieldFunction(skew_ff);

Step-4) Assign region to the report: Region reg_x = sim_1.getRegionManager() .getRegion(reg_name); max_rep.getParts() .setObjects(reg_x);

Step-5) Print the report in output log or store as a variable to save in a text file: max_rep.printReport();

public double getMaxSkewness(Simulation simX, Region region) {
  MaxReport max_skew = simX.getReportManager .create("star.base .report .MaxReport");
  SkewnessAngleFunction skew_ff = (SkewnessAngleFunction) simX.getFieldFunctionManager() 
    .getFunction("SkewnessAngle");
  max_skew.setFieldFunction(skew_ff);
  max_skew.getParts().setObjects(region);
  max_skew.printReport();
}
private void summarizeZones(Simulation simX, Boundary bndry) {
    Collection <Region> region_list = simX.getRegionManager().getObjects();
    System.out.println("Number of regions in model = " + region_list.size());
    
    for (Region region_i : region_list) {
      Collection <Boundary> boundary_list = simX.getBoundaryManager().getObjects();
      System.out.println("Number of boundarie in " + "region_i + " is " + 
        boundary_list.size());
    }
    Collection <Interface> iface_list = simX.getInterfaceManager().getObjects();
    integer n_iface = 0;
    for (Interface iface : iface_list) {
      n_iface = n_iface + 1;
    }
    System.out.println("Number of interfaces in domain = " + n_iface);
    
    // Ref: community.sw.siemens.com/.../getting-surface-area-using-java-api
    // Create a Surface Integral Report of the unity field funcion and then
    // use following lines to get or print on those boundaries.
    SurfaceIntegralReport surf_int = (SurfaceIntegralReport) simX.getReportManager()
      .getReport("Area");
    double surf_area = surf_int.getValue();
    simX.println(surf_area);
    Boundary b_wall_x = reg.getBoundaryManager().getBoundary("Wall_Pipe");
    surf_int.getParts().setObjects(b_wall_x);
    simX.println("Area of boundary is "  + area);
  }
  private void solverSettings(Simulation simX) {

    Simulation sim_1 = getActiveSimulation();
    for (int i=1; i<=3; i++) {
	  sim_1.saveState("Case_" + i + ".sim");
      
      ...
      
      StepStoppingCriterion stopCrit = (StepStoppingCriterion) 
        sim_1.getSolverStoppingCriterionManager()
        .getSolverStoppingCriterion("Maximum Steps");

      //Get max stopping criteria number and add additional iteration steps
      IntegerValue iter_count = stopCrit.getMaximumNumberStepsObject();
      double j = iter_count.getQuantity().getValue();
      iter_count.getQuantity().setValue(j);

      sim_1.getSimulationIterator().run();
    }
    // Save final sim file and exit
    sim_1.saveState("Case_" + i + "_Full.sim");
  }
}
public class CreateMassBalanceMonitor {
    Simulation sim = getActiveSimulation();
    // Obtain the region object
    Region region = sim.getRegionManager().getRegion(Region_Name);

    // Create mass flow monitors for all inlets and outlets
    MassFlowReport mass_flow_report_1 = sim.getReportManager()
      .createReport(MassFlowReport.class);
    mass_flow_report_1.setPresentationName("MF_inlets");

    MassFlowReport mass_flow_report_2 = sim.getReportManager()
      .createReport(MassFlowReport.class);
    mass_flow_report_2.setPresentationName("MF_outlets");

    for (Boundary boundary : region.getBoundaryManager().getBoundaries()) {
      if (boundary.getBoundaryType() instanceof InletBoundary) {
        mass_flow_report_1.getParts().addObjects(boundary);
      } else if (boundary.getBoundaryType() instanceof OutletBoundary) {
        mass_flow_report_2.getParts().addObjects(boundary);
      }
    }
    // Calculate mass balance
    ExpressionReport massBalanceReport = sim.getReportManager()
      .createReport(ExpressionReport.class);
    massBalanceReport.setPresentationName("Mass_Balance");
    massBalanceReport.setDefinition(
      "${MF_inlets.Report} - ${MF_outlets.Report}"
    );
    // Optional: Adding these reports to scalar and XY plots
    MonitorPlot massFlowRatePlot = sim.getPlotManager().createMonitorPlot();
    massFlowRatePlot.setPresentationName("Mass Flow Rate Plot");
    massFlowRatePlot.getMonitorManager().addObjects(massFlowRateReportInlet, 
      massFlowRateReportOutlet);

    MonitorPlot massBalancePlot = sim.getPlotManager().createMonitorPlot();
    massBalancePlot.setPresentationName("Mass Balance Plot");
    massBalancePlot.getMonitorManager().addObjects(massBalanceReport);
  }
}
  private void generateReports(Simulation simX) {
    String rept_file = "Rep_Output.txt";
    PrintWriter out_file = new PrintWriter(new FileWriter(new File(resolvePath(rept_file))));
    Collection <Report> report_list = simX.getReportManager().getObjects();
    Iterator<Integer> rep_counter = report_list.iterator();
    while (rep_counter.hasNext()) {
      String report_name  = report_list.next().getPresentationName();
      double report_value = report_list.next().getReportMonitorValue();
      String report_units = report_list.next().getUnits().GetPresentationName();
      System.out.println(report_name + " has value " + report_value + " " 
        + report_units(); 
    }
  }
  private void saveReptPlots(Simulation simX) {
    String sep = System.getProperty("file.separator");
    for (StarPlot p : simX.getPlotManager().getObjects()) {
      simX.println("Data exported for plot: " + p.getPresentationName());
      p.export(simX.getSessionDir() + sep + p.getPresentationName() + ".csv", ",");
    }
  }
From github.com/nitronayak /StarCCMAutomation /blob /main /ExportScenesAndPlots.java
import star.common.*;
import star.vis.*;
import java.io.File;
import java.util.Scanner; 

public class ExportScenesAndPlots extends StarMacro {
  public void execute() {
    Simulation sim = getActiveSimulation();
    
    //get the name of the simulation's directory
    String dir = sim.getSessionDir(); 
    //get the right separator for your operative system
    String sep = System.getProperty("file.separator");
    File resultFolder = new File(dir + "\\" + sim + "_Results");
    resultFolder.mkdir();

    File sceneFolder = new File(resultFolder + "\\Scenes");
    sceneFolder.mkdir();
    File plotFolder = new File(resultFolder + "\\Plots");
    plotFolder.mkdir();
    
    for (Scene scn: sim.getSceneManager().getScenes()) {
      sim.println("Saving Scene: " + scn.getPresentationName());
      scn.printAndWait(resolvePath(sceneFolder + sep + scn.getPresentationName() + ".jpg"), 1,800,450);	
    }
    for (StarPlot plt : sim.getPlotManager().getObjects()) {
      sim.println("Saving Plot: " + plt.getPresentationName());
      plt.encode(resolvePath(plotFolder + sep + plt.getPresentationName() + ".jpg"), "jpg", 800, 450);
    }
  }
}
Print materials defined in the set-up and their thermodynamic properties
public class printMatProps extends StarMacro { 
  public void execute() {
    Simulation sim = getActiveSimulation(); 
    Collection<Material> materials = sim.get(MaterialManager.class).getObjects(); 
    for (Material mat : materials) { 
      String matName = mat.getPresentationName(); 
      System.out.println("Material: " + matName); 
      
      Collection<MaterialProperty> properties = mat.getMaterialProperties(); 
      for (MaterialProperty property : properties) { 
        String propertyName = property.getPresentationName(); 
        double propertyValue = property.getValue(); 
        System.out.println(" Property: " + propertyName + ", Value: " + propertyValue); 
      } 
    } 
  } 
}
public class CreateHistograms extends StarMacro {
  public void execute() {
    createHistogramsMeshQuality("CellQuality");
    createHistogramsMeshQuality("Skewness");
  }
  private void createHistogramsMeshQuality(String quality_type) {
    Simulation sim = getActiveSimulation();
    
    RegionManager regionManager = sim.getRegionManager();
    Collection<Region> allRegions = regionManager.getRegions();
    List<Region> solidRegions = new ArrayList<>();
    List<Region> fluidRegions = new ArrayList<>();
    for (Region region : allRegions) {
      // Check if region contains solid cells
      if (region.getInterfaceBoundaryManager().getInterfaceBoundaries().size() > 0) {
        solidRegions.add(region);
      } else {
        fluidRegions.add(region);
      }
    }
    // Define the cell quality scalar field function
    PrimitiveFieldFunction cellQualityFunction = 
      (PrimitiveFieldFunction) sim.getFieldFunctionManager().getFunction(quality_type);

    // Create histograms for solid regions
    for (Region solidRegion : solidRegions) {
      createHistogram(sim, solidRegion, cellQualityFunction, 
        solidRegion.getPresentationName() + " " + quality_type + " Histogram";
    }
    // Create histograms for fluid regions
    for (Region fluidRegion : fluidRegions) {
      createHistogram(sim, fluidRegion, cellQualityFunction, 
        fluidRegion.getPresentationName() + " " + quality_type + " Histogram";
    }
  }
  private void createHistogram(Simulation sim, Region region, 
                 PrimitiveFieldFunction function, String plotName) {
    // Create histogram report
    HistogramReport histogramReport = sim.getReportManager()
      .createReport(HistogramReport.class);
    histogramReport.setFieldFunction(function);
    histogramReport.getParts().setObjects(region);
    histogramReport.setPresentationName(plotName);

    // Create and display the plot
    ReportPlot histogramPlot = sim.getPlotManager().createReportPlot(histogramReport);
    histogramPlot.open();
  }
}
STAR-CCM+ java code as functions to generate scalar scenes on planes aligned to Cartesian coordinate systems passing though specified point, align the view perpendicular to the plane and save the plot as PNG file.
  public void execute() {
    // Specify the point through which the planes pass and field function and range
    double[] point = {0.0, 0.0, 0.0}; 
    double[] v_range = {0.0, 10.0};
    double[] p_range = {1000, 1E6};
    double[] t_range = {300, 400};
    String scalarFieldFunctionName = "VelocityMagnitude"; 
    createScalarSceneOnPlane("X", point, "Pressure", p_range);
    createScalarSceneOnPlane("Y", point, "Temperature", t_range);
    createScalarSceneOnPlane("Z", point, "Velocity", v_range);
  }
  private void createScalarSceneOnPlane(String planeAxis, double[] point, 
    String scalarFF, double[] scalarRange) {
    Simulation sim = getActiveSimulation();
    
    ScalarScene scalarScene = sim.getSceneManager().createScalarScene("Scalar Scene", "Scalar Scene");
    scalarScene.initializeAndWait();
    FieldFunction scalarFieldFunction = sim.getFieldFunctionManager().getFunction(scalarFF);
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().setFieldFunction(scalarFieldFunction);

    // Set the number of color bands to 11
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().getColorMap().setNumberOfColors(11);
    scalarScene.getDisplayerManager().getScalarDisplayers().get(0)
      .getScalarDisplayQuantity().setRange(scalarRange);

    // Create and set plane section
    PlaneSection planeSection = (PlaneSection) sim.getPartManager().createImplicitPart(new 
      NeoObjectVector(new Object[] {}), new NeoObjectVector(new Object[] {}), "PlaneSection", 0, 0, 0, 0);
    planeSection.getInputParts().setObjects(sim.getRegionManager().getRegions());
    planeSection.getOriginCoordinate().setCoordinate(point[0], point[1], point[2]);

    // Set plane normal based on the specified axis
    if (planeAxis.equalsIgnoreCase("X")) {
      planeSection.getOrientationCoordinate().setCoordinate(1, 0, 0);
    } else if (planeAxis.equalsIgnoreCase("Y")) {
      planeSection.getOrientationCoordinate().setCoordinate(0, 1, 0);
    } else if (planeAxis.equalsIgnoreCase("Z")) {
      planeSection.getOrientationCoordinate().setCoordinate(0, 0, 1);
    }

    // Add plane section to scalar scene
    scalarScene.getDisplayerManager().getPartDisplayer("Scalar Scene 1")
      .getInputParts().setObjects(planeSection);

    // Align view perpendicular to the plane and zoom to fit window (reset camera)
    if (planeAxis.equalsIgnoreCase("X")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.XY);
    } else if (planeAxis.equalsIgnoreCase("Y")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.YZ);
    } else if (planeAxis.equalsIgnoreCase("Z")) {
      scalarScene.open(true);
      scalarScene.resetCamera();
      scalarScene.getViewManager().getAxesOrientation().setCoordinateSystemView(
        scalarScene.getActiveCamera(), CoordinateSystemViewType.ZX);
    }
    String file_name = scalarFF + "_" + planeAxis + "_"+ point[0] + "_"point[1] +
      "_" + point[2] + ".png";
    scalarScene.printAndWait(resolvePath(file_name), 1, 800, 600);
    scalarScene.close();
  }
Process all *.sim files stored in a specified folder.
public class ProcessSimFiles {

  public static void main(String[] args) {
    // Folder containing the *.sim files
    File folder = new File("E:/CFD_Projects");
    String b_inlet = "inlet;
    
    // List all .sim files in the folder
    File[] files = folder.listFiles((dir, name)->name.toLowerCase().endsWith(".sim"));
    if (files == null || files.length == 0) {
      System.out.println("No .sim files found.");
      return;
    }
    Simulation sim = getActiveSimulation();
    for (File f : files) {
      postProcesSim(sim, f, b_inlet);
    }
  }
  private static void postProcesSim(Simulation sim, File file, String bnd_name) {
    ...
  }
}
Create Animation from a Transient Run
public void CreateAnimation (Simulation sim, double fps, Scene sc_name, String field_var) {
  
  // Set up the time steps for the animation
  SolutionHistory solutionHistory = (SolutionHistory) sim.get(SolutionHistoryManager.class)
    .getObjects().iterator().next();
  RecordedSolutionView recordedSolutionView = solutionHistory.getRecordedSolutionViewManager().createView();
  recordedSolutionView.setMode(RecordedSolutionViewMode.DISPLAY_EVERY_STEP);
  
  // Create an animation from the recorded solution view
  Animation animation = 
    (Animation) sim.getRepresentationManager().createRepresentation(Animation.class, "Animation", "");
  animation.setFramesFromView(recordedSolutionView);
  
  // Set the scalar scene for the animation
  Scene scene = sim.getSceneManager().getScenes().get(sc_name);
  ScalarDisplayer scalarDisplayer = 
    (ScalarDisplayer) scene.getDisplayerManager().getDisplayer(field_var);
  scalarDisplayer.setRepresentation(animation);
  
  // Set the animation properties
  animation.setFramesPerSecond(fps);
  animation.setStartFrame(0);
  animation.setEndFrame(recordedSolutionView.getLastFrame());
  
  // Export the animation as a video
  File animationFile = new File("STAR-animation.mp4");
  File exportFile = new File(animationFile.getAbsolutePath());
  sim.getAnimationExporterManager().exportVideo(animation, exportFile, "mp4");
  }
}
Create Sweep Animation of an XY-Plane
public void SweepAnimation (Simulation sim, Scene sc_name, double fps, double z0,
  double zn, double dz) {   
  // Create a new XY-Plane section at origin
  PartManager partManager = simulation.getPartManager();
  plane_xy plane_xy = (plane_xy) partManager.createImplicitPart(new NeoObjectVector(
    new Object[]{}), new DoubleVector(new double[]{0.0, 0.0, 1.0}), 
    new DoubleVector(new double[]{0.0, 0.0, 0.0}));
  plane_xy.getOrientationCoordinate().setCoordinate(new DoubleVector(new double[] {0.0, 0.0, 1.0}));
  plane_xy.getPositionCoordinate().setCoordinate(new DoubleVector(new double[] {0.0, 0.0, 0.0}));
  plane_xy.getInputParts().setQuery(null);
  
  // Add the plane section to the scene and set the displayer
  sc_name.setInputParts(new NeoObjectVector(new Object[] {plane_xy}));
  sc_name.open();
  ScalarDisplayer scalarDisplayer = sc_name.getDisplayerManager()
    .createDisplayer(ScalarDisplayer.class);
  scalarDisplayer.getInputParts().setQuery(null);
  scalarDisplayer.getInputParts().setObjects(plane_xy);
  
  // Set up the animation properties
  Animation animation = simulation.getRepresentationManager().createRepresentation(
    Animation.class, "Sweep Animation", "");
  animation.setFramesPerSecond(fps);
  
  // Loop through the range and update plane position
  for (double zp = z0; zp <= zn; zp += dz) {
    plane_xy.getPositionCoordinate().setCoordinate(new DoubleVector(new double[] {0.0, 0.0, zp}));
    sc_name.printAndWait();
    animation.addFrame(scene);
  }
  // Export the animation as a video
  File animationFile = new File("sweep_animation.mp4");
  File exportFile = new File(animationFile.getAbsolutePath());
  simulation.getAnimationExporterManager().exportVideo(animation, exportFile, "mp4");
  }
}
Create a tabulated summary of maximum temperature at the outer walls of each solid zone:
public double maxWallTemperature(Simulation simX, Region region_name) {
  MaxReport max_t = simX.getReportManager().create("star.base.report.MaxReport");
  PrimitiveFieldFunction ff_t = (PrimitiveFieldFunction) 
    simX.getFieldFunctionManager().getFunction("Temperature");
  max_t.setFieldFunction(ff_t);
  MeshPart part_1 = (MeshPart) simX.get(SimulationPartManager.class).getPart(region_name);
  max_t.getParts().setObjects(part_1);
  max_t.setPresentationName("max_wall_t");
  Units deg_C = (Units) simX.getUnitsManager(0.getObjects("C");
  max_t.setUnits(deg_C);
  max_t.printReport();
}
Contact us
Disclaimers and Policies

The content on CFDyna.com is being constantly refined and improvised with on-the-job experience, testing, and training. Examples might be simplified to improve insight into the physics and basic understanding. Linked pages, articles, references, and examples are constantly reviewed to reduce errors, but we cannot warrant full correctness of all content.