Macros in Java for STAR-CCM+
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.
Table of Contents:
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'.
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class readVariablesFromFile { public static void main(String[] args) { String file_name = "input.txt"; Map<String, Object> variables = readVariablesFromFile(file_name); // Print the variables 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) { String[] parts = line.split("=", 2); if (parts.length == 2) { String variableName = parts[0].trim(); String value = parts[1].trim(); Object parsedValue = parseValue(value); variables.put(variableName, parsedValue); } } } 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 existsif(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 continuapublic void createContinuum() { PhysicsContinuum continuum = physicsContinuumCondition.getSatisfyingObject(); if (continuum != null) { notifyUser("Continuum \"" + continuum.getPresentationName() + "\" already created"); return; } createContinuum(gas_models); } |
private double getZones(Simulation simX, String region_type) { double cell_count = 0; ElementCountReport el_count = simX.getReportManager().createReport(ElementCountReport.clss); 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") { elem_count.getParts().setObjects("fluid_region"); cell_count = el_count.getReportMonitorValue(); } if(region_type = "solid") { elem_count.getParts().setObjects("solid_region"); 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)) }Following code was generated by AI in Copilot. This can be tweaked to convert into a function with user-inputs taken from a text file or explicitly defined in Main function. public class SetInletBoundary { 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.getVelocityMagnitude().setValue(b_inlet_v); break; case 2: // Set Pressure Inlet inletBoundary.getPressure().setValue(b_inlet_p); break; case 3: // Set Mass Flow Inlet inletBoundary.getMassFlowRate().setValue(b_inlet_mf); break; default: System.out.println("Invalid choice!"); break; } 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 wallBoundary.getTemperature().setValue(temperature); break; case 2: // Set Known Wall Flux wallBoundary.getHeatFlux().setValue(flux); break; case 3: // Set HTC wallBoundary.getConvectiveHeatTransferCoefficient().setValue(htc); wallBoundary.getFreeStreamTemperature().setValue(Tref); break; case 4: // Set Radiation wallBoundary.getEmissivity().setValue(emissivity); break; default: System.out.println("Invalid choice!"); break; } // Set Surface Roughness SurfaceRoughnessProperty surfaceRoughness = (SurfaceRoughnessProperty) wallBoundary.getValues() .get(SurfaceRoughnessProperty.class); surfaceRoughness.getRoughnessHeight().setValue(w_roughness); // Enable Shell Conduction ShellConductionProperty shellConduction = (ShellConductionProperty) wallBoundary.getValues() .get(ShellConductionProperty.class); shellConduction.setEnabled(true); sim.saveState("Setup.sim"); } } |
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 CreateMonitorPoints { Simulation sim = getActiveSimulation(); // Create mass flow monitor MassFlowReport mass_flow_report = sim.getReportManager() .createReport(MassFlowReport.class); mass_flow_report.setPresentationName("Mass Flow Rate Inlet"); mass_flow_report.getParts().setObjects(sim.getRegionManager() .getRegion("RegionName").getBoundaryManager().getBoundary("Inlet_Boundary")); // Create energy balance monitor EnergyBalanceReport energyBalanceReport = sim.getReportManager() .createReport(EnergyBalanceReport.class); energyBalanceReport.setPresentationName("Energy Balance"); energyBalanceReport.getParts().setObjects(sim.getRegionManager() .getRegion("Region_Name")); // Optional: Adding these reports to scalar and XY plots MonitorPlot massFlowRatePlot = sim.getPlotManager().createMonitorPlot(); massFlowRatePlot.setPresentationName("Mass Flow Rate Plot"); massFlowRatePlot.getMonitorManager().addObjects(massFlowRateReport); MonitorPlot energyBalancePlot = sim.getPlotManager().createMonitorPlot(); energyBalancePlot.setPresentationName("Energy Balance Plot"); energyBalancePlot.getMonitorManager().addObjects(energyBalanceReport); } |
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 defineReports() { ... } public void addAnnotationToScene(Simulation simX, String annoText, double xLoc, double yLoc) { Annotation textAnnotation = new Annotation(); textAnnotation.setText(annoText); textAnnotation.setPresentationName("Annotation_1"); simX.getAnnotationManager().getAnnotations().add(textAnnotation); Scene scene = simX.getSceneManager().getScene("contour_v"); scene.getAnnotations().add(textAnnotation); textAnnotation.setX(xLoc); textAnnotation.setY(yLoc; textAnnotation.setFontSize(12); textAnnotation.setColor(new Color(0, 0, 1)); } |
private void defineScenes() { ... } |
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); } } } |
Following code is generated by AI approach: creates a short summary of simulation set-upimport star.common.*; import star.base.neo.*; public class SimulationSummary { public static void main(String[] args) { Simulation sim = getActiveSimulation(); // Get basic simulation details String simName = sim.getPresentationName(); String physicsContinuum = sim.getPhysicsContinuumManager().getContinuumNames().toString(); String solver = sim.getSolverManager().getSolverNames().toString(); // Get mesh details MeshPipelineController meshController = sim.get(MeshPipelineController.class); String meshOperation = meshController.getMeshOperation().getClass().getSimpleName(); // Get boundary conditions summary StringBuilder bcSummary = new StringBuilder(); Collection<Boundary> boundaries = sim.getRegionManager().getBoundaries(); for (Boundary boundary : boundaries) { bcSummary.append(boundary.getPresentationName()).append(": "); bcSummary.append(boundary.getBoundaryType()).append("\n"); } // Create summary string String summary = "Simulation Name: " + simName + "\n" + "Physics Continuum: " + physicsContinuum + "\n" + "Solver: " + solver + "\n" + "Mesh Operation: " + meshOperation + "\n" + "Boundary Conditions:\n" + bcSummary.toString(); // Print summary to the output window sim.println(summary); } } |
Print materials defined in the set-up and their thermodynamic propertiespublic 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 = StarCCM.getNewSimulation(); for (File f : files) { postProcesSim(sim, f, b_inlet); } } private static void postProcesSim(Simulation sim, File file, String b_inlet) { try { // Clear the previous simulation data and read a new simulation sim.getSimulationIterator().clearSimulation(); sim.getSimulationIterator().readSimulation(file.getAbsolutePath()); // Create a scene (e.g. Scalar Scene) Scene scene = sim.getSceneManager().createScalarScene("Scalar Scene", "Outline", "Scalar"); scene.initializeAndWait(); // Generate mass flow rate at the specified boundary String boundaryName = b_inlet; Boundary boundary = sim.getRegionManager().getBoundary(boundaryName); MassFlowRateReport massFlowRate = sim.getReportManager().createReport(MassFlowRateReport.class); massFlowRate.setObjects(boundary); massFlowRate.printReport(); // Get the maximum and minimum values of field variables for (FieldFunction field : sim.getFieldFunctionManager().getObjects()) { PrimitiveFieldFunction primitiveField = (PrimitiveFieldFunction) field; MinReport minReport = sim.getReportManager().createReport(MinReport.class); minReport.setFieldFunction(primitiveField); minReport.printReport(); MaxReport maxReport = sim.getReportManager().createReport(MaxReport.class); maxReport.setFieldFunction(primitiveField); maxReport.printReport(); } sim.close(); } catch (Exception e) { e.printStackTrace(); } } } |
Java code for STAR-CCM+ to report mesh quality summary to a text file. The text file includes tabular data of the region name, mesh quality parameter, and the worst value of that mesh quality.
import star.common.*; import star.meshing.*; public class MeshQualityReport { public static void main(String[] args) { // Path to the output text file String outputFilePath = "mesh_q_rep.txt"; // Start a new session Simulation sim = StarCCM.getNewSimulation(); try (FileWriter writer = new FileWriter(outputFilePath)) { // Write the header writer.write("Region Name\tMesh Quality Parameter\tWorst Value\n"); // Iterate over all regions for (Region region : sim.getRegionManager().getRegions()) { String regionName = region.getPresentationName(); // Mesh quality parameters to check String[] qualityParameters = {"Aspect Ratio", "Skewness", "Orthogonality"}; for (String parameter : qualityParameters) { double worstValue = getWorstMeshQuality(region, parameter); writer.write(regionName + "\t" + parameter + "\t" + worstValue + "\n"); } } } catch (IOException e) { e.printStackTrace(); } finally { // Close the session sim.close(); } } private static double getWorstMeshQuality(Region region, String parameter) { double worstMeshQuality = Double.NaN; // Assume we have methods to calculate mesh quality switch (parameter) { case "Aspect Ratio": worstMeshQuality = getWorstAspectRatio(region); break; case "Skewness": worstMeshQuality = getWorstSkewness(region); break; case "Orthogonality": worstMeshQuality = getWorstOrthogonality(region); break; default: break; } return worstMeshQuality; } /*SkewnessAngleFunction skew_func = (SkewnessAngleFunction) simX.getFieldFunctionManager().getFunction("SkewnessAngle"); VolumeChangeFunction skew_func = (VolumeChangeFunction) simX.getFieldFunctionManager().getFunction("VolumeChange);*/ private static double getWorstAspectRatio(Region region) { double highestAspectRatio = -1.0; // Iterate over all cells in the region for (Cell cell : region.getCells()) { double aspectRatio = cell.getAspectRatio(); if (aspectRatio > highestAspectRatio) { highestAspectRatio = aspectRatio; } } return highestAspectRatio; } private static double getWorstSkewness(Region region) { double worstSkewness = -1.0; // Iterate over all cells in the region for (Cell cell : region.getCells()) { double cellSkew = cell.getSkewness(); if (cellSkew > worstSkewness) { worstSkewness = cellSkew; } } return worstSkewness; } private static double getWorstOrthogonality(Region region) { double worstOrtho = 10.0; // Iterate over all cells in the region for (Cell cell : region.getCells()) { double cellOrtho = cell.getOrthogonality(); if (cellOrtho < worstOrtho) { worstOrtho = cellOrtho; } } return worstOrtho; } } |
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 static void zoneWallsMaxT(Simulation sim, String field_name) { Map<String, Double> solidZoneMaxT = new HashMap<>(); SimulationPartManager partManager = sim.getPartManager(); FieldFunctionManager fieldManager = sim.getFieldFunctionManager(); FieldFunction field_var = fieldManager.getFieldFunction(field_name); for (Region region : sim.getRegionManager().getRegions()) { if (region.getEntityType() == Region.SOLID) { double maxTemperature = Double.NEGATIVE_INFINITY; for (SolidBoundary boundary : region.getSolidBoundaries()) { SimulationIterator iterator = boundary.getSimulationIterator(field_var); while (iterator.hasNext()) { double field_value = iterator.next(FieldFunctionUnits.CELSIUS); if (field_value > maxTemperature) { maxTemperature = field_value; } } } for (PartSurface surface : region.getPartSurfaces()) { SimulationIterator iterator = surface.getSimulationIterator(field_var); while (iterator.hasNext()) { double field_value = iterator.next(FieldFunctionUnits.CELSIUS); if (field_value > maxTemperature) { maxTemperature = field_value; } } } solidZoneMaxT.put(region.getPresentationName(), maxTemperature); } } System.out.println("Summary of Maximum Temperatures in Solid Zones:"); System.out.println("---------------------------------------------"); for (Map.Entry<String, Double> entry : solidZoneMaxT.entrySet()) { System.out.printf("%-20s: %.2f °C%n", entry.getKey(), entry.getValue()); } } |
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.
Template by OS Templates