【问题标题】:In Scheme language, how to assign a variable counter in an inner do-loop connected with the outer do-loop?在Scheme语言中,如何在与外部do-loop相连的内部do-loop中分配一个变量counter?
【发布时间】:2017-12-17 22:53:58
【问题描述】:

我想在 Ansys Fluent 中读取 10 个案例文件,每个案例文件有 10 个要读取的数据文件。 Ansys Fluent 使用 Scheme 编程语言。 我必须设法在此处 (Evaluating a floating point variable in Scheme language) 和此处的代码中找到个别问题的答案 (How to increase counter in a do-loop within Scheme language?),但是在收集个人答案时,我意识到我需要一个新的计数器代码,用于通过 do-loop 读取数据文件。 这是包含其他问题的解决方案的代码:

(do ((i 10 (+ i 1))
     (j 5  (+ j 1)))
    ((>= i 20) 'my-return-value)
  (ti-menu-load-string 
   (format #f "/file/read-case \"C:/DataProcessing/Case~a-time~a-sec/test/Case~a-time~a-sec.cas\"" i j i j))
  (do ((datafilenum 5.100 (+ datafilenum 0.100)))
      ((>= datafilenum 6.000))
    (ti-menu-load-string (format #f "/file/read-data \"C:/DataProcessing/Case~a-time~a-sec/test/Case~a-time~a-sec-~.3f.dat\"" i j i j datafilenum))
    (ti-menu-load-string (format #f "/plot plot n \"C:/DataProcessing/Case~a-time~a-sec/test/water-vof/column-water-vof-at-~.3fs.txt\" y n n water vof y 0 1 0 16 ()" i j datafilenum))))

我在这里想要实现的是: 阅读案例文件

Case10-time5-sec.cas

然后它读取 10 个数据文件并绘制答案

Case10-time5-sec-5.100.dat
Case10-time5-sec-5.200.dat
...
Case10-time5-sec-6.000.dat

下一个循环:

Case11-time6-sec.cas

读取 10 个数据文件并绘制答案

Case11-time6-sec-6.100.dat
Case11-time6-sec-6.200.dat
...
Case11-time6-sec-7.000.dat

下一个循环...

那么,当j 在上层循环中更改值时,如何将代码中以5.100 开头的datafilenum 更改为6.1007.1007.100 等,例如j.100 和将此值附加到导出的文本文件column-water-vof-at-~.3fs.txt。而且,当然可以将6.000 更改为7.0008.000...,类似于j+1.000?这让我很困惑,因为我通过反复试验来实现它!

【问题讨论】:

    标签: variables scheme counter do-loops


    【解决方案1】:

    如何获取号码。如果 j 为 6,而您想要 6.1,则使用标准数学运算将 1/10 添加到其中。

    (define j 6)
    (+ j 1/10)
    ; ==> 61/10 (aka 6.1 exact)
    

    format 函数不是标准的,因此有许多相互竞争的实现。在SRFI-48 Intermediate Format Strings 中,您可以这样做以使61/10 显示为6.100

    (format #f "~0,3F" (+ j 1/10)) 
    ; ==> "6.100"
    

    所以把它们放在一起:

    (do ((i 10 (+ i 1))
         (j 5  (+ j 1)))
        ((>= i 20))
      (ti-menu-load-string 
       (format #f "/file/read-case \"C:/DataProcessing/Case~a-time~a-sec/test/Case~a-time~a-sec.cas\"" i j i j))
      (do ((datafilenum (+ j 1/10) (+ datafilenum 1/10)))
          ((>= datafilenum (+ j 1)))
        (ti-menu-load-string (format #f "/file/read-data \"C:/DataProcessing/Case~a-time~a-sec/test/Case~a-time~a-sec-~0,3F.dat\"" i j i j datafilenum))
        (ti-menu-load-string (format #f "/plot plot n \"C:/DataProcessing/Case~a-time~a-sec/test/water-vof/column-water-vof-at-~0,3Fs.txt\" y n n water vof y 0 1 0 16 ()" i j datafilenum))))
    

    如果这不起作用,您需要编辑您正在使用的实现。例如。 Racket 有 format,这是不同的,但它也支持 SRFI-48,所以我用 (require srfi/48) 测试了这个。我更喜欢使用 SRFI 而不是实现版本,因为以后移植到不同的实现或 RNRS 修订版会更容易。

    【讨论】:

    • 由于某种原因,我收到以下错误:Error: eval: unbound variable Error Object: 1/10 可能是什么问题?
    • 1/10(/ 1 10)替换时错误解决
    • @Emma 您的方案可能没有完整的数字塔。如果它是 R5RS 或更早版本,则不需要,因为“只有浮点数的方案很有用”。 1/10 是一个数字文字,就像支持有理数的 Scheme 中的 5 一样。您使用的是哪种实现方式?
    • 我找不到 ANSYS Fluent 使用的 Scheme 语言的实现!
    【解决方案2】:

    Ansys Fluent 没有明确的方案标准,也没有完整的数字塔。使用“MIT 方案 3 和 4 的混合物”。

    当循环遍历浮点数时,总是会因为任意精度而出现问题,尤其是在将这些数字放入字符串时。 正如您已经提到的,Fluent 不直接支持精确算术的小数。

    你会在某个时候得到这样的结果

    Case11-time6-sec-6.100.dat
    Case11-time6-sec-6.200.dat
    ...
    Case11-time6-sec-6.499987987.dat
    ...
    Case11-time6-sec-7.000.dat
    

    到目前为止,我想出的最佳解决方案是编写一个函数来评估一对,这是 Sheme 中的一种原生且快速的结构,其中包含一个数字和一个基于舍入的相应字符串。

    如果您仍然关注此主题,我可以扩展此答案并提供更多详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多