|
|
|
## 2. Defining the problem
|
|
|
|
The second step is to define a problem which will manage the fluid domain, the boundary conditions, etc. This is done by using the C++ class dart::Problem as,
|
|
|
|
```python
|
|
|
|
pbl = dart.Problem(msh, dim, alpha, beta, minf, sref, lref, xref, yref, zref)
|
|
|
|
```
|
|
|
|
where `alpha` and `beta` are the angles of attack and sideslip of the oncoming flow, `minf` is the freestream Mach number, `sref` and `lref` are the reference area and length, and `xref`, `yref` and `zref` are the coordinates of the reference point. The reference quantities are used to compute the aerodynamic loads coefficients.
|
|
|
|
|
|
|
|
**2.1 Defining the fluid domain**
|
|
|
|
The fluid domain is set using the class dart::Fluid,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Fluid(msh, 'fld', minf, dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'fld'` is the name of the physical group of the mesh containing the element belonging to the fluid domain. If `minf = 0`, the flow will be considered as incompressible, otherwise it will be considered compressible. Adding the fluid will automatically add C++ functions computing the density, the Mach number and the pressure coefficient. To avoid singular behavior, these functions are limited for high values of the velocity. Original non-limited function can also be used, but the code must be recompiled (see the class dart::Fluid). Note that, `beta` can be omitted if it is zero.
|
|
|
|
|
|
|
|
**2.2 Adding the initial and boundary conditions**
|
|
|
|
The intial condition is added using the dart::Initial class as,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Initial(msh, 'fld', dim, alpha, beta))
|
|
|
|
```
|
|
|
|
Dirichlet boundary conditions can be explicitely added with the dart::Dirichlet class as,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Dirichlet(msh, 'dirichlet', dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'dirichlet'` is the name of the physical group of the mesh containing the elements belonging to the boundary onto which the Dirichlet condition will be enforced. If no Dirichlet condition is provided, one node will be clamped automatically. Since using Dirichlet conditions requires to use larger computational domains, it is preferrable not to enforce these conditions explicitely, and provide Neumann boundary conditions instead.
|
|
|
|
Freestream (Neumann) boundary conditions can be added with the dart::Freestream class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Freestream(msh, 'freestream', dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'freestream'` is the name of the physical group of the mesh containing the elements belonging to the boundary onto which the Freestream condition will be enforced. In all the cases, `beta` can be omitted if it is zero.
|
|
|
|
Note that the downstream boundary of the domain MUST ALWAYS be assigned a Freestream boundary condition since it will intersect a wake. Also note that zero mass flux boundary conditions are naturally enforced by the FEM. The slip boundary conditions hence do not require to be explicitly added on bodies immersed in the flow.
|
|
|
|
|
|
|
|
**2.3 Adding wake boundary conditions and the Kutta condition**
|
|
|
|
Two additional conditions must be prescribed to allow lifting configurations to generate aerodynamic loads. Firstly, boundary conditions must be enforced on wake surfaces and secondly, the Kutta condition needs to be enforced on the trailing edge of any lifting surfaces. For 2D flows, the wake boundary conditions are added using the dart::Wake class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Wake(msh, ['wake', 'wake_', 'field']))
|
|
|
|
```
|
|
|
|
where `'wake_'` is the physical group of the mesh containing the lower wake elements, and is automatically created by tbox::MshCrack. For 3D flows, an additional parameter is required, and the use of dart::Wake slightly differs,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Wake(msh, ['wake', 'wake_', 'field', 'tips']))
|
|
|
|
```
|
|
|
|
where `'tips'` is the physical group of the mesh containing the edge boundaries of the wake to be excluded from the formulation (no contributions will be added to the nodes belonging to this group). This group includes the free edge of the wake for wings and tails. Additionally, if a fuselage is considered, it should also include the intersection of the wake with the fuselage.
|
|
|
|
The Kutta conditions is added using the dart::Kutta for both 2D and 3D flows,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Kutta(msh, ['te', 'wake_', 'body', 'field']))
|
|
|
|
```
|
|
|
|
where `'body'` is the name of the physical group of the mesh containing the element of the body surface on which the wake is attached, and `'te'` is the name of the physical group of the mesh containing the elements defining the trailing edge of `'body'`. Note that the wake surface does not need to be aligned with trailing edge bissector because dart::Kutta adds a supplementary term on the elements touching the trailing edge that correctly computes the local flow direction.
|
|
|
|
|
|
|
|
**2.4 Adding bodies immersed in the fluid**
|
|
|
|
A lifting body can be added by using the dart::Body class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Body(msh, ['body', 'field']))
|
|
|
|
```
|
|
|
|
This will allow the computation of the aerodynamic load coefficients on this body, as well as further data manipulation, e.g. for fluid-structure interaction or optimzation problems. |
|
|
|
## 2. Defining the problem
|
|
|
|
The second step is to define a problem which will manage the fluid domain, the boundary conditions, etc. This is done by using the C++ class dart::Problem as,
|
|
|
|
```python
|
|
|
|
pbl = dart.Problem(msh, dim, alpha, beta, minf, sref, lref, xref, yref, zref)
|
|
|
|
```
|
|
|
|
where `alpha` and `beta` are the angles of attack and sideslip of the oncoming flow, `minf` is the freestream Mach number, `sref` and `lref` are the reference area and length, and `xref`, `yref` and `zref` are the coordinates of the reference point. The reference quantities are used to compute the aerodynamic loads coefficients.
|
|
|
|
|
|
|
|
**2.1 Defining the fluid domain**
|
|
|
|
The fluid domain is set using the class dart::Fluid,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Fluid(msh, 'field', minf, dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'field'` is the name of the physical group of the mesh containing the fluid domain. If `minf = 0`, the flow will be considered as incompressible, otherwise it will be considered compressible. Adding the fluid will automatically add C++ functions computing the density, the Mach number and the pressure coefficient. To avoid singular behavior, these functions are limited for high values of the velocity. Original non-limited function can also be used, but the code must be recompiled (see the class dart::Fluid). Note that, `beta` can be omitted if it is zero.
|
|
|
|
|
|
|
|
**2.2 Adding the initial and boundary conditions**
|
|
|
|
The intial condition is added using the dart::Initial class as,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Initial(msh, 'field', dim, alpha, beta))
|
|
|
|
```
|
|
|
|
Dirichlet boundary conditions can be explicitely added with the dart::Dirichlet class as,
|
|
|
|
```python
|
|
|
|
pbl.set(dart.Dirichlet(msh, 'dirichlet', dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'dirichlet'` is the name of the physical group of the mesh containing the boundary onto which the Dirichlet condition will be enforced. If no Dirichlet condition is provided, one node will be clamped automatically. Since using Dirichlet conditions requires to use larger computational domains, it is preferrable not to enforce these conditions explicitely, and provide Neumann boundary conditions instead.
|
|
|
|
Freestream (Neumann) boundary conditions can be added with the dart::Freestream class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Freestream(msh, 'freestream', dim, alpha, beta=0))
|
|
|
|
```
|
|
|
|
where `'freestream'` is the name of the physical group of the mesh containing the boundary onto which the Freestream condition will be enforced. In all the cases, `beta` can be omitted if it is zero.
|
|
|
|
Note that the downstream boundary of the domain MUST ALWAYS be assigned a Freestream boundary condition since it will intersect a wake. Also note that zero mass flux boundary conditions are naturally enforced by the FEM. The slip boundary conditions hence do not require to be explicitly added on bodies immersed in the flow.
|
|
|
|
|
|
|
|
**2.3 Adding bodies immersed in the fluid**
|
|
|
|
A body can be added by using the dart::Body class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Body(msh, 'body', 'field'))
|
|
|
|
```
|
|
|
|
where `'body'` is the name of the physical group of the mesh containing the body surface. This will allow the computation of the aerodynamic load coefficients on this body, as well as further data manipulation, e.g. for fluid-structure interaction or optimzation problems.
|
|
|
|
|
|
|
|
**2.4 Adding wake boundary conditions and the Kutta condition**
|
|
|
|
Two additional conditions must be prescribed to allow lifting configurations to generate aerodynamic loads. Firstly, boundary conditions must be enforced on wake surfaces and secondly, the Kutta condition needs to be enforced on the trailing edge of any lifting surfaces. The wake boundary conditions are added using the dart::Wake class as,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Wake(msh, 'wake', 'wake_', 'field', ['free_edge_0', ...], is_linear))
|
|
|
|
```
|
|
|
|
where `'wake'` and `'wake_'` are the physical groups of the mesh containing the upper and the lower wake elements, the latter being automatically created by tbox::MshCrack. The optional list `['free_edge_0', ...]` contains the physical groups of the mesh containing the edge boundaries of the wake to be excluded from the formulation (no contributions will be added to the nodes belonging to this group). This group typically includes the free edge of the wake for wings and tails. Additionally, if a fuselage is considered, it should also include the intersection of the wake with the fuselage. The boolean flag `is_linear` indicates whether the linearized wake boundary conditions must be used.
|
|
|
|
The Kutta conditions is added using the dart::Kutta for both 2D and 3D flows,
|
|
|
|
```python
|
|
|
|
pbl.add(dart.Kutta(msh, 'te', 'wake_', 'body', 'field', is_linear))
|
|
|
|
```
|
|
|
|
where `'te'` is the name of the physical group of the mesh containing the trailing edge of `'body'` and the flag `is_linear` indicates whether the linearized Kutta conditions must be used. Note that the wake surface does not need to be aligned with trailing edge bissector because dart::Kutta adds a supplementary term on the elements touching the trailing edge that correctly computes the local flow direction. |
|
|
\ No newline at end of file |