Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with creating simulation box and locating stl in simulation box #57

Closed
VijayN10 opened this issue Feb 18, 2023 · 2 comments
Closed
Labels
good first issue good for newcomers

Comments

@VijayN10
Copy link

Hello!

I want to simulate fluid - structure interactions for coastal waves. But have few queries regarding creation of simulation box (domain) and locating stl file in the simulation box. The desired set up would look like as in figure below with a domain size of 6m x 30m x 4m. It is having fluid below 0.75m.

geom

The stl file would look like following image, where blue coordinate symbol represents origin -
stl

I have used following code -

#include "setup.hpp"

void main_setup() { 
    const float f = 0.001f; 
    const float u = 0.276f; // peak velocity of speaker membrane (Need to calculate)
    const float frequency = 0.043f; // amplitude = u/(2.0f*pif*frequency);
    // ######################################################### define simulation box size, viscosity and volume force ############################################################################
    
    // Actual simulation box dimensions  = 6m x 30m x 4m 
    LBM lbm(60, 300, 40, 0.001);   // Nx, Ny, Nx. nu    // 1. Can we add more refinement in lattice? I want more resolution in height

    const float3 size = float3(6.0f, 30.0f, 4.0f); // 2. Is it related to scaling of stl object?

    const float3 center = float3(lbm.center().x, lbm.center().y, size.z / 2.0f); //3. Is it relative position between center of stl and center of simulation box?

    lbm.voxelize_stl(get_exe_path() + "../stl/kyoto.stl", center, size);
    const ulong N = lbm.get_N(); const uint Nx = lbm.get_Nx(), Ny = lbm.get_Ny(), Nz = lbm.get_Nz(); for (ulong n = 0ull; n < N; n++) {
        uint x = 0u, y = 0u, z = 0u; lbm.coordinates(n, x, y, z);
        // ########################################################################### define geometry #############################################################################################
        if (lbm.flags[n] == TYPE_S) lbm.flags[n] = TYPE_S;
        else if (z < 7.5) {   // 0.75 m   // 4. Is this conversion correct? I want to have fluid below 0.75 m 
            lbm.flags[n] = TYPE_F;
            lbm.rho[n] = units.rho_hydrostatic(f, (float)z, 7.95f);
        }
        if (x == 0u || x == Nx - 1u || y == 0u || y == Ny - 1u || z == 0u || z == Nz - 1u) lbm.flags[n] = TYPE_S; // all non periodic
        if (y == 0u && x > 0u && x < Nx - 1u && z>0u && z < Nz - 1u) lbm.flags[n] = TYPE_E;
    }
    lbm.run(0u);
    while (running) {
        lbm.u.read_from_device();
        const float uy = u * sin(2.0f * pif * frequency * (float)lbm.get_t());
        const float uz = 0.5f * u * cos(2.0f * pif * frequency * (float)lbm.get_t());
        for (uint z = 1u; z < Nz - 1u; z++) {
            for (uint y = 0u; y < 1u; y++) {
                for (uint x = 1u; x < Nx - 1u; x++) {
                    if (y == 0u) { // only set velocity at inlet
                        const uint n = x + (y + z * Ny) * Nx;
                        lbm.u.y[n] = uy;
                        lbm.u.z[n] = uz;
                    }
                }
            }
        }
        lbm.u.write_to_device();
        lbm.run(100u);
    }
}

But, when I run the case. The set up appears as below image -

FluidX3D 18-Feb-23 8_11_01 PM

Here, the stl gets scaled up uneven. And also the water level seems not correct.

I have written my doubts in the respective code lines

  1. LBM lbm - Can we add more refinement in lattice? I want more resolution in height
  2. Size - Is it related to scaling of stl object?
  3. Center - Is it relative position between center of stl and center of simulation box?
  4. Z < 0.75 or Z < 7.5 - Which conversion correct? I want to have fluid below 0.75 m

Thank you for your time and assistance and look forward to hearing back from you!

@ProjectPhysX
Copy link
Owner

ProjectPhysX commented Mar 11, 2023

Hi @VijayN10,

apologies for the delayed response! This is a very interesting setup and I wanted to give a very detailed response, but my schedule was too busy until now. I hope this helps you, and please let me know if there is still something unclear.

The size parameter in lbm.voxelize_stl(...) must be a scalar (float) value, not a float3 vector. It's value describes the longest side of the bounding box of the geometry in LBM units, in your case 30.0f cells.

You want to place the geometry such that it is sitting flush on the bottom (-z) and right (+y) walls of the simulation box, also taking into account the one grid layer for the simulation box walls.. Here it is easiest to split the stl voxelization into 2 parts:

  1. loading the stl geometry into a Mesh* and scaling it to the desired size (30.0f), and
  2. translating it to the correct position.

The loading step puts it in the center of the simulation box, and then we need to translate it from the center by mesh_translation:

Mesh* mesh = read_stl(get_exe_path()+"../stl/kyoto.stl", lbm.size(), lbm.center(), 30.0f);
const float3 mesh_size = mesh->pmax-mesh->pmin;
const float3 mesh_translation = float3(0.0f, -1.0f+0.5f*lbm.size().y-0.5f*mesh_size.y, 1.0f-0.5f*lbm.size().z+0.5f*mesh_size.z); // "+-1.0f" to account for simulation box boundary
mesh->translate(mesh_translation);
lbm.voxelize_mesh_on_device(mesh);

To your specific questions:

  1. There is no local refinement on the lattice. If you need a finer grid at one region in the box, you have to make it finer everywhere. This is admittedly rather unfortunate; since a lot of users have requested this already, I'm planning to find a solution for local mesh refinement in the future.
  2. The size parameter (scalar float) in the lbm.voxelize_stl(...) or read_stl(...) functions sets the largest length of the bounding box of the geometry. If you set size=0.0f, the geometry is scaled such that it fits in the simulation box exactly at largest possible inflation. You can also assign the size parameter a negative value; then it becomes a scaling factor relative to the original coordinates in the .stl file, such that no auto-scaling is applied.
  3. The center parameter (vector float3) defines the center of the bounding box of the stl geometry in the simulation box. (0,0,0) here is the back left bottom corner of the simulation box, and (0.5f*(float)Nx-0.5f, 0.5f*(float)Ny-0.5f, 0.5f*(float)Nz-0.5f) or lbm.center() is the middle of the simulation box.
  4. Your box is 4m high and fluid should be < 0.75m. The simulation box in LBM units has a hight of 40 cells, so the water level in LBM units must be < 0.75m/4m * 40 = 7.5.

Note that you also need to set a volume force in the LBM cionstructor such that the water stays at the bottom and does not start to float around in zero-g. Have a look at the "raindrop" sample setup, and also how the unit conversion is done there with the aid of the units struct.

Thank you for using FluidX3D, have fun with it!

@VijayN10
Copy link
Author

@ProjectPhysX , thank you so much for the detailed explanation!

I will definitely try this out and will update you sooner.

@ProjectPhysX ProjectPhysX added the good first issue good for newcomers label Mar 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants