About Bill

EnSight Engineering Software Developer

Merging multiple time periods of a CFx simulation into one

During the calculation of a CFx simulation, the solver can stop and restart. When this happens, the user can only export one dataset in Case Gold format for each one of the restarts, making it impossible to load the solution in EnSight as a single transient dataset. In this scenario, some operations such as the calculation of the temporal average, or the creation of plots vs. time over all the timeline, will not be possible.

If this is the problem you are facing, then you can use this User Defined Tool presented in this article to concatenate the datasets from the restarts into a single transient Case Gold dataset. The Tool will take care of distinguishing between changing or static connectivity, and will check the sequence of timesteps to create a unique timeset with increasing timesteps.

Shown below is the structure of the directories with the data that you need to have to run this UDT. Note that there is no constraint on the directory names – only on their structure

Transient data

Data1

Data2

…..

DataN

In this example, Data1 will contain the dataset for the first restart, Data2 will contain the dataset for the second restart, and so on.

Download the attached file, un-zip it and place the files into your local UDT directory (which by default is in $CEI_HOME/ensight101/site_preferences/extensions/user_defined/Tools). Open EnSight a first time with the “-no_prefs” option to initially load this tool, and then restart EnSight  normally. Now, you will find the tool among the User Defined Tools.

Double-click on the tool lo launch it. It will pop-up a window asking for the first .case file. Select it and give “Ok”.

The script creates an additional ZData directory under the Transient_Data directory. In this new ZData you will find the new concatenated dataset. Note that the script makes a copy of the original files, doesn’t move/delete them. This means that you can end up using a lot of disk space, if your initial dataset is large.

Please feel free to contact us if you have any question or problem in using this Tool

Marina

CFX_join

Converting Plot3D variables to dimensional variables

PLOT3D variables in EnSight are non-dimensional.  They are non-dimensionalized in a somewhat arcane calculation.  The density is scaled by the freestream density, the momentum is scaled by the product of the  freestream density and the speed of sound, and the Energy is scaled by the product of the freestream density and the speed of sound squared.

For those who don’t want to go through this calculation of dimensioned variables manually and want access to the engineering variables in consistent, user-selected units at a user-selected altitude from a PLOT3D calculation, this script calculates the extended plot3d variables in either SI or English units. This script uses the non-dimensional Plot3D Energy, Density, and Momentum variables in its calculation. This script is assumes Earth atmospheric data. So, it is not valid for calculations on Mars, nor is it valid for calculations in water.

If ‘Energy’, ‘Density’ and ‘Momentum’ all exist then the script will prompt the user for unit type (SI or English) and the altitude and then use a lookup table to find the corresponding variables in consistent units.  The code will then calculate a Density_true, Momentum_true, and Energy_true variables (which have consistent units for the user input)  and use those to calculate the extended CFD variables.

Click below to download the zipped EnSight Python Script

extended_cfd_with_units4.py

Gamma Uniformity Index

The Gamma Uniformity Index is a measure of flow uniformity on a clip plane.

It is the normalized RMS of the difference between the local velocity and the spatial mean of the velocity integrated over the area of the clip plane.  See the attached equation.

Gamma Uniformity Equation

Equation for Gamma Uniformity

Attached is a demonstration of EnSight Python for calculating the Gamma Uniformity Index. This is only intended as a prototype demonstration script for calculating this variable.

Directions for use: make a clip plane in your flow. Select the clip plane part.  If your velocity variable is different than ‘VELOCITY’ then you will have to edit this .py file to the correct variable name. Now run this script. You will have several intermediate variables calculated, but the gamma uniformity index is a constant named gam_uniform.

gamma_uniformity_index.py

 

temporal statistics

The EnSight calculator has the StatMoment function to calculate spatial  statistical quantities: mean, variance, skew, and kurtosis as shown in the image below from the User Manual.

But the EnSight calculator includes only the ability to calculate three temporal statistical quantities, min max and mean using two calculator functions.  An EnSight Python script is provided to calculate temporal mean, temporal variance, temporal skew and temporal kurtosis as well as temporal sum, temporal RMS, temporal min and temporal max scalars.  These are calculated over time rather than space, resulting in a spatial scalar with each element containing it’s temporal statistics.

These variables are named per the comments in the python script.

The user will have to edit this python script and change the variable name var_name to be their variable name, change the begin and end time values, and change the values of the variance_flag, skew_flag, and kurt_flag to True or False, in order to calculate these values.  Note that in order to calculate variance, skew or kurtosis, all other previous values must be True.

Note that an entire pass through all the timesteps is required for each of the temporal statistical values requested. That is, mean, variance, skew and kurtosis will require a total of 4 passes through all time.  Temporal sum, temporal RMS, temporal min, and temporal max will require an additional 4 passes.  For large datasets with a large number of times this can take quite a while.  First run this with the variance, skew and kurtosis flags set to false and set the min and max time close together to get an idea of how long it takes for one pass through.

Note that this will work for static geometry with temporal variables, or changing coordinate geometry with temporal variables.  It will not work for changing connectivity geometry, where the geometry connectivity changes at each timestep.  Do a query>dataset to determine if what kind of geometry is in your specific dataset.

The python script makes creative use of the temporal mean function included in EnSight to do temporal integrations using intermediate variables.  The Temporal Mean calculator function in EnSight uses, by default, the Trapezoidal rule for temporal integration.  The results using this integration are shown below.

 

Temporal Statistics Results for Flow2d Dataset

As of EnSight 9.2.2(e), a statistical integration option is allowed for Temporal Mean.  This methodology simply uses the data and the step size in a rectangular integration. This python script turns this form of integration on for the duration of the script then restores it back to the default of using Trapezoidal Rule.  Shown below are the results using this new statistical integration.  For this dataset there is not significant difference until the kurtosis.

and the temporal sum, min, max, and RMS are shown below.

Click on the link below to get the python script.

temporal_statistics7

Python float to C-standard string

import os
#
#    This routine converts a float value to a % 12.5e  string with two places for the exponent.
#      Microsoft has decided to defy the C Standards and write out three values in the
#        exponent [-]m.ddddde+xxx  rather than only two per the C STANDARD [-]m.ddddde+xx
#
def float_to_exponent_string(float_val):
    # converts a float to a 12-character string with three-character exponent (windows)
    #   or a two-character exponent on all other platforms.
    # First, get positives and negatives printed out with 13 characters
    #  (positives get padded with a space on left)
    if (os.name == 'nt'):
        out_str = " %12.5e" % float(float_val)
        # first digit of three-digit exponent should be a zero; remove it
        # else round to exponent of 99
        for i in range(len(out_str)):
            if out_str[i] == 'e':
                first_ex = i+2
                break
        #print "\npreconvert: '",out_str,"'"
        #print "out_str[",first_ex,"]: '",out_str[first_ex],"'"
        #print "out_str[0:",first_ex,"]: '",out_str[0:first_ex],"'"
        #print "out_str[",first_ex+1,":13]: '",out_str[first_ex+1:first_ex+3],"'"
        if (out_str[first_ex] != '0'):
            out_str = out_str[0:first_ex] + '99'
        else:
            out_str = out_str[0:first_ex] + out_str[first_ex+1:first_ex+3]
    else:
        out_str = " %12.5e" % float(float_val)
#
    if out_str[1] == '-' or (out_str[0]==' ' and out_str[1]==' '):
        out_str = out_str[1:]

    #print "length out_str = ",len(out_str)
    #print "postconvert: '",out_str,"'"

    return(out_str)

select 0d, 1d, 2d, 3d parts

here’s how to select parts based on element type

 

Here is a link to a python file

select_parts_0D_1D_2D.py

from ensight.objs import *

#
#
#
def echo_part_elem_type(p):
    if p.HAS1DELEMENTS:
        print p.DESCRIPTION, " has 1D line elements"
    if p.HAS2DELEMENTS:
        print p.DESCRIPTION, " has 2D surface elements"
    if p.HAS3DELEMENTS:
        print p.DESCRIPTION, " has 3D volume elements"
    #  Ensight 10 only
    #if p.HAS0DELEMENTS:
    #    print p.DESCRIPTION, " has 0D point elements"
    #
    # STRUCTURED MODEL PART
    #
    if p.PARTTYPE == ensight.PART_MODEL:
        if p.NODERANGESTEPI[0] > 0 and p.NODERANGESTEPI[1] > 0 and p.NODERANGESTEPI[2] > 0:
            print "Structured I from ", p.NODERANGESTEPI[0] , " to ", p.NODERANGESTEPI[1], " by step " , p.NODERANGESTEPI[2]
        if p.NODERANGESTEPJ[0] > 0 and p.NODERANGESTEPJ[1] > 0 and p.NODERANGESTEPJ[2] > 0:
            print "Structured J from ", p.NODERANGESTEPJ[0] , " to ", p.NODERANGESTEPJ[1], " by step " , p.NODERANGESTEPJ[2]
        if p.NODERANGESTEPK[0] > 0 and p.NODERANGESTEPK[1] > 0 and p.NODERANGESTEPK[2] > 0:
            print "Structured K from ", p.NODERANGESTEPK[0] , " to ", p.NODERANGESTEPK[1], " by step " , p.NODERANGESTEPK[2]
    print
    return
#
#  Note this methodology will work in ES10
#
for p in core.PARTS:
    if p.ISGROUP == True:
        if p.sources:
            for subp in p.sources:
                echo_part_elem_type(subp)
    else:
        echo_part_elem_type(p)