Introducing MUI code coupling library into OpenFOAM
Functionality to add/problem to solve
Integrate the code coupling library Multiscale Universal Interface in OpenFOAM as a third-party library to couple OpenFOAM with other solvers or OpenFOAM with itself.
Target audience
Users who want to couple OpenFOAM with other solvers or OpenFOAM with itself.
Proposal
A working general integration of MUI is proposed by applying the following patch to the OpenFOAM repository.
Below is a summarise of what have been added and modified.
-
Configure MUI inclusion in OpenFOAM.
-
Added MUI related commands in the following files
bin/tools/foamConfigurePathsetc/config.csh/functionsetc/config.csh/setupetc/config.csh/unsetetc/config.sh/functionsetc/config.sh/setupetc/config.sh/unset
-
Created the following files to setup MUI include through ThirdParty installation. These files also act as switches for MUI inclusion. MUI is enabled by setting
mui_version=MUI-2.0in these files and a global variable at compile timeexport FOAM_USE_MUI=1will be set. MUI is disabled by settingmui_version=MUI-nonein these files. MUI will be disabled by default.etc/config.csh/muietc/config.sh/mui
-
-
There is a new folder named
mpi-MUIinsrc/Pstreamcontains the MUI integrated Pstream. Make filessrc/Pstream/Allwmakeandsrc/Pstream/Allwcleanhave been modified so that the newly created make filessrc/Pstream/Allwmake-mpi-MUIandsrc/Pstream/Allwclean-mpi-MUIcan be called andmpi-MUIcan be built onceFOAM_USE_MUI=1is set. -
A new variable
extern MPI_Comm commWorld_;has been added insrc/Pstream/mpi/PstreamGlobals.H,src/Pstream/mpi/PstreamGlobals.Candsrc/Pstream/mpi/UPstream.Cso that to facilitate the replacing of the defaultMPI_COMM_WORLDinto the MUI enabled MPI communicator inmpi-MUIfolder. -
The code piece of
MPI_Init_thread()insrc/Pstream/mpi/UPstream.Cis proposed to be separated into a header filempiInitThread.Hso that to facilitate the MUI library to setup the MPI communicator inmpi-MUIfolder. In this way, there is no need to modify codes insrc/Pstream/mpi/UPstream.Cdirectly. -
In
mpi-MUIfolder, there is only two header filessrc/Pstream/mpi-MUI/mpiInitThread.Hthat contains the MUI returned MPI communicator andsrc/Pstream/mpi-MUI/PstreamGlobals.Haiming to includemui.hheader file. Oncempi-MUIfolder is building, thesrc/Pstream/Allwclean-mpi-MUIwill copyUPstream.Cfrommpifolder tompi-MUIso that the two header files inmpi-MUIfolder can be included. Other Pstream related header/source files will be used directly from thempifolder as shown insrc/Pstream/mpi-MUI/Make/files. The inclusion of-I../mpihas been put insrc/Pstream/mpi-MUI/Make/optionsto enable the directly reuse of files inmpifolder. An alternative way to consider is to create soft links of these header/source files from thempifolder. -
Created a new general purpose header file in creating MUI coupling interfaces
src/OpenFOAM/include/createCouplingMUI.H
-
There is a new solver in
applications/solvers/basic/laplacianFoamMUIthat shows how to utilise the integration and the way to compile a solver is also shown in the corresponding Make folder options file. Key to this is the inclusion of a newmpi-MUI-ruleswhich is located inwmake/rules/Generaland effectively replaces the usualmpi-rulesnormally used. It is mostly the same file but just adds an extra line at the bottomPINC += -I$(WM_THIRD_PARTY_DIR)/sources/mui/MUI-2.0/src. There is a new filewmake/scripts/have_muito detection/setup of MUI. -
There is a new tutorial case in
tutorials/basic/laplacianFoamMUIthat shows how to use the laplacianFoamMUI solver and a demo of couplingDict to set MUI coupling related variables. -
There is a new test code in
applications/test/coupling-MUIthat provide a unit test on MUI integration. -
Added MUI library related documentations in the following files in OpenFOAM
doc/Requirements.md
Related issue
What does success look like, and how can we measure that?
The Patch has been tested with the OpenFOAM development repository (commit e651d635).
The proposed changes can be patched and tested as follows
- Clone Development Repositories
git clone https://develop.openfoam.com/Development/ThirdParty-common.git
git clone https://develop.openfoam.com/Development/openfoam.git
- Obtain the MUI source file in the ThirdParty Repository
cd ThirdParty-common/sources
mkdir mui && cd mui
wget https://github.com/MxUI/MUI/archive/refs/tags/2.0.tar.gz
tar -xf 2.0.tar.gz && rm 2.0.tar.gz
-
Obtain and place patches in Repositories
-
Patch
cd openfoam/
patch -p2 < muiIntegrationOF.patch
rm muiIntegrationOF.patch
cd ../ThirdParty-common/
patch -p2 < muiIntegrationTP.patch
rm muiIntegrationTP.patch
-
Change permission of newly added files if needed
-
Enable MUI support (MUI is disabled by default)
- Modify L37 of
openfoam/etc/config.shto changemui_version=MUI-noneintomui_version=MUI-2.0
- Modify L37 of
-
Source and Allwmake
cd openfoam/
source etc/bashrc
./Allwmake -j 4
- Test MUI enabled OpenFOAM
cd openfoam/applications/test/coupling-MUI
./testCase/Allrun
cd openfoam/tutorials/basic/laplacianFoamMUI
./AllrunCoupled
If MUI library successfully integrated, the following log messages can be found for the coupling-MUI unit test.
...
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time
Create mesh for time = 0
If MUI library successfully integrated, the following log messages can be found for the laplacianFoamMUI tutorial.
....
MUI [lib_mpi_multidomain]: Rank: 2, "domain2" registered interface "interface_twoD_1" as 59a4e385
MUI [lib_mpi_multidomain]: Rank: 3, "domain2" registered interface "interface_twoD_1" as 59a4e385
MUI Info [lib_mpi_multidomain]: 1 distinct interface(s) found
MUI [lib_mpi_multidomain]: Setting up interface interface_twoD_1 [59a4e385] (rank ids are local to each interface)
MUI [comm_mpi.h]: Rank: 3, Identifier: mpi://domain2/interface_twoD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 2, Identifier: mpi://domain2/interface_twoD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 1, Identifier: mpi://domain1/interface_twoD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 0, Identifier: mpi://domain1/interface_twoD_1, Domain size: 2, Peers: 2
MUI [lib_mpi_multidomain]: Rank: 2, "domain2" registered interface "interface_threeD_1" as 31f80b7e
MUI [lib_mpi_multidomain]: Rank: 1, "domain1" registered interface "interface_threeD_1" as 31f80b7e
MUI [lib_mpi_multidomain]: Rank: 3, "domain2" registered interface "interface_threeD_1" as 31f80b7e
MUI [lib_mpi_multidomain]: Rank: 0, "domain1" registered interface "interface_threeD_1" as 31f80b7e
MUI Info [lib_mpi_multidomain]: 1 distinct interface(s) found
MUI [lib_mpi_multidomain]: Setting up interface interface_threeD_1 [31f80b7e] (rank ids are local to each interface)
MUI [comm_mpi.h]: Rank: 0, Identifier: mpi://domain1/interface_threeD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 3, Identifier: mpi://domain2/interface_threeD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 2, Identifier: mpi://domain2/interface_threeD_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 1, Identifier: mpi://domain1/interface_threeD_1, Domain size: 2, Peers: 2
MUI [lib_mpi_multidomain]: Rank: 2, "domain2" registered interface "interface_T_1" as 4a5523ab
MUI [lib_mpi_multidomain]: Rank: 1, "domain1" registered interface "interface_T_1" as 4a5523ab
MUI [lib_mpi_multidomain]: Rank: 0, "domain1" registered interface "interface_T_1" as 4a5523ab
MUI [lib_mpi_multidomain]: Rank: 3, "domain2" registered interface "interface_T_1" as 4a5523ab
MUI Info [lib_mpi_multidomain]: 1 distinct interface(s) found
MUI [lib_mpi_multidomain]: Setting up interface interface_T_1 [4a5523ab] (rank ids are local to each interface)
MUI [comm_mpi.h]: Rank: 0, Identifier: mpi://domain1/interface_T_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 1, Identifier: mpi://domain1/interface_T_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 3, Identifier: mpi://domain2/interface_T_1, Domain size: 2, Peers: 2
MUI [comm_mpi.h]: Rank: 2, Identifier: mpi://domain2/interface_T_1, Domain size: 2, Peers: 2
Calculating temperature distribution
Calculating temperature distribution
Time = 0.005
Time = 0.005
MUI interface "domain1"/"interface_twoD_1" value committed: 1 at Iteration = 0
MUI interface "domain2"/"interface_twoD_1" value committed: 1 at Iteration = 0
MUI interface "domain1"/"interface_threeD_1" value committed: 2 at Iteration = 0
MUI interface "domain1"/"interface_T_1" value committed: 3 at Iteration = 0
MUI interface "domain2"/"interface_threeD_1" value committed: 2 at Iteration = 0
MUI interface "domain2"/"interface_T_1" value committed: 3 at Iteration = 0
DICPCG: Solving for T, Initial residual = 1, Final residual = 8.33243e-07, No Iterations 7
DICPCG: Solving for T, Initial residual = 0.00446911, Final residual = 7.14892e-07, No Iterations 4
DICPCG: Solving for T, Initial residual = 0.000148123, Final residual = 6.63323e-07, No Iterations 2
MUI interface "domain1"/"interface_twoD_1" value fetched: 1 at Iteration = 0
MUI interface "domain1"/"interface_threeD_1" value fetched: 2 at Iteration = 0
MUI interface "domain1"/"interface_T_1" value fetched: 3 at Iteration = 0
ExecutionTime = 0.07 s ClockTime = 0 s
Time = 0.01
MUI interface "domain1"/"interface_twoD_1" value committed: 1 at Iteration = 1
MUI interface "domain1"/"interface_threeD_1" value committed: 2 at Iteration = 1
MUI interface "domain1"/"interface_T_1" value committed: 3 at Iteration = 1
DICPCG: Solving for T, Initial residual = 0.203755, Final residual = 1.57027e-07, No Iterations 7
DICPCG: Solving for T, Initial residual = 0.00184337, Final residual = 2.32416e-07, No Iterations 4
DICPCG: Solving for T, Initial residual = 1, Final residual = 8.33243e-07, No Iterations 7
DICPCG: Solving for T, Initial residual = 5.70921e-05, Final residual = 2.8776e-07, No Iterations 2
DICPCG: Solving for T, Initial residual = 0.00446911, Final residual = 7.14892e-07, No Iterations 4
DICPCG: Solving for T, Initial residual = 0.000148123, Final residual = 6.63323e-07, No Iterations 2
MUI interface "domain2"/"interface_twoD_1" value fetched: 1 at Iteration = 0
MUI interface "domain2"/"interface_threeD_1" value fetched: 2 at Iteration = 0
MUI interface "domain2"/"interface_T_1" value fetched: 3 at Iteration = 0
ExecutionTime = 0.1 s ClockTime = 0 s
Time = 0.01
MUI interface "domain2"/"interface_twoD_1" value committed: 1 at Iteration = 1
MUI interface "domain2"/"interface_threeD_1" value committed: 2 at Iteration = 1
MUI interface "domain2"/"interface_T_1" value committed: 3 at Iteration = 1
MUI interface "domain1"/"interface_twoD_1" value fetched: 1 at Iteration = 1
MUI interface "domain1"/"interface_threeD_1" value fetched: 2 at Iteration = 1
MUI interface "domain1"/"interface_T_1" value fetched: 3 at Iteration = 1
ExecutionTime = 0.08 s ClockTime = 0 s
Time = 0.015
MUI interface "domain1"/"interface_twoD_1" value committed: 1 at Iteration = 2
MUI interface "domain1"/"interface_threeD_1" value committed: 2 at Iteration = 2
MUI interface "domain1"/"interface_T_1" value committed: 3 at Iteration = 2
DICPCG: Solving for T, Initial residual = 0.109922, Final residual = 4.92455e-07, No Iterations 6
DICPCG: Solving for T, Initial residual = 0.00104616, Final residual = 7.0666e-07, No Iterations 3
DICPCG: Solving for T, Initial residual = 3.13839e-05, Final residual = 1.66653e-07, No Iterations 2
DICPCG: Solving for T, Initial residual = 0.203755, Final residual = 1.57027e-07, No Iterations 7
DICPCG: Solving for T, Initial residual = 0.00184337, Final residual = 2.32416e-07, No Iterations 4
DICPCG: Solving for T, Initial residual = 5.70921e-05, Final residual = 2.8776e-07, No Iterations 2
MUI interface "domain2"/"interface_twoD_1" value fetched: 1 at Iteration = 1
MUI interface "domain2"/"interface_threeD_1" value fetched: 2 at Iteration = 1
MUI interface "domain2"/"interface_T_1" value fetched: 3 at Iteration = 1
ExecutionTime = 0.11 s ClockTime = 1 s
Time = 0.015
MUI interface "domain2"/"interface_twoD_1" value committed: 1 at Iteration = 2
MUI interface "domain2"/"interface_threeD_1" value committed: 2 at Iteration = 2
MUI interface "domain2"/"interface_T_1" value committed: 3 at Iteration = 2
DICPCG: Solving for T, Initial residual = 0.109922, Final residual = 4.92455e-07, No Iterations 6
MUI interface "domain1"/"interface_twoD_1" value fetched: 1 at Iteration = 2
MUI interface "domain1"/"interface_threeD_1" value fetched: 2 at Iteration = 2
MUI interface "domain1"/"interface_T_1" value fetched: 3 at Iteration = 2
ExecutionTime = 0.1 s ClockTime = 1 s
...