ProjectPhysX / FluidX3D

The fastest and most memory efficient lattice Boltzmann CFD software, running on all GPUs via OpenCL. Free for non-commercial use.
https://youtube.com/@ProjectPhysX
Other
3.84k stars 303 forks source link

Boat in water simulation setup #220

Open antoniopucciarelli opened 1 month ago

antoniopucciarelli commented 1 month ago

Dear Community / @ProjectPhysX ,

I am struggling with the setup of a boat moving through water in FluidX3D.

The issue i have is the following: Screenshot from 2024-09-01 10-36-39

As you can see, the flow at the outlet of the domain is flowing in at the inlet. Do you know how to solve this problem?

The setup I use is the following:

void main_setup() { // stable boat

    const uint3 lbm_N = resolution(float3(1.0f, 2.0f, 1.0f), 1000u); // input: simulation box aspect ratio and VRAM occupation in MB, output: grid resolution

    const float si_u       = 15.0f;
    const float si_length  = 2.4f;
    const float si_nu      = 1.48E-5f;
    const float si_rho     = 1.225f;
    const float lbm_length = 0.65f * (float)lbm_N.y;
    const float lbm_u      = 0.05f;

    units.set_m_kg_s(lbm_length, lbm_u, 1.0f, si_length, si_u, si_rho);

    print_info("Re = " + to_string(to_uint(units.si_Re(si_length, si_u, si_nu))));

    // ################################################################## define simulation box size, viscosity and volume force ###################################################################
    LBM lbm(lbm_N, units.nu(si_nu));

    // ###################################################################################### define geometry ######################################################################################
    const uint  Nx = lbm.get_Nx();
    const uint  Ny = lbm.get_Ny();
    const uint  Nz = lbm.get_Nz();
    const float R  = 20.0f;
    const float H  = 90.0f;

    // const float lbm_length = 0.4f * (float)Nx;

    // mesh properties
    string pathName = "??/FluidX3D/stl/boat.stl";
    Mesh* boatMesh  = read_stl(pathName);

    const float scale = lbm_length / boatMesh->get_bounding_box_size().y / 3.5f; 
    boatMesh->scale(scale);

    const float3 offset = lbm.center() - boatMesh->get_bounding_box_center() - float3(0.0f, boatMesh->get_bounding_box_center().y / 2.0f, boatMesh->get_bounding_box_center().z * -0.15f);
    boatMesh->translate(offset);
    boatMesh->set_center(boatMesh->get_bounding_box_center());

    lbm.voxelize_mesh_on_device(boatMesh, TYPE_S|TYPE_X, offset, float3(0.0f), float3(0.0f, 0.0f, 0.0f));

    parallel_for(lbm.get_N(), [&](ulong n) { uint x=0u, y=0u, z=0u; lbm.coordinates(n, x, y, z);
        if(z == 0) 
        {
            lbm.flags[n] = TYPE_S;
            lbm.u.y[n]   = lbm_u;
        }
        else if(lbm.flags[n] != (TYPE_S|TYPE_X) && z < H) 
        {
            lbm.flags[n] = TYPE_F;
            lbm.u.y[n]   = lbm_u;
        }

        if(x==0u||x==Nx-1u) 
        {
            lbm.flags[n] = TYPE_S;
        }
    }); 
    // ####################################################################### run simulation, export images and data ##########################################################################
    lbm.graphics.visualization_modes = VIS_FLAG_LATTICE | (lbm.get_D() == 1u ? VIS_PHI_RAYTRACE : VIS_PHI_RASTERIZE);
    lbm.run(0u); // initialize simulation

    while(true) 
    { 
        lbm.u.read_from_device();

        lbm.calculate_force_on_boundaries();
        lbm.F.read_from_device();

        // optional: export force field as .vtk file
        lbm.F.write_host_to_vtk(); // F is already copied from GPU memory to host memory

        // sum force over all boundary
        const float3 lbm_force = lbm.calculate_force_on_object(TYPE_S|TYPE_X);
        const float3 lbm_torque = lbm.calculate_torque_on_object(TYPE_S|TYPE_X);

        // transition back to SI units
        const float si_force_x  = units.si_F(lbm_force.x); // force in Newton
        const float si_force_y  = units.si_F(lbm_force.y);
        const float si_force_z  = units.si_F(lbm_force.z);
        const float si_torque_x = units.si_M(lbm_torque.x); // torque in Newton * meters
        const float si_torque_y = units.si_M(lbm_torque.y);
        const float si_torque_z = units.si_M(lbm_torque.z);

        // print lift/drag force components
        print_info(">>> FORCE");
        print_info("\tlift force    = " + to_string(si_force_z) + " N");
        print_info("\tdrag force    = " + to_string(si_force_y) + " N");
        print_info("\tlateral force = " + to_string(si_force_x) + " N");
        print_info(">>> TORQUE");
        print_info("\troll torque = " + to_string(si_torque_x) + " Nm");
        print_info("\tpitch torque = " + to_string(si_torque_y) + " Nm");
        print_info("\tyaw torque = " + to_string(si_torque_z) + " Nm");

        // moving sphere
        lbm.u.write_to_device();
        lbm.run(100u);
    }
}

Attached there is the .stl geometry. boat.zip

My final aim is to simulate the motion of the boat inside water taking into account forces and moments.

If you have some scripts dealing with conservation of momentum and angular momentum, feel free to share it.

Thank you for the support.

Freekbaars commented 1 week ago

hi i'm currently running through the simulation. (now i myself only started with FluidX3D today and not that much C++ experience) but now i have a little problem it seems like out of nowhere all of a sudden some kind of ball enters the domain. this causes it to stop working completely.

Schermafbeelding 2024-09-20 144138 Schermafbeelding 2024-09-20 144218 Schermafbeelding 2024-09-20 144256