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