ABAQUS是支持C++子程序开发的,相比于传统的Fortran,C++作为高级语言的优势不言而喻,再搭配优秀的C++程序库,使得我们的编程效率大大提高,尤其是对于熟悉C++编程的开发者,不失为一种更好的选择。
我使用的开发软件搭配是Abaqus 2022 + Visual Studio 2019 + OneAPI 2022。虽然我们使用C++进行子程序开发,但是使用Intel的OneAPI中的Fortran模块是必须的,否则在编译链接C++源程序时,会发生如下错误:
LINK: fatal error LNK1104: cannot open file “LIBIFCOREMD.LIB”
“LIBIFCOREMD.LIB” 这个库是Intel的Fortran库,所以必须要使用到OneAPI中的Fortran模块。
要特别注意Visual Studio和OneAPI版本搭配的问题,否则在安装OneAPI的时候会无报错闪退。我曾经尝试Visual Studio 2019 + OneAPI 2021,结果OneAPI安装时总是在continue后无情退出,当卸载VS后,就可以正常安装了,所以一定要注意相关软件版本的搭配,避开这些bug的折磨。
软件的安装顺序需要保证VS2019的安装在OneAPI之前,因为其安装需要依赖VS2019。
(1)Abaqus 2022安装网上有很多教程,正常安装就行;
(2)VS2019安装社区版,组件只需要勾选C++桌面开发选项;
(3)OneAPI只需要安装HPCKit中的Fortran模块。(节省磁盘空间。。)
找到abq2022.bat编辑打开。
添加如下语句:
call "C:\Program Files (x86)\Intel\oneAPI\compiler\2022.2.1\env\vars.bat" intel64 vs2019
这里给出一段测试代码,将其放在Abaqus Command命令执行目录下,如果能正常编译,说明关联没有问题。
#include <cmath>
#include <aba_for_c.h>
extern "C" void FOR_NAME(dload,DLOAD) (
double & F, // VALUE TO BE RETURNED: Magnitude of the distributed load
const int & KSTEP, // Step number
const int & KINC, // Increment number
const double(& TIME)[2], // (1) step time; (2) total time
const int & NOEL, // Element number
const int & NPT, // Load integration point number
const int & LAYER, // Layer number
const int & KSPT, // Section point number within the current layer
const double(& COORDS)[3], // Array containing the coordinates of the load integration point
const int & JLTYPE, // Load type for which this call to DLOAD is made
const char (&SNAME)[80] // Surface name
) {
F = 100;
}
编译后生成目标文件。
为了后续发挥出C++编程的优势,我们配置好第三方科学计算库,方便直接调用。这里我使用Armadillo(C++ library for linear algebra & scientific computing)。
将下载好的Armadillo文件夹里/examples/lib_win64路径下的 libopenblas.lib
复制C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64
到路径下,而libopenblas.dll
复制到C:\Windows\System32
。
当然还需要告诉VS2019 Armadillo的头文件的位置。直接将下载的Armadillo中include文件夹下的两个文件,复制到此路径C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include
下,这样VS就可以找到相关头文件了。
在VS中测试下使用效果:
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
int main() {
// construct a matrix according to given size and form of element initialisation
mat A(2, 3, fill::zeros);
// .n_rows and .n_cols are read only
cout << "A.n_rows: " << A.n_rows << endl;
cout << "A.n_cols: " << A.n_cols << endl;
system("pause");
return 0;
}
为了后续能够使用Abaqus方式编译,我们需要将此文件C:\SIMULIA\EstProducts\2022\win_b64\SMA\site\win86_64.env
中的link_sl变量末尾添加文件名:libopenblas.lib
。
Abaqus的C++子程序开发在帮助文档中很少提及,但是文档在About User Subroutines and Utilities还是进行了简单介绍。只要C++代码外形按照格式开始编写,里面的内容就可以自由发挥啦。关于外形格式我们可以参照Fortran进行编写。
上面其实我们已经给出了Dload子程序的C++形式,我们可以将其与帮助文档给出的Fortran格式,做个对比,可以看到函数参数是一致的。所以对于任意Fortran格式的子程序,完全可以改写为C++格式。
SUBROUTINE DLOAD(F,KSTEP,KINC,TIME,NOEL,NPT,LAYER,KSPT,
1 COORDS,JLTYP,SNAME)
C
INCLUDE 'ABA_PARAM.INC'
C
DIMENSION TIME(2), COORDS (3)
CHARACTER*80 SNAME
user coding to define F
RETURN
END
下面我们通过上述子程序对一个平板表面施加一个压力F=100(Distribution选择User-defined),和直接在abaqus给定的压力做一个对比,验证子程序是否能够正确运行。
上述选项选择编译好的main-std.obj,提交分析。
Job-1是使用子程序计算的结果,Job-2是未使用子程序,二者结果比较在合理误差范围内。
同时,我们也可以使用Abaqus Command提交任务:abq2022 job=xxx.inp user=xxx.obj int' 这样可以在Command窗口监控程序的运行过程。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删