ubuntu下CGNS套件的编译安装。

CGNS(CFD General Notation System)是什么就不废话了,搞CFD编程的应该有所了解

这里给出CGNS lib 和 CGNS Tools的编译安装方法。

(以下方法在ubuntu 9.04上完成。)

Part A 安装CGNS lib

1.下载源代码包

wget http://nchc.dl.sourceforge.net/sourceforge/cgns/cgnslib_2.5-3.tar.gz

2.解压缩

tar cgnslib_2.5-3.tar.gz
cd cgnslib_2.5

3.配置

./configure --enable-gcc

4.编译

make

5.安装

sudo make install
cd ..
注1:前几天惊喜的发现,在ubuntu9.04的源里面居然有cgns lib。如果不需要cgns tools的话可以直接安装源里的cgns lib。从源里安装命令如下
sudo apt-get install libcgns2 libcgns-dev

注2:在第三步配置时需要注意加选项 --enable-gcc。如果没有加,就不能用ifort、gfortran等进行编译时会报错如下:

 

/usr/local/lib/libcgns.a(cgnslib.o): In function `cg_version':
cgnslib.c:(.text+0x7dc): undefined reference to `__xtol'

/usr/local/lib/libcgns.a(cgnslib.o): In function `cg_field_read':
cgnslib.c:(.text+0x38f0): undefined reference to `__xtol'

cgnslib.c:(.text+0x39c4): undefined reference to `__xtol'
/usr/local/lib/libcgns.a(cgnslib.o): In function `cg_conn_read'
:
cgnslib.c:(.text+0x4c05): undefined reference to `__xtol'
cgnslib.c:(.text+0x4c5d): undefined reference to `__xtol'

这个错误折磨了我好几天。

Part B 安装CGNS Tools

由于编译时需要用到Part A中生成的make文件,所以最好接着Part A做。就是在做完Part A之后不要删除 cgnslib_2.5目录

为了编译还需要安装一些文件,命令如下:

sudo apt-get install tk-dev libglu1-mesa-dev  libxmu-dev libgl1-mesa-dev

1.下载源代码包

wget http://nchc.dl.sourceforge.net/sourceforge/cgns/cgnstools-2-5-2.tar.gz

2.解压缩

tar xvzf cgnstools-2-5-2.tar.gz
cd cgnstools

3.配置

./configure --enable-gcc

此处需要对make.defs文件修改。在文件中用下面两行替代上面两行。

TKINCS =
TKLIBS = -ltcl -ltk

TKINCS = -I/usr/include/tk
TKLIBS = -ltcl8.4 -ltk8.4 -lX11 -ldl  -lpthread -lieee -lm

注:应该只改 TKINCS = -I/usr/include/tk 就可以。

4.编译

make all

5.安装

sudo make install all

此处需要注意的是,虽然用的是 install all ,但是cgnsplot还没有安装,因此需要执行以下命令

cd cgnsplot
sudo make install
cd ..

如果没有问题的话就大功告成了。别忘了把这两个编译目录删除。

注:貌似还有一些编译好的可执行程序没有进行安装(如tools目录下的cgnslist等)。不过应该是没什么用的。

简单Fortran工程的 makefile 的模版

试着用automake生成fortran的make文件,总是搞不定。无奈只好通过google搜索,然后自己修改了一份makefile。存之……

#############################################################
#      ________________________
#     /  Makefile for Fortran  \
#     | Compile on Linux Write |
#     |  by wangbo 2009.2.14   |
#     |       2009.2.14        |
#     \        IN NUAA         /
#      ------------------------
#      \     /\  ___  /\
#       \   // \/   \/ \\
#          ((    O O    ))
#           \\ /     \ //
#            \/  | |  \/
#             |  | |  | 
#             |  | |  | 
#             |   o   | 
#             | |   | | 
#             |m|   |m| 
#############################################################
#              Globle set
# project name
PRO_NAME = hover

# FPE
FPEFLAGS = -fpe3

# output
FFLAGS = -o

# compiler
FF = ifort

# files & objects
FILES= variable.f90 main.f90 output.f90 solver.f90 timestep.f90
OBJECTS= variable.o main.o output.o solver.o timestep.o

#############################################################
#              default build
$(PRO_NAME): release
       
#############################################################
#              Clean files
clean:
        -rm -f *.o  *.mod $(PRO_NAME) d$(PRO_NAME)

#############################################################
#              Build Object file
$(OBJECTS) : $(FILES)
        $(FF) $(LFLAGS)  -c $(FILES)

#############################################################
#              Release
release : LFLAGS= -O3 $(FPEFLAGS)
release : $(OBJECTS)
        $(FF) $(LFLAGS) $(OBJECTS) $(FFLAGS) $(PRO_NAME)
        @echo -e "\033[;31m$(PRO_NAME)\033[0m : \033[33mRelease is now up2dated!\033[0m"

#############################################################
#              debug
debug : LFLAGS = -O0 -g $(FPEFLAGS)
debug : $(OBJECTS)
        $(FF) -g $(LFLAGS) $(OBJECTS) $(FFLAGS) d$(PRO_NAME)
        @echo -e "\033[;31m$(PRO_NAME)\033[0m : \033[33mDebug is now up2dated!\033[0m"

#############################################################
#                clean && debug
#               clean && release
cdebug : clean debug
crelease : clean $(PRO_NAME)

#############################################################
#                make tags
tag : $(FILES)
        rm -f tags
        ctags -R *90
cscope : $(FILES)
        rm -f cscope.*
        cscope -Rbq *.f90
 

 

 

 

程序计算完成的短信提醒

你是否有过这样的经历:程序不知道什么时候运算完,因此你不得不频繁的查看运行状态。或者不知道程序会在什么时候出现错误,因此溜号的时候总是提心吊胆。

这篇文章就是用来帮助你解决这个问题的。前提是你是中国移动用户,并且那个让你牵肠挂肚的的电脑可以上网。

在我的工作中,CFD(包括很多科学运算)程序需要运行很长的时间,完成时间难以确定。因此如果可以在计算完成后进行短信提醒则会起到很大的帮助。

通过google搜索,我发现可以采用 程序->脚本->电子邮件->短信 这样的流程来完成这一功能。

1.电子邮件->短信

    这一步可以采用139的信箱来完成。如果你是移动的用户就可以免费注册一个139信箱(mail.139.com)。这个信箱在收到邮件后会给注册的手机发送提醒短信,内容包括发件人和邮件标题。注册后邮箱名为 "手机号码@139.com"  例如 1391302****@139.com。

2.命令(脚本)->电子邮件

    对我来说这一步是最麻烦的(对于有些可以直接用命令行发送邮件的电脑来说这一步就极其简单了),我参考了网上的文章,用Gmail账户发送邮件。

主要参考http://www.61dh.com/blog/2009/01/ubuntu.html

1. 安装所需的软件

$ sudo apt-get install msmtp

$ sudo apt-get install nail

2. 安装Gamil的Thawte证书

$ mkdir -p ~/etc/.certs

$ chmod 0700 ~/etc/.certs

$ cd ~/etc/.certs

$ wget https://www.verisign.com/support/thawte-roots.zip --no-check-certificate

$ unzip thawte-roots.zip

$ cp Thawte\ Server\ Roots/ThawtePremiumServerCA_b64.txt ThawtePremiumServerCA.crt

3. 配置msmtp,我是用Vim打开的,原文使用gedit

$ gedit ~/.msmtprc

或者:

$ vim ~/.msmtprc

这将打开一个空白文档,你只需把下面大写部分改为你的个人设置后粘帖即可。因为我只想使用gmail account,所以我没有设置isp account,并且把account default改为gmail。 别忘了改“USER”!!!

# config options: http://msmtp.sourceforge.net/doc/msmtp.html#A-user-configuration-file

defaults

logfile /tmp/msmtp.log

# isp account

account isp

auth login

host SMTP.YOURISP.COM

port 25

user YOURNAME@ISP.COM

from YOURNAME@ISP.COM

password *****

# gmail account

account gmail

auth on

host smtp.gmail.com

port 587

user YOURNAME@gmail.com

password *****

from YOURNAME@gmail.com

tls on

tls_trust_file /home/USER/etc/.certs/ThawtePremiumServerCA.crt

# set default account to use (from above)

account default : isp

# 注意:我把默认改为 gmail

4. 更改msmtprc文件的许可

$ chmod 600 ~/.msmtprc

5. 配置nail,我是用Vim打开的,原文使用gedit

$ gedit ~/.mailrc

或者

$ vim ~/.mailrc

这将打开一个空白文档,你只需把下面大写部分改为你的个人设置后粘帖即可。因为我只想使用gmail account,所以我没有设置isp account。

# set smtp for nail

# ref: http://ubuntuforums.org/showpost.php...94&postcount=6

# docs: http://msmtp.sourceforge.net/doc/msm...guration-files

# isp account (default)

# $ nail -s "subject line" -a /path/file recipient@email.com < /path/body.txt

set from="YOURNAME@ISP.COM"

set sendmail="/usr/bin/msmtp"

set message-sendmail-extra-arguments="-a isp"

# gmail account

# $ nail -A gmail -s "subject line" -a /path/file recipient@email.com < /path/body.txt

account gmail {

set from="YOURNAME@gmail.com (YOURNAME)"

set sendmail="/usr/bin/msmtp"

set message-sendmail-extra-arguments="-a gmail"

}

搞定!!!

发送测试:

$ echo -e "testing email from the command line" > /tmp/test_email

$ nail -A gmail -s "gmail test" YOURNAME@gmail.com < /tmp/test_email

    完成了这个设置后建立两个文件第一个是~/etc/null 这个文件里面是所发邮件的内容。我把它设置为空内容。

    第二个文件是执行脚本/usr/local/bin/sms内容如下。请将其中的USER换为对应的用户名,1391302****@139.com改用你自己的邮箱。

#!/bin/bash
nail -A gmail -s "$1" 1391302****@139.com < /home/USER/etc/null

    完成后,请执行如下命令进行测试。如果一切顺利你可以收到一条提示你接收邮件的短信。

$sms  短信测试

3.程序->命令

    在所执行的程序中调用系统函数。这里给出对应的fortran代码

program test
    call system('sms 我是一个Fortran程序')
end program test

    其他语言也可以采用同样的方法完成这个工作。这就是我的解决办法,希望对大家有用。

 

如果你觉得你有更好地方案,请留言告诉我。

 

用Fortran在Linux终端输出彩色文字

采用彩色的文字可以给出明显的提示,增加程序的易用性(例如采用“错误:压力出现负值” 比 “错误:压力出现负值”要醒目得多)。然而Fortran无法在命令行下直接输出彩色文字,不过通过调用系统函数可以解决这一难题。

通过参考http://bbs.stupc.org/thread-16335-1-1.html 关于echo命令的详解如下:

信息来源:
akaedu@akaedu.org

格式: echo \"\\033[字背景颜色;字体颜色m字符串\\033[0m\"

例如:
echo \"\\033[41;36m something here \\033[0m\"

其中41的位置代表底色, 36的位置是代表字的颜色

那些ascii code 是对颜色调用的始末.
\\033[ ; m …… \\033[0m

字背景颜色范围:40----49
40:黑
41:深红
42:绿
43:黄色
44:蓝色
45:紫色
46:深绿
47:白色

字颜色:30-----------39
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色

===========ANSI控制码的说明
\\33[0m 关闭所有属性
\\33[1m 设置高亮度
\\33[4m 下划线
\\33[5m 闪烁
\\33[7m 反显
\\33[8m 消隐
\\33[30m -- \\33[37m 设置前景色
\\33[40m -- \\33[47m 设置背景色
\\33[nA 光标上移n行
\\33[nB 光标下移n行
\\33[nC 光标右移n行
\\33[nD 光标左移n行
\\33[y;xH设置光标位置
\\33[2J 清屏
\\33[K 清除从光标到行尾的内容
\\33[s 保存光标位置
\\33[u 恢复光标位置
\\33[?25l 隐藏光标
\\33[?25h 显示光标

给出演示 Fortran 代码如下:

program color
implicit none
character*64::title
    title='echo -e "\033[42;30m TEST \033[0m "'
    call system(trim(title))
    call system('echo -ne "\033[41;30m color \033[0m"')
    call system('echo -ne "\033[42;31m color \033[0m"')
    call system('echo -ne "\033[43;32m color \033[0m"')
    call system('echo -ne "\033[44;33m color \033[0m"')
    call system('echo -ne "\033[45;34m color \033[0m"')
    call system('echo -ne "\033[46;35m color \033[0m"')
    call system('echo -ne "\033[47;36m color \033[0m"')
    call system('echo -e "\033[40;37m color \033[0m"')

    call system('echo -ne "\033[30m color \033[0m"')
    call system('echo -ne "\033[31m color \033[0m"')
    call system('echo -ne "\033[32m color \033[0m"')
    call system('echo -ne "\033[33m color \033[0m"')
    call system('echo -ne "\033[34m color \033[0m"')
    call system('echo -ne "\033[35m color \033[0m"')
    call system('echo -ne "\033[36m color \033[0m"')
    call system('echo -e "\033[37m color \033[0m"')
stop
end program

 在ubuntu8.04.1 32bit +Intel Fortran 10 测试通过 ,测试显示"\33"可能会出现问题,因此采用“\033"。

此外,由于此方法是通过调用系统函数完成,执行效率不高,不建议在数值计算中频繁使用。

以上代码是我自己编写,如果你有更好的改进方案或者发现错误,请与我联系。

Plot3D网格文件的读写

PLot3D是一种在CFD领域很常见的格式。几乎所有的网格生成软件都支持这种格式的输出,因此搞清楚这种文件的格式的读入和输出对CFD研究人员的工作带来很大的帮助。这里给出的都是读入ASCII格式文件的代码,输出方式类似。

PLot3D的网格文件后缀名为"xyz",可能是二进制(bin)格式或者文本文件格式(ASCII)。

1.单块网格(Single Grid

 读入3维单块网格

PROGRAM PLOT3D_SINGLE
IMPLICIT NONE
CHARACTER :: BUFFER*30
INTEGER :: I,J,K,IMAX,JMAX,KMAX
REAL,ALLOCATABLE::MESH(:,:,:,:) !MESH存储网格的点坐标

WRITE(*,*)"Please input file name:"
READ(*,*)BUFFER
OPEN(200,FILE=TRIM(buffer))
READ(200,*) IMAX,JMAX,KMAX !获得网格尺寸
ALLOCATE(MESH(3,IMAX,JMAX,KMAX)) !划分网格所需要的内存空间
READ(200,*)      (((MESH(1,I,J,K), I=1,IMAX), J=1,JMAX), K=1,KMAX),&
                       (((MESH(2,I,J,K), I=1,IMAX), J=1,JMAX), K=1,KMAX),&
                       (((MESH(3,I,J,K), I=1,IMAX), J=1,JMAX), K=1,KMAX)
CLOSE(200)
STOP
END PROGRAM

2.多块网格(Multiple Grids

读入3维多块网格(似乎GRIDGEN读入网格时需采用这种格式的文件,你可以将其改成输出程序,所输出的网格就可以用GRIDGEN读入了)

PROGRAM PLOT3D_MULTI
IMPLICIT NONE
CHARACTER :: BUFFER*30
INTEGER :: I,J,K,IMAX,JMAX,KMAX,NMESH,N
INTEGER,ALLOCATABLE::IJK(:,:)   !IJK存储每块网格的尺寸
REAL,ALLOCATABLE::MESH(:,:,:,:,:) !MESH存储网格的点坐标

WRITE(*,*)"Please input file name:"
READ(*,*)BUFFER
OPEN(200,FILE=TRIM(buffer))
READ(200,*)NMESH !读入网格块数
ALLOCATE(IJK(3,NMESH))
READ(200,*) ((IJK(1,N),IJK(2,N),IJK(3,N)), N=1,NMESH) !获得多块网格尺寸
DO N=1,NMESH
  IMAX=MAX(IMAX,IJK(1,N))
  JMAX=MAX(IMAX,IJK(2,N))
  KMAX=MAX(IMAX,IJK(3,N))
END DO
ALLOCATE(MESH(3,IMAX,JMAX,KMAX,NMESH)) !划分网格所需要的内存空间
READ(200,*)    ((((MESH(1,I,J,K,N), I=1,IJK(1,N)), J=1,IJK(2,N)), K=1,IJK(3,N)),&
                      (((MESH(2,I,J,K,N), I=1,IJK(1,N)), J=1,IJK(2,N)), K=1,IJK(3,N)),&
                      (((MESH(3,I,J,K,N), I=1,IJK(1,N)), J=1,IJK(2,N)), K=1,IJK(3,N)),N=1,NMESH)
CLOSE(200)
STOP
END PROGRAM
 

 

以上代码是我自己编写,如果你有更好的改进方案或者发现错误,请与我联系。