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#

Load model, contour composite stress and export H3D / PNG#
 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(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#

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(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#

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(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 NumPy Array with Default Settings#

Query scalar, vecor and tensor results using default settings#
 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
 9ses = hw.Session()
10ses.new()
11win= ses.get(hw.Window)
12# Set Window to Animation
13win.type = 'animation'
14# Add Model
15win.addModelAndResult(modelFile, result=resultFile)
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# Set View
28hw.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')
29# Set time step
30animTool=hw.AnimationTool()
31animTool.currentFrame=res.getSimulationIds()[-2]
32win.draw()
33print('')
34print('Query with Defaults')
35print('-------------------')
36# Create Query Result Tool
37import hw.hv.queryresultstool as hv
38qt=hv.QueryResultsTool()
39print('Data Source Info:')
40# Get available data source info array
41dataSourceInfoArray = qt.getDataSourceInfo()
42print(dataSourceInfoArray)
43# Query NumPy with default settings
44na=qt.query()
45print('')
46# Get data source query created by default
47dsq = qt.getDataSourceQuery()
48print('Default data source query = {}'.format(dsq))
49# Get default collection
50entCol=qt.collection
51print('Size of default {} collection = {}'.format(entCol.entityType,entCol.getSize()))
52print('')
53# NumPY array
54print('NumPy Array:')
55print('Length numpy array = {}'.format(len(na)))
56print(na)
../../_images/image_HV_query_default_settings.PNG

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

Example 05 - Query NumPy Array with Custom Query#

Query scalar values and other element attributes using custom query#
 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
 9ses = hw.Session()
10ses.new()
11win=ses.get(hw.Window)
12# Set Window to Animation
13win.type = 'animation'
14# Add Model
15win.addModelAndResult(modelFile, result=resultFile)
16model = ses.get(hv.Model)
17# Set scalar results
18res = ses.get(hv.Result)
19resScalar = hv.ResultDefinitionScalar(dataType='Stress',
20                dataComponent='vonMises')
21res.plot(resScalar)
22
23animTool=hw.AnimationTool()
24animTool.currentFrame=1
25win.draw()
26
27# Create element collection
28elemCol=hv.Collection(hv.Element,populate=False)
29# Add all elements with a value > 0
30valFilter=hv.FilterByScalar(operator='>',value=100)
31elemCol.addByFilter(valFilter)
32
33# Create Query Result Tool
34qt=hv.QueryResultsTool()
35# Set Element Collection
36qt.collection = elemCol
37print('')
38qt.setDataSourceQuery(
39    [['element', 'id'],
40    ['contour', 'value'],
41    ['element','config'],
42    ['component','pool'],
43    ['component','name'],
44    ['element','normal']]
45)
46# Data source query
47print('Data source query = {}'.format(qt.getDataSourceQuery()))
48# Query NumPy array
49na=qt.query()
50print('')
51# Get default collection
52print('Size of {} collection with value > 0 = {}'.format(elemCol.entityType,elemCol.getSize()))
53print('')
54# NumPY array
55print('NumPy Array:')
56print('Length numpy array = {}'.format(len(na)))
57print(na)
../../_images/image_HV_query_custom_settings.PNG

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