Palace 是AWS Labs推出的一款用于全波 3D 电磁仿真的并行有限元求解器,开源许可证为Apache 2.0,求解器支持频域/时域全波、特征模、静电/静磁集总参数提取,适配笔记本到超算的多平台与 GPU 加速,可以用于量子计算硬件、射频 / 微波器件、天线等建模。笔者曾经简要介绍了如何在Windows下编译Palace的文章,参见《Windows环境下编译电磁仿真求解器Palace》一文。本文是在前文的基础上,更为详细的介绍编译过程,尤其着重介绍依赖库的编译。本文讨论的依赖库有:Hypre:大型线性代数矩阵计算包,使用2.30版本。MUMPS:来自法国的求解大规模稀疏线性方程组的开源软件库。ARPACK-NG:支持复数线性矩阵计算,用于特征值计算。以Fortran程序为主,无需依赖PETSc,可以独立编译。GSLIB:用于高阶谱单元的插值计算。libCEED:是一款线性代数计算管理终端,支持对各种CPU,GPU和集群的并行计算。MFEM:提供灵活、高效、可扩展的有限元离散化框架。是Palace的核心求解依赖库。系统环境与依赖库操作系统:Windows 11, 64-bit编译器:Visual Studio 2022 Community, C++17。Inter Fortran Compiler 2022,Intel MKL 2024。Palace版本:0.15编译HypreHypre是劳伦斯利弗莫尔国家实验室 LLNL 开发的开源高性能并行线性求解器库,专为大规模科学计算和工程模拟设计。核心目标是高效求解大规模稀疏线性方程组(形如 Ax=b),尤其擅长处理超大规模、分布式内存并行环境下的问题。hypre 原生支持 MPI并行,能充分利用超级计算机、集群等分布式内存架构的算力,轻松处理数百万甚至数十亿自由度的线性系统,这是它区别于小型求解器(如 Eigen)的核心优势。Windows下编译hypre并不复杂,可以直接使用自带的CMakeFile文件,生成Visual Studio的项目文件,生成静态库文件。在配置CMake时,参数如下设置:HYPRE_WITH_MPI = ONHYPRE_USING_OPENMP = ONHYPRE_WITH_CUDA = OFFHYPRE_ENABLE_SYCL = OFFHYPRE_INSTALL_PREFIX=D:/WelSimLLC/CodeDV/3rdParty/hypre/myInstallCMAKE_INSTALL_PREFIX=D:/WelSimLLC/CodeDV/3rdParty/hypre/myInstall如果编译顺利,会生成hyper.lib静态库文件。编译 MUMPSPalace求解器需要SuperLU, StrumPack,或者MUMPS三个直接线代求解器中的一个,才能求解Wave Port问题。由于笔者比较熟悉MUMPS,因此就选择的MUMPS求解器作为依赖库。MUMPS是由法国 INRIA、CNRS 等机构联合开发的开源并行稀疏直接求解器库。它的核心目标是用 “直接法” 求解大规模稀疏线性方程组(Ax=b),区别于 hypre 以 “迭代法” 为主,MUMPS 用直接法通过矩阵分解(LU/Cholesky)计算出解,无需迭代,精度更高、鲁棒性更强,尤其适合求解非对称、对称正定 / 不定的稀疏矩阵问题。 MUMPS 依赖 BLAS/LAPACK(基础线性代数库)、SCALAPACK(并行线性代数库)。这里我们使用Intel的MKL库作为依赖库。原始版本的MUMPS不提供Windows的编译方式,可以选择GitHub上的scivision/mumps版本,提供了基于CMake的编译方式,可以轻易实现编译。本例下载的是最新的5.8.1版本。确保环境变量中含有MKLTOOL= C:\Program Files (x86)\Intel\oneAPI\mkl\latest在CMake编译下,设置MUMPS_openmp = ONMUMP_parallel = OFF生成Visual Studio的项目文件后,直接编译即可生成MUMPS的所有静态库。生成的静态库如下图所示。编译ARPACKPalace在计算特征值相关的功能时,如计算Eigenmode,需要有SLEPc或者ARPACK复数求解器。由于SLEPc依赖PETSc,而PETSc在Windows下的编译较为复杂,因此就不选用SLEPc,这里选择ARPACK作为Palace的复数求解器。ARPACK是由莱斯大学、桑迪亚国家实验室等机构,联合开发的开源大规模特征值/特征向量求解库。它的核心目标是高效计算大型稀疏矩阵的少数特征值与对应特征向量,和 hypre、MUMPS 这类求解线性方程组(Ax=b)的库不同,ARPACK 专注于处理特征值问题(Ax=λx 或 Ax=λBx)。从GitHub上下载ARPACK-ng,使用自带的CMake编译方式。在CMake中设置如下ICE = ONEigen = ONBuild_SHARED_LIBS = OFF同时,确保环境变量中含有MKLTOOL= C:\Program Files (x86)\Intel\oneAPI\mkl\latest,这样CMake会自动找到MKL里的BLAS和Lapack。生成Visual Studio项目文件后,既可以直接编译得到Arpack的静态库。编译GSLibGSLIB是一个开源的并行稀疏通信库,它专为有限元、谱元、有限差分等并行数值模拟场景,提供高效的稀疏数据聚合 – 分发(Gather/Scatter)通信与算子支持。大幅简化并行稀疏通信开发,降低分布式内存编程门槛;自适应算法保证大规模并行下的通信效率,适配超大规模仿真需求。 由于GSLib并没有CMake文件,无法在Windows下自动生成Visual Studio的项目文件,需要用户自己建立Visual Studio的项目文件。新建一个静态库项目,取名为gslib-palace,并将所有的源文件和头文件添加到此项目中。在Visual Studio的项目预处理定义中,添加GSLIB_USE_CBLAS, GSLIB_USE_MKL。编译时,当遇到以下错误提示时:unary minus operator applied to unsigned type, result still unsigned需要修改代码,如将 p[map->n].el = -(uint)1;改为 p[map->n].el = 0-(uint)1;以通过编译。当遇到以下错误提示时:potentially uninitialized local pointer variable 'h' used需要修改代码,给指针添加NULL初始值。如果提示fgs_free函数已经有重复的定义。将fgs_setup, fgs_free与fgs_unique函数注释掉即可。编译libCEEMlibCEED 是一个高效可扩展的离散化库,专注于基于有限元和谱元方法的高效计算离散化。它提供轻量级代数接口,用于线性和非线性算子及预条件子,支持基于 CPU、GPU 等多种计算设备的运行时选择优化实现。编译libCEEM是整个工作的难点,由于libCEED不提供CMakeFile文件,同时含有较多的选项,同时Visual Studio不支持C99的语法,需要大量手动修改源文件,尤其是对于动态数组的修改。如将以下动态数组CeedInt num_points[num_elem];修改成为CeedInt *num_points = (CeedInt *)malloc(num_elem * sizeof(CeedInt));使用完成后,还需在结尾处,使用free函数,从内存中删除此数组,free(num_points)。一些含有路径的字符串,也需要做修改。如*(relative_file_path) = strstr(absolute_file_path, "ceed/jit-source");改为#ifdef _WIN32 *(relative_file_path) = strstr(absolute_file_path, "ceed\\jit-source");#else *(relative_file_path) = strstr(absolute_file_path, "ceed/jit-source");#endif由于Visual Studio对weak的函数支持方式与Linux不一样,需要对源码中的weak函数做如下修改:#define CEED_BACKEND(name, num_prefixes, ...) \ CEED_INTERN int name(void) __attribute__((weak)); \ int name(void) { return CeedRegister_Weak(__func__, num_prefixes, __VA_ARGS__); }#include "ceed-backend-list.h"改为#ifdef _WIN32#define CEED_BACKEND(name, num_prefixes, ...) \ CEED_INTERN int name(void) __declspec(selectany); \ int name(void) { return CeedRegister_Weak(__func__, num_prefixes, __VA_ARGS__); }#else#define CEED_BACKEND(name, num_prefixes, ...) \ CEED_INTERN int name(void) __attribute__((weak)); \ int name(void) { return CeedRegister_Weak(__func__, num_prefixes, __VA_ARGS__); } #include "ceed-backend-list.h"#endifVisual Studio不支持__restrict__关键字,需要改成__restrict。还有一些小范围的修改,如将popen改成_popen,将pclose改成 _pclose。有一处环境变量设定setenv("RUST_TOOLCHAIN", "nightly", 0),需要做如下修改:char env_str[1024];snprintf(env_str, sizeof(env_str), "%s=%s", "nightly", 0);_putenv(env_str);为了减少不必要的复杂度,本次编译只支持CPU并行计算的内容,GPU并行无需支持,因此在ceed-backend-list.h文件中,只需要支持以下功能:CEED_BACKEND(CeedRegister_Opt_Blocked, 1, "/cpu/self/opt/blocked")CEED_BACKEND(CeedRegister_Opt_Serial, 1, "/cpu/self/opt/serial")CEED_BACKEND(CeedRegister_Ref, 1, "/cpu/self/ref/serial")CEED_BACKEND(CeedRegister_Ref_Blocked, 1, "/cpu/self/ref/blocked")CEED_BACKEND(CeedRegister_Xs mm_Blocked, 1, "/cpu/self/xs mm/blocked")CEED_BACKEND(CeedRegister_Xs mm_Serial, 1, "/cpu/self/xs mm/serial")其余的计算功能可以注释掉。编译成功后会生成libCEEM的静态库。编译MFEMMFEM是Palace的核心求解器,由劳伦斯利弗莫尔国家实验室(LLNL)主导开发的开源高阶有限元库,专为大规模科学计算和工程仿真设计,核心目标是提供灵活、高效、可扩展的有限元离散化框架。MFEM 也是计算流体力学、电磁仿真、结构力学、核物理模拟等领域的主流开源有限元工具。编译MFEM相对简单,可以通过CMake的方式生成Visual Studio项目文件来编译。在CMake的选项中,选择激活的选项如下:MFEM_USE_MPI = ONMFEM_USE_ZLIB = ONMFEM_USE_METIS = ONMFEM_USE_LAPACK = ONMFEM_USE_LEGACY_OPENMP = ONMFEM_THREAD_SAFE = ONMFEM_USE_MUMPS = ON生成Visual Studio的项目文件,直接编译,即可得到mfem的静态库。编译Palace至此,复杂的依赖库都已经编译完成。开始整个项目的最后一步,使用自带的CMakeFile文件,生成Visual Studio的项目文件,编译Palace。这里要注意的是,应该选择在palace子目录中的CMakeFile.txt文件,而不是根目录下的CMakeFile.txt,因为后者是用于生成Superbuild的。CMake下设置:PALACE_WITH_ARPACK = ONPALACE_WITH_OPENMP = ONPALACE_WITH_SLEPC = OFFMPI_Fortran_WORKS = C:/Program Files (x86)/Microsoft SDKs/MPI/Include/x64设置路径nlohmann_json_DIR = D:/WelSimLLC/CodeDV/3rdParty/nlohmann_json/json-3.12.0/myInstall/share/cmake/nlohmann_jsonfmt_DIR = D:\WelSimLLC\CodeDV\3rdParty\fmt\fmt-11.0.2\myInstall\lib\cmake\fmtscn_DIR = D:\WelSimLLC\CodeDV\libPack\lib\scn\cmake\scnMFEM_DIR = D:/WelSimLLC/CodeDV/libPack/lib/palace/mfem-cmakearpackng_DIR = D:\WelSimLLC\CodeDV\libPack\lib\palace\arpack-cmake\arpackng打开生成的Visual Studio项目,可以看到名为libpalace的静态库项目,和名为palace的可执行文件项目。如果在编译时提示找不到头文件,或者连接时缺少相关函数,可以直接在项目中添加相关路径和静态库。完成编译后,可以试运行一下palace.exe。注意使用时,需要将动态依赖库放置与palace.exe同一个文件夹下,如MKL系列的相关动态库文件。计算一个简单算例,得到如下显示。表明编译基本成功。总结目前可用的开源电磁场仿真求解器不多,Palace是目前功能最多的开源电磁求解器。Palace的依赖库较多,版本还在不断更新迭代,一些依赖库只支持Linux版本,增加了Windows下编译的难度。本文记录编译整个Palace的过程,同时给开源社区提供一些Windows下编译Palace的参考。还有一些其他依赖库编译相对容易,如Eigen, fmt, Metis,nlhmann/json等。有经验的开发者可以自行在Windows下成功编译,就不在本文中赘述了。笔者已将编译好的palace.exe可执行文件收录在WELSIM安装包中,用户也可以直接从WELSIM安装包中获得Windows版本的palace.exe,无需自己编译。本文介绍的是CPU多核并行计算下的Palace,GPU版本的编译方法,如CUDA, HIP,或SYCL版本,会在以后的文章中讨论。WelSim与作者不隶属于Palace, Hypre, MUMPS, Arpack, GSLib, libCEEM, 和MFEM。和Palace, Hypre, MUMPS, Arpack, GSLib, libCEEM, 和MFEM开发团队与机构没有直接关系。这里引用这些开源软件的名称和图片仅用作技术博客文章与软件使用的参考。 来源:WELSIM