CAA: Basics of Acoustics […]
CFD simulations of turbo-machines […]
A random process that can be simulated using Monte Carlo method. […]
Octave scripts have high level of portability to MATLAB! […]
Steps to check correctness of CFD simulation results! […]
View our blog topics! […]
Automation
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.
A sophisticated automation approach requires developement of a consistent naming convention for the geometry, surface, boundaries and volumetric regions (domains). This include CAD package, the pre-processor, solve and post-processor. Even the structure of CAD program (such as model tree) to represent an assembly need to be simple and consistent with CFD pre-processor. It may be an uphill task if the CAD program, the pre-processors and solvers uses different programming and scripting languages. For example, ANSYS SpaceClaim uses Python, FLUENT is based on SCHEME and the syntax in CFD-Post is CEL/PERL. In such cases, end-to-end automation may not yield desired advantages and a separate automation should be worked out at each step. FLUENT GUI is based on Qt Toolkit and graphical attributes can be modified using Qt stylesheets such as cxdisplay.css for FLUENT. This file needs to be placed in home directory (location where FLUENT executables are placed during installation). This article "Scripted CFD simulations and postprocessing in Fluent and ParaVIEW" by Lukas Muttenthaler et al at Johannes Kepler University Linz provides a detailed automation method which can be improvised further.
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. In SCHEME, a string literal is continued from one line to another, the string will contain the newline character (#\newline) at the line break. Like most of the programming languages: string is written as a sequence of characters enclosed within double quotes " ". To include a double quote inside a string, precede the double quote with a backslash \ (escape it).
CFX uses PERL for automation such as for-loop and lists. It does not accept underscore or hyphen in names, though spaces are allowed.
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)).
(ti-menu-load-string) is used to invoke a TUI command in SCHEME journal i.e. to convert a journal command to Scheme command. 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
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
Some basic pre-processing can be done faster on a HPC cluster: file read-case oldCase.cas.h5, file write-setting setUp.bc, file replace-mesh newMesh.msh.h5, file read-setting setUp.bc, mesh scale 0.001 0.001 0.001, file write-case newCase.cas.h5 - These 6 statements in a journal file can be used to read a case file, replace mesh and creates a new case file.
Note that the HPC server needs a trigger from the solver to stop or exit the job when there is any error while iterating. As per FLUENT user guide: "Batch option settings are not saved with case files. They are meant to apply for the duration of the current ANSYS FLUENT session only. As batch options are not saved with case files, journal files developed for use in batch mode should begin by enabling the desired batch option settings". The TUI command that should be added to the journal file before iterate statement is /file/set-batch-options n y y n where n, y, y and n stands for answer to "Confirm Overwrite?", "Exit on Error", "Hide Questions" and "Redisplay the Questions" respectively.
(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 /mesh/modify-zones/slit-interior-between-different-solids ;-----------Steady State Runs--------- /solve/iterate 2000 ;-----------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 0.0 surface/plane-surface pNameXY xy-plane z0 surface/plane-surface pNameYZ yz-plane x0 surface/plane-surface pNameZX zx-plane y0 surface/plane-surface pName3P three-points x1 y1 z1 x2 y2 z2 x3 y3 z3 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.txt n n n pressure y 1 0 L1 () plot/file PL1 display/save-picture PL1.png plot/plot y PL1.txt 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
Define new materials: define material copy solid aluminum cstl csteel - this line of code copies aluminum to a new material cstl short form of cast-steel and csteel the new material formula. Note that aluminum (and not aluminium) is the default material when a new ANSYS FLUENT session is created. Some line of codes to create different types of solids are:
Create a probe point: display surface point-surface pName x y z where x, y and z are respective coordinates.
The list of all the SCHEME codes impemented in FLUENT is summarized in attached file. It is being categorized into appropriate steps of simulation activites.
SCHEME Summary: Not all the built-in functions available in standard SCHEME are incorporated into FLUENT. For example, string-trim, string-prefix, string-suffix, string-replace... do not work in FLUENT TUI.
(if(not(rp-var-object 'hflx-id)) (rp-var-define 'hflx-id 10 'integer #f) () ) (rpgetvar 'hflx-id) -> This will print 10 in console. (if (zone-name->id 'wall_hflx) (rpsetvar 'hflx-id (zone-name->id 'wall_hflx)) (rpsetvar 'hflx-id 10) )
TUI commands that take single or multiple zone names support the use of wildcards. For example, to copy boundary conditions (copy-bc) to all zones of a certain type, use a * in the name of the zone to which you want to copy the conditions. Example: report surface-integrals facet-avg w-htc* , temperature no
Similarly, following script can be used to change all walls having names ending in 'shadow' to type coupled: define b-c wall *shadow () 0 n 0 y steel y coupled n n 1
(list-bc "settings.bc") prints a list of type (zone name : zone type) where the input file "settings.bc" were created by TUI operation "file write-settings settings.bc".
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
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 no n 0 n 0 n 0 n 0 n 0 n 0 n no no
Set Mass Flow Inlet boundary conditions: /define/b-c/mass-flow-inlet zNAME y y n 0.75 n 50.0 n 10000 n y n n y 2 5
Create Named Expressions:
In case of field values: /define/named-expressions add exprName definition "MassFlowAve(StaticPressure, ['outlet-1', 'outlet-1']" q - here 'outlet-1' and 'outlet-2' are names of the zone of type outlet.
(display get-thread-list): output is #[compound-procedure]
(display (get-thread-list)): it results in error with following message:
Error Object: name --- this indicates the argument is missing for get-thread-list
Scheme codes which try to access mesh elements shall make the program crash. For example, (get-all-thread) or (display get-all-thread) shall make FLUENT session crash. However, (map thread-id (get-all-threads)) shall print the ID of all threads (zones) in the set-up (case) file. Similarly (get-threads-of-type 'interior) or (get-threads-of-type 'velocity-inlet) make the cortex crash, (map thread-id (get-threads-of-type 'wall)) prints the IDs of all zone of type wall
In FLUENT, a 'surface' is defined as any plane created for post-processing purposes and not the one used in computation. Hence, Scheme codes working on surface shall not accept boundary face zone as input. e.g. (define tp (surface-area-average (list (surface-name->id "plane-10")) "temperature")) works but (define tp (surface-area-average (list (surface-name->id "w-htc-x")) "temperature")) does not work where w-htc-x is a face zone with specified HTC boundary conditions. (list (surface-name->id) "plane-10") shall print (10) as output. However (surface-area-average) will give following error: Error: eval: unbound variable Error object: s
(define (print-list items) (for-each (lambda (ii) (display ii) (display " ") (newline) ) items ) (newline) ) (print-list '(a b c))
This function prints each member of the list on separate lines. The following code creates 'sum' function to add each member of the list. Note 'list' is a reserved word in SCHEME to define built-in variable. Hence, do not use the word 'list' as an argument to a function.
(define (sum items) (if (null? items) 0 (+ (car items) (sum (cdr items) ) ) ) )
(define (avg ist) (/ (sum ist) (length ist) ) )
Thus following function can be used in FLUENT mesher to rename solid (cell) or/and boundary (face) zones or add a prefix / suffix to face and/or cell zones. The code to rename only cell zones are defined below. Note that strings (such as zone names) with hyphen '-' needs to be converted into string using format ~s option.
(define (rename-cell-zones items) (for-each (lambda (zid) (define zold (zone-id->name zid) ) (define zolx (format #f "~s" zold) ) (define znew (string-append zolx "_mat") ) (ti-menu-load-string (string-append "mesh manage name " zolx " " znew) ) ) items ) (newline) ) (rename-cell-zones (get-cell-zones-of-filter '*))
Split String: Splits a string into a list of strings separated by the delimiter character such as comma, space, colon... Few important procedures related to string manipulations are: string-ref string idx - (which returns character string[idx], using 0-origin indexing), substring string start end - returns a string containing the characters of string beginning with index 'start' (inclusive) and ending with index 'end' (exclusive). string-take str nc - returns a string containing the first 'nc' charactoers of string 'str', string-drop str nc - returns a string containing all but the first 'nc' character of string 'str', string-take-right str nc - returns a string containing the last 'nc' characters of string 'str', string-drop-right str nc - returns a string containing all but the last 'nc' characters of string 'str'. Out of these functions, only string-ref and substring works in FLUENT Mesher.
(define (str-split str ch) (let ( (len (string-length str)) ) (letrec ( (split (lambda (a b) (cond ( (>= b len) (if (= a b) '() (cons (substring str a b) '())) ) ( (char=? ch (string-ref str b)) (if (= a b) (split (+ 1 a) (+ 1 b)) ( cons (substring str a b) (split b b)) ) ) (else (split a (+ 1 b))) ) ) ) ) (split 0 0) ) ) )
Join list of strings with delimiter
(define (string-join lst delimiter) (if (null? lst) "" (let loop ((result (car lst)) (lst (cdr lst))) (if (null? lst) result (loop (string-append result delimiter (car lst)) (cdr lst) ) ) ) ) )
IF-Loop
(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'.
(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") ) )
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)
Read multiple data files (usually created during transient runs) and save images of a pre-defined contour plot in PNG format
(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
(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) )
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 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)
Display a message if certain criteria is met: e.g. if temperature is less than or equal to 373 [K], report 'pass' or 'fail'.
(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: this is applicable to FLUENT pre-post and not FLUENT Mesher. Once this journal is copy-pasted in TUI or read through a journal file, one need to type commmand (export-bc-names) in the TUI - including the parentheses.
(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) ) ) (export-bc-names)
(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"}
Scheme script to rename shadow wall pairs. This code was downloaded from the public domain and variable names have been shortened a bit and text indented.
;------------------------------------------------------------------------------ ; Scheme function to identify which interior zones are "immersed" in a certain ; fluid zone. To use it, load the Scheme function through ; File>Read>Scheme ... or through (load "immersed.scm") and then use the TUI ; command (for example): (imme-info 'fluidX) ; It will print 1 or several interior zones that are completely immersed into ; the fluid zone specified. One of them is for sure the Default-Interior type ; associated with that fluid zone named fluidX ;------------------------------------------------------------------------------ (define (imme-info fzn) (let ( (id-fz (thread-name->id fzn) ) (int-list (map thread-id (get-threads-of-type 'interior)) ) ) (for-each (lambda (id) (let ( (zz (inquire-adjacent-threads id)) (id1)(id2)) (set! id1 (car zz)) (set! id2 (cadr zz)) (if (eqv? id1 id2) (if (eqv? id1 id-fz) (format "\n Interior zone "~a" is immersed in "~a" \n" (thread-id->name id) fzn) ) ) ) ) int-list ) ) )
A Scheme code referenced from ANSYS Learning Forum is described below.
(cond ((and (> (rpgetvar 'flow-time) 0.1) (< (rpgetvar 'flow-time) 0.2) ) (ti-menu-load-string "define/b-c/z-t 6 wall") (ti-menu-load-string "define/b-c/z-t 7 pressure-outlet")) ((and (> (rpgetvar 'flow-time) 0.5) (< (rpgetvar 'flow-time) 0.6) ) (ti-menu-load-string "define/b-c/z-t 6 wall") (ti-menu-load-string "define/b-c/z-t 7 pressure-outlet")) (else (ti-menu-load-string "define/b-c/z-t 7 wall") (ti-menu-load-string "define/b-c wall 7 no no no no 0 no 0.5") (ti-menu-load-string "define/b-c/z-t 6 pressure-inlet") (ti-menu-load-string "define/b-c pressure-inlet 6 yes no 0 no 0 no yes no no yes 2 5")) )
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) ) ) ) )
(define (disp) (ti-menu-load-string "display contour temperature 300 500") )
(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") ) )
Few examples from posts on cfd-online.com: This piece of code prints centroid of boundaries defined at type "velocity-inlet".
(display (map (lambda (zone) (format #f "~a: (~a,~a,~a)\n" zone (pick-a-real (format #f "/report/surface-int/a-w-a ~a () x-coordinate no" zone) ) (pick-a-real (format #f "/report/surface-int/a-w-a ~a () y-coordinate no" zone) ) (pick-a-real (format #f "/report/surface-int/a-w-a ~a () z-coordinate no" zone) ) ) ) (filter (lambda (zn) (eq? (zone-type (get-zone zn)) 'velocity-inlet)) (inquire-zone-names) ) ) )
Check whether a cell thread is adjacent to a face thread or not
(define (check_adjacency fluid_id face_id) (let ( (fluid_chk (inquire-adjacent-threads face_id)) (aa) ) (set! aa (car fluid_chk)) (if(eqv? aa fluid_id) (display "Face and Fluid adjacent.") (display "Face and Fluid not adjacent.") ) ) )
ANSYS FLUENT star-up customization: This can be complementary to options available under Preferences in latest versions (V2021...)
(let (old-rc client-read-case) (set! client-read-case (lambda args (apply old-rc args) (if (cx-gui?) (begin (rpsetvar 'residuals/plot? #t) ;Turning off convergence check (rpsetvar 'residuals/settings '( (continuity #t 0 #f 0.0001) (x-velocity #t 0 #f 0.0001) (y-velocity #t 0 #f 0.0001) (z-velocity #t 0 #f 0.0001) (energy #t 0 #f 1e-08) (k #t 0 #f 0.0001) (epsilon #t 0 #f 0.0001) ) ) (rpsetvar 'mom/relax 0.4) (rpsetvar 'pressure/relax 0.5) (rpsetvar 'realizable-epsilon? #t) (cxsetvar 'vector/style "arrow") ) ) ) ) )
Read a custom color map or write an existing one. The procedure consists of: Loading the Scheme file >> (load "rw-colormap.scm") >> Reading a new color map: /file/read-colormap >> Writing an existing color map: /file/write-colormap. Reference: Fluent Tips & Tricks - UGM 2004 by Sutikno Wirogo and Samir Rid.
(define (write-cmap fn) (let ( (port (open-output-file (cx-expand-filename fn))) (cmap (cxgetvar 'def-cmap)) ) (write (cons cmap (cx-get-cmap cmap)) port) (newline port) (close-output-port port) ) ) (define (read-cmap fn) (if (file-exists? fn) (let ((cmap (read (open-input-file (cx-expandfilename fn))))) (cx-add-cmap (car cmap) (cons (length (cdr cmap)) (cdr cmap) ) ) (cxsetvar 'def-cmap (car cmap)) ) (cx-error-dialog (format #f "Macro file ~s not found." fn) ) ) ) (define (ti-write-cmap) (let ((fn (read-filename "colormap filename" "cmap.scm"))) (if (ok-to-overwrite? fn) (write-cmap fn) ) ) ) (define (ti-read-cmap) (read-cmap (read-filename "colormap filename" "cmap.scm")) ) (ti-menu-insert-item! file-menu (make-menu-item "read-colormap" #t ti-read-cmap "Read colormap from file") ) (ti-menu-insert-item! file-menu (make-menu-item "write-colormap" #t ti-writecmap "Write colormap to file") )
Replace all occurrenece of characters in a string. Reference: stackoverflow.com/.../flexible-replace-substring-scheme. Note that this code require (prefix?) to work as it is not implemented in all Scheme environments.
(define (rplc-all input trgt src) (let ( (input (string->list input)) (trgt (string->list trgt)) (src (string->list src)) (trgt-len (string-length trgt)) ) (let loop ((input input) (acc '())) (cond ((null? input) (list->string (reverse acc)) ) ((prefix? input trgt) (loop (list-tail input trgt-len) (reverse-append src acc) ) ) (else (loop (cdr input) (cons (car input) acc)) ) ) ) ) ) (rplc-all "w-htc_2" "-" "_)
(let um (cx-add-menu "usrMenu" #\M)): it adds a menu named usrMenu in the top main menu bar with M underlined to indicate keyboard shortcut. The ID of the newly created menu is printed in console which can also be access by code (cx-get-menu-id "usrMenu"). To add items to this menau: (cx-add-item um "CFD Steps" #\O #f and (lambda () (system "chrome.exe https://cfdyna.com &")))
(scale-grid): This will give following errors:
(inquire-grid) shall print summary of mesh such as (0 874 2056 342 2) where the numbers correspond to cells, faces and node. (map domain-type (get-all-domains)) prints (mixture). (map domain-type (get-all-domains)) prints (geom-domain). (fluent-exec-name) prints the path of executables (*.exe) files. (list-database-materials) prints the names of all materials defined inside ANSYS FLUENT. (get-database-material 'air) prints all the properties currently defined for material air. Note the single quote before the name for material.
(volume-integrals) results in error with message "Error eval: unbound variable". (%volume-integrals) also results in error with differnt message: Error: eval: too few arguments(0) Error Object: #[primitive procedure %volume-integrals]
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.
/* 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; }
DEFINE_ON_DEMAND is a general-purpose macro that can be used to specify a UDF that is executed as needed in ANSYS FLUENT, rather than having ANSYS FLUENT call it automatically during the calculation. UDF will be executed immediately, after it is activated, but it is not accessible while the solver is iterating. Note that the domain pointer d is not explicitly passed as an argument to DEFINE_ON_DEMAND. Therefore, if you want to use the domain variable in your on-demand function, you will need to first retrieve it using the Get_Domain utility.
Excerpt from UDF Manual: The following UDF, named on demand calc, computes and prints the minimum, maximum, and average temperatures for the current data field. It then computes a temperature function f(T) = [T − TMIN]/[TMAX − TMIN] and stores it in user-defined memory location 0. After the on-demand UDF is hooked, the field values for f(T) will be available in drop-down lists in postprocessing dialog boxes in ANSYS FLUENT. This field can be accessed by choosing User Memory 0 in the User-Defined Memory... category.
#include "udf.h" DEFINE_ON_DEMAND(Tavg) { /* declare domain pointer: it isn't passed as an argument to the DEFINE macro */ Domain *d; real tavg = 0.0; real tmax = 0.0; real tmin = 0.0; real tp, volm, vtot; Thread *t; cell_t c; /* Get the domain using ANSYS FLUENT utility */ d = Get_Domain(1); /* Loop over all cell threads in the domain */ thread_loop_c(t,d) { /* Compute max, min, volume-averaged temperature */ /* Loop over all cells */ begin_c_loop(c,t) { volm = C_VOLUME(c,t); /* get cell volume */ tp = C_T(c,t); /* get cell temperature */ if (tp < tmin || tmin == 0.0) tmin = tp; if (tp > tmax || tmax == 0.0) tmax = tp; vtot = vtot + volm; tavg = tavg + tp*volm; } end_c_loop(c,t) tavg /= vtot; printf("\n Tmin = %g Tmax = %g Tavg = %g\n",tmin,tmax,tavg); /* Compute temperature function and store in UDM*/ /*(location index 0) */ begin_c_loop(c,t) { tp = C_T(c,t); C_UDMI(c,t,0) = (tp-tmin)/(tmax-tmin); } end_c_loop(c,t) } }
This UDF will print the volume of cells with temperature withing specified [in K] range.
DEFINE_ON_DEMAND(isoVolume) { /* declare domain pointer: it isn't passed as an argument to the DEFINE macro */ Domain *d; real tmax = 300.0; /* This value should in [K] */ real tmin = 320.0; /* This value should in [K] */ real temp, volm, vtot; Thread *t; integer zid; cell_t c; /* Get the domain using ANSYS FLUENT utility */ d = Get_Domain(1); /* Loop over all cell threads in the domain */ thread_loop_c(t, d) { vtot = 0.0; /* Loop over all cells */ begin_c_loop(c,t) { tp = C_T(c,t); /* get cell temperature */ if (tp <= tmax && tp >= tmax) { /*Get cell volume and add to total volume */ volm = C_VOLUME(c,t); vtot = vtot + volm; } } end_c_loop(c,t) zid = THREAD_ID(t); printf("\n Zone - %d -- Volume in specified range = %g \n", zid, vtot); } }
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.
/*--------------------------------------------------------------------*/ /* 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.
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);
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; }
#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.
Scheme examples from web such as cookbook.scheme.org, schemers.org....
Find first occurrence of an element in a list
(define (list-index fn list) (let iter ((list list) (index 0)) (if (null? list) -1 (let ((item (car list))) (if (fn item) index (iter (cdr list) (+ index 1)) ) ) ) ) )
Remove duplicate (repeat) entries from a list which are adjacent to each other
(define (delete-adjacent-duplicates xs) (let loop ((prev-pair #f) (xs xs) (new-list '())) (if (null? xs) (reverse new-list) (loop xs (cdr xs) (let ((x (car xs))) (if (and prev-pair (equal? x (car prev-pair))) new-list (cons x new-list) ) ) ) ) ) )
Find substring in string: this will work only is (char?) is defined.
(define (string-find haystack needle . rest) (let ((start (if (null? rest) 0 (car rest)))) (let* ((haystack-len (string-length haystack)) (needle-len (string-length needle)) (start 0)) (let loop ((h-index start) (n-index 0)) (let ((h-char (string-ref haystack h-index)) (n-char (string-ref needle n-index))) (if (char=? h-char n-char) (if (= (+ n-index 1) needle-len) (+ (- h-index needle-len) 1) (loop (+ h-index 1) (+ n-index 1)) ) (if (= (+ h-index 1) haystack-len) #f (loop (+ h-index 1) 0) ) ) ) ) ) ) )
(define (list? x) (if (equal? (length x) 0) #f) (if (> (length x) 0) #t) )
Examples from stackoverflow.com/ ... /searching-and-replacing-n-element-on-list-scheme: the keyword list has been replaced with xlst.
(define (find-replace a b xlst) (cond ;Start with a list. If it's empty, leave it ((null? xlst) '()) ;If the first element is a list, call function recursively. If the first ;element is equal to what your searching for, cons the replacement onto a ;recursive call of your function on the rest of the list...keep searching ((list? (car xlst)) (cons (find-replace a b (car xlst)) (find-replace a b (cdr xlst))) ) ((eq? (car xlst) a) (cons b (find-replace a b (cdr xlst)))) ;If none of the earlier conditions are true, cons the first element on to ;a recursive call of your function for the rest of the list (else (cons (car xlst) (find-replace a b (cdr xlst))) ) ) )
(define atom? (lambda (x) (and (not (pair? x)) (not (null? x))) ) )
Substitute every occurrence of old with an occurrence of new. Note that this code will work only if (atom?) is defined which is not the case in all Scheme implementations.
(define subst-lst (lambda (new old l) (cond ((null? l) (quote ())) ((atom? (car l)) (cond ((eq? (car l) old) (cons new (subst new old (cdr l))) ) (else (cons (car l) (subst new old (cdr l))) ) ) ) (else (cons (subst new old (car l)) (subst new old (cdr l))) ) ) ) )
(define (delete-n list n) (if (= n 0) (cdr list) (cons (car list) (delete-n (cdr list) (- n 1))) ) ) (define (insert-n list item n) (if (= n 0) (cons item list) (cons (car list) (insert-n (cdr list) item (- n 1))) ) ) (define (list-nth list n) (if (= n 0) (car list) (list-nth (cdr list) (- n 1)) ) ) (define (replace-nth list n item) (if (= n 0) (cons item (cdr list)) (cons (car list) (replace-nth (cdr list) (- n 1) item)) ) ) (define (swap-item list m n) (let ( (a (list-nth list m)) (b (list-nth list n)) ) ( replace-nth (replace-nth list m b) n a ) ) ) Examples: (swap-item (list 1 2 3 6) 2 3) (replace-nth (list 3 2 9 2) 2 8) (delete-n (list 1 2 3 4 5) 2) (insert-n (list 1 2 3 4 5) 8 2) (list-nth (list 1 2 3 4 5) 3)
From the Book: Concrete Abstractions - An Introduction to Computer Science Using Scheme
(define length (lambda (lst) (if (null? lst) 0 (+ 1 (length (cdr lst))) ) ) )
Procedure that selects those elements of a given list that satisfy a given predicate:
(define filter (lambda (ok? lst) (cond ((null? lst) '()) ((ok? (car lst)) (cons (car lst) (filter ok? (cdr lst))) ) (else (filter ok? (cdr lst))) ) ) )
If an UDF is interpreted which resulted in error, a fresh FLUENT session is needed to compile the UDF.
Accessing FLUENT from Python
Python Code to create Summary of a FLUENT Case File
Most of the programs such as ANSYS FLUENT and STAR-CCM+ have a well-defined structure to report summary of the set-up file. This Python code can be used to summary the lines containing specific keyword. The code has been tested on this sample text file.
Another version of Python codes containing the functions to summarize various types of boundary conditions are in this code. You can check how many shadow zones are not coupled, how many walls have Convective boundary conditions...
Similarly, the classes and functions defined in all Python script files stored in a folder and its subfolders can be summarized using this code.
Python Library for Fluid Mechanics: A library is available at github.com/CalebBell/fluids. The installation method is explained in the Readme file. An alternate method to use all the functions available in 'fluids' library is described below. Once source code is downloaded, this folder needs to be copied in your working directory.
import sys sys.path.append('fluids') import fluids nRe = 5000 RRH = 0.002 fricFac = fluids.friction.Colebrook(nRe, RRH) print("\n Friction factor - Colebrook formula: {0:8.3f}".format(fricFac),'\n')
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}] }
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); }
// 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"); x = $$Position[0] y = $$Position[1] uFF_1.setDefinition("sqrt(x*x + y*y)"); } }
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()
Print mass flow rate, area and area-average velocity on single line: here 'front' is the name of the boundary.
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
Create a pressure contour on PlaneYZ created earlier.
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_HighTI_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 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 # ---------------------------------------------------------------------+ Set Boundary Conditions and Solver Parameters 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
Set Boundary Conditions and Solver Parameters
Post-processing statements in PERL
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]
DOS Scripts: Batch Scripting for Windows
'DOS' (the Disk Operating System) is used to describe cmd (ther command terminal). 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. echo. prints an empty (blank) lines.
Colour of Fonts and Terminal Window: "colour bg_colur fg_colour" is used to set the font (foreground) and terminal window (background) colours. Colours are hexadecimal numbers as per the table below:
Command: "colour 70" (without double quotes) shall change the appearance of terminal to white background and black fonts.
Get User Input while Running a Batch Script: set /p "choice= Choose Option (1: ANSYS, 2: STAR, 3: Both -- ". Note that the space after = is important and %choice% can be used as a parameter to another command or conditional operator say IF-block.
Run multiple commands one after another in DOS Terminal- Conditional Execution: Linux and Powershell use semi-colon ; to concatenate commands (similar but not exactly same as & described below). Use of semi-colon executes all commands in the chain irrespective of success or failure in each command. && and || works in Powershell as described below.
Examples:
Global and Local Scope of Variables: By default, variables are global for entire batch script. SET LOCAL ... END LOCAL block can be used to make variables local in scope.
File parsing consists of reading the output, string, or file content, and then breaking it into individual lines of text and parsing each line into zero or more tokens.
Escape Character:
To display an exclamation mark (!) in batch scripts, wrap the word or phrase in double quotes followed by a caret before the exclamation mark ("Hello World^!"). Alternatively, a double caret (^^) can be used without the need for double quotes (Hello World^^!).
To display a pipe (|), ampersand (&) or redirection character (< or >) when you are using echo, use a caret (^) immediately before that character. For example, ^|, ^&, ^>, or ^<. To display a caret, type two carets in succession (^^).
Arithmetic Operations and Expressions:
Create Arrays and Lists
set "n = 0" :arrayLength if defined Ar[%n%] ( call echo %%Ar[%n%]%% set /a "n = n + 1" GOTO :arrayLength ) echo "The length of the array is" %n%
findstr [/b] [/e] [/l | /r] [/s] [/i] [/x] [/v] [/n] [/m] [/o] [/p] [/f:<file>:] [/c:<string>] [/g:<file>:] [/d:<dirlist>] [/a:<colorattribute>] [/off[line]] <strings> [<drive>:][<path>]<filename>[ ...] ---Options--- /b: Matches the text pattern if it is at the beginning of a line. /e: Matches the text pattern if it is at the end of a line. /l: Processes search strings literally. /r: Processes search strings as regular expressions. This is the default setting. /s: Searches the current directory and all subdirectories. /i: Ignores the case of the characters when searching for the string. /x: Prints lines that match exactly. /v: Prints only lines that don't contain a match. /n: Prints the line number of each line that matches. /m: Prints only the file name if a file contains a match. /o: Prints character offset before each matching line. /p: Skips files with non-printable characters. /off[line]: Does not skip files that have the offline attribute set. /f:<file>: Gets a file list from the specified file.
Example: To find all occurrences of lines that begin with DEFGH and are preceded by zero or more spaces, and to display the line number where each occurrence is found: findstr /b /n /r /c:^ *DEFGH *.txt
Example: To search for 'hello' or 'there' in file List.txt: findstr hello there x.y, To search for "Batch Script" in file UserGuide.txt, type: findstr /c:"Batch Script" UserGuide.txt
/c:<string>: Uses the specified text as a literal search string. /g:<file>: Gets search strings from the specified file. /d:<dirlist>: Searches the specified list of directories. Each directory must be separated with a semicolon (;), for example dir1;dir2;dir3. /a:<colorattribute> - Specifies color attributes with two hexadecimal digits. Type color /? for additional information. <strings> - Specifies the text to search for in filename. Required. [\<drive>:][<path>]<filename>[...] - Specifies the location and file or files to search. At least one file name is required. /?: Displays Help at the command prompt.
String Concatenation: Simply type the strings or variable like a sentence. E.g. echo This is String Concatenation, set str=%str1% %str2% %str3% - note NO space between 'str' and '='. Mid-string and sub-strings are created with :~ operator such as echo %str:~5,8% shall display characters 5 to 8 in string 'str'. set stg=%stg:~-5% shall use 5 character from the right (end of the string). Convert a string into number or evaluate an expression: set /A x = 10.
Delayed Expansion: In a command block ( ... ), all % variables are expanded before the block gets executed. !var_name! is used for delayed expansion.
Loops in Batch Scripts: To process a file: The arguments within brackets should be used without bracket - for example ["options"] should be replaced with something like "skip=10 tokens=5 delims=" where default delimiter for strings is a space or TAB. Almost any character can be used as a delimiter, but they are case sensitive. SKIP will skip processing a number of lines from the beginning of the file including empty lines, but after the SKIP is complete, FOR /F ignores (does not iterate) empty lines. It is recommended to always place delims as the last option before the closing quotation. File names with spaces have to be surrounded in "quotes" which have to be escaped using ^ such as ^"c:\Program Files\*.txt^"
FOR /F ["options"] %%var IN (filename) DO ( command )
FOR /F ["options"] %%var IN ("Text String") DO ( command )
FOR /F ["options"] %%var IN ('command to run') DO ( command echo Press any key to exit . . . pause>nul )
EXAMPLES
Loops and Conditional Operators
FOR /F "tokens=1,3 delims=," %%G IN (file.txt) DO @echo %%G %%H ≡ FOR /F "tokens=1,2,3 delims=," %%G IN (file.txt) DO @echo %%G %%I. for /f eol=; tokens=2,3* ... ignores any line starting with character semi-colon. This method can be used to ignore comments.
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 ) echo Press any key to exit . . . pause>nul ) 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: Check if a file or directory exists
@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
For if-else loops: both the closing and opening parentheses for else block should be on same line. That is ') else (' otherwise you will get an error: "else is not recognized as an internal or external command, operable program, or bath file".
find: Searches for a string of text in a file or files, and displays lines of text that contain the specified string
Find Total Number of Occurrences: The example below counts the total number of e-mail ID by counting @ in the file Email.txt
set "count=0" for /F %N in ('find /C "@" ^< "Email.txt"') do ( set "count=%N" ) echo %count%
Sort: Reads input, sorts data, and writes the results to the screen, to a file, or to another device. find /i "userid" Emp*.txt | sort.
Multiline comments: ;' ... ... '
Substring: subStr = ${str:5:3} where 5 is the starting point and 3 is the length of the string. Date can be parsed using Y, m, d, H, M and S characters. echo `date +%Y` or day = `date +%d`
String Concatenation a='Shell' b='Script' c="${a} ${b}" echo "${c}" -- Output would be "Shell Script".
Shell Parameter Expansion: Unlike in DOS, instead of '%' character, the ‘$’ character is used for parameter expansion, command substitution, or arithmetic expansion. If parameter is ‘@’ or ‘*’, the result is length positional parameters beginning at specified offset that is ${@:5} shall start at fifth position. ${#parameter} - the '#' or hash parameter expands into the length of the parameter. Other hash and double hash expansions are ${parameter#string} and ${parameter##string}: The 'string' is expanded to produce a pattern.
filename=$(basename "$1") name="${filename%.*}" # '##' parameter expansion operator extn="${filename##*.}" echo "File $name has extension $extn" echo "${#name}"
new_name="$name"_new."$extn" cp $1 $new_name
Read Files
fileName = 'List.txt' while read line; do echo $line done < $fileName
To print a folder size in specific format: du -c -s Documents/ | tail -1 | awk '{printf "\n Folder size is %.4f MB\n", ($1/1024)}' or du -c -s Documents/ | tail -1 | awk '{printf "\n Folder size is %.4f GB\n", ($1/1024^2)}' du prints file size in kB.
xdu() { du -c -s "$1" | tail -1 | awk '{printf "\n Folder size is %.4f GB\n", ($1/1024^2)}' }
Install a package (program): sudo apt install okular
Uninstall a package excluding dependent packages: sudo apt remove okular
Uninstall a package including dependent packages: sudo apt remove --auto-remove okular
Uninstall a package including configuration and dependent packages: sudo apt purge okular
Uninstall everything related to a package (recommended before reinstalling a package): sudo apt purge --auto-remove okular
Before running any of the command dealing with file copy, remove, delete - make sure to back-up your data.
D A N G E R .:^~!DDDDD!~^:. .~?YDDDDDDDDDDDDDY?!: .?DDDDDDDDDDDDDDDDDDDDD?: :YDDDDDDDDDDDDDDDDDDDDDDDD: ?DDDDDDDDDDDDDDDDDDDDDDDDD? DDDDDJ~^^~?DDDDDY!^^~DDDDD! \JDDY Q YDDDD: Q ?DD? DDD~. .~DDDDDD. .^YDD `YDDDYYDDDD YDDYYYDDY ^?YDDDDDD !DDDDDY? .~D~: DYY?DDDDD?YY! .^!~. .DDDDJ!. ||JDDDDDJ|| ^?DDDD DDDDDD?!^:. .^~DYDDDDD DDDDY??JYDDDDDJD~:. .:^!?YDDDDY?D?YDDDD :^!?JDDDYJYDDDY?!^: .^DYDDDDDDDYD^. .^DJDDDD?!:.^!JDDDDJ!^. :~!D??JYDDDYD^. .^DYDDDDJ?D!~^. !DDDDDDDDDD^ ^DDDDDDDDDD DDJDDDD ~DDDDY?
Note: All the commands and shell scripts mentioned here have been tested on Ubuntu 20.04 on Lenovo G50-45 x86_64 with GNOME version 3.36.8. Find or list all the files in current directory and sub-directrories modified in last 30 days. For any other directory, replace . with path of that folder: find . -mtime -90 -ls > toCopyBackup.txt --Note that 'ls' is interpreted as "ls -dils" which lists the complete details of each file including the size, owner, last modified date... To list only the full relative path of desired files: find . -mtime -90 > toCopyBackup.txt --Numeric arguments such as '90' here can be specified as: +n - for > n, -n for < n and n for exactly n.
The utility 'find' by default shall print the names of the folder (as folder are a type of file). To prevent printing the folder names, use: find . -mtime -90 -type f > toCopyBackup.txt.
Find and recursively copy all the files in current directory and sub-directrories modified in last 10 days (precisely 10 * 24 hours and not calendar days). Keep the source directory in parent folder to pwd (where this command is run) else you would get warning the files aleardy exist in backUpFolder. find . -mtime -10 -exec cp -r {} ../backUpFolder \; To exclude listing from a folder 'excludeFolder': find . -mtime -90 -not -path "./excludeFolder/*" > toCopyBackup.txt
What if a folder of same name already exist in destination folder ../backUpFolder? It (the folder) shall be overwritten and you may lose existing data. Use -n that is --no-clobber option which instructs cp to not overwrite an existing file (overrides a previous -i option). Thus it will be: find . -mtime -10 -exec cp -rn {} ../backUpFolder \;
If you want to specify a date: cp -rn `find . -type f -newermt '27 Apr 2023'` ../backUpFolder --- this method uses -newerXY option for command find where X = m and Y = t in this case.
Search for files modified between two dates find Documents/ -type f -mtime -90 ! -mtime -15 [Prints file modified between 90 to 15 days before today]. Next example prints only the file having rounded-up value of size ≥ 2 MB: find Documents/ -type f -size 2M -mtime -90 ! -mtime -5. Next example prints only the total sum: find Documents/ -type f -mtime -20 ! -mtime -10 -printf "%s\\n" | awk '{s = s+$1} END {printf "%.2f MB \n", s/1024^2}'. For files modified between two particular dates: find Documents/ -type f -newermt '10 Apr 2023' ! -newermt '10 Apr 2023'. To print folders, change -type f to -type d.
Search of folder modified between two dates and then print the size of files modified within same period. Remove -maxdepth 1 if you want to print the information for every sub-folder inside main or parent or root folder specified by variable dirName.
clear d1='10 Apr 2023' d2='30 Apr 2023' dirName='Documents' for dr in `find $dirName -maxdepth 1 -type d -newermt "$d1" ! -newermt "$d2"`; do echo Processing $dr echo "---------------------------------------------------------------" fs=0 for ss in `find $dr -type f -newermt "$d1" ! -newermt "$d2" -printf "%s\\n"`; do #In Bash shell, only integer arithmetic can be performed fs=$(((ss + fs)/1024)) done echo Total size of files is approx. $fs MB echo $'===============================================================\n' done
Incremental Back-up of Files: Use the methods explained earlier to save the names of the desired files (based on modification date, size, type...) to a text file. Use the following shell script (save the content in a file say backUp.sh) and run it in terminal. Note that it dumps all the files listed in cat toCopyBackup.txt into target folder irrespective the absolute path of source files.
TARGET_PATH="./BackUp/" #Note there shouldn't be any space before or after = clear if [ -d "$TARGET_PATH" ]; then for file in `cat toCopyBackup.txt`; do cp "$file" $TARGET_PATH; filePath=(${file//// }) echo Copied file ${filePath[-1]} done else echo Target directory $TARGET_PATH does not exist! fi
Copy a Folder Structure: Before creating an incremental copy (added and modfified files or folders), one may first try to check the folder structure and update the missing or modified folders using following shell script. Note that the script checks for existence of only the TARGET folder and not the SOURCE folder.
clear SOURCE_PATH="./Payment/" TARGET_PATH="./back_Up/" dirList='folderStruct.txt' find $SOURCE_PATH -mtime -90 -type d > "$dirList" if [ ! -d "$TARGET_PATH" ]; then echo Target directory $TARGET_PATH does not exist! mkdir $TARGET_PATH echo Target directory $TARGET_PATH created! echo "==============================================================" fi for file in $(cat $dirList); do echo Processing folder $file if [ ! $file = "." ]; then newPath=$TARGET_PATH${file:2:${#file}} if [ ! -d "$newPath" ]; then echo Target Folder: $newPath echo TARGET Folder Does not Exist, Creating it mkdir $newPath; echo -- Folder $newPath created echo "--------------------------------------------------------------" echo else echo "Target folder already exists, no new folder created!" echo "--------------------------------------------------------------" fi fi done
Sometimes it may be required to copy the source files into target folder structure where only the root folder may change. For example: ./dir1/file1.pdf needs to be copied or moved to /home/user/backUp/dir1/file.pdf. This is not strictly a data back-up process as it may overwrite existing files. The following script works but it has not been tested for all possible scenarios and user inputs.
find . -mtime -30 -ls > toCopyBackup.txt TARGET_PATH="./BackUp/" clear if [ -d "$TARGET_PATH" ]; then for file in `cat toCopyBackup.txt`; do filePath=(${file//// }) #Get length of an array filePath np=${#filePath[@]} #Get relative path of file trimming last characters defined by file name nf=${#filePath[-1]} rPath=${file::-nf} echo Relative path of SOURCE file is: $rPath #Check if relative path starts with a . stg=${rPath:0:2} e=${#rPath} if [ $stg == "./" ]; then newPath=$TARGET_PATH${rPath:2:e} if [ ! -d "$newPath" ]; then echo Target Folder: $newPath echo "----------------------------------------" echo TARGET Folder Does not Exist, Creating it mkdir $newPath; echo New Folder $newPath created echo "----------------------------------------" echo fi cp "$file" $newPath; filePath=(${file//// }) echo Copied file ${filePath[-1]} to $newPath echo "==========================================" fi done else echo Target directory $TARGET_PATH does not exist! fi
AWK Programming: Due to some inherent limitations in Bash shell (such as only integer arithmetic operations, less number of format styles available...) AWK programming (named after Alfred Aho, Peter Weinberger, and Brian Kernighan) needs to be used in conjuction with shell scripting. It can be used to scan files line by line, split each input line into fields or tokens, compare input lines and fields to patterns, performing specified actions on matching lines...
To print the first and third columns: $ awk '{print $1 "\t" $3}' empList.txt, To match all entries with letter or string 'strg': $ awk '/strg/ {print $0}' empList.txt, ls -l | awk '{print $1}': print the first column of output from command ls -l. To run multiple commands, separate them with the vertical bar '|' known as pipe.
Field Separator: Space is the default field separator. OFS (Output Field Separator) variable is used to specify custom field separator. date | awk 'OFS="/" {print$2,$3,$6}' shall give ouput as Mar/15/2022. Input field separator is specified by option -F. Date command produces output: Saturday 06 May 2023 09:58:31 AM IST, date | awk -F: '{print $1}' will result in Saturday 06 May 2023 09.
Pre- and Post-Processing: shell scripts are a set of commands. They come into action immediately. To delay or add operations before or after the actual AWK action, BEGIN and END options are available. As expected, BEGIN rule is executed once before any text processing starts whereas END rule is executed after all processing has completed. Example: date | awk -F: 'BEGIN {printf "%s", "Output of Date split with FS : "} {print $1}'
Read AWK Script from a File: awk -F: -f awkScript.sh empList.txt
Pattern Matching: The search for string can be made more specific by adding pattern such as start of line, end of a string... awk '/^KUMAR/ {print $0}' empList.txt mathes lines that start with KUMAR.
Monitor Usage of a Remote Server (HPC Cluster)
An enhancement over DOS shell, this is analogous to linux Bash where files are stored with extension PS1. The commands are called cmdlets and variables are assigned with prefixing $. $loc = Get-Location - here Get-Location is equivalent to pwd. $HOME: Represents the full path of the user's home directory. Powershell codes or scripts can be run from legacy cmd terminal using the command 'powershell'. echo ≡ Write-Host, variable; $x = 1.0
From Microsoft Website: "PowerShell is a cross-platform task automation solution made up of a command-line shell, a scripting language, and a configuration management framework. PowerShell runs on Windows, Linux, and macOS."
Powershelll commands are in the format Verb-Object or Action-Method such as Write-Host where Write is an action and Host is object. Frequently used Verbs or Actions are: Copy, Convert, Clear, Get, Import, List, Measure, Move, Out, New, Rename, Remove, Restart, Resume, Select, Set, Stop, Suspend, Where, Write, Update ...
Frequently used Objects are: ChildItem, Command, Content, History, Host, Item, Location, Member, Object, Transcript, Service...
File files in a folder based on size and last modified date
Get-ChildItem -Path C:\Users\Data -Recurse -Include *.DOC | Where-Object -FilterScript { ($_.LastWriteTime -gt '2023-01-01') -and ($_.Length -ge 1mb) -and ($_.Length -le 5mb) }
Get total numer of lines in a file: $nL = (get-content "C:\Users\EmpList.dat" | measure-object).count
Get the size of all first-level subfolders in the specified directory, reference: woshub.com/powershell-get-folder-sizes - save this block of code in a file with extension PS1 and right click to use the option "Run in Powershell".
$targetFolder='C:\Users\Data' Get-ChildItem -force $targetFolder -ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | ForEach-Object { $len = 0 Get-ChildItem -recurse -force $_.fullname -ErrorAction ` SilentlyContinue | ForEach-Object { $len = $len + $_.length } $_.fullname, "`t | `t", '{0:N2} GB' -f ($len / 1Gb) Read-Host -Prompt "Press Any Key to Exit..." }
Function to get file size of a folder, reference: woshub.com/powershell-get-folder-sizes. The function can be used as GetFolderSize($targetFolder).
function GetFolderSize { [CmdletBinding()] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] $Path ) if((Test-Path $Path) -and (Get-Item $Path).PSIsContainer ) { $Measure = Get-ChildItem $Path -Recurse -Force -ErrorAction ` SilentlyContinue | Measure-Object -Property Length -Sum $Sum = '{0:N2}' -f ($Measure.Sum / 1Gb) [PSCustomObject]@{ "Path" = $Path Size($Gb)" = $Sum } } Write-Host -NoNewLine 'Press any key to exit...'; #Following line is optional $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); }
Arrays and Lists in Powershell
$data = @( 'This' 'is' 'Sample' 'Array' )
Range Operator: $C = 5..8. Iterate over elements of an array.
foreach ($e in $a) { $x = $e * $e }
The following table is being developed only to list the activity and typical method. Before jumping to the command, read the manual pages to unserstand the complete syntax.
Additional Explanation:
03: Network nodes have three identities: Hostname, logical address, and physical address. When you connect to a public or open network, the MAC address gets exposed. Spoofing or changing your MAC address keeps your ID hidden from other users.
10: Network connection occur through ports - these are not any physical devices but a standard to identify the type of connection. HTTP (Port 80) or HTTPS (Port 443). Foreign Address is the IP adress of the remote machine to which your machine is connected with. Local address is IP address of host with port number.
Good Scripting and Programming Practices
Examples: First comment after function definition is used as Documentation String in MATLAB, Similarly, in Python first block of comments in the body of a method or function (those within triple quotes ''' ... ''') are used as Documentation String for that functions which can be printed by command help(funcName).
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