PRECICE 工具介绍与使用示例

PRECICE 工具介绍与使用示例

PRECICE 简介

PRECICE (Precise Code Interaction Coupling Environment) 是一个开源的耦合库,用于实现多物理场仿真中不同求解器之间的协同仿真。它允许不同的仿真软件(如计算流体力学(CFD)和结构力学(CSM)工具)在运行时交换数据并进行耦合计算。

主要特点:

  • 支持并行计算
  • 提供灵活的耦合配置
  • 可处理非匹配网格
  • 支持显式和隐式耦合方案
  • 提供多种数据映射方法

安装 PRECICE

Linux 系统安装

# 使用预编译包 (Ubuntu/Debian)
sudo apt-get install precice

# 或者从源码编译
git clone https://github.com/precice/precice.git
cd precice
mkdir build && cd build
cmake -DBUILD_SHARED_LIBS=ON ..
make -j 4
sudo make install

使用示例:流体-结构相互作用 (FSI)

下面展示一个简单的流体-结构相互作用(FSI)示例,使用 PRECICE 耦合一个简化的流体求解器和一个结构求解器。

1. 创建 PRECICE 配置文件 (precice-config.xml)

<?xml version="1.0"?>
<precice-configuration>
    <solver-interface dimensions="2">
        
        <data:vector name="Forces" />
        <data:vector name="Displacements" />
        
        <mesh name="FluidMesh">
            <use-data name="Forces" />
            <use-data name="Displacements" />
        </mesh>
        
        <mesh name="StructureMesh">
            <use-data name="Forces" />
            <use-data name="Displacements" />
        </mesh>
        
        <participant name="FluidSolver">
            <provide-mesh name="FluidMesh" />
            <receive-data name="Displacements" mesh="FluidMesh" />
            <write-data name="Forces" mesh="FluidMesh" />
        </participant>
        
        <participant name="StructureSolver">
            <provide-mesh name="StructureMesh" />
            <receive-data name="Forces" mesh="StructureMesh" />
            <write-data name="Displacements" mesh="StructureMesh" />
        </participant>
        
        <m2n:sockets from="FluidSolver" to="StructureSolver" />
        
        <coupling-scheme:serial-implicit>
            <participants first="FluidSolver" second="StructureSolver" />
            <max-time-windows value="10" />
            <time-window-size value="0.1" />
            <relative-convergence-measure limit="1e-3" data="Displacements" mesh="StructureMesh" />
            <exchange data="Forces" mesh="FluidMesh" from="FluidSolver" to="StructureSolver" />
            <exchange data="Displacements" mesh="StructureMesh" from="StructureSolver" to="FluidSolver" />
        </coupling-scheme:serial-implicit>
    
    </solver-interface>
</precice-configuration>

2. 简化的流体求解器示例 (Python)

import numpy as np
import precice

# 设置PRECICE接口
participant_name = "FluidSolver"
config_file_name = "precice-config.xml"
solver_process_index = 0
solver_process_size = 1

interface = precice.Interface(participant_name, config_file_name, 
                             solver_process_index, solver_process_size)

mesh_name = "FluidMesh"
mesh_id = interface.get_mesh_id(mesh_name)

# 定义网格和顶点
vertices = np.array([[0, 0], [1, 0], [1, 1], [0, 1]])  # 简单正方形网格
vertex_ids = interface.set_mesh_vertices(mesh_id, vertices)

# 定义数据
displacements_id = interface.get_data_id("Displacements", mesh_id)
forces_id = interface.get_data_id("Forces", mesh_id)

# 初始化PRECICE
precice_dt = interface.initialize()

# 模拟时间步进
while interface.is_coupling_ongoing():
    
    # 接收来自结构求解器的位移
    displacements = interface.read_block_vector_data(displacements_id, vertex_ids)
    
    # 在这里进行流体计算...
    # 这是一个简化示例,实际应用中会有完整的流体求解器
    
    # 计算作用在结构上的力 (简化示例)
    forces = np.random.rand(len(vertices), 2)  # 随机力,实际应用中应计算真实力
    
    # 发送力给结构求解器
    interface.write_block_vector_data(forces_id, vertex_ids, forces)
    
    # 推进耦合
    precice_dt = interface.advance(precice_dt)

# 结束耦合
interface.finalize()

3. 简化的结构求解器示例 (Python)

import numpy as np
import precice

# 设置PRECICE接口
participant_name = "StructureSolver"
config_file_name = "precice-config.xml"
solver_process_index = 0
solver_process_size = 1

interface = precice.Interface(participant_name, config_file_name,
                            solver_process_index, solver_process_size)

mesh_name = "StructureMesh"
mesh_id = interface.get_mesh_id(mesh_name)

# 定义网格和顶点 (应与流体网格对应)
vertices = np.array([[0, 0], [1, 0], [1, 1], [0, 1]])  # 简单正方形网格
vertex_ids = interface.set_mesh_vertices(mesh_id, vertices)

# 定义数据
displacements_id = interface.get_data_id("Displacements", mesh_id)
forces_id = interface.get_data_id("Forces", mesh_id)

# 初始化PRECICE
precice_dt = interface.initialize()

# 初始位移
displacements = np.zeros((len(vertices), 2))

# 模拟时间步进
while interface.is_coupling_ongoing():
    
    # 接收来自流体求解器的力
    forces = interface.read_block_vector_data(forces_id, vertex_ids)
    
    # 在这里进行结构计算...
    # 这是一个简化示例,实际应用中会有完整的结构求解器
    
    # 计算位移 (简化示例)
    stiffness = 0.1
    displacements = forces * stiffness
    
    # 发送位移给流体求解器
    interface.write_block_vector_data(displacements_id, vertex_ids, displacements)
    
    # 推进耦合
    precice_dt = interface.advance(precice_dt)

# 结束耦合
interface.finalize()

运行耦合仿真

要运行这个耦合仿真,你需要:

  1. 将上述代码保存为三个文件:

    • precice-config.xml (配置文件)
    • fluid_solver.py (流体求解器)
    • structure_solver.py (结构求解器)
  2. 在两个不同的终端中分别运行:

    python fluid_solver.py
    

    python structure_solver.py
    

实际应用中的注意事项

  1. 网格匹配:在实际应用中,流体和结构网格通常不完全匹配,PRECICE 提供了多种数据映射方法。

  2. 收敛标准:隐式耦合需要设置适当的收敛标准。

  3. 并行计算:PRECICE 支持并行计算,可以显著提高大规模仿真的效率。

  4. 时间步长:耦合时间步长需要仔细选择以确保数值稳定性。

  5. 真实求解器:实际应用中,你会用真实的 CFD 和 CSM 求解器(如 OpenFOAM、CalculiX 等)替代上述简化示例。

PRECICE 提供了与多种流行仿真工具的适配器,可以方便地集成到现有仿真工作流程中。


使用preCICE在OpenFOAM求解器之间进行耦合计算

preCICE是一个用于分区多物理场耦合的库,可以方便地在不同求解器之间建立耦合关系。下面我将介绍如何在两个OpenFOAM求解器之间使用preCICE进行耦合计算,并提供示例代码。

基本配置步骤

  1. 安装preCICE和OpenFOAM的preCICE适配器
  2. 准备两个OpenFOAM案例
  3. 为每个案例创建preCICE配置文件
  4. 配置OpenFOAM案例以使用preCICE适配器

示例场景

假设我们有两个OpenFOAM求解器:

  • 求解器A:计算流体流动(如pimpleFoam)
  • 求解器B:计算热传递(如buoyantPimpleFoam)

我们希望在这两个求解器之间耦合传热(温度)和壁面热通量。

示例代码结构

1. preCICE配置文件 (precice-config.xml)

<?xml version="1.0"?>
<precice-configuration>
    <solver-interface dimensions="3">
        
        <data:vector name="Velocity" />
        <data:scalar name="Temperature" />
        <data:scalar name="Heat-Flux" />
        
        <participant name="FluidSolver">
            <use-mesh name="FluidMesh" provide="yes" />
            <write-data name="Temperature" mesh="FluidMesh" />
            <read-data name="Heat-Flux" mesh="FluidMesh" />
        </participant>
        
        <participant name="ThermalSolver">
            <use-mesh name="ThermalMesh" provide="yes" />
            <read-data name="Temperature" mesh="ThermalMesh" />
            <write-data name="Heat-Flux" mesh="ThermalMesh" />
        </participant>
        
        <m2n:sockets from="FluidSolver" to="ThermalSolver" />
        
        <coupling-scheme:serial-implicit>
            <participants first="FluidSolver" second="ThermalSolver" />
            <max-time-windows value="100" />
            <time-window-size value="0.1" />
            <relative-convergence-measure limit="1e-3" data="Heat-Flux" />
            <exchange data="Temperature" mesh="FluidMesh" from="FluidSolver" to="ThermalSolver" />
            <exchange data="Heat-Flux" mesh="ThermalMesh" from="ThermalSolver" to="FluidSolver" />
        </coupling-scheme:serial-implicit>
    </solver-interface>
</precice-configuration>

2. OpenFOAM案例配置

对于每个OpenFOAM案例,你需要在system/目录下添加preCICE配置:

system/preciceDict (流体求解器)
preciceConfig "precice-config.xml";
participantName "FluidSolver";
modules (FF);

interfaces
{
    interface
    {
        mesh "FluidMesh";
        patches (wall);
        
        writeData
        (
            Temperature
        );
        
        readData
        (
            Heat-Flux
        );
    }
};
system/preciceDict (热求解器)
preciceConfig "precice-config.xml";
participantName "ThermalSolver";
modules (CHT);

interfaces
{
    interface
    {
        mesh "ThermalMesh";
        patches (wall);
        
        writeData
        (
            Heat-Flux
        );
        
        readData
        (
            Temperature
        );
    }
};

3. 修改边界条件

在流体求解器的0/T文件中:

wall
{
    type            preciceTemperature;
    preciceConfig   "precice-config.xml";
    participantName "FluidSolver";
    meshName        "FluidMesh";
    dataName        "Temperature";
    value           $internalField;
}

在热求解器的0/q文件中:

wall
{
    type            preciceHeatFlux;
    preciceConfig   "precice-config.xml";
    participantName "ThermalSolver";
    meshName        "ThermalMesh";
    dataName        "Heat-Flux";
    value           $internalField;
}

4. 运行脚本

创建一个运行两个求解器的脚本runCoupled.sh:

#!/bin/bash

# 在一个终端中运行流体求解器
gnome-terminal -- bash -c "cd fluidCase && pimpleFoam -precice-participant FluidSolver; exec bash"

# 在另一个终端中运行热求解器
gnome-terminal -- bash -c "cd thermalCase && buoyantPimpleFoam -precice-participant ThermalSolver; exec bash"

关键点说明

  1. preCICE配置:

    • 定义了参与耦合的两个求解器
    • 指定了交换的数据类型(标量/矢量)
    • 设置了耦合方案(这里使用串行隐式)
  2. OpenFOAM适配器配置:

    • 每个求解器通过preciceDict指定其在preCICE配置中的名称
    • 定义接口面和交换的数据
  3. 边界条件:

    • 使用特殊的preCICE边界条件类型替换常规边界条件
    • 确保数据名称与preCICE配置中一致

注意事项

  1. 确保两个案例的耦合面网格在几何上是兼容的(不一定需要节点匹配)
  2. 时间步长设置应该协调,通常使用固定时间步长
  3. 初始条件应该合理设置以避免数值不稳定
  4. 耦合收敛标准需要根据具体问题调整

扩展

对于更复杂的耦合场景,你还可以:

  • 添加更多耦合数据(如压力、位移等)
  • 使用并行耦合方案
  • 结合其他求解器(如结构力学求解器)
  • 实现动态网格变形耦合

希望这个示例能帮助你开始使用preCICE进行OpenFOAM求解器之间的耦合计算。实际应用中可能需要根据具体问题调整配置和参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值