Releasing Streamlines from Centroids of Elements

imgoutA request came in the other day to release streamlines from the centroids of all of the 2D elements of the selected parts. Now, EnSight, the default seed locations are from the nodes of the parts, not the centroids. However, this user would like to release from the centroids of the parts selected.

Python to rescue. We can utilize the Calculator Capability in EnSight to compute the X,Y,Z coordinates of the selected parts, and use the “NodeToElem” to convert those three scalar variable field values to be at the centroids of each element. With Elemental Values at the centroids of the parts, we use the FlatFile export with the “CELLID” parameter and ascii format to write out the elements of selected part(s) and their elemental variables to a text file. We can then just reformat this text file into a qualified “Particle Emitter File”. Voila. Within the standard streamline creation of EnSight, we can use a “Particle Emitter File” as the seed locations for the Streamlines, and therefore generate streamlines from the centroids of all elements in the selected part(s).

See below a short little Python Code to do this operation, as well as an image of what such a release would look like.

Python Utility to create Particle Emitter File from Centroids of Parts Selected

Custom Image Save Shortcut

A customer recently asked if a more custom save image could be created. He always wants to use the “Default Print Colors”, and always wants to save out a certain image type and size. His main concern was always having to toggle on the “default print colors”, (as they are turned off after the image is saved), and the 6 mouse clicks/operations to save an image (File (1), Export(2), Image (3), specify filename (4), Default Print colors (5), and Ok (6)).

One option is to use the right Click (Right Click to Viewport — > default print colors), the Right Click again to Save image to file, then specify file name, and Ok. These are perfectly okay when saving a few images, but having to save 20 or 30 images, and you would want to look for a shortcut way to do this.

With EnSight’s scripting, and two lines of python, this can be made into a nice short macro, which would do the above steps in a single keystroke.

Here is the python macro (you can directly assign this to any of your favorite keyboard short cuts):

# Example Python to Create new Output image
import datetime
Basename = "EnSight_Image_"

# Use datetime to generate a filename with unique name
now = datetime.datetime.now()
unique_part = now.strftime("%Y-%m-%d_%H-%M-%S")
new_filename = str(Basename) + str(unique_part)

# Save the image
ensight.file.image_format("png")
ensight.anim_recorders.render_offscreen("ON")
ensight.file.image_numpasses(4)
ensight.file.image_stereo("current")
ensight.file.image_screen_tiling(1,1)
ensight.file.image_file(new_filename)
ensight.file.image_convert("ON")
ensight.file.image_window_size("HD1080p")
ensight.file.save_image()
ensight.file.image_convert("OFF")

 

Here, the three lines of python obtain the current time, and append that to the name “EnSight_Image_” in order to create a unique filename to be saved. The remaining lines in the file are direct EnSight journal commands converted to Python. Note here the use of the “image_convert” lines which do the operation of the default print colors.

So, with only three lines of python, you now can take the journal commands from a file save and make them into a quick shortcut to save an image out.

Absolute Min or Max over time

User recently asked : What is the minimum temperature experienced at any point, throughout the whole time domain?  (absolute temporal minimum) Good question. This conceptually boils down to finding the minimum at each time, and then traversing the temporal domain looking for new minimum.

The Min() function works at a particular timestep, and will automatically update when the timestep is changed, but it is not easy to keep track of what the Min(Min()) is.

EnSight already has some very helpful temporal functions to return new variables that are sampled over time. One of them is “TempMinmaxField”, which returns the minimum or maximum over time in a particular element or node. This returns a new scalar or vector field which is minimum or maximum experienced over time in each element or node. This works great, but is limited to a geometry which does not change connectivity. His geometry is changing, so this feature does not work.

However, there are some Python provided hooks into the variable information which will immediately return items like the minimum or maximum. Now, this function is not tied to any particular part, but is rather the variable attribute rather than part related quantity.

Here is an example of using that Python call to return both the absolute minimum and maximum over time for a particular variable:

# SUBROUTINE to loop through all timesteps to figure out min and max over time
def find_minmax(step_min,step_max,varname):
nstep = step_max – step_min + 1
min_val = 9e99
max_val = -9e99
ensight.variables.activate(varname)
a = ensight.query(ensight.VARIABLE_OBJECTS)
var_list = a[2]
for i in range(len(var_list)):
name_now = var_list[i]
if name_now == varname:
var_id = i
#
for i in range(nstep):
ensight.solution_time.current_step(i)
ensight.solution_time.update_to_current()
b = ensight.query(ensight.VARIABLE_INFORMATION,var_id)
local_min_val = b[2][0]
local_max_val = b[2][1]
if local_min_val < min_val:
min_val = local_min_val
if local_max_val > max_val:
max_val = local_max_val
#
return(min_val,max_val)

Part and Variable Information

For those who would like to get detailed information about their model, including part composition, elemental makeup, variable information, there is a little python tool to obtain that. Courtesy of Mr. Bill Dunn, this routine sniffs through the model and returns dataset information such as datafiles used, part composition, element counts, variables, total node and element counts.

Download recipe part_var_core_details here

Direct Access to Variable information

Want a quick look at the variables in your model? Want to figure out minimums and maximums in a few steps? Through the use of Python in EnSight, you can get direct access to items such as what variable names are available (to check to see what the dataset has, or figure out if your potential new names conflict with any already there). You can also get quick access to items like min and max (for the model). This is particularly handy with regards to Vectors, where you can direct return of all components and magnitude.

# Obtain variable min and max info
varname = "Momentum"

print "========================="
a = ensight.query(ensight.VARIABLE_OBJECTS)
var_list = a[2]
for i in range(len(var_list)):
    name_now = var_list[i]
    if name_now == varname:
        print "Found ",varname
        var_id = i
        print "Var_Id = ",var_id
        type_flag = a[1][var_id + 1]
        print "Type_flag = ",type_flag
        ensight.variables.activate(varname)
        b = ensight.query(ensight.VARIABLE_INFORMATION,var_id)
        if type_flag == 0:
            min_val = b[2][0]
            max_val = b[2][1]
            print "Min_val = ",min_val
            print "Max_val = ",max_val
        if type_flag == 1:
            minx = b[2][0]
            maxx = b[2][1]
            miny = b[2][2]
            maxy = b[2][3]
            minz = b[2][4]
            maxz = b[2][5]
            minmag = b[2][6]
            maxmag = b[2][7]
            print "Minvals = ",minx,miny,minz
            print "Maxvals = ",maxx,maxy,maxz
            print "Mag     = ",minmag,maxmag

Time and System Info

In the good ole days, users of EnSight could execute the “test: start_timer” and the “test: print_timer” to attempt to retrieve information about the time that it took to perform the operations between those two commands. Well, that may be not really enough information, or information that you can easily use or report. Python to the rescue again, this time courtesy of Randy’s “snapshot” function.

You can now use EnSight’s Python “snapshot” function to store in a dictionary not only timestamp information, but also information about client and server application memory as well as client and server memory load.

In python, you can call:

ensight.message_window.memory_snapshot("Info_t1")

“Info_t1” can be anything that you want. This creates a snapshot of client and server memory, as well timestamp information.

The call :

ensight.query(ensight.SYSINFO)['memory_snapshots']

returns a dictionary of the snapshots, indexed by the name that you gave it (in this case “Info_t1”). If you then print this line, you would get the following information:

{ 'Info_t1': {'server_freeram': 5980388,
             'timestamp': 1310502681.3050001,
             'client_freeram': 5980388,
             'server_totalram': 10485092,
             'client_appram': 247852,
             'client_cores': 8,
             'server_appram': 14288,
             'server_cores': 8,
             'client_totalram': 10485092},
}

So, let’s put this together into something useful:

ensight.message_window.memory_snapshot("Info_t1")
# Do something interesting here.
ensight.message_window.memory_snapshot("Info_t2")
d = ensight.query(ensight.SYSINFO)['memory_snapshots']
print "="*36
print "Client Ram Increase " ,(float(d['Info_t2']['client_appram']) - float(d['Info_t1']['client_appram'])) / 1024.0, " Mb"
print "Server Ram Increase " ,(float(d['Info_t2']['server_appram']) - float(d['Info_t1']['server_appram'])) / 1024.0, " Mb"
print "Time to execute was    " ,float(d['Info_t2']['timestamp']) - float(d['Info_t1']['timestamp']), " sec"

 

Side by Side Animations

As an engineer working with multiple solutions, or comparing multiple variables, it is quite useful to be able to compare images side by side, but also animations side by side. Image comparison side by side is quite easily done with Word, or Powerpoint, or even image viewers. However, the comparison of multiple animations in a side by side layout is not quite so straight forward. Sure, there are probably some fancy, and/or expensive options out there for video editing, but there is a simpler solution —- EnVe from EnSight.

Given two animations of equal length (number of frames), EnVe’s multiple tiled movie format (.mtm) can be utilized to place two animations side by side, and a new single animation created.

Here are two example animations:

Case 1 AVI

Case 2 AVI

These two animations are each 826 pixels in X, and 574 pixels in Y, and each are 30 frames. In this example of side-by-side, both animations should be the same height (but could vary in width). You can also place the animations one on top of the other, in which case you’d want to have the animations the same width, but could vary each heights.

A Simple “Multiple Tiled Movie Format” file (.mtm) contains information about how to arrange these two animations together. Here is what that file looks like:

MTM 1.0
#
# This is a Multi-Tile Movie file.
#

nummovies 2

fullresolution 1652 574

movie
   imageoffset 0 0
   format AVI
   file Case1.avi

movie
   imageoffset 826 0
   format AVI
   file Case2.avi

You can see above that we set the total number of movies, and the total dimensions of the two movies together (1652 x 574). For each movie, you can therefore set the offset (from the lower left corner). Movie #1 will have a zero offset in X and Y, while Movie #2 will be offset by 826 pixels in X.

You can read this .mtm file into EnVideo, and view a live playing of two animation files, or you can read the .mtm file into EnVe, and simply save out a new single animation file which will have both animations playing side by side. This works great to control the comparison of different models, results, or different variables from separate single animations. Given the flexibility of the .mtm file, you can tile many animations together to make a multiple animation comparison easily and without cost.

Please see below a link which has the animation files, mtm file, and the combined movie example.

Multiple Animation Example

Please see the attached PDF file for similar other operations that can be performed using EnVe… Using EnVe to Create a Single Movie from Existing Movies that Play Simultaneously

Exporting Data for Boundary Condition Input

An Engineer’s tasks is never a single input/output process. In most all problem solving situations, the engineer needs to use the tools available to “navigate the road” from problem statement to an end solution/conclusion. The exports from one tool are typically the input the next… from CAD to Grid Generation, from Grid Generation to Solver, etc. With EnSight’s flexible output capability, along with a little python knowledge, users can take the output from EnSight and construct the input/boundary condition deck for the next solver.

In this particular example, EnSight was used to analyze the results from a Discrete Element Model to visualize and analyze the forces on the surface of the DEM model. However, the next step in the engineer’s process is to take these forces and use them as a boundary condition for the particular stress solver, to resolve the deformations, stresses, and load paths as a result of these particles. Well, EnSight + Python can help here too.

Within EnSight, we read in the DEM solution, and interrogated the forces on the surface of the DEM model. We used EnSight’s capability to read in multiple models to read in a second case containing just the grid for the stress analysis. We used EnSight’s CaseMap function to map the forces from the DEM model onto the stress analysis grid.  From here, we exported the stress analysis grid (and its new force values) out of EnSight to the EnSight Case Gold format. Here is where python comes in to help us out. We need to reformat this data into a form that the stress analysis package can interpret as boundary condition information. The following python code takes the EnSight Case Gold format geometry file, along with the exported Force Vector information and generated a new input deck containing the boundary condition information for the stress analysis solver. I’ve tried to keep the code simple enough so that you can edit and customize this for your particular data, solver, and situation.

Convert Export to Boundary Condition. (remember you can run this python outside of EnSight by typing : cpython22 conv_bcs.py

EnSight Version 9.2.2; 10.0

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)