Results#

Some examples require external input files. Before you start, please follow the link in the Example Scripts section to download the zip file with model and result files.

Example 01 - Contour Model and Export#

The example code shows how to set the window to HyperView client (type="animation") and display a contour plot of Von Mises composite stress using the ResultDefinitionScalar class. Once the results are plotted, two new objects are created - instances of the ExportModelH3D class and CaptureImageTool class respectively. The exportH3D object is used to export an H3D file containing the displayed results and the captureImage object provides the method to capture a screenshot of the window.

 1import hw
 2import hw.hv as hv
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8h3dFile = os.path.join(scriptDir, "demo_model_export.h3d")
 9jpgFile = os.path.join(scriptDir, "demo_image_export.jpeg")
10
11ses = hw.Session()
12ses.new()
13win = ses.get(hw.Window)
14win.type = "animation"
15
16win.addModelAndResult(model=modelFile, result=resultFile)
17res = ses.get(hv.Result)
18resScalar = hv.ResultDefinitionScalar(
19    dataType="Composite Stress",
20    dataComponent="vonMises",
21    layer="Max"
22)
23res.plot(resScalar)
24
25exportH3D = hv.ExportModelH3D(
26    animation=True,
27    previewImage=False,
28    compressOutput=True,
29    compressionLoss=0.05,
30    file=h3dFile,
31)
32
33captureImage = hw.CaptureImageTool(
34    type="jpg",
35     width=3000,
36    height=2000,
37    file=jpgFile
38)
39
40animTool = hw.AnimationTool()
41animTool.currentFrame = 1
42
43hw.evalHWC("view orientation iso")
44exportH3D.export()
45captureImage.capture()
../../_images/image_model_contour_and_export.png

Figure 1. Output of ‘Contour Model and Export’

Example 02 - Macro with GUI#

The Macro with GUI example consists of two main functions - MyCustomGui() and postprocAuto().

MyCustomGui() generates a custom dialog using the Dialog class with the following widgets:

  • OpenFileEntry to specify the model file

  • OpenFileEntry to specify the result file

  • ChooseDirEntry to specify the output directory

  • Button to provide the close function

  • Button to provide the run function

The widgets are organized into a vertical frame using the VFrame class. The example also includes code to automatically populate the file paths for demo purposes.

postprocAuto() provides the postprocessing logic. Two new objects are created at the start: capture for screenshot generation and exportH3D for H3D file export. This is followed by the definition of two dictionaries: resDict contains list of data components for four different data types and legDict contains legend settings for each of the four data types. These dictionaries are used in nested loops to generate a page per data type, each page containing four windows (layout=9), one window per data component.

Macro with GUI, loop over results, export of images and H3D#
  1import hw
  2import hw.hv as hv
  3from hwx import gui
  4import os
  5
  6def MyCustomGui():
  7
  8    # Method called on clicking 'Close'.
  9    def onClose(event):
 10        dialog.Hide()
 11
 12    def onRun(event):
 13        dialog.Hide()
 14        postprocAuto(modelFile.value, resultFile.value, folderSel.value)
 15        gui.tellUser("Done!")
 16
 17    label1 = gui.Label(text="Model File")
 18    modelFile = gui.OpenFileEntry(placeHolderText="Model File")
 19    label2 = gui.Label(text="Result File")
 20    resultFile = gui.OpenFileEntry(placeHolderText="Result File")
 21    label3 = gui.Label(text="Screenshot Folder")
 22    folderSel = gui.ChooseDirEntry(tooltip="Select output directory")
 23
 24    close = gui.Button("Close", command=onClose)
 25    create = gui.Button("Run", command=onRun)
 26
 27    # Default file settings for quick demo purposes
 28    if True:
 29        src_path = os.path.dirname(os.path.abspath(__file__))
 30        modelFile.value = os.path.join(src_path, "aerobox", "aerobox.fem").replace(
 31            "\\", "/"
 32        )
 33        resultFile.value = os.path.join(
 34            src_path, "aerobox", "aerobox-LC1-2.op2"
 35        ).replace("\\", "/")
 36        folderSel.value = os.path.join(src_path, "outDir").replace("\\", "/")
 37
 38    mainFrame = gui.VFrame(
 39        (label1, 20, modelFile),
 40        (label2, 20, resultFile),
 41        (label3, 20, folderSel),
 42        (create, close),
 43    )
 44
 45    dialog = gui.Dialog(caption="Post Automation")
 46    dialog.addChildren(mainFrame)
 47    dialog.width = 400
 48    dialog.height = 100
 49    dialog.show()
 50
 51
 52def postprocAuto(modelPath, resultPath, outDir):
 53
 54    # Create Session Pointer
 55    ses = hw.Session()
 56    # New
 57    ses.new()
 58
 59    # Define Capture Image Tool
 60    capture = hw.CaptureImageTool()
 61    capture.type = "jpg"
 62    capture.width = 1200
 63    capture.height = 800
 64
 65    # Define H3D export
 66    exportH3D = hv.ExportModelH3D(
 67        animation=True, previewImage=False, compressOutput=True, compressionLoss=0.05
 68    )
 69
 70    # Dictionary with dataType dependent result scalar settings
 71    resDict = {
 72        "Displacement": ["Mag", "X", "Y", "Z"],
 73        "Composite Stress": ["vonMises", "P1 (major)", "P2 (mid)", "P3 (minor)"],
 74        "Composite Strain": ["vonMises", "XX", "YY", "ZZ"],
 75        "Stress": [
 76            "vonMises",
 77            "MaxShear",
 78            "In-plane P1 (major)",
 79            "In-plane P2 (minor)",
 80        ],
 81    }
 82
 83    # Dictionary with dataType dependent legend settings (precision, numerical format,
 84    legDict = {
 85        "Displacement": [5, "scientific", 2],
 86        "Composite Stress": [6, "engineering", 4],
 87        "Composite Strain": [7, "fixed", 6],
 88        "Stress": [10, "engineering", 2],
 89    }
 90    # Change window type
 91    ses.get(hw.Window).type = "animation"
 92
 93    startPageId = ses.get(hw.Page).id + 1
 94
 95    # Loop over data types, 1 page per data type
 96    for dType in list(resDict.keys()):
 97        ap = hw.Page(title=dType, layout=9)
 98        ses.setActive(hw.Page, page=ap)
 99
100        # Loop over data components, one window per component
101        for i, w in enumerate(ses.getWindows()):
102            dComp = resDict.get(dType)[i]
103            ses.setActive(hw.Window, window=w)
104
105            # Load Model
106            w.addModelAndResult(model = modelPath, result=resultPath)
107
108            # Set scalar results
109            res = ses.get(hv.Result)
110            resScalar = ses.get(hv.ResultDefinitionScalar)
111            resScalar.setAttributes(dataType=dType, dataComponent=dComp)
112
113            # Plot results
114            res.plot(resScalar)
115
116            # Define legend settings
117            leg = ses.get(hv.LegendScalar)
118            leg.setAttributes(
119                numberOfLevels=legDict.get(dType)[0],
120                numericFormat=legDict.get(dType)[1],
121                numericPrecision=legDict.get(dType)[2],
122            )
123
124            # Define ISO settings
125            resIso = ses.get(hv.ResultDefinitionIso)
126            resIso.setAttributes(dataType=dType, dataComponent=dComp)
127            dispIso = ses.get(hv.ResultDisplayIso)
128            res.plotIso(resIso)
129
130            # Set ISO value dependent on min/max
131            dispIso.value = leg.minValue + (leg.maxValue - leg.minValue) / 5
132
133            # Set animation frame 1
134            animTool = hw.AnimationTool()
135            animTool.currentFrame = 1
136
137            # Capture jpg
138            jpgPath = os.path.join(outDir, dType + " - " + dComp + "_iso_view.jpg")
139            capture.file = jpgPath
140            capture.capture()
141
142            # Capture H3D
143            h3dPath = os.path.join(outDir, dType + " - " + dComp + ".h3d")
144            exportH3D.setAttributes(file=h3dPath, window=w)
145            exportH3D.export()
146
147            # Use Model, Collection and Part class to isolate component
148            if True:
149                mod = ses.get(hv.Model)
150                col = hv.Collection(hv.Part)
151                mod.hide(col)
152                mod.get(hv.Part, 172).visibility = True
153            # Use evalHWC isolate component for export
154            else:
155                hw.evalHWC("hide component all")
156                hw.evalHWC("show component 172")
157
158            # Set Views and export
159            hw.evalHWC("view orientation left")
160            jpgPath = os.path.join(outDir, dType + " - " + dComp + "_left_view.jpg")
161            capture.file = jpgPath
162            hw.evalHWC("show component all")
163            hw.evalHWC("view orientation iso")
164
165    ses.setActive(hw.Page, id=startPageId)
166
167
168if __name__ == "__main__":
169    MyCustomGui()
../../_images/image_Macro_GUI_and_Export.png

Figure 2. Start GUI and exported images / H3D’s of ‘Macro with GUI’

../../_images/image_Macro_Page_per_DataType.PNG

Figure 3. hw.Page created for one data type by ‘Macro with GUI’

Example 03 - Contour Maximum by Sphere#

After the standard steps (setting up the window, loading the model/result files, and contouring the results), the example shows the user how to select elements around the element with the maximum contour plot value using FilterBySphere. It proceeds with setting up custom properties of the legend, including custom header font. It then displays the contour plot only on the entities inside the sphere collection. Finally, it creates a note using the HWC commands, sets the results to the first animation frame and puts the model into an iso orientation.

Contour max sphere by collection with filters, modify legend#
 1import hw
 2import hw.hv as hv
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8
 9hotspotRadius = 400
10
11# Load Model
12ses = hw.Session()
13ses.new()
14page = ses.get(hw.Page)
15win = ses.get(hw.Window)
16win.type = "animation"
17win.addModelAndResult(model=modelFile, result=resultFile)
18
19# Contour scalar
20res = ses.get(hv.Result)
21resScalar = ses.get(hv.ResultDefinitionScalar)
22resScalar.setAttributes(
23    dataType="Composite Stress", dataComponent="vonMises", layer="Max"
24)
25res.plot(resScalar)
26
27# Create Collection via TopN filter
28maxElemCol = hv.Collection(hv.Element, populate=False)
29elemFilter = hv.FilterByScalar(operator="topN", value=1)
30maxElemCol.addByFilter(elemFilter)
31
32# Get centroid of element with maximum scalar value
33maxElem = maxElemCol.getEntities()[0]
34centroid = maxElem.centroid
35
36# Create collection with given radius
37sphereCol = hv.Collection(hv.Element, populate=False)
38sphereFilter = hv.FilterBySphere(
39    x=centroid[0],
40    y=centroid[1],
41    z=centroid[2],
42    radius=hotspotRadius
43)
44sphereCol.addByFilter(sphereFilter)
45
46# Define font
47headFont = hw.Font(size=14, style="bold")
48
49# Modify legend
50legend = ses.get(hv.LegendScalar)
51legend.setAttributes(
52    headerText="Hostpot Radius = " + str(hotspotRadius),
53    headerVisible=True,
54    headerFont=headFont,
55    numberOfLevels=8,
56    numericFormat="fixed",
57    numericPrecision=0,
58)
59
60# Contour only sphere collection
61resScalar.collection = sphereCol
62res.plot(resScalar)
63
64# Attach max note with evalHWC
65maxId = str(maxElem.id)
66maxLabel = "Max Element " + maxId
67hw.evalHWC('annotation note create "' + maxLabel + '"')
68hw.evalHWC('annotation note "'
69        + maxLabel
70        + '" attach entity element '
71        + maxId
72)
73hw.evalHWC(
74    'annotation note "'
75    + maxLabel
76    + '" \
77    display text= "Max Element: {entity.id}\\nMax Value: {entity.contour_val}" \
78    movetoentity=true \
79    filltransparency=false \
80    fillcolor="255 255 255"'
81)
82
83# Set frame with AnimationTool()
84animTool = hw.AnimationTool()
85animTool.currentFrame = 1
86
87# Modify view with evalHWC
88hw.evalHWC("view orientation iso")
../../_images/image_Contour_by_Sphere.png

Figure 4. Output of ‘Contour Maximum by Sphere

Example 04 - Query Result Data with Default Settings#

The example shows how to set up a contour, vector, and tensor plot, followed by the querying of the displayed results using QueryResultsTool. An instance of this class is created and the result data is extracted into a Numpy array using the query() method. The default settings/attribute of the QueryResultsTool object are used.

 1import hw
 2import hw.hv as hv
 3import os
 4
 5ALTAIR_HOME = os.path.abspath(os.environ['ALTAIR_HOME'])
 6modelFile   = os.path.join(ALTAIR_HOME,'demos','mv_hv_hg','animation','dyna','bumper','bumper_deck.key')
 7resultFile  = os.path.join(ALTAIR_HOME,'demos','mv_hv_hg','animation','dyna','bumper','d3plot')
 8
 9# Load Model/Results
10ses = hw.Session()
11ses.new()
12win = ses.get(hw.Window)
13win.type = 'animation'
14win.addModelAndResult(model=modelFile, result=resultFile)
15
16# Set scalar, vector and tensor results
17res = ses.get(hv.Result)
18resScalar = hv.ResultDefinitionScalar(dataType='Stress',
19                dataComponent='vonMises')
20res.plot(resScalar)
21resVector = hv.ResultDefinitionVector(dataType='Stress')
22res.plot(resVector)
23resTensor = hv.ResultDefinitionTensor(dataType='Stress')
24resTensor.format = 'component'
25resTensor.setComponentStatus(xx=True,yy=True,zz=True,xy=True,yz=True,zx=True)
26res.plot(resTensor)
27
28# Set View
29hw.evalHWC('view projection orthographic | view matrix -0.021537 0.988942 0.146732 0.000000 0.872753 0.090190 -0.479758 0.000000 -0.487686 0.117728 -0.865045 0.000000 -99.918198 345.190369 584.070618 1.000000 | view clippingregion -284.806213 129.713852 528.670959 864.158752 -722.333801 601.748169')
30
31# Set time step
32animTool = hw.AnimationTool()
33animTool.currentFrame = res.getSimulationIds()[-2]
34win.draw()
35print('')
36print('Query with Defaults')
37print('-------------------')
38
39# Create Query Result Tool
40queryTool = hv.QueryResultsTool()
41print('Data Source Info:')
42
43# Get available data source info array
44dataSourceInfoArray = queryTool.getDataSourceInfo()
45print(dataSourceInfoArray)
46
47# Query NumPy with default settings
48queriedData = queryTool.query()
49print('')
50
51# Get data source query created by default
52dataSource = queryTool.getDataSourceQuery()
53print('Default data source query = {}'.format(dataSource))
54
55# Get default collection
56entCol = queryTool.collection
57print('Size of default {} collection = {}'.format(entCol.entityType,entCol.getSize()))
58print('')
59
60# NumPY array
61print('NumPy Array:')
62print('Length numpy array = {}'.format(len(queriedData)))
63print(queriedData)
../../_images/image_HV_query_default_settings.PNG

Figure 5. Console output of query NumPy array with default settings

Example 05 - Query Result Data with Custom Query#

After the standard steps (setting up the window, loading the model/result files, and contouring the results), the example shows how to create a collection of elements with the scalar value greater than 100 using FilterByScalar. This collection is used as the input for the QueryResultsTool object in order to extract the data only for a specific entity selection. The queried data is defined via the setDataSourceQuery() method and extracted into a Numpy array using the query() method.

 1import hw
 2import hw.hv as hv
 3import os
 4
 5ALTAIR_HOME = os.path.abspath(os.environ['ALTAIR_HOME'])
 6modelFile   = os.path.join(ALTAIR_HOME,'demos','mv_hv_hg','animation','dyna','bumper','bumper_deck.key')
 7resultFile  = os.path.join(ALTAIR_HOME,'demos','mv_hv_hg','animation','dyna','bumper','d3plot')
 8
 9# Load Model/Results
10ses = hw.Session()
11ses.new()
12win=ses.get(hw.Window)
13win.type = 'animation'
14win.addModelAndResult(model=modelFile, result=resultFile)
15
16# Set scalar results
17res = ses.get(hv.Result)
18resScalar = hv.ResultDefinitionScalar(dataType='Stress',
19                dataComponent='vonMises')
20res.plot(resScalar)
21
22animTool = hw.AnimationTool()
23animTool.currentFrame = 1
24win.draw()
25
26# Create element collection
27elemCol = hv.Collection(hv.Element,populate=False)
28
29# Add all elements with a value > 0
30valFilter = hv.FilterByScalar(operator='>',value=100)
31elemCol.addByFilter(valFilter)
32
33# Create Query Result Tool
34queryTool =  hv.QueryResultsTool()
35
36# Set Element Collection
37queryTool.collection = elemCol
38print('')
39queryTool.setDataSourceQuery(
40    [['element', 'id'],
41    ['contour', 'value'],
42    ['element','config'],
43    ['component','pool'],
44    ['component','name'],
45    ['element','normal']]
46)
47
48# Data source query
49print('Data source query = {}'.format(queryTool.getDataSourceQuery()))
50
51# Query NumPy array
52queriedData = queryTool.query()
53print('')
54
55# Get default collection
56print('Size of {} collection with value > 0 = {}'.format(elemCol.entityType,elemCol.getSize()))
57print('')
58
59# NumPY array
60print('NumPy Array:')
61print('Length numpy array = {}'.format(len(queriedData)))
62print(queriedData)
../../_images/image_HV_query_custom_settings.PNG

Figure 6. Console output of query NumPy array with custom query