Search code examples
schemesimulationfluid-dynamics

Replacing number by variable or loop in Scheme (Fluent) doesn't work


I'm using the ANSYS Fluent program for CFD simulations. This program allows some partial automation of the simulation setup using a so-called Journal File, and I just came to know that this Journal File is written in Scheme. Unfortunately I never even heard of Scheme, I just know it's a Lisp dialect (which I also know nothing of).

I'm trying to automate some boring tasks by using a loop to automatically set a bunch of parameters to my simulation. If I run this command from Fluent's command interface:

(cx-gui-do cx-set-list-selections "Boundary Conditions*Table1*List2(Zone)" '( 4))

it does what's expected (it selects item 4 from a list). However, if I stick that into a loop:

(do ((z 4 (+ z 1))) ((> z 27))
  (cx-gui-do cx-set-list-selections "Boundary Conditions*Table1*List2(Zone)" '( z))
)

nothing happens and the program prints a #f in the command window. Then, if I do:

(define z 4)
(cx-gui-do cx-set-list-selections "Boundary Conditions*Table1*List2(Zone)" '( z))

nothing happens at all.

Why does replacing the number 4 by a variable doesn't work? And why does the loop returns a #f?


Solution

  • The problem here I think comes from '(z) part. This tick ' is called quote and is a short hand for (quote ...) call. It does not create a list, it's for returning something without evaluation. In your case if you pass (4) instead of '(4) you will get an error, because Scheme will try to evaluate it, and there is no function called 4. It's ok to use quote when you pass some static data (variable or list) as in your first example. But when you use '(z), this list will be passed to cx-gui-do as is, variable z will not be substituted here, it will stay as a symbol z.

    It might sound a bit misterious, so to make this short - when you dynamically create a list, you have to use list function. This should work:

    (do ((z 4 (+ 1 z)))
        ((> z 27))
      (cx-gui-do cx-set-list-selections "Boundary Conditions*Table1*List2(Zone)" (list z)))
    

    EDIT: #f you see when you use do loop is a return value. Every time you evaluate something in Schemes REPL / prompt / Command Interface, return value is printed (ie if you try (+ 1 20) you should get as 21 printed). For do loop you have to provide return expression. If not, it's unspecified what do loop will return (so in some implementations it might be #f meaning false, in other () aka NIL). Nothing wrong is happening there :)