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

Scripting Languages

Automation

Scripts, Journals, UDF, Field Functions

A collection of scripts, journals and macros in CFD simulations to automate some tasks as well as enhance simulation capabilities. One may need such functions to apply special boundary conditions such as inlet velocity which is function of both time and space. Scripts or macros can be used to repeat the same simulation with changed boundary conditions or can be used to create a checking log where the summary of boundary conditions, solver setting, material properties and interface/periodicity information can be written out in a log file for self and peer review.


Definitions and concepts
  • A STAR-CCM+ macro is a Java program that is compiled and executed within the STAR-CCM+ workspace. A FLUENT UDF is a C program that is compiled and executed within the FLUENT workspace.
  • CFX uses a high level programming called CCL or CFX command language. Unlike UDF or JAVA macros, it does not need to be interpreted or compiled. However, for special post processing, commands in PERL and accessing solver program in FORTRAN is required.
  • Note that specific heat capacity Cp cannot be accessed or changed via UDF in FLUENT.

Programs and Scripting/Macro Language
ICEM CFD STAR-CCM+ FLUENT CFX OpenFOAM ParaView ANSA HyperMesh
Tck/Tk Java SCHEME, C CCL, PERL, FORTRAN C++ Python Python Tcl/Tk
  • A guide describing syntax used in SCHEME language can be found here (scheme programming).
  • A summary of few basic yet key features of the programming languages mentioned above is tabulated below.
  • SCHEME is a dialect of LISP and is the second-oldest high-level programming language after Fortran. The command and variable names are case-insensitive (though should only contain small letters in ANSYS FLUENT).
  • ANSYS has a feature ACT to facilitate automation an customization of simulation workflows.
Feature Tcl/Tk FORTRAN C JAVA
Case-sensitive Y N Y Y
Comment # C, ! /* ... */ //
End of Statement ; Newline character ; ;
Line Continuation \ Any character \ Not required
Variable Definition set x = 1; real x = 1 real x = 1; real x = 1;
If Loop if { x == y } {
 x = x + 1;
}
if (x .EQ. y) then
 x = x + 1
endif
if (x = y) {
 x = x + 1;
}
if (x = y) {
 x = x + 1;
}
For Loop for {set j 1} {$j <= $n} {incr j} {
  ...
}
DO Loop for (i=0; i<= 10, i++) {
 ...
}
for (i=0; i<= 10, i++)
{
 ...
}
Arrays $x(5); x(5) x[5]; x[5];
File Embedding source "common.dat"; include "common.dat" #include "common.h"; import common.class;
Note:

Java doesn't need a "line continuation character" since the end of the line has no significance so long a semi-colon is added at the end of a statement. It acts just as any other whitespace character. In other words, one can end the line immediately after an x = and continue on the assignment (say 10 in x = 10) on next line without any problems. For Tck/Tk used in ICEM CFD, the end of statement is also a newline character. However, if more than one statements are to be put on a line, they can be separated by a semi-colon.


CFX uses PERL for automation such as for-loop and lists. It does not accept underscore or hyphen in names, though spaces are allowed.


Examples: In FLUENT, the in-built macros used to access components of the velocity are
  • C_U(c,t): x-component of velocity
  • C_V(c,t): y-component of velocity
  • C_W(c,t): z-component of velocity
In STAR-CCM, it is achieved as:
  • Magnitude: mag($$Velocity)
  • X-component: $$Velocity[1]
  • Y-Component: $$Velocity[1]...
  • The directions X,Y,Z are represented by [0],[1],[2] respectively.

An example of a journal script which can be used in FLUENT to set-up a solver is as follows. This journal just needs to be edited for user's need. Note that there should be no empty line till the end of file. An empty line is assumed to be end of input. Use the remark character ; instead. The journal can be further parametrized by defining parameter using syntax (define X 0.7). Similarly, mathematical operation can be performed e.g. a = a + 0.1 can be written as (define a (+ a 0.1)).

Script and Macros

(ti-menu-load-string) is used to invoke a TUI comman in SCHEME journal. e.g. (ti-menu-load-string "solve set time-step 0.01"). Return value: #t if successful, #f if error occurs or cancelled by pressing Ctrl-C. Note all the SCHEME commands should be inside parentheses ( ... ).


Example scripts to make batch runs: SINGLE PHASE

Steady State Cold Flow SIMPLE Gravity OFF Energy OFF
Steady State Cold Flow Coupled Psuedo-Transient Gravity OFF Energy OFF
Steady State Cold Flow Coupled Gravity OFF Energy OFF
Steady State Conjugate Heat Transfer SIMPLE Gravity OFF Energy ON
Steady State Conjugate Heat Transfer Coupled Psuedo-Transient Gravity OFF Energy ON

Terminate or Save and Terminate a FLUENT job running in batch-mode on remote server (cluter): GUI based method is to use "Remote Visualization Client". Another option is to create checkpoints in the script: e.g. (set! checkpoint/exit-filename "/FOLDER/exit-fluent-FILENAME") where 'FOLDER' is location to store the case and data files. FILENAME is some which needs to be created whenever you want to save the data: touch /FOLDER/exit-fluent-FILENAME


 (define rf 0.7)
  file/read-case fluent.msh
  ;
  ;Change solid-domains into fluid type
  define/boundary-conditions/modify-zones/zone-type 4 fluid
  ;
  mesh/repair-improve/allow-repair-at-boundaries y
  mesh/repair-improve/repair
  ;Check and reorder the mesh to reduce the bandwidth of matrix
  mesh/check
  mesh/mesh-info 0
  mesh/reorder/reorder-domain
  mesh/reorder/reorder-domain
  ;
  /file/set-batch-options no yes yes no
  (set! *cx-exit-on-error* #t)
  define/models/solver/pressure-based yes
  ;
  define/models/viscous/ke-standard yes ke-realizable yes
  define/models/viscous/near-wall-treatment enhanced-wall-treatment yes
  ;-----------CONSTANT DENSITY ---------
  define/materials/change-create air air y constant 1.187 n n y constant 0.0000182 n n n
  ;-----------IDEAL-GAS ----------------
  define/materials/change-create air air yes ideal-gas yes polynomial 
  3 1033.33 -0.196044 3.93365e-4 yes polynomial 3 6.24978e-6 9.73517e-5 -3.31177e-8 
  yes sutherland two-coefficient-method two-coefficient-method 1.458e-6 110.4 yes 28.966 no no no no no
  ;-----------As on older version-------
  define/boundary-conditions/zone-type inlet pressure-inlet
  define/boundary-conditions/pressure-inlet inlet no 0 no 0 no 300 no yes no yes 5 0.1
  define/boundary-conditions/zone-type outlet pressure-outlet
  define/boundary-conditions/pressure-outlet outlet no 0 no 0 no 300 no yes no yes 5 0.1 
  ;-----------As on version 19.X--------
  define b-c zone-type z-right mass-flow-outlet
  define b-c zone-type z-right mass-flow-inlet 
  define b-c zone-type z-right pressure-outlet 
  define b-c zone-type z-right mass-flow-inlet 
  define b-c set vel-inlet z-right z-left () vmag no 1.25
  define b-c set vel-inlet z-right () vel-spec turb-intensity 2 () turb-visc-ratio 5 ()
  def b-c set m-f-i z-right () dir-spec no yes 
  def b-c set m-f-i z-right () mass-flow no 1.50 ()
  def b-c set m-f-i z-right () t-i 5 ()
  def b-c set m-f-i z-right () t-v-r 10 ()    
  ;
  define/operating-conditions operating-pressure 101325
  define/operating-conditions reference-pressure-location 0 0 0
  define/operating-conditions gravity no
  ;
  ;Define Discretization Scheme
  ;0-1st UDS, 1->2nd UDS, 2->Power Law, 4-> QUICK, 6->3rd Order MUSCL
  solve/set/discretization-scheme density 1
  solve/set/discretization-scheme mom 1
  solve/set/discretization-scheme k 1
  solve/set/discretization-scheme epsilon 1
  solve/set/discretization-scheme temperature 1
  ;
  ;Press: 10->Std, 11->Linear, 12-> 2nd Order, 13->Body Force Weighted, 14-> PRESTO!
  solve/set/discretization-scheme pressure 12
  ;
  ;Flow: 20->SIMPLE, 21->SIMPLEC, 22->PISO
  solve/set/p-v-coupling 21
  ;
  ;Define Under-Relaxation Factors: method varies based on PV-coupling
  ;SIMPLE/SIMPLEC
  solve/set/under-relaxation body-force 0.8
  solve/set/under-relaxation k 0.8
  solve/set/under-relaxation epsilon 0.8
  solve/set/under-relaxation density 0.8
  solve/set/under-relaxation mom 0.4
  ;
  ;COUPLED with Psuedo-Transient
  solve/set/psuedo-under-relaxation mom 0.4
  ;
  solve/set/under-relaxation pressure rf
  solve/set/under-relaxation turb-viscosity 0.8
  solve/set/under-relaxation temperature 1.0
  solve/set/limits 50000 150000 250 400 1e-14 1e-20 40000
  ;
  solve/monitors/residual convergence-criteria 1.0e-6 1.0e-6 1.0e-6 1.0e-6 1.0e-6 1.0e-6
  solve/monitors/residual plot y
  solve/monitors/residual print y
  ;
  ; Initialize the solution and set auto-save data frequency: 3 options
  /solve/initialize/hybrid-initialization
  ;
  /solve/initialize/compute-defaults all-zones
  ;
  /solve/initialize/set-default/k 0.01
  /solve/initialize/set-default/e 0.01
  /solve/initialize/set-default/pressure 10
  /solve/initialize/set-default/temperature 300
  /solve/initialize/set-default/x-velocity 0.1
  /solve/initialize/set-default/y-velocity 0.1
  /solve/initialize/set-default/z-velocity 0.1
  ;
  /file/auto-save/data-frequency 200
  file/auto-save/case-frequency if-case-is-modified
  /file/auto-save/retain-most-recent-files yes
  ;Field Functions
  define/custom-field-functions/define "vort1" dz_velocity_dy-dy_velocity_dz
  ;-----------Transient Runs------------
  solve/set/data-sampling y 1 y y
  solve/set/time-step 0.00001
  solve/set/adaptive-time-stepping y n 0.01 1.50 0.000001 0.001 0.5 2 5
  solve/dual-time-iterate 10000 20
  ;-----------Post-Processing-----------
  surface/line-surface L1 0.0 1.0 5.0 1.0
  surface/point-surface P1 5.0 0.5
  surface/plane-surf-aligned newsurf refsurf 0.0 0.25 0.0
  solve/monitors/surface/set-monitor P1 "Area-Weighted Average" pressure P1 () n n y P1.txt 1 y flow-time
  ;
  ;Save pressure xy plots of lines
  plot/plot y PL1 n n n pressure y 1 0 L1 ()
  plot/file PL1
  display/save-picture PL1.png
  plot/plot y PL1 n n n x-velocity y 1 0 L1 ()
  plot/file XVL1
  display/save-picture XVL1.png
  ;
  parallel/timer/usage
  report/system/proc-stats
  report/system/sys-stats
  report/system/time-stats
  ;
  file/confirm-overwrite yes    
  exit yes

SCHEME Summary

  • Statements are always included in small brackets such as (...)
  • Semi-colon ; is used at the beginning of a line to comment it, Comma , is used to accept default value in a command, () are used to define a list of selection. For instance (d1 d2 d3) or d1 d2 d3 () would both choose the three named zones and end the list.
  • Boolean: #t = true, #f = false
  • "string" is a string, 'string is a symbol. No distinction between variable types (Integer, Real, String, ...)
  • Example of strings: (define fn "backStep") (ti-menu-load-string (string-append "file read-case-data " fn ".cas")). Note the space after 'read-case-data'.
  • (symbol-bound? 'symbol (the-environment) ) - check if a symbol is defined (bound)
  • (symbol-assigned 'symbol (the-environment)) - check if a symbol is assigned a value
  • (define x 3) - x = 3
  • LISP and hence SCHEME uses prefix notation where operators are written before their operands. Thus: a * ( b + c ) / d is expressed as (/ (* a (+ b c) ) d)
  • LISP programs has 3 basic building blocks − atom, list and string
  • (+ 2 4 5) = 11, (/ 6 3) = 2, (/ 2) = (/ 1 2) = 0.5
  • Function f(x) is called as (f x) such as (abs x), (sqrt x), (expt xy) = xy, (exp x) = ex, (log x) = ln(x), (sin x), (cos x), (atan x), (atan y x) = arctan(x/y)...
  • (remainder 45 6) = 3, (modulo 5 2) = 1, (truncate x), (round x), (ceiling x), (floor x), (max x y ...), (min x y ...) e.g. from a list search for maximum: (apply max (1 5 8 3 4)) = 8
  • (define y '(+ x 2)) = y is a 'list' with elements +, x, 2 and hence it is not evaluated
  • (eval y (the-environment)) = 5, 'list' y interpreted as a SCHEME command
  • Equality of numbers: (= a b), equality of objects: (eq? a b) or (equal? a b), same value objects: (eqv? a b)
  • Relations: (positive? x), (negative? x) (< a b) (> a b) (<= a b) (>= a b)
  • Boolean functions: (not a), (and a b c ...), (or a b c ...)
  • (Define zNames '(w-bot w-top vi-front po-rear symmetry))
    • First item of a list: (car zNames) = w-bot
    • Rest of a list (i.e. list without first element): (cdr zNames) = (w-top vi-front po-rear symmetry)
    • Number of list elements: (length zNames) = 5
    • (list-union list-1 list-2 list-3), (list-intersection list-1 list-2 list-3), (list-subtract list-1 list-2)
  • Similar to the %-character in C the tilde (~) controls a pattern.
  • Format commands:
    • ~a: placeholder for a variable in general format (string without "")
    • ~d: integer number
    • ~04d: integer with zeros on the front is always 4 digits fill ( 5 is about 0005). e.g. this is important for file names.
    • ~f: floating-point number
    • ~4.2f: floating point number, a total of 4 characters long, 2 digits after the decimal: 1.2 will be 1.20
    • ~s: string with "" included: from (format #f "string: ~s!" "text") = "text"!
  • \n: newline character line feed, \" = " i.e. the double quotes are escaped by backslash.
  • (display expression) - write a printable representation of 'expression' to the default output port. (newline) - writes a newline character to the default output port.
  • (format #f "~6.4f" avgPr) - format AvgPr with 4 digits are decimal.
  • Vector or Array operations
    • (vector expr1 expr2 . . .) - creates a new vector containing the values of the given expressions. Vector elements are 0-indexed.
    • (make-vector n [expression]) - creates a new vector of 'n' elements each initialized to the value of the given 'expression' when provided. [...] indicates this is optional.
    • (vector-ref v n) - returns the element at position 'n' of vector v, where 0 is the index of the first element of the vector. Error will be reported if n < 0 or n is > the last element in the vector.
    • (vector-set! v n expression) - sets the value at position 'n' of vector v to the value of the 'expression'.
  • (zone-id->name zid) returns (displays in TUI console) the name of zone having id 'zid'
  • Define a variable to store ID of a zone: (rp-var-define 'iz 1 'integer #f)
  • Set the value of zone ID to the variable: (rpsetvar 'iz (zone-name-> 'front))
  • Use the value of zone ID: (rpgetvar 'iz)
  • Wildcard character * on its own will only chose all entities, (*) will chose all entities and close the list
  • Obtain a list of all zones: (define all-face-zones (get-face-zones-of-filter '*))
  • Get number of facets of a face zone: (tg-get-thread-count zID) where zID is the zone ID

Set Wall Rotation for zone having id ZID about X-axis passing through [XC YC ZC] and speed RPM: /define/b-c/wall ZID y n n n y n n 0 n 0 n RPM XC YC ZC 1 0 0

ZID Zone ID or name of the zone
y Change current value?
n Change shear-bc-noslip?
n Chnge rough-bc-standard?
n Wall motion relative to cell zone?
y Apply rotation velocity?
n Define wall velocity components?
n Use profile for wall-roughness height?
0 Wall roughness height
n
0
n
RPM Wall rotation speed in RPM
XC X-coordinate of a point on axis of rotation
YC Y-coordinate of a point on axis of rotation
ZC Z-coordinate of a point on axis of rotation
1 Direction cosine of X-axis
0 Direction cosine of Y-axis
0 Direction cosine of Z-axis

Set volumetric heat source for a zone with id ZID and material MATNAME: /define/b-c/solid ZID y MATNAME y 1 y 1250 n n n 0 n 0 n 0 n 0 n 0 n 0 n no

ZID Zone ID or name of the zone
y Change current value?
MATNAME Name of the material defined
y Specify soure terms?
1 Number of energy sources
y Use constant or expression for Energy 1
1250 Heat density in [W/m3]
n Specify fixed value?
n Frame motion?
n Use profile for reference frame X-origin of rotation axis?
0
n Use profile for reference frame Y-origin of rotation axis?
0
n Use profile for reference frame Z-origin of rotation axis?
0
n Use profile for reference frame X-component of rotation axis?
0
n Use profile for reference frame Y-component of rotation axis?
0
n Use profile for reference frame Z-component of rotation axis?
0
n Mesh motion?
no Solid motion (entre 'no' and not 'n')

IF-Loop

(if cond true-value false-value) - 'cond' is a boolean expression that is either #t (true) or #f (false). ((if #f + *) 3 4) = (* 3 4) = 12, ((if #t + *) 2 5) = (+ 2 5) = 7. (if (> 1 0) 'yes 'no) = yes, if (> 2 3) 'yes 'no) = no
(if (cond 
 (begin  
   (if ... True-value ) 
 )
 (begin 
   (else ... False-value)
 )   
)

Conditionals - similar to IF-Loop

(cond
  (test1 value1) 
  (test2 value2) 
  ... 
  (else value)
)
(define x 5)
(cond 
  ((> x 3) 'pass)
  ((< x 3) 'fail)
  (else 'retry)
)  
  
e.g. Check if a boundary zone, plane... exists or not
(if 
 (equal? (surface-name-> id 'planeXY)  
  #f
 )
)
(surface-name/id? 'planeXY) produces #t is a surface named 'front' exists. Similarly, (display (zone-name-> id 'water)) shall display/print the ID of zone named 'water'. 
Define a boundary condition if a zone-name exists. The syntax uses 'member' as in (member x LIST) which return the first item or sub-list of 'LIST' whose 'car' (the first element) is 'x' or returns '#f' if x does not occur in the list. Equal? can be used for comparison. The script also uses 'map' which is a higher order procedure: (map fn list-1 list-2 . . .): Apply 'fn' to each element of all the input lists and collect the return values into a list which is returned from 'map'.
(if 
 (member 'bc-inlet 
  (map thread-name 
   (get-face-thread)
  )
 )
 (begin
  (ti-menu-load-string "define b-c vel-in n n y y n 5.0 n 0 n n y 5 10")
 )
)
Wildcard character '*' can be used to specify zone names. E.g. (fuid*) refers to all the zones starting with 'fluid'. Since this method of refering multiple zones creates a list, it has to be included in (...) i.e. (fluid*) and not fluid*. e.g. "report volume volume-average (fluid*) temperature no".

DO-Loop

(do 
 (
   (x start-x (+ x delta-x))  ((> x x-end))
   ... loop body ...
)
Merge free and non-free odes with increasing value of tolerance:
(do 
 ( (i 10 (+ i 10)) (> i 50) )
  (ti-menu-load-string (format #f "boundary/merge-nodes (*) (*) no yes ~a" i) )
 )
)

Create multiple planes every 0.2 [m]: do(x = 0, x = x + 0.2,  x < 3.0)
(do 
 ( (x 0 (+ x 0.2)) (>= x 3.0) )
  (ti-menu-load-string (format #f "surface iso-surface x-coordinate x-3.1f ~a () 3.1f ~a ()" x x)) 
)
Output: Creates the following text interface commands: 
surface iso-surface x-coordinate x-0.0 () 0.0 () 
surface iso-surface x-coordinate x-0.2 () 0.2 () 
surface iso-surface x-coordinate x-0.4 () 0.4 () 
... 
surface iso-surface x-coordinate x-3.0 () 3.0 ()

To add a '+' symbol for positive numbers:
(if (> x = 0)
  "+" "") x x)
(define datfile "Run-1-A-")
(define suffix ".000.dat.gz")
(define m 10)
(define n 50)
(define s 5
(do 
 (
  (i  m (+ i  s) )
 )
 (
  (> i  n)
 )
 (ti-menu-load-string (string-append "file read-data " datfile (number->string i) suffix))
 (ti-menu-load-string "display objects display contour-vel")
 (define pic (string-append datfile (number->string i) ".png"))
 (ti-menu-load-string (string-append "display save-picture " pic))
) 

Local Function: lambda - a lambda expression evaluates to a procedure. The result of the last expression in the body will be returned as the result of the procedure call.

e.g.(lambda (x) (+ x x)): the function or procedure || ((lambda (x) (* x x)) 5) = 25 - the value is returned by procedure

(lambda (arg1 arg2 ...) 
  ... 
  function value
)

FOR EACH-Loop

Set temperature and wall velocity for several BC wall zones:
(for-each 
 (lambda (zone) 
  (ti-menu-load-string 
   (format #f "def b-c wall ~a 0 y steel y temperature n 300 n n n n 0 no 0.5 no 1" zone) 
  ) 
 (newline) (display "") 
 )
)

Create a function:

(map 
 (lambda(x)
   x*x + 5.0
 )
 '(1 2 3)
) 
Output: (6.0, 9.0, 14.0)

CASE-Loop: discrete values of a variable - If x in one of the lists found (eg in (x11 x12 x13 ...)), then the corresponding value is returned (value1).

(case x 
 ((x11 x12 x13 ...) 
    value1
 ) 
 ((x21 x22 x23 ...) 
    value2
 ) 
 ... 
 (else value)
) 

Boundary condition for specified heat flux: def b-c wall top 0 n 0 y steel n n 2000 n n n n 0 no 0.5 no 1. The default setting in FLUENT is aluminum as material, heat flux as boundary conditions and no-slip stationary walls.


Monitor Points

Define velocity inlet b.c. by components: def b-c v-i bc_inlet n y y n 0 y n 1.0 n 2.0 n 3.0 n n y 5 10
Define velocity inlet b.c. by magnitude and direction: def b-c v-i bc_inlet y y n 5.0 n 0 y n 0.707 n 0 n 0.707 n n y 5 10
solve report-definitions add mf-inlet flux-mass-massFlow zone-names mf-inlet ()
solve report-files add mf-inlet report-definitions mf-inlet () file-name mf-inlet.out print yes ()
solve report-definitions add p-inlet surface-areaavg field pressure surface-names srf-1 srf-2 ()
Field (flow) variables in FLUENT: pressure, entropy, x-surface-area, pressure-coefficient, total-energy, y-surface-area, dynamic-pressure, internal-energy, z-surface-area, rel-total-temperature, x-coordinate, dp-dx, wall-temp-out-surf, y-coordinate, dp-dy, wall-temp-in-surf, z-coordinate, dz-dp...

Define zone name as variable and use it in post-processing:

(define zName '(vi_inlet))
(display zName)
(define avgPr 
  (pick-a-real
    (format #f "/report/s-i/a-w-a ~a pressure no ()" zName)
  )
)
(display avgPr) 
Note: (display (format "~6.4f" avgPr)) will produce 0.0247*the-non-printing-object*. The statement (display (format #f "~6.4f" avgPr)) will give the desired output 0.0247.

Display a message if certain criteria is met: e.g. if temperature is less than or equal to 373 [K], report 'pass' or 'faail'.

(if 
 (<= 373
  (pick-a-real 
   (format #f "report/surf-integral/a-w-a w-cht-hx temperature no)
  )
 )
 (display "pass") (display "fail")
) 

Export fluent zone names

(define (export-bc-names) 
 (for-each 
  (lambda (name) 
   (display 
    (format #f " {~a, \"~a\", \"~a\"}, \n" 
     (zone-name->id name) name (zone-type (get-zone name)) 
    )
   )
  )
  (inquire-zone-names) 
 ) 
)
Fluent output:
(export-bc-names) 
{26, "w-top", "wall"}, 
{2, "fluid", "fluid"}, 
{29, "w-bot", "wall"}, 
{15, "w-side", "wall"}, 
{17, "inlet", "vi-inlet"}, 
{25, "default-interior", "interior"}

Creating animation: Create animation from the data files of a transient simulation, single frames will be created for an animation. The names of the data files are numbered with initial, final value with a step size. Errors encountered during the execution of a Fluent command, or a termination by Ctrl-C will also cause the Scheme program to quit. File names are twophase-0010.dat, twophase-0020.dat... and images generated are image-01.png, image-02.png... Note that 'hardcopy' has been replaced by 'picture' in version 2020-R1 though there is backward compatibiity.
(define datfile "twophase") 
(define f-index 10) 
(define l-index 100) 
(define delta 10) 
(define imgfile "image")
(define (time) (rpgetvar 'flow-time)) 
(define t0 0)
; ------------------------------------------------ ------------------------
;       Function to create frames for the film 
; ------------- ----------------------------------------------------------- 
(define (pp) 
 (let ((break #f)) 
  (ti-menu-load-string "display set hardcopy driver png")
  (ti-menu-load-string "display set hardcopy color-mode color")
  (do ((j f-index (j + delta)) (i 1 (+ i 1))) ((or (> j l-index) break))
   (set! break 
    (not
	 (and
	  (ti-menu-load-string (format #f "file r-d ~a ~04d.dat" datfile j))
	  (begin (if (= i 1) (set! t0 (time))) #t)
	  (ti-menu-load-string "display hardcopy ~a ~02d.png" imgfile i) 
      )
    )
   ) 
  ) 
  (if break 
   (begin (newline) (newline) 
    (display "Scheme interrupted!") 
    (newline)
   )
  )
 )
)

Simple example (disp)-function for contour-plot:
(define (disp) 
 (ti-menu-load-string "display contour temperature 300 500")
) 
Example (disp) function: overlay contours and velocity-vectors. To call the (disp) function for testing: (disp), call the function to generate the images: (pp).
(define (disp) 
 (and 
  (ti-menu-load-string (format #f "display lang set title \" Time 5.1fs = ~ \ "" (- (time) t0)))
  (ti-menu-load-string "display set overlays no") 
  (ti-menu-load - string "display temperature contour 300 500") 
  (ti-menu-load-string "display set yes overlays") 
  (ti-menu-load-string "display lang velocity vectors, velocity-magnitude 0.0 1.0 5 0") 
 ) 
)

GUI Components in FLUENT and SCHEME Script


Customization vs. Extensibility
Customization Extensibility
In-product operation Out of product feature expansion
Modify existng functionality, Create new feature Enhance a software package with minimum development

EXAMPLE OF UDF
Only velocities in Cartesian coordinates (Ux,Uy,Uz) are accessible through the UDF macros. Radial, tangential & axial velocities (Ur, Ut, Ua) within a fluid zone will need to be computed using the UDF itself. The UDF below can be used to define inlet velocity as a function of radius and time. It is assumed that the centre of inlet face is at origin.
  Note that in order to access UDF parameters in post-processing, UDM (User Defined Memory) needs to be initialized using GUI path: Parameters & Customization → User Defined Memory → Number of User-Defined Memory Location where the UDM numbering starts from 0. In your UDF, assign your variable to a specific UDM. E.g. F_UDMI(face, thread, 0) = U_txyz; C_UDMI(cell, threat, 0) = vol_heat_source; '0' here refers to the UDM number.

Note that the DEFINE_XX macros implement general solver functions that are independent of the model(s) being used in ANSYS Fluent. For example, DEFINE_ADJUST is a general-purpose macro that can be used to adjust or modify variables that are not passed as arguments. For example, modify flow variables (velocities, pressure...) and compute integrals of a scalar quantity over a domain which can be used to adjust a boundary condition based on the result. A function that is defined using DEFINE_ADJUST executes at every iteration and is called at the beginning of every iteration before transport equations are solved.

#include "udf.h"
DEFINE_PROFILE(U_txyz, thread, position) {
  /*position: Index of variable say 'U' to be set                 */
  real x[ND_ND];             /* Position vector of nodes          */
  real xi, yi, zi, r;
  face_t f;
  real R = 0.050;            /* Radius in [m]                     */
  real t = CURRENT_TIME;     /* Current time of simulation        */
  begin_f_loop(f, b)         /* Loops over all faces in thread 'b'*/
  {
    /* C_CENTROID(x,c,t): returns centroid in real x[ND_ND]       */

    F_CENTROID(x, f, b);    /* Gets centroid of face f            */
    
    /* x[ND_ND]: Position vector of nodes                         */
    xi = x[0]; yi = x[1]; zi = x[2];
    r = sqrt(xi*xi + yi*yi + zi*zi);
    F_PROFILE(f, b, position) = 2.0 + 0.5*sin(t/5)*sin(0.31416*r/R);
  } 
  end_f_loop(f, thread)
} 

Note: The constant ND_ND is defined as 2 for RP_2D (2D domain) and 3 for RP_3D (3D domain). It can be used when it is require to build a 2x2 matrix in 2D and a 3x3 matrix in 3D. Instead if ND_ND is used, the UDF will work for both 2D and 3D cases, without requiring any modifications.


Another example of UDF which can be used to define a linear translation and angular displacement to a cylinder of plate with dynamic mesh motion setting is described below.
/* Rigid body motion of a cylinder: translation and rotations,
can be used for a flapping plate if translation is set 0.    */

#include "udf.h"
/* -----  Define frequency of rotation / flapping in Hz.     */
  #define f 5.0  
/* -----  Define angular velocity in [rad/s].                */
  #define omega 2.0*M_PI*f
/* -----  Define maximum angular deflection in [rad]         */
  #define thetaMax M_PI/180
/* -----  Define linear translation in [m]                   */
  #define xMax 0.01;
  
DEFINE_CG_MOTION(TransRot, dt, cg_vel, cg_omega, time, dtime) {
  real angVel, linVel;
  
  linVel = xMax * omega * cos(omega*time);
  cg_vel[0] = linVel;
  cg_vel[1] = 0.0;
  cg_vel[2] = 0.0;
  
  /*cg_omega[0] -> wx, cg_omega[1] -> wy, cg_omega[2] - wz   */
  /*Axis of rotation is about origin and should be ensured.  */
  angVel = ThetaMax * omega * sin(omega*time);
  cg_omega[1] = angVel;
  cg_omega[2] = 0.0;
  cg_omega[3] = 0.0;
}

Summary of UDF commands
Exerpts from user manual: Think of a ‘zone’ as being the same as a ‘thread’ data structure when programming UDFs. Thus: node thread = grouping of nodes, face thread = grouping of faces, cell thread = grouping of cells. A domain is a data structure in ANSYS FLUENT that is used to store information about a collection of node, face threads, and cell threads in a mesh.
UDF thread domain hierarchy
  • Data Types: Node is a structure data type that stores data associated with a mesh point, face_t is an integer data type that identifies a particular face within a face thread, cell_t is an integer data type that identifies a particular cell within a cell thread, Thread is a structure data type that stores data that is common to the group of cells or faces that it represents.
  • NODE_X(node) = X-coordinate of node
  • NODE_Y(node) = Y-coordinate of node
  • NODE_Z(node) = Z-coordinate of node
  • F_NNODES(f, t) = number of nodes in a face
  • C_CENTROID(x, c, t) / F_CENTROID(x, f, t): = returns centroid in a 1x3 array real x[ND_ND]
  • F_AREA(a, f, t): returns face area (normal) vector in real a[ND_ND]
  • C_VOLUME(c, t) = volume of cell
  • C_NNODES(c, t) = number of nodes
  • C_NFACES(c, t) = number of faces
  • C_FACE(c, t, i) = global face index, corresponding to local face index i
  • C_R(c, t) / F_R(f, t) = Access cell / boundary face flow variable density
  • C_P(c, t) / F_P(f, t) = Access cell / boundary and interior face flow variable pressure
  • C_U(c, t) / F_U(f, t) = Access cell / boundary face flow variable x-velocity
  • C_V(c, t) / F_V(f, t) = Access cell / boundary face flow variable y-velocity
  • C_W(c, t) / F_W(f, t) = Access cell / boundary face flow variable z-velocity
  • C_T(c, t) / F_T(f, t) = Access cell / boundary face flow variable temperature
  • C_H(c, t) / F_H(f, t) = Access cell / boundary face flow variable enthalpy
  • C_K_L(c, t) = Access cell material property "thermal conductivity". 'L', 'T' and 'EFF' suffix is used for 'Laminar', 'Turbulent' and 'Effective' properties. For example, C_MU_L, C_MU_T and C_MU_EFF refers to 'Laminar', 'Turbulent' and 'Effective' viscosities respectively.
  • Similarly, K, NUT, D, O and YI can be added to C_ to access TKE, turbulent viscosity of Spalart-Allmaras model, TED (ε), specific dissipation rate (ω) and mass fraction respectively
  • F_FLUX(f, t) = Access face flow variable mass flux
  • d = Get_Domain(1) = Get domain using FLUENT utility. Here, domain_id = 1 is an integer for the mixture or fluid domain, but the values for the phase domains can be any integer greater than 1. E.g. porousDomain = Get_Domain(2);
  • Derivative macro: C_UDSI(c, t, VORTICITY_Z) = C_DVDX(c,t) - C_DUDY(c,t) = define z-component of vorticity
  • C_R_G(c, t), C_P_G(c, t), C_U_G(c, t) ... can be used to get gradient vector: {dp/dx dp/dy dp/dz)
  • The M1 suffix can be applied to some of the cell variable macros to access value of the variable at the previous time step (t - Δt). These data may be useful in unsteady simulations. For example, C_T_M1(cell, thread); returns the value of the cell temperature at the previous time step
  • Similarly, M2 suffix can be applied to some of the cell variable macros to access value of the variable at second previous time step (t -2Δt). These data may be useful in unsteady simulations. For example, C_T_M2(cell, thread); returns the value of the cell temperature at the previous to previous time step
  • PRINCIPAL_FACE_P(f,t) = test if the face is the principle face - not required for serial operation, applicable to compiled UDFs only
  • C_VOLUME = get the cell volume and accumulates it. The end result is total volume of each cell of respective mesh.
  • C_UDMI(c, t,0) = store result in user-defined memory, location index 0. The user-defined memory field gets saved to the data file and can be used to generate contours and any other post-processing activity.
  • The NV_ macros have the same purpose as ND macros, but they operate on vectors (that is, arrays of length ND_ND) instead of separate components.
    • NV_V: The utility NV_V performs an operation on two vectors. NV_V(a, =, x) will result in a[0] = x[0], a[1] = x[1] and a[2] = x[2]
    • Use of '+ =' instead of '=' in the above equation results in summation. NV_V(a, +=, x) will result in a[0] = a[0] + x[0], a[1] = a[1] + x[1] and a[2] = a[2] + x[2]
    • NV_VV performs operations on vector elements. The operation that is performed on the elements depends upon what symbol (-, /, *) is used as an argument. NV_VV(a, =, x, +, y) will yield a[0] = x[0] + y[0], a[1] = x[1] + y[1] and a[2] = x[2] + y[2]
    • NV_V_VS utility operates (+, -, *, /) a vector to another vector which is multiplied or divided by a scalar. NV_V_VS(a, =, x, +, y, *, 0.5) will result in 2D: a[0] = x[0] + y[0] * 0.5, a[1] = x[1] + y[1] * 0.5
    • NV_VS_VS utility operates (+, -, *, /) a vector to another vector where both are multiplied or divided by a scalar. NV_VS_VS(a, /, 2.0, x, +, y, *, 5.0) will result in a[0] = x[0] / 2.0 + y[0] * 5.0, a[1] = x[1] / 2.0 + y[1] * 5.0, a[3] = x[3] / 2.0 + y[3] * 5.0
  • Other NV_ operations:
    • NV_VEC(A) - declare vector A
    • NV_D(psi, =, F_U(f,t), F_V(f,t), F_W(f,t)) - define psi in terms of velocity field, NV_D(axis, =, 0.0, 1.0, 0.0), NV_D(origin, =, 0.0, 0.0, 5.0)
    • NV_VV(rvec, =, NODE_COORD(v), -, origin)
    • NV_S(q, =, 0.0), NV_S(psi, *=, F_R(f,t)) - multiplying density to get psi vector
    • NV_DOT(A, B) - dot product of the two vectors, NV_CROSS(A, B) - crosss product of the two vectors
  • boolean FLUID_THREAD_P(thread): Check if 'thread' is of type FLUID
  • Some macros are defined in 'mem.h' and not in 'udf.h'. Example includes: C_FACE_THREAD(c, t, i), C_FACE(c, t, i), C_R(c,t), C_P(c,t), C_U(c,t), C_V(c,t)... F_PROFILE.

UDF in Parallel Computing on Clusters

Serial solver contains Cortex and only a single ANSYS Fluent process.

The parallel solver contains 3 types of executable: Cortex, host, and compute node (or simply 'node' for short). When ANSYS Fluent runs in parallel, an instance of Cortex starts, followed by one host and n compute nodes, thereby giving a total of (n + 2) running processes. For this reason, UDF for parallel run will need to be developed such that the function will successfully execute as a host and a node process.

Example of operations that require parallelization of serial source code include the following:
  • Reading and Writing Files
  • Global Reductions, Global Logicals
  • Global Sums, Global Minimums and Maximums
  • Certain Loops over Cells and Faces
  • Displaying Messages on a Console, Printing to a Host or Node Process
List of parallel compiler directives:
/*--------------------------------------------------------------------*/
/* Compiler Directives                                                */
/*--------------------------------------------------------------------*/
#if RP_HOST       /* only host process is involved                    */
#if !RP_HOST      /*either serial or compute node process is involved */
  ...
#endif

#if RP_NODE       /* only compute nodes are involved                  */
#if !RP_NODE      /* either serial or host process is involved        */
  ...
#endif

#if PARALLEL     /* both host and compute nodes are involved, but not */
                 /* serial equivalent to #if RP_HOST || RP_NODE       */
#if !PARALLEL    /* only serial process is involved                   */
  ...
  
#endif

Depending upon a UDF, the UDF written in C language needs to be compiled before it can be used in FLUENT. Best a UDF should be compiled on a system with the same operating system (OS) and processor architecture as the compute cluster. Typically the compute nodes are diskless nodes with bare minimum boot image, it lacks a C or CPP programming environment (compiler, linker, libraries). Hence, it is not possible to compile a UDF in batch mode on a compute node of the Linux clusters.


More examples of FLUENT UDF
UDF for Temperature Dependent Viscosity
DEFINE_PROPERTY(visc_T, c, Tp)		{
  real mu; real a = C_T(c,t);  
  mu = 2.414e-05 * pow(10, 247.8/(Tp - 140));
  return mu;						
}

Compute area of a face zone:

 #include "udf.h" 
 real Ar1 = 0.0; 
 begin_f_loop(f, t) 
 if PRINCIPAL_FACE_P(f, t) {  
  /* compute area of each face */  
  F_AREA(area, f, t);   
  /*compute total face area by summing areas of each face*/  
  Ar1 = Ar1 + NV_MAG(area);   
 }  
 end_f_loop(f,t)  
 Ar1 = PRF_GRSUM1(Ar1);  
 Message("Area = %12.4e \n", Ar1); 

Compute volume of a cell zone:

 #include "udf.h" 
 real Vm1 = 0.0; 
 begin_C_loop(c, t) 
  /*compute total volume by summing volumes of each cell*/  
  Vm1 = Vm1 + C_VOLUME(c, t);   
 }  
 end_f_loop(c, t)  
 Vm1 = PRF_GRSUM1(Vm1);  
 Message("Volume = %12.4e \n", Vm1);

UDF: change time step value in Transient Simulation

This example, UDF needs to operate on a particular thread in a domain (instead of looping over all threads) and the DEFINE macro DEFINE_DELTAT used in UDF does not have the thread pointer passed to it from the solver. Hence, Lookup_Thread is required in the UDF to get the desired thread pointer.

 #include "udf.h"
 DEFINE_DELTAT(timeStep, d) { 
 real newTime = CURRENT_TIME; real oldT; real minT = 0.0; real maxT = 0.0;
 Thread *t; cell_t c; d = Get_Domain(1); 
 int zID = 1; Thread *t = Lookup_Thread(d, zID); 
 begin_f_loop(f, t) { /* Loop over all face elements*/
   oldT = F_T_M1(f, t); /* Get face temperature at previous time-step */
   if (oldT < minT || minT == 0.0) minT = oldT;
   if (oldT > maxT || maxT == 0.0) maxT = oldT;
 }
 end_f_loop(f, t)

 if(maxT < 100.0) 
  timeStep = 0.5; 
 else 
  timeStep = 0.1; 
 return timeStep; 
 } 

Density as function of temperature:

#include "udf.h"
DEFINE_PROPERTY(rho_T, c, Tp) {
  real rho;
  /* Get temperature of the cell in K and convert into C */
  real Tp = C_T(c,t) - 273.11; 
  real a0 =  999.8396;
  real a1 =  18.22494;
  real a2 = -7.92221e-03;
  real a3 = -5.54485e-05;
  real a4 =  1.49756e-07;
  real a5 = -3.93295e-10;
  real b =   1.81597e-02;

  rho = a0 + a1*Tp + a2*Tp*Tp + a3*pow(Tp, 3) + a4*pow(Tp, 4) + a5*pow(Tp, 5);
  rho = rho / (1 + b*Tp);
  return rho;						
}

Sample UDF for 6DOF case. DEFINE_SDOF_PROPERTIES (name, properties, dt, time, dtime) specifies custom properties of moving objects for the six degrees of freedom (SDOF) solver which includes mass, moment and products of inertia, external forces and external moments. real *properties - pointer to the array that stores the SDOF properties. The properties of an object which can consist of multiple zones can change in time, if desired. External load forces and moments can either be specified as global coordinates or body coordinates. In addition, you can specify custom transformation matrices using DEFINE_SDOF_PROPERTIES. The boolean properties[SDOF_LOAD_LOCAL] can be used to determine whether the forces and moments are expressed in terms of global coordinates (FALSE) or body coordinates (TRUE). The default value for properties[SDOF_LOAD_LOCAL] is FALSE.

#include "udf.h"
#include "math.h"
DEFINE_SDOF_PROPERTIES(valve_6dof, prop, dt, time, dtime) {
prop[SDOF_MASS] = 0.10; /*Mass of the valve in [kg] */
prop[SDOF_IZZ] = 1.5e-3;/*Mass moment of inertia about Z axis [kg/m^2]*/
/* Translational motion setting, use TRUE and FALSE as applicable */
prop[SDOF_ZERO_TRANS_X] = TRUE; /*Translation allowed in X-Direction? */
prop[SDOF_ZERO_TRANS_Y] = TRUE; /*Translation allowed in Y-Direction? */
prop[SDOF_ZERO_TRANS_Z] = TRUE; /*Translation allowed in Z-Direction? */
/* Rotational motion setting, use TRUE and FALSE as applicable*/
prop[SDOF_ZERO_ROT_X] = TRUE; /*Rotation allowed about X-Axis? */
prop[SDOF_ZERO_ROT_Y] = TRUE; /*Rotation allowed about Y-Axis? */
prop[SDOF_ZERO_ROT_Z] = FALSE; /*Rotation allowed about Z-Axis? */
/* Gravitational, External Forces/Moments: SDOF_LOAD_F_X, SDOF_LOAD_F_Y ... SDOF_LOAD_M_Z */
M = prop[SDOF_MASS]; Larm = 0.10 */
prop[SDOF_LOAD_M_Z] = -9.81 * M * Larm * sin(DT_THETA(dt)[2] ;
Message("\n 2D: updated 6DOF properties DT_THETA_Z: %e, Mz: %e, Mass: %e \n",
DT_THETA(dt)[2], prop[SDOF_LOAD_M_Z], prop[SDOF_MASS]);
}

Tips and Tricks on UDF / UFF
  • To write output to a file from UDF operation / loop: open a file using statement: FILE *fileName; fileName = fopen("udfOutput.txt", "a"); fprintf(fileName,"%g %g\n", x[0], source); fclose(fileName); However, all the fopen / fprintf / fclose commands are incompatible with parallel operation.
  • To send output to the console: Message("x = %g source = %g\n", x[0], source);)
  • In STAR-CCM+ du/dy = grad($Velocity[0]/grad($Centroid[1]), in FLUENT UDF: C_DUDY(cell, thread). Similarly, C_DVDX(cell, thread) can be defined.
  • Similarly in FLUENT, C_T_G(cell, thread)[0] returns the x-component of the cell temperature gradient vector.

ICEM CFD: Tck/Tk Examples
For loop to copy a point entity:
for {set i 1} {$i <= $NS} {incr i}  {  
  ic_geo_duplicate_set_fam_and_data point ps$j ps[expr {$j+2}] {} _0  
  ic_move_geometry point names ps[expr {$j+2}] translate "0 $L 0"  
  ic_geo_duplicate_set_fam_and_data point ps[expr {$j+1}] ps[expr {$j+3}] {} _0  
  ic_move_geometry point names ps[expr {$j+3}] translate "0 $L 0"  
  set j [expr {$i*10+1}]  
} 


Macros in STAR-CCM+
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: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(1506);
  hardcopyProperties_0.setCurrentResolutionHeight(618);
  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");
 }
}

Field Functions in STAR-CCM+

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");
  uFF_1.setDefinition("sqrt(($$Position[0]*$$Position[0])
    +($$Position[1]*$$Position[1]))");
  }
} 

Scripting in ANSA

ANSA uses Python as scripting and automation capabilities.
import os
import ansa
#from ansa import *

from ansa import base
def openFile():
	base.Open("C:/Users/myFile.ansa")

#Collect sets for different areas
deck = ansa.constants.LSDYNA
set1 = ansa.base.PickEntities(deck,("SET",))
parts = base.PickEntities(deck, ("SECTION_SHELL","SECTION_SOLID",))
set2 = base.CreateEntity(deck, "SET", {'Name' : "SetName", })
set3 = base.CollectEntities(deck, None, "__PROPERTIES__", )

def printPIDname():
	deck = constants.OpenFOAM  #NASTRAN, FLUENT, STAR, LSDYNA
	pid_list = base.collecEntities(deck, none, "PSHELL", False, True)
	#pid_list = base.collecEntities(deck, none, "__PROPERTIES__", False, True)
	for pid in pid_list:
		print(pid._name)
		oldPID = pid._name
		if "grille" in oldPID:
			newPID = "po_"+oldPID
			base.ReplaceProperty(oldPID, newPID)
		#subifm($,'oldPID','newPID')
		
def openMultipleFiles():
    #Select multiple files
	files = utils.SelectOpenFileIn('C:/Users/XYZ', 1)
	i = 1
	for f in files:
		print("File Number {1} is {2}:", i, f)
		#Opening the file
		ansa.base.Open(f) 
		i = i + 1
#------------------------------------------------------------------------------
#Print all PID and their names
import ansa
from ansa import *

idList = []
nameList = []
def main():
	deck = constants.LSDYNA
	pName = base.CollectEntities(deck, None, "__PROPERTIES__", False, True)
	for i in part_name:
		idList.append(i._id)
		nameList.append(i._name)
        pass
main()
mergeList = list(zip(idList, nameList))
for i in mergeList:      
    print(i)
	if __name__ == '__main__':
		main() 

Scripting in CFX and CFD-Post

A CCL CFX Command Language file required for scripting and automation in CFX is as follows. This file can also be used to set orthotropic thermal conductivity which is otherwise not possible through GUI. PERL statements can be directly embedded in CCL syntax. CCL syntax starting with 'gt;' is execution statement. The PERL statements start with '!'. \ is the line continuation character and lists are separated by comma. CFD-Post session file have extension .cse (CFX SEssion) and .cst (CFX STate).
dP = massFlowAve(Pressure)@inlet – massFlowAve(Pressure)@outlet
Pv = 0.5 * areaAve(Density)@Inlet * areaAve(Velocity)@Inlet^2
areaAve(p)@Inlet - area-weighted average of 'pressure' on the boundary named 'Inlet'
area()@REGION:Inlet - area of a 2D mesh region named 'Inlet' belonging to domain REGION. area_x()@Inlet is area projected in direction 'X'.
massFlow()@Inlet: mass flow rate through 'Inlet'. Add multiple zones separated by space. e.g. massFlow()@Out1 Out2 Out3
>calculate area, Inlet, - calculates the area of the locator 'Inlet'. Note that adding the comma after 'Inlet' removes the axis specification.
@Xlocs = (0.05, 0.10, 0.15, 0.20) - define a list in PERL, $Xlocs[$i] - accesss a member in the list.
volumeInt(Density)@Tank - calculate mass of luid in volume named 'Tank'

Print mass flow rate, area and area-average velocity on single line: here 'front' is the name of the boundary.

!print("front: Mass Flow Rate [kg/s] = 10%5f, Area [m^2] = %10.6f, Area-Avg-Velocity [m/s] = %10.2f", massFlow("front"), area("front"), areaAve("Velocity", "front"), "\n");

Example PERL script - use it in command editor, the output would be printed in CFD-Post terminal.

! ($MFinlet, $MFunit) = evaluate("massFlow()\@Inlet");
! printf (Mass Flow at Inlet "%10.5f [$MFunit] \n", $MF01);

! for ($i = 1; $i <= 8; $i++) {
!  if ($i < 10) { 
!   $i = '0'.$i; 
!  }
!
!  ($ARi, $ARunit) = area()@OUTLET_.$i;
!  ($MFi, $MFunit) = massFlow("OUTLET_.$i");
!  printf("OUTLET_.$i = %10.5f [$ARunit], MF = %10.5f [$MFunit] \n", $ARi, $MFi);
! }

Write output or results of function calculators to a FILE.

! $AvQ=areaAve("Wall Heat Flux", "WALL_CYL");
! open(RESULT, ">Output.dat");
! print RESULT "-------------------------------------------------\n";
! print RESULT "$AvQ\n";
! print RESULT "-------------------------------------------------\n";
! close(RESULT); 

Create a PLANE in CFD-Post

PLANE:PlaneYZ
  Apply Instancing Transform = On
  Apply Texture = Off
  Blend Texture = On
  Bound Radius = 0.5 [m]
  Colour = 0.75, 0.75, 0.75
  Colour Map = Default Colour Map
  Colour Mode = Variable
  Colour Scale = Linear
  Colour Variable = Pressure
  Colour Variable Boundary Values = Hybrid
  Culling Mode = No Culling
  Direction 1 Bound = 1.0 [m]
  Direction 1 Orientation = 0 [degree]
  Direction 1 Points = 10
  Direction 2 Bound = 1.0 [m]
  Direction 2 Points = 10
  Domain List = /DOMAIN GROUP:All Domains
  Draw Faces = On
  Draw Lines = Off
  Instancing Transform = /DEFAULT INSTANCE TRANSFORM:Default Transform
  Invert Plane Bound = Off
  Lighting = On
  Line Colour = 0, 0, 0
  Line Colour Mode = Default
  Line Width = 1
  Max = 0.0 [Pa]
  Min = 0.0 [Pa]
  Normal = 1 , 0 , 0
  Option = YZ Plane
  Plane Bound = None
  Plane Type = Slice
  Point = 0 [m], 0 [m], 0 [m]
  Point 1 = 0 [m], 0 [m], 0 [m]
  Point 2 = 1 [m], 0 [m], 0 [m]
  Point 3 = 0 [m], 1 [m], 0 [m]
  Range = Global
  Render Edge Angle = 0 [degree]
  Specular Lighting = On
  Surface Drawing = Smooth Shading
  Texture Angle = 0
  Texture Direction = 0 , 1 , 0
  Texture File =
  Texture Material = Metal
  Texture Position = 0 , 0
  Texture Scale = 1
  Texture Type = Predefined
  Tile Texture = Off
  Transform Texture = Off
  Transparency = 0.0
  X = 0.0 [m]
  Y = 0.0 [m]
  Z = 0.0 [m]
  OBJECT VIEW TRANSFORM:
    Apply Reflection = Off
    Apply Rotation = Off
    Apply Scale = Off
    Apply Translation = Off
    Principal Axis = Z
    Reflection Plane Option = XY Plane
    Rotation Angle = 0.0 [degree]
    Rotation Axis From = 0 [m], 0 [m], 0 [m]
    Rotation Axis To = 0 [m], 0 [m], 0 [m]
    Rotation Axis Type = Principal Axis
    Scale Vector = 1 , 1 , 1
    Translation Vector = 0 [m], 0 [m], 0 [m]
    X = 0.0 [m]
    Y = 0.0 [m]
    Z = 0.0 [m]
  END
END

Create a pressure contour on PlaneYZ created earlier.

CONTOUR:ContourPlaneYZ
  Apply Instancing Transform = On
  Clip Contour = Off
  Colour Map = Default Colour Map
  Colour Scale = Linear
  Colour Variable = Pressure
  Colour Variable Boundary Values = Hybrid
  Constant Contour Colour = On
  Contour Range = Global
  Culling Mode = No Culling
  Domain List = /DOMAIN GROUP:All Domains
  Draw Contours = On
  Font = Sans Serif
  Fringe Fill = On
  Instancing Transform = /DEFAULT INSTANCE TRANSFORM:Default Transform
  Lighting = On
  Line Colour = 0, 0, 0
  Line Colour Mode = Default
  Line Width = 1
  Location List = /PLANE:PlaneYZ
  Max = 0.0 [Pa]
  Min = 0.0 [Pa]
  Number of Contours = 11
  Show Numbers = Off
  Specular Lighting = On
  Surface Drawing = Smooth Shading
  Text Colour = 0, 0, 0
  Text Colour Mode = Default
  Text Height = 0.024
  Transparency = 0.0
  Value List = 0 [Pa], 5 [Pa], 10 [Pa]
  OBJECT VIEW TRANSFORM:
    Apply Reflection = Off
    Apply Rotation = Off
    Apply Scale = Off
    Apply Translation = Off
    Principal Axis = Z
    Reflection Plane Option = XY Plane
    Rotation Angle = 0.0 [degree]
    Rotation Axis From = 0 [m], 0 [m], 0 [m]
    Rotation Axis To = 0 [m], 0 [m], 0 [m]
    Rotation Axis Type = Principal Axis
    Scale Vector = 1 , 1 , 1
    Translation Vector = 0 [m], 0 [m], 0 [m]
    X = 0.0 [m]
    Y = 0.0 [m]
    Z = 0.0 [m]
  END
END

Set Camera Views, Show/Hide Contours and save hardcopies

# Sending visibility action from ViewUtilities
>show /CONTOUR:ContourPlaneYZ, view=/VIEW:View 1

# Sending visibility action from ViewUtilities
>hide /PLANE:PlaneYZ, view=/VIEW:View 1

>setcamera viewport=1, camera=-X
HARDCOPY:
  Antialiasing = On
  Hardcopy Filename = Orifice_Walled_Duct_Flow_VeryHighTI_001.png
  Hardcopy Format = png
  Hardcopy Tolerance = 0.0001
  Image Height = 600
  Image Scale = 100
  Image Width = 600
  JPEG Image Quality = 80
  Screen Capture = Off
  Use Screen Size = On
  White Background = On
END
>print 

CCL and PERL are case sensitive.

COMMAND FILE:
  CFX Pre Version = 12.1
END
# Define all the variables in a PERL file and include with 'require' statement.
! require "VarCFX_Pre.pl";
>load mode=new
>update

>gtmImport filename=$FCFX5, type= Generic, genOpt= -n, units=mm, \
nameStrategy=$Name
> update
>writeCaseFile filename=$CASE
> update

FLOW: Flow Analysis 1
  &replace   SOLUTION UNITS:
    Angle Units = [rad]
    Length Units = [m]   #Options: [cm], [mm], [in], [ft], [yd], [mile]
    Mass Units = [kg]    #Options: [g], [lb], [slug], [tonne]
    Solid Angle Units = [sr]
    Temperature Units = [K]  #Options; [R]
    Time Units = [s]     #Options: [min], [hr], [day], [year]
  END # SOLUTION UNITS:
END # FLOW:Flow Analysis 1
> update
# ---------------------------------------------------------------------+
LIBRARY:
 CEL:
  EXPRESSIONS:
   CpAir=1005.6 [J kg^-1 K^-1] + 5.6E-3 [J kg^-1 K^-2] * T
  END
 END
END
> update

LIBRARY:
 CEL:
  EXPRESSIONS:
   kAir = -3.9333E-4[W m^-1 K^-1] + 1.0184E-4 [W m^-1 K^-2]*T \
    -4.8574E-8 [W m^-1 K^-3]*T*T + 1.5207E-11 [W m^-1 K^-4]*T^3
  END
 END
END
> update

LIBRARY:
 CEL:
  EXPRESSIONS:
   MuAir=1.72E-5 [kg m^-1 s^-1] *(T / 293 [K])^0.742
  END
 END
END
> update

LIBRARY:
 CEL:
  EXPRESSIONS:
   AvHeatFlux=areaAve(Wall Heat Flux )@REGION:$WallName
  END
 END
END
> update
# ---------------------------------------------------------------------+
LIBRARY:
  &replace   MATERIAL: UserMat
    Material Description = User-defined Material
    Material Group = User
    Object Origin = User
    Option = Pure Substance
    Thermodynamic State = Gas
    PROPERTIES:
      Option = General Material
      DYNAMIC VISCOSITY:
        Dynamic Viscosity = MuAir
        Option = Value
      END # DYNAMIC VISCOSITY:
      EQUATION OF STATE:
        Molar Mass = $MolM [kg kmol^-1]
        Option = Ideal Gas
      END # EQUATION OF STATE:
      SPECIFIC HEAT CAPACITY:
        Option = Value
        Specific Heat Capacity = CpAir
        Specific Heat Type = Constant Pressure
      END # SPECIFIC HEAT CAPACITY:
      THERMAL CONDUCTIVITY:
        Option = Value
        Thermal Conductivity = kAir
      END # THERMAL CONDUCTIVITY:
    END # PROPERTIES:
  END # MATERIAL:UserMat
END # LIBRARY:
> update

FLOW: Flow Analysis 1
  &replace   DOMAIN: Domain_Pipe
    Coord Frame = Coord 0
    Domain Type = Fluid
    Location = $BlkName
    DOMAIN MODELS:
      BUOYANCY MODEL:
        Option = Non Buoyant
      END # BUOYANCY MODEL:
      DOMAIN MOTION:
        Option = Stationary
      END # DOMAIN MOTION:
      MESH DEFORMATION:
        Option = None
      END # MESH DEFORMATION:
      REFERENCE PRESSURE:
        Reference Pressure = $RefPress [atm]
      END # REFERENCE PRESSURE:
    END # DOMAIN MODELS:
    FLUID DEFINITION: Fluid 1
      Material = Air Ideal Gas
      Option = Material Library
      MORPHOLOGY:
        Option = Continuous Fluid
      END # MORPHOLOGY:
    END # FLUID DEFINITION:Fluid 1
    FLUID MODELS:
      COMBUSTION MODEL:
        Option = None
      END # COMBUSTION MODEL:
      HEAT TRANSFER MODEL:
        Option = Thermal Energy
      END # HEAT TRANSFER MODEL:
      THERMAL RADIATION MODEL:
        Option = None
      END # THERMAL RADIATION MODEL:
      TURBULENCE MODEL:
        Option = $TurbModel
      END # TURBULENCE MODEL:
      TURBULENT WALL FUNCTIONS:
        Option = Scalable
      END # TURBULENT WALL FUNCTIONS:
    END # FLUID MODELS:
  END # DOMAIN:Domain_Pipe
END # FLOW:Flow Analysis 1
> update

FLOW: Flow Analysis 1
  DOMAIN: Domain_Pipe
    &replace     BOUNDARY: $WallName 
      Boundary Type = WALL
      Create Other Side = Off
      Interface Boundary = Off
      Location = $WallName
      BOUNDARY CONDITIONS:
        HEAT TRANSFER:
          Fixed Temperature = $WallT [K]
          Option = Fixed Temperature
        END # HEAT TRANSFER:
        MASS AND MOMENTUM:
          Option = No Slip Wall
        END # MASS AND MOMENTUM:
        WALL ROUGHNESS:
          Option = Smooth Wall
        END # WALL ROUGHNESS:
      END # BOUNDARY CONDITIONS:
    END # BOUNDARY: $WallName
  END # DOMAIN:Domain_Pipe
END # FLOW:Flow Analysis 1
> update

FLOW: Flow Analysis 1
  DOMAIN: Domain_Pipe
    &replace     BOUNDARY: Inlet
      Boundary Type = INLET
      Interface Boundary = Off
      Location = INLET
      BOUNDARY CONDITIONS:
        FLOW DIRECTION:
          Option = Normal to Boundary Condition
        END # FLOW DIRECTION:
        FLOW REGIME:
          Option = Subsonic
        END # FLOW REGIME:
        HEAT TRANSFER:
          Option = Static Temperature
          Static Temperature = $InletT [K]
        END # HEAT TRANSFER:
        MASS AND MOMENTUM:
          Mass Flow Rate = 0.1 [kg s^-1]
          Option = Mass Flow Rate
        END # MASS AND MOMENTUM:
        TURBULENCE:
          Option = Medium Intensity and Eddy Viscosity Ratio
        END # TURBULENCE:
      END # BOUNDARY CONDITIONS:
    END # BOUNDARY:Inlet
  END # DOMAIN:Domain_Pipe
END # FLOW:Flow Analysis 1
> update

FLOW: Flow Analysis 1
  DOMAIN: Domain_Pipe
    &replace     BOUNDARY: Outlet
      Boundary Type = OUTLET
      Interface Boundary = Off
      Location = OUTLET
      BOUNDARY CONDITIONS:
        FLOW REGIME:
          Option = Subsonic
        END # FLOW REGIME:
        MASS AND MOMENTUM:
          Option = $OutBC
          Relative Pressure = $OutBCValue [Pa]
        END # MASS AND MOMENTUM:
      END # BOUNDARY CONDITIONS:
    END # BOUNDARY:Outlet
  END # DOMAIN:Domain_Pipe
END # FLOW:Flow Analysis 1
> update

FLOW: Flow Analysis 1
  &replace   INITIALISATION:
    Option = Automatic
    INITIAL CONDITIONS:
      Velocity Type = Cartesian
      CARTESIAN VELOCITY COMPONENTS:
        Option = Automatic with Value
        U = $InitU [m s^-1]
        V = $InitV [m s^-1]
        W = $InitW [m s^-1]
      END # CARTESIAN VELOCITY COMPONENTS:
      STATIC PRESSURE:
        Option = Automatic with Value
        Relative Pressure = $InitP [Pa]
      END # STATIC PRESSURE:
      TEMPERATURE:
        Option = Automatic with Value
        Temperature = $InitT [K]
      END # TEMPERATURE:
      TURBULENCE INITIAL CONDITIONS:
        Option = Low Intensity and Eddy Viscosity Ratio
      END # TURBULENCE INITIAL CONDITIONS:
    END # INITIAL CONDITIONS:
  END # INITIALISATION:
END # FLOW:Flow Analysis 1
> update

FLOW: Flow Analysis 1
  &replace   SOLVER CONTROL:
    Turbulence Numerics = $TurbNum
    ADVECTION SCHEME:
      Option = $Advect
    END # ADVECTION SCHEME:
    CONVERGENCE CONTROL:
      Length Scale Option = Conservative
      Maximum Number of Iterations = $nMax
      Minimum Number of Iterations = $nMin
      Timescale Control = Auto Timescale
      Timescale Factor = 1.0
    END # CONVERGENCE CONTROL:
    CONVERGENCE CRITERIA:
      Residual Target = $Norm
      Residual Type = $Type
    END # CONVERGENCE CRITERIA:
    DYNAMIC MODEL CONTROL:
      Global Dynamic Model Control = On
    END # DYNAMIC MODEL CONTROL:
  END # SOLVER CONTROL:
END # FLOW:Flow Analysis 1
> update

LIBRARY:
 CEL:
  EXPRESSIONS:
    VF=maxVal(Velocity u)@REGION:OUTLET / massFlowAve(Velocity u)@REGION:OUTLET
  END
 END
END
> update


 
 


FLOW: Flow Analysis 1
  &replace   OUTPUT CONTROL:
    MONITOR OBJECTS:
      MONITOR BALANCES:
        Option = Full
      END # MONITOR BALANCES:
      MONITOR FORCES:
        Option = Full
      END # MONITOR FORCES:
      MONITOR PARTICLES:
        Option = Full
      END # MONITOR PARTICLES:
      MONITOR POINT: Mon1
        Expression Value = VF
        Option = Expression
      END # MONITOR POINT:Mon1
      MONITOR RESIDUALS:
        Option = Full
      END # MONITOR RESIDUALS:
      MONITOR TOTALS:
        Option = Full
      END # MONITOR TOTALS:
    END # MONITOR OBJECTS:
    RESULTS:
      File Compression Level = Default
      Option = Standard
    END # RESULTS:
  END # OUTPUT CONTROL:
END # FLOW:Flow Analysis 1
> update

# ---------------------------------------------------------------------+
> writeCaseFile
> update
>writeCaseFile filename=$DEF, operation=start solver interactive
# operation="write def file" or "start solver batch"
> update
Post-processing statements in PERL:
! $Zc = 50;
! $var = "Temperature";
! $mdot = massFlow("Plane$Zc");
! $MFavg = massFlowAve($var, "Plane$Zc");
! $Pin = massFlowAve("Pressure","inlet");
! $Pout = massFlowAve("Pressure","outlet");
! $dp = $Pin-$Pout;
! print "The pressure drop is $dp\n"; 
! ($Pout, $punits) = evaluate( "massFlowAve(Pressure)\@Outlet" );

# For Loop - to set boundary conditions on various faces
! $n = 10;
! for ($i=0; $i < $n; $i++) {
  --- CCL Statements ---
  
   PLANE: Plane-$i
    Option = Point and Normal
    Point = 2*$i, 0.0, 0.0
    Normal = 1,0,0
    Draw Lines = On
    Line Color = 1,0,0
    Color Mode = Variable
    Color Variable = Pressure
    Range = Local
   END
  PLANE:plane2
   Option = Point and Normal
   Point = 0.0, $i*3,0.0
   Normal = 0,1,0
   Draw Faces = Off
   Draw Lines = On
   Line Color = 0,1,0
   Color Variable = Velocity
   Range = Local
  END
  --- CCL Statements ---
! } 

DOS Scripts
In Windows OS, DOS commands are stored in a text file with extension *.bat (BATch) files. These files can be used to run programs in batch (non-GUI) mode and automated repeated tasks. By default, a batch file will display its command as it runs. Command "echo off" turns off the display for the whole script, except command itself. Sign '@' in front makes the command apply to itself as well.
  1. The redirect operator > directs the output to specfied location (terminal, file...). >> is used to append the output to an existing content
  2. The command line arguments can be called through the variables %1, %2, %3 and so on
  3. Variables: set /A X=10, echo %X%, SET /A c = %a% + %b% - variable is assigned using 'set' command and value is accessed using %...% operator

File Seach in Windows 10

From Command Line - search files bigger than 10 MB --- forfiles /P F:\DataFiles\XYZ /M * /S /C "cmd /c if @fsize GEQ 10485760 echo @path > bigFiles.log" --- note that it creates files bigFiles.log in each sub-directory of parent directoty [F:\DataFiles\XYZ in this case]

Here GEQ = ≥, 1kB = 1,024 bytes -- 1 MB = 10,48,576 byts -- 1 GB = 1,07,37,41,824 bytes. forfiles takes following arguments: /P "pathname" - Specifies the path from which to start the search. By default, searching starts in the current working directory. /M "searchmask" - Searches files according to the specified search mask. The default searchmask is *. /S - Instructs the forfiles command to search in subdirectories recursively. /C "command" - Runs the specified command [should be wrapped in double quotes] on each file. Default command is "cmd /c echo @file".

File Search by Size in Windows 10

The options and range of file size which is seached is summarized as follows:
  1. small: 16kB ~ 1 MB
  2. medium: 1 ~ 128 MB
  3. large: 128 MB ~ 1 GB
  4. huge: 1 ~ 4 GB
  5. gigantic: > 4 GB
  • % is used to refer to a variable: e.g. %f IN (in*.f) where %f refers to file names matching 'in*.f'
  • REM (REMark) or :: is used for comments. DOS commands are not case-sensitive
  • Line contunuation: You may break up long lines of code with the caret ^. Put it at the end of a line, next line must have space at the begining
  • dir /T:W >> list.txt: write files of the current folder into file list.txt
  • dir /T:W C:\commands.docx: Get the last modified time for the file 'C:\commands.docx'
  • dir /T:W -> Get modified date/time for all files and folders in the current directory
  • dir /T:W /A:-D -> Get modified date/time only for files in the current directory (exclude folders)
  • Using forfiles command we can get modified date/time for all files in a directory: forfiles /C "cmd /c echo @file @fdate @ftime"
  • Restrict the command only to certain files using * command. E.g. get modified time/date only for pdf files: forfiles /M *.pdf /C "cmd /c echo @file @fdate @ftime"
  • List the content of folder and its sub-folders: dir C:\XYZ /ad /b /s > List.log
  • rmdir /q /s "%%I" -> it will delete directories quietly and removes all files, sub-folders and the directory itself
  • Calls another batch file and returns control to the first when done: CALL C:\NEW.bat
  • To echo special characters, precede them with a caret: ECHO ^<
  • Spliting strings: "tokens=1-5 delims=/ " - How many tokens the incoming data (in this case the date) will be broken into. 1-5 is five different tokens. The 'delims' argument is short for delimiters and is what is used to break up the date, in this example the / (forward slash) and a space (space before the quote)
  • for /f "tokens=1-5 delims=/ " %%d in ("%date%") do rename "hope.txt" %%e-%%f-%%g.txt, use the date command within the for command to extract the current date and use that data to rename the file.

EAMPLES

Merge Files:
FOR %f IN (in*.f) 
 DO 
  type %f >> ..\merge.txt & echo. >> ..\merge.txt

@echo off 
set list=1 2 3 4 
(for %%a in (%list%) do ( 
   echo %%a 
))

Open many files using NOTEPAD:
cd C:\Test
for %X in (*.f) 
 do 
   notepad %X

Create a file name based on current date and time:
Set Mn = %DATE:~7,2%
Set Yr = %DATE:~10,4%
Set Hr = %TIME:~0,2%
Set Mi = %TIME:~3,2%
dir "C:\XYZ"  /-C /O:GN /Q /S /T:A > "%Day%-%Mn%-%Yr% %Hr%-%Mi%.log"

Use of CONDITIONAL statements:
@echo off
if exist c:\XYZ goto exists
  echo Directory not found
  pause
goto end
:exists
  echo The directory exists
  echo .
:end
  Set FilePath=%FilePath%\%Day%
  IF NOT EXIST %FilePath% MKDIR %FilePath%
  @echo off
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.