|
1 | 1 | """
|
2 | 2 | .. _ref_cycles_to_failure:
|
3 | 3 |
|
4 |
| -Generate a Cycles to Failure Result |
5 |
| -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
6 |
| -Reducing the number of calls to the server is key to improving |
7 |
| -performance. Using the ``as_local_field`` option brings the data |
8 |
| -from the server to your local machine where you can work on it. |
9 |
| -When finished, you send the updated data back to the server |
10 |
| -in one transaction. |
11 |
| -
|
12 |
| -Import necessary modules: |
| 4 | +PF-Core Fatigue Engineering Simple Example |
| 5 | +~~~~~~~~~~~~~~~~~~~~ |
| 6 | +This example shows how to generate and use a result file to calculate the |
| 7 | +cycles to failure result for a simple model. |
| 8 | +
|
| 9 | +Material data is manually imported, Structural Steel from Ansys Mechanical: |
| 10 | +Youngs Modulus (youngsSteel) |
| 11 | +Poisson's Ratio (prxySteel) |
| 12 | +Cycles to Failure (snData) |
| 13 | +
|
| 14 | +The first step is to generate a simple model with high stress and save the |
| 15 | +results .rst locally. For this we use a short pyMapdl script, commented-out here. |
| 16 | +
|
| 17 | +The second step uses DPF-Core to generate the cycles to failure result. |
| 18 | +The locally saved rst is imported and plotted. |
| 19 | +Then the von Mises stress is generated and plotted with DPF operators. |
| 20 | +The python package numpy is then used to interpolate the cycles to failure values. |
| 21 | +The nodal von Mises equivalent stress value is used in the interpolation. |
| 22 | +Note the cycles to failure data needs to be manipulated to use numpy interpolation. |
| 23 | +
|
| 24 | +An empty field is created and filled with the resulting cycles to failure values. |
| 25 | +Cycles to failure result plotted. |
| 26 | +
|
| 27 | +The cycles to failure result is the (interpolated) negative of the stress result. |
| 28 | +The higher the stress result, the lower the number of cycles to failure. |
13 | 29 | """
|
14 | 30 |
|
15 | 31 | from ansys.dpf import core as dpf
|
|
19 | 35 | # The first step is to generate a simple model with high stress
|
20 | 36 |
|
21 | 37 | # # Material parameters from Ansys Mechanical Structural Steel
|
22 |
| -# TODO: can we share that? Or that it comes from there? |
23 | 38 | youngsSteel = 200e9
|
24 | 39 | prxySteel = 0.3
|
25 | 40 | snData = np.empty((11, 2)) # initialize empty np matrix
|
26 | 41 | snData[:, 0] = [10, 20, 50, 100, 200, 2000, 10000, 20000, 1e5, 2e5, 1e6]
|
27 | 42 | snData[:, 1] = [3.999e9, 2.8327e9, 1.896e9, 1.413e9, 1.069e9, 4.41e8, 2.62e8, 2.14e8, 1.38e8,
|
28 | 43 | 1.14e8, 8.62e7]
|
29 | 44 |
|
| 45 | +############################################################################### |
| 46 | + |
30 | 47 | # This .rst file is here already available but can be obtained using the short pyMapdl code below:
|
31 | 48 |
|
32 | 49 | # # ### Launch pymapdl to generate rst file in myDir
|
33 | 50 | # from ansys.mapdl.core import launch_mapdl
|
| 51 | +# import os |
34 | 52 | #
|
35 | 53 | #
|
36 |
| -# myDir = r'c:\temp' |
37 |
| -# mapdl = launch_mapdl(run_location=myDir) |
| 54 | +# mapdl = launch_mapdl() |
38 | 55 | # mapdl.prep7()
|
39 | 56 | # # Model
|
40 | 57 | # mapdl.cylind(0.5, 0, 10, 0)
|
|
56 | 73 | # # #### Solve
|
57 | 74 | # mapdl.run("/SOLU")
|
58 | 75 | # sol_output = mapdl.solve()
|
| 76 | +# rst = os.path.join(mapdl.directory, 'file.rst') |
59 | 77 | # mapdl.exit()
|
60 | 78 | # print('apdl model solved.')
|
61 |
| -# rst = myDir + '\\file.rst' |
62 | 79 |
|
63 |
| -# ##### pydpf is then used to post process the .rst in order to estimate the cycles to failure |
| 80 | +############################################################################### |
| 81 | + |
| 82 | +# PyDPF-Core is then used to post process the .rst in order to estimate the cycles to failure |
64 | 83 |
|
65 |
| -# Comment the two following lines if solving the mapdl problem first |
| 84 | +# Comment the two following lines if solving the mapdl problem first. |
66 | 85 | from ansys.dpf.core import examples
|
67 | 86 | rst = examples.cyclic_to_failure
|
| 87 | +# |
68 | 88 |
|
| 89 | +# Import the result as a DPF Model object. |
69 | 90 | model = dpf.Model(rst)
|
70 | 91 | print(model)
|
| 92 | +# Get the mesh. |
71 | 93 | mesh = model.metadata.meshed_region
|
72 | 94 |
|
73 |
| -# Get the von mises equivalent stress, requires an operator |
| 95 | +############################################################################### |
| 96 | + |
| 97 | +# Get the von mises equivalent stress, requires an operator. |
74 | 98 | s_eqv_op = dpf.operators.result.stress_von_mises()
|
75 | 99 | s_eqv_op.inputs.data_sources.connect(model)
|
76 | 100 | vm_stress_fields = s_eqv_op.outputs.fields_container()
|
77 | 101 | vm_stress_nodal = vm_stress_fields[0]
|
78 | 102 | vm_stress_nodal.plot()
|
79 | 103 |
|
| 104 | +############################################################################### |
| 105 | + |
80 | 106 | # Use numpy to interpolate the results.
|
81 | 107 | vm_stress = vm_stress_nodal.data
|
82 | 108 | myNodes = vm_stress_nodal.scoping.ids
|
83 | 109 | xPoints = snData[:, 1][::-1] # the x values are the stress ranges in ascending order
|
84 | 110 | yValues = snData[:, 0][::-1] # y values are inverted cycles to failure
|
85 | 111 |
|
86 |
| -myResult = np.ones((len(myNodes), 3)) |
87 |
| -myResult[:, 0] = myNodes |
88 |
| -myResult[:, 1] = vm_stress # UNITS!!!! |
89 |
| -myResult[:, 2] = np.interp(myResult[:, 1], xPoints, yValues) |
| 112 | +my_result = np.ones((len(myNodes), 3)) |
| 113 | +my_result[:, 0] = myNodes |
| 114 | +my_result[:, 1] = vm_stress # UNITS!!!! |
| 115 | +my_result[:, 2] = np.interp(my_result[:, 1], xPoints, yValues) |
| 116 | + |
| 117 | +############################################################################### |
90 | 118 |
|
91 |
| -# #Create an empty field, add nodes/results and plot |
92 |
| -myResultField = dpf.Field(len(myNodes), dpf.natures.scalar, 'Nodal') |
| 119 | +# Create an empty field, add nodes/results and plot |
| 120 | +my_result_field = dpf.Field(len(myNodes), dpf.natures.scalar, 'Nodal') |
93 | 121 | my_scoping = dpf.Scoping()
|
94 | 122 | my_scoping.location = 'Nodal'
|
95 |
| -my_scoping.ids = myResult[:, 0] |
96 |
| -myResultField.scoping = my_scoping |
97 |
| -myResultField.data = myResult[:, 2] |
98 |
| -mesh.plot(myResultField) |
99 |
| -# This is a way to plot w/out units/label |
100 |
| - |
101 |
| -# # The cycles to failure result is the (interpolated) negative of the stress result. |
102 |
| -# # The higher the stress result, the lower number of cycles to failure. |
| 123 | +my_scoping.ids = my_result[:, 0] |
| 124 | +my_result_field.scoping = my_scoping |
| 125 | +my_result_field.data = my_result[:, 2] |
| 126 | +mesh.plot(my_result_field) |
0 commit comments