... | @@ -11,7 +11,7 @@ Some steps have to be followed in order to properly define the application you w |
... | @@ -11,7 +11,7 @@ Some steps have to be followed in order to properly define the application you w |
|
In an application, many variables are required to define :
|
|
In an application, many variables are required to define :
|
|
* [fluid and grains properties](https://git.immc.ucl.ac.be/fluidparticles/migflow/blob/master/testcases/depot-2d/depot.py#L69)
|
|
* [fluid and grains properties](https://git.immc.ucl.ac.be/fluidparticles/migflow/blob/master/testcases/depot-2d/depot.py#L69)
|
|
```python
|
|
```python
|
|
g = -9.81 # gravity
|
|
g = np.array([0,-9.81,0]) # gravity
|
|
r = 1e-3 # grains radius
|
|
r = 1e-3 # grains radius
|
|
rhop = 1500 # grains density
|
|
rhop = 1500 # grains density
|
|
rho = 1000 # fluid density
|
|
rho = 1000 # fluid density
|
... | @@ -78,6 +78,7 @@ fluid = fluid.FluidProblem(2,g,[nu*rho],[rho]) |
... | @@ -78,6 +78,7 @@ fluid = fluid.FluidProblem(2,g,[nu*rho],[rho]) |
|
# Set the mesh geometry for the fluid computation
|
|
# Set the mesh geometry for the fluid computation
|
|
fluid.load_msh("mesh.msh")
|
|
fluid.load_msh("mesh.msh")
|
|
```
|
|
```
|
|
|
|
It is possible to solve simplified fluid equations using the temporal and advection parameters of the FluidProblem builder. If temporal is set to False, steady flows are computed. If advection is set to False, Stokes flows are computed. Default value for both temporal and advection is True to compute unsteady Navier-Stokes equations.
|
|
4. Once the fluid variables and properties are created, it is mandatory to set the boundary conditions of the fluid problem. Boundary conditions are of two types:
|
|
4. Once the fluid variables and properties are created, it is mandatory to set the boundary conditions of the fluid problem. Boundary conditions are of two types:
|
|
|
|
|
|
* Strong boundaries (Optional) constrain a field variable to a specified value. This is done by suppressing an equation of the linear system to replace it by this constraint :
|
|
* Strong boundaries (Optional) constrain a field variable to a specified value. This is done by suppressing an equation of the linear system to replace it by this constraint :
|
... | @@ -108,7 +109,9 @@ fluid.set_open_boundary(tag, velocity=None, pressure=None, porosity=1, concentra |
... | @@ -108,7 +109,9 @@ fluid.set_open_boundary(tag, velocity=None, pressure=None, porosity=1, concentra |
|
concentration -- the volume fraction of the first continuous phase
|
|
concentration -- the volume fraction of the first continuous phase
|
|
|
|
|
|
Raises:
|
|
Raises:
|
|
ValueError -- if the number of values set in the list callback_or_value do not match what is expected for this boundary type.
|
|
NameError -- If the specified porosity outside the boundary is too small
|
|
|
|
NameError -- If velocity and pressure are not specified or if they are both specified at the open boundary. It should be one or the other
|
|
|
|
NameError -- if the dimension of the velocity vector is not equal to the physical dimension of the problem
|
|
|
|
|
|
"""
|
|
"""
|
|
```
|
|
```
|
... | @@ -118,27 +121,39 @@ For now, the open boundary condition only allow to specify velocity and concentr |
... | @@ -118,27 +121,39 @@ For now, the open boundary condition only allow to specify velocity and concentr |
|
5. Coupling between fluid and solid is mainly based on the detection of the mesh cells in which grains are. Computing fluid fraction in a cell or evaluating the fluid velocity at the grain position both imply to know where the grains are in the fluid. The tree structure based on mesh cells is used to locate them.
|
|
5. Coupling between fluid and solid is mainly based on the detection of the mesh cells in which grains are. Computing fluid fraction in a cell or evaluating the fluid velocity at the grain position both imply to know where the grains are in the fluid. The tree structure based on mesh cells is used to locate them.
|
|
|
|
|
|
```python
|
|
```python
|
|
fluid.set_particles(p.mass(), p.volume(), p.position(), p.velocity())
|
|
fluid.set_particles(p.mass(), p.volume(), p.position(), p.velocity(),p.contact_forces(),init=True)
|
|
```
|
|
```
|
|
|
|
|
|
6. At this step, the initial state is completely defined and all the variables and parametres have been created. Then the computation can start. The [computational loop](https://git.immc.ucl.ac.be/fluidparticles/migflow/blob/master/testcases/depot-2d/depot.py#L117) is composed of three main steps:
|
|
6. At this step, the initial state is completely defined and all the variables and parametres have been created. Then the computation can start. The [computational loop](https://git.immc.ucl.ac.be/fluidparticles/migflow/blob/master/testcases/depot-2d/depot.py#L117) contains the time integration method solving the fluid and the grains phase:
|
|
|
|
|
|
* Fluid equations solving
|
|
* Fluid equations solving
|
|
```python
|
|
```python
|
|
while t < tEnd :
|
|
while t < tEnd :
|
|
fluid.implicit_euler(dt)
|
|
time_integration.iterate(fluid, p, dt, min_nsub=5, external_particles_forces=G)
|
|
|
|
t += dt
|
|
```
|
|
```
|
|
* Computation of the new grain free velocities
|
|
This function can be used to solve problem with fluid only, or grains only, or fluid and grains. The external_particle_forces argument contains the external forces that are applied on the grains. For instance, if the grains are falling under falling, this force will be set as:
|
|
```python
|
|
```python
|
|
forces = fluid.compute_node_force(dt)
|
|
G = p.mass()*g
|
|
vn = p.velocity() + forces * dt / p.mass()
|
|
|
|
```
|
|
```
|
|
* Contacts solving using a sub-timestep and grains displacement
|
|
The complete documentation of the function and its parameters are given:
|
|
```python
|
|
```python
|
|
for i in range(nsub) :
|
|
def iterate(fluid, particles, dt, min_nsub=1, contact_tol=1e-8, external_particles_forces=None, fixed_grains=False) :
|
|
tol = 1e-6
|
|
"""Migflow solver: the solver type depends on the fluid and particles given as arguments.
|
|
p.iterate(dt/nsub, forces, tol)
|
|
|
|
|
|
|
|
|
|
Keyword arguments:
|
|
|
|
fluid -- fluid structure
|
|
|
|
particles -- particles structure
|
|
|
|
dt -- time step
|
|
|
|
min_nsub -- minimal nsub for the particles iterations
|
|
|
|
contact_tol -- tolerance for the contact solver
|
|
|
|
external_particles_forces -- vector of external forces applied on the particles
|
|
|
|
fixed_grains -- boolean variable specifying if the grains are fixed in the fluid
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError -- fluid and particles cannot be both None
|
|
|
|
ValueError -- external_particles_forces must have shape (number of particles,dimension)
|
|
|
|
"""
|
|
```
|
|
```
|
|
The loop also contains instruction to write output files. It is important to note that after moving the grains in the computational loop you have to use the _set_particles()_ function to search the new location of the grains in the mesh.
|
|
The loop also contains instruction to write output files. It is important to note that after moving the grains in the computational loop you have to use the _set_particles()_ function to search the new location of the grains in the mesh.
|
|
|
|
|
... | @@ -146,23 +161,23 @@ for i in range(nsub) : |
... | @@ -146,23 +161,23 @@ for i in range(nsub) : |
|
### Handy Test Cases List
|
|
### Handy Test Cases List
|
|
|
|
|
|
|
|
|
|
| __Prerequisite Directory__ | __Prerequisite Run__ | __Test Case Directory__ | __Test Case__ |
|
|
| __Prerequisite Directory__ | __Prerequisite Run__ | __Test Case Directory__ | __Test Case__ | __State__ |
|
|
| ------ | ------ | ------ | ------ |
|
|
| ------ | ------ | ------ | ------ | ------ |
|
|
| ~MigFlow/testcases/ | | ~MigFlow/testcases/ | |
|
|
| ~MigFlow/testcases/ | | ~MigFlow/testcases/ | |
|
|
| avalanch/depot/ | depot.py | avalanch/avalanch1fluid/ | avalanch1fluidnofriction.py |
|
|
| avalanch/depot/ | depot.py | avalanch/avalanch1fluid/ | avalanch1fluidnofriction.py | Maintained |
|
|
| avalanch/depot/ | depot.py | avalanch/avalanch2fluids/ | avalanch2fluids.py |
|
|
| avalanch/depot/ | depot.py | avalanch/avalanch2fluids/ | avalanch2fluids.py | Broken |
|
|
| | | avalanch/avalanch2fluids/ | avalanch2fluidsnofriction.py |
|
|
| | | avalanch/avalanch2fluids/ | avalanch2fluidsnofriction.py | Broken |
|
|
| | | couette-2d/ | melangeur.py |
|
|
| | | couette-2d/ | melangeur.py | Mainained |
|
|
| | | depot-2d/ | depot.py |
|
|
| | | depot-2d/ | depot.py | Maintained | |
|
|
| | | depot-3d/ | depot.py |
|
|
| | | depot-3d/ | depot.py | Broken | |
|
|
| | | drop-2/SimpleDrop/ | drop.py |
|
|
| | | drop-2/SimpleDrop/ | drop.py | Maintained | |
|
|
| | | drop-2d/InteractingDrops/Vert/ | 2VertDrops.py |
|
|
| | | drop-2d/InteractingDrops/Vert/ | 2VertDrops.py | Maintained | |
|
|
| | | drop-2d/InteractingDrops/Diag/ | 2DiagDrops.py |
|
|
| | | drop-2d/InteractingDrops/Diag/ | 2DiagDrops.py | Maintained | |
|
|
| | | drop-3d/SimpleDrop/ | drop.py |
|
|
| | | drop-3d/SimpleDrop/ | drop.py | Maintained | |
|
|
| | | drop-3d/InteractingDrops/Vert/ | 2VertDrops.py |
|
|
| | | drop-3d/InteractingDrops/Vert/ | 2VertDrops.py | Maintained | |
|
|
| | | drop-3d/InteractingDrops/Diag/ | 2DiagDrops.py |
|
|
| | | drop-3d/InteractingDrops/Diag/ | 2DiagDrops.py | Maintained | |
|
|
| | | drop-3d/InteractingDrops/DeifferentDensities | 2DDDrops.py |
|
|
| | | drop-3d/InteractingDrops/DeifferentDensities | 2DDDrops.py | Maintained | |
|
|
| | | funnel/ | depot.py |
|
|
| | | funnel/ | depot.py | Broken | |
|
|
| | | sablier-2d/ | sablier.py |
|
|
| | | sablier-2d/ | sablier.py | Maintained | |
|
|
| | | shaker/ | shaker.py |
|
|
| | | shaker/ | shaker.py | Maintained | |
|
|
| | | smallDepot-3d/ | depot.py | |
|
| | | smallDepot-3d/ | depot.py | Broken | | |