Skip to content
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
CFD中文网

CFD中文网

X

xyl308120

@xyl308120
关于
帖子
4
主题
0
群组
0
粉丝
0
关注
0

帖子

最新

  • OpenFOAM libtorch tutorial step by step
    X xyl308120

    @李东岳
    东岳老师你好,我训练的时候GPU占比%38左右。 我还想顺便请教一下

    loss_ini = 1000*crit(meanU, init)
    

    这个损失的意义。 因为我发现1D槽道流openfoam基准数据的平均值差不多就是1左右,而这里相当于是要对训练添加一个整体约束之类的东西吗。


  • OpenFOAM libtorch tutorial step by step
    X xyl308120

    @剑金锋

    老哥,我把东岳老师那个1D槽道流的代码用AI改成了CUDA版本。然后在https://download.pytorch.org/libtorch/cu117 (我的cuda版本是11.7)下载的gpu版本的libtorch。现在发现已经可以用gpu训练了,但是训练速度还不如cpu,慢不少。 准备后续再捣鼓一下。 我机器配置 GPU: nvidia T400 4G, CPU:I7-12700,供参考

    #include <torch/torch.h>
    #include <torch/cuda.h> // 添加CUDA支持
    
    using namespace std;
    
    class NN : public torch::nn::Module {
        torch::nn::Sequential net_;
    public:
        NN() {
            net_ = register_module("net", torch::nn::Sequential(
                torch::nn::Linear(1,8),
                torch::nn::Tanh(),
                torch::nn::Linear(8,1)
            ));
        }
        torch::Tensor forward(torch::Tensor x) {
            return net_->forward(x);
        }
    };
    
    int main() {
        // 设备检测与设置
        torch::Device device = torch::kCPU;
        if (torch::cuda::is_available()) {
            std::cout << "CUDA可用,使用GPU加速训练" << std::endl;
            device = torch::kCUDA;
        }
    
        int iter = 1;
        int IterationNum = 1000000;
        double learning_rate = 0.001;
        double dy = 0.00125;
        int cellN = static_cast<int>(0.05/dy);
    
        // 模型迁移至GPU
        auto model = std::make_shared<NN>();
        model->to(device);
        
        // 优化器
        auto opti = std::make_shared<torch::optim::AdamW>(
            model->parameters(), 
            torch::optim::AdamWOptions(learning_rate)
        );
    
        // 数据迁移至GPU (关键步骤!)
        auto init = torch::full({}, 1.0).to(device);
        auto mesh = torch::arange(-0.05, 0, dy, torch::requires_grad())
                    .unsqueeze(1).to(device);
        auto dpdxByNu = torch::ones({cellN, 1}, torch::kFloat).to(device);
        auto nut = torch::zeros({cellN}).to(device);
            
        for (int i = 0; i < IterationNum; i++) {
            opti->zero_grad();
            auto upred = model->forward(mesh);
            
            // 梯度计算(确保权重张量在GPU)
            auto dudy = torch::autograd::grad(
                {upred}, {mesh}, 
                {torch::ones_like(upred).to(device)}, true, true
            )[0];
            
            auto dudyy = torch::autograd::grad(
                {dudy}, {mesh}, 
                {torch::ones_like(upred).to(device)}, true, true
            )[0];
    
            auto dudyTop = dudy[cellN - 1][0];
            auto meanU = torch::mean(upred);
            auto ubottom = torch::full_like(upred[0], 0.0375).to(device); // 边界条件迁移
            auto dpdxByNu = torch::full({cellN}, 1.2e-05/1e-08).to(device);
            
            // 损失计算
            auto loss_bottom = torch::mse_loss(upred[0], ubottom);
            auto loss_top = torch::mse_loss(dudyTop, torch::zeros_like(dudyTop));
            auto loss_bd = loss_bottom + 1000*loss_top;
            auto loss_ini = 1000*torch::mse_loss(meanU, init);
            auto loss_pde = torch::mse_loss(-dudyy.reshape({cellN}), dpdxByNu);
            auto loss = loss_pde + loss_bd + loss_ini;
    
            // 反向传播
            loss.backward();
            opti->step();
            
            // 输出需同步到CPU
            if (iter % 500 == 0) {
                double loss_value = loss.item<double>();
                cout << iter << " loss = " << loss_value << endl;
            }
            iter++;
        }
    
        torch::save(model, "model.pth");
        std::cout << "训练完成!" << std::endl;
        return 0;
    }
    

  • 通过wallShearStress求壁面平均剪切应力
    X xyl308120

    我也想问一下,不知道理解对不对。对于湍流粘度(Eddy Viscosity)模型,壁面切应力应该是这个
    $$ \tau_{w}=\tau_{d} \cdot {n}_f =-\mu_{eff} \cdot {dev}(2S) \cdot {n}_f $$

    $ S $是应变率张量, $\mu_{eff}$ 是流体的有效动力粘度(考虑湍流影响), $dev$ 是二阶应力张量的deviatoric操作,用以获取该项的剪切应力部分
    $$ dev(\tau)=\tau - \frac{1}{3}tr(\tau)\bf{I} $$

    $$ S = \frac{1}{2}(L + L^T) = \begin{bmatrix} \frac{\partial u}{\partial x} & \frac{1}{2}(\frac{\partial v}{\partial x} + \frac{\partial u}{\partial y}) & \frac{1}{2}(\frac{\partial v}{\partial x} + \frac{\partial u}{\partial y}) \\ \frac{1}{2}(\frac{\partial u}{\partial y} + \frac{\partial v}{\partial x}) & \frac{\partial v}{\partial y} & \frac{1}{2}(\frac{\partial w}{\partial y} + \frac{\partial v}{\partial z}) \\ \frac{1}{2}(\frac{\partial u}{\partial z} + \frac{\partial w}{\partial x}) & \frac{1}{2}(\frac{\partial v}{\partial z} + \frac{\partial w}{\partial y}) & \frac{\partial w}{\partial z}\end{bmatrix}$$

    这样看的话,假设 $\tau_d$ 可以写成

    $$\tau_d = \begin{bmatrix} \sigma_{xx} & \sigma_{xy} & \sigma_{xz} \\ \sigma_{yx} & \sigma_{yy} & \sigma_{yz} \\ \sigma_{zx} & \sigma_{zy} & \sigma_{zz}\end{bmatrix}$$

    有$ {n}_f$为沿 z轴垂直于xy的平面A的法向矢量,写成

    $$\bf{n}_f =\begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix}$$

    那么得到的 $\tau_w $为,其中 $\sigma_{xz}$ 和 $\sigma_{yz}$为 A平面平行于 x 和 y 轴的分量, $\sigma_{zz}$ 为沿 z 轴 垂直于 A 平面的法向分量

    $$\tau_w =\begin{bmatrix} \sigma_{xz} \\ \sigma_{yz} \\ \sigma_{zz} \end{bmatrix}$$

    所以壁面切应力矢量$\tau_w $和面法向$\bf{n}_f$矢量方向不一致


  • CFD中文网 定位与规范
    X xyl308120

    终于注册上了!

  • 登录

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 最新
  • 版块
  • 东岳流体
  • 随机看[请狂点我]