Gradient

Description

This treatment computes the gradient of given nodes variables, two methods are available.

The first method (vtk = False) is based on the Green-Ostrogradski theorem to compute the gradient and the volume at cells. i.e. \(\displaystyle V = \frac{1}{3} \oint_S C.n \, dS\) with V the volume, C one point on the surface S, and n the normal. It handles both structured and unstructured grids.

The second method (vtk = True) is based on the vtk library to compute the gradients at nodes. It handles only unstructured grids. Note that the Treatment Unstructure can always be use if structured grids.

The gradient computed are added to the input base with the names ‘grad_<var_name>_<coordinate_name>’. The volume variable is added to the input base with the name (‘cell_volume’, ‘cell’).

The curl computed are added to the input base with the names ‘<curl_name>_<coordinate_name>’ and ‘<curl_name>_modulus’

The divergence computed are added to the input base with the names ‘<div_name>’.

The Qcriterion computed are added to the input base with the names ‘Qcrit’.

Construction

import antares
myt = antares.Treatment('gradient')

Parameters

  • base: antares.Base

    The base on which the gradient will be computed.

  • coordinates: list(str)

    The coordinates used for gradient.

  • variables: list(str), default= []

    The variables for which gradient will be computed. If not given, gradient will be computed on all variables other than the coordinates.

  • vtk: bool, default= False

    If False, use the method based on Green-Ostrogradski theorem. if True, use vtk library.

  • curl: list(list(str, list(str))), default= []

    The list of list of the name of the curl to compute and the list of the vector variables for which the curl will be computed. Exemple : [ [‘vorticity’, [‘U’, ‘V’, ‘W’] ] ] the variables vorticity_<coordinate_name> and vorticity_modulus will be computed. It is assumed that vector variables are listed in the same order than coordinates.

  • divergence: list(list(str, list(str))), default= []

    The list of list of the name of the divergence to compute and the list of the vector variables for which the curl will be computed. Exemple : [ [‘dilatation’, [‘U’, ‘V’, ‘W’] ] ] the variables dilatation will be computed. It is assumed that vector variables are listed in the same order than coordinates.

  • Q criterion: list(str), default= []

    The list the velocity variables for which the Q criterion will be computed. Exemple : [‘U’, ‘V’, ‘W’] the variables Qcrit will be computed. It is assumed that vector variables are listed in the same order than coordinates.

Preconditions

Zones may be either structured or unstructured without vtk. Zones must be unstructured with vtk.

Zones may contain multiple instants and shared instant.

Coordinate and variables must be available at nodes.

Postconditions

The output base is the input base that has been modified.

If input variables are shared, then output gradients are shared.

If curl, divergence and Qcriterion of vectors are computed, intermediate computed gradients are kept in the base.

Example

The following example shows gradient computations.

import antares
myt = antares.Treatment('gradient')
myt['base'] = base
myt['coordinates'] = ['x', 'y', 'z']
myt['variables'] = ['Density', 'Pressure']
myt['vtk'] = False
myt['curl'] = [['vorticity', ['U', 'V', 'W']]]
myt['divergence'] = [['dilatation', ['U', 'V', 'W']]]
myt['Qcrit'] = ['U', 'V', 'W']
base = myt.execute()

Warning

Dependency on VTK

Warning

Gradient computation with the first method has only been implemented in 3D, and 2D with triangles.

Warning

The coordinate and variables must be available at nodes.

Warning

The gradient computed are either at cells or at nodes depending of the method used.

Warning

The computations of curl, divergence and Qcriterion assumes 3D cartesian coordinates

Main functions

class antares.treatment.TreatmentGradient.TreatmentGradient
execute()

Execute the treatment.

Returns

the base containing the initial variables and the newly computed gradient variables

Return type

antares.Base

Example

"""
This example shows how to compute the gradient of variables on a 3D base.
Note that the gradient vector computed for each variable is stored
at cell centers in the input base.
"""
import os
if not os.path.isdir('OUTPUT'):
    os.makedirs('OUTPUT')

from antares import Reader, Treatment, Writer

# ------------------
# Reading the files
# ------------------
reader = Reader('bin_tp')
reader['filename'] = os.path.join('..', 'data', 'ROTOR37', 'GENERIC', 'flow_<zone>_ite0.dat')
ini_base = reader.read()

# ---------------------
# Gradient computation
# ---------------------
treatment = Treatment('gradient')
treatment['base'] = ini_base
result = treatment.execute()

result.compute_cell_volume()
# -------------------
# Writing the result
# -------------------
writer = Writer('bin_tp')
writer['filename'] = os.path.join('OUTPUT', 'ex_gradients.plt')
writer['base'] = result
writer.dump()
"""
This example shows how to use the Treatment gradient on a poiseuille flow.
Gradients, vorticity, dilatation and stress tensors are computed.
"""
import os
import antares
import numpy as np

OUTPUT = 'OUTPUT'
if not os.path.isdir(OUTPUT):
    os.makedirs(OUTPUT)

# Define case
Re = 100000.                  # [-] Reynolds number
Mu = 8.9e-4                   # [Pa.s] Dynamic Viscosity
Rho = 997.                    # [Kg.m-3] Density
H = 0.1                       # [m] Height
L = 0.1                       # [m] Length
l = L*0.01                    # [m] thickness
Nx, Ny, Nz = 100, 100, 2      # [-] Number of nodes
P0 = 0.                       # [Pa] Ref Pressure

# Compute some values
U_mean = Re*Mu/H/Rho
U_max = 1.5*U_mean
Q = U_mean*H
dpdx = -Q/(H**3)*12.*Mu
Tau_w = -H/2.*dpdx

# Define geometry
xmin, ymin, zmin = 0., 0., 0.
xmax, ymax, zmax = L, H, l

x = np.linspace(xmin, xmax, Nx)
y = np.linspace(ymin, ymax, Ny)
z = np.linspace(zmin, zmax, Nz)

X, Y, Z = np.meshgrid(x, y, z)

# Define velocity and pressure field
U = -H**2/2./Mu*dpdx*(Y/H*(1-Y/H))
V = np.zeros_like(U)
W = np.zeros_like(V)
Pressure = P0 + X*dpdx

# Initialisation
base = antares.Base()
zone = antares.Zone()
instant = antares.Instant()
base['zone_0'] = zone
base['zone_0'].shared[('x', 'node')] = X
base['zone_0'].shared[('y', 'node')] = Y
base['zone_0'].shared[('z', 'node')] = Z
base['zone_0']['instant_0'] = instant
base['zone_0']['instant_0'][('Pressure', 'node')] = Pressure
base['zone_0']['instant_0'][('U', 'node')] = U
base['zone_0']['instant_0'][('V', 'node')] = V
base['zone_0']['instant_0'][('W', 'node')] = W

# Use vtk or not
use_vtk = False

# Unstructure base if vtk
if use_vtk:
    t = antares.Treatment('unstructure')
    t['base'] = base
    base = t.execute()
    loc = 'node'
else:
    loc = 'cell'
    base.node_to_cell(variables=['Pressure'])

# Compute gradients
treatment = antares.Treatment('Gradient')
treatment['base'] = base
treatment['coordinates'] = ['x', 'y', 'z']
treatment['variables'] = ['Pressure']
treatment['vtk'] = use_vtk
treatment['curl'] = [['vorticity', ['U', 'V', 'W']]]
treatment['divergence'] = [['dilatation', ['U', 'V', 'W']]]
base = treatment.execute()

# Compute stress tensors
base.set_computer_model('internal')

base.set_formula('Mu={:f}'.format(Mu))

base.compute('tau_xx = -2. / 3. * Mu * dilatation + Mu * (2 * grad_U_x)', location=loc)
base.compute('tau_yy = -2. / 3. * Mu * dilatation + Mu * (2 * grad_V_y)', location=loc)
base.compute('tau_zz = -2. / 3. * Mu * dilatation + Mu * (2 * grad_W_z)', location=loc)
base.compute('tau_xy = Mu * (grad_V_x + grad_U_y)', location=loc)
base.compute('tau_xz = Mu * (grad_W_x + grad_U_z)', location=loc)
base.compute('tau_yz = Mu * (grad_W_y + grad_V_z)', location=loc)

base.compute('sigma_xx = Pressure + tau_xx', location=loc)
base.compute('sigma_yy = Pressure + tau_yy', location=loc)
base.compute('sigma_zz = Pressure + tau_zz', location=loc)
base.compute('sigma_xy = tau_xy', location=loc)
base.compute('sigma_xz = tau_xz', location=loc)
base.compute('sigma_yz = tau_yz', location=loc)

# Write output
writer = antares.Writer('bin_vtk')
writer['filename'] = os.path.join(OUTPUT, 'results')
writer['base'] = base
writer.dump()