|
1 | | -""" |
2 | | -/usr/ansys_inc/v241/ansys/bin/ansys241 -port 50005 -grpc |
3 | | -""" |
| 1 | +"""/usr/ansys_inc/v241/ansys/bin/ansys241 -port 50005 -grpc""" |
| 2 | + |
4 | 3 | import os |
5 | 4 |
|
6 | 5 | import numpy as np |
7 | 6 | from tesseract_core import Tesseract |
8 | 7 |
|
9 | | - |
10 | 8 | # load the MAPDL server's address from your environment |
11 | 9 | host = os.getenv("MAPDL_HOST") |
12 | 10 | if host is None: |
13 | | - raise ValueError("Unable to read $MAPDL_HOST from the environment. " + \ |
14 | | - "Use 'export MAPDL_HOST=X.X.X.X' for local IP address of your MAPDL Instance.") |
| 11 | + raise ValueError( |
| 12 | + "Unable to read $MAPDL_HOST from the environment. " |
| 13 | + + "Use 'export MAPDL_HOST=X.X.X.X' for local IP address of your MAPDL Instance." |
| 14 | + ) |
15 | 15 | port = os.getenv("MAPDL_PORT") |
16 | 16 | if port is None: |
17 | | - raise ValueError("Unable to read $MAPDL_PORT from the environment. " + \ |
18 | | - "Use 'export MAPDL_PORT=X' for the port of your MAPDL Instance.") |
| 17 | + raise ValueError( |
| 18 | + "Unable to read $MAPDL_PORT from the environment. " |
| 19 | + + "Use 'export MAPDL_PORT=X' for the port of your MAPDL Instance." |
| 20 | + ) |
19 | 21 |
|
20 | 22 |
|
21 | 23 | # Initialize Tesseract from api (for testing) |
22 | 24 | try: |
23 | | - tess_simp_compliance = Tesseract.from_tesseract_api( |
24 | | - "./tesseract_api.py" |
| 25 | + tess_simp_compliance = Tesseract.from_tesseract_api("./tesseract_api.py") |
| 26 | +except RuntimeError: |
| 27 | + raise RuntimeError( |
| 28 | + "Unable to load tesseract from api. " |
| 29 | + "Ensure that you have installed the build requirements using 'pip install -r tesseract_requirements.txt'" |
25 | 30 | ) |
26 | | -except RuntimeError as e: |
27 | | - raise RuntimeError("Unable to load tesseract from api. " \ |
28 | | - "Ensure that you have installed the build requirements using 'pip install -r tesseract_requirements.txt'") |
29 | | - |
| 31 | + |
30 | 32 | # TODO |
31 | 33 | # we should probably create some re-usable mesh constructors... |
32 | 34 | # create a simple Hex mesh using Pyvista |
33 | 35 | import pyvista as pv |
| 36 | + |
34 | 37 | Lx, Ly, Lz = 3, 2, 1 |
35 | 38 | Nx, Ny, Nz = 60, 40, 20 |
36 | 39 | Nx, Ny, Nz = 6, 4, 2 |
37 | 40 | grid = pv.ImageData( |
38 | 41 | dimensions=np.array((Nx, Ny, Nz)) + 1, |
39 | | - #origin=(-Lx / 2, -Ly / 2, -Lz / 2), # The bottom left corner of the data set |
40 | | - origin=(0, 0, 0), # TODO |
41 | | - spacing=(Lx / Nx, Ly / Ny, Lz / Nz), # These are the cell sizes along each axis |
| 42 | + # origin=(-Lx / 2, -Ly / 2, -Lz / 2), # The bottom left corner of the data set |
| 43 | + origin=(0, 0, 0), # TODO |
| 44 | + spacing=(Lx / Nx, Ly / Ny, Lz / Nz), # These are the cell sizes along each axis |
42 | 45 | ) |
43 | 46 | # repeated casts will eventually expose cell_connectivitiy |
44 | | -mesh = grid.cast_to_structured_grid().cast_to_explicit_structured_grid().cast_to_unstructured_grid() |
| 47 | +mesh = ( |
| 48 | + grid.cast_to_structured_grid() |
| 49 | + .cast_to_explicit_structured_grid() |
| 50 | + .cast_to_unstructured_grid() |
| 51 | +) |
45 | 52 |
|
46 | 53 | from tesseract_api import HexMesh |
| 54 | + |
47 | 55 | hex_mesh = HexMesh( |
48 | 56 | points=mesh.points, |
49 | 57 | faces=mesh.cell_connectivity.reshape((Nx * Ny * Nz, 8)), |
|
58 | 66 | # dirichlet_mask = np.zeros(hex_mesh.n_points) |
59 | 67 | # dirichlet_mask[dirichlet_indices] = 1 |
60 | 68 | dirichlet_mask = np.where(on_lhs)[0] |
61 | | -dirichlet_values = np.zeros((dirichlet_mask.shape[0])) |
| 69 | +dirichlet_values = np.zeros(dirichlet_mask.shape[0]) |
62 | 70 |
|
63 | 71 | # von Neumann condition (select nodes at x=Lx with constraints on y and z) |
64 | 72 | x_lim = Lx |
|
69 | 77 | von_neumann = np.logical_and( |
70 | 78 | mesh.points[:, 0] >= x_lim, |
71 | 79 | np.logical_and( |
72 | | - np.logical_and(mesh.points[:,1] >= y_min, mesh.points[:,1] <= y_max), |
73 | | - np.logical_and(mesh.points[:,2] >= z_min, mesh.points[:,2] <= z_max) |
74 | | - ) |
| 80 | + np.logical_and(mesh.points[:, 1] >= y_min, mesh.points[:, 1] <= y_max), |
| 81 | + np.logical_and(mesh.points[:, 2] >= z_min, mesh.points[:, 2] <= z_max), |
| 82 | + ), |
75 | 83 | ) |
76 | 84 | # TODO should this be an n_node array? |
77 | 85 | von_neumann_mask = np.where(von_neumann)[0] |
78 | | -von_neumann_values = (0, 0.0, 0.1 / len(von_neumann_mask)) + np.zeros((von_neumann_mask.shape[0], 3)) |
| 86 | +von_neumann_values = (0, 0.0, 0.1 / len(von_neumann_mask)) + np.zeros( |
| 87 | + (von_neumann_mask.shape[0], 3) |
| 88 | +) |
79 | 89 |
|
80 | 90 | # Create a test density field varying from 0 to 1 |
81 | 91 | n_elem = Nx * Ny * Nz |
82 | 92 | rho = (np.arange(0, n_elem, 1) / n_elem).reshape((n_elem, 1)) |
83 | 93 | rho = 0.5 * np.ones((n_elem, 1)) |
84 | | - |
85 | | - |
| 94 | + |
| 95 | + |
86 | 96 | inputs = { |
87 | 97 | "dirichlet_mask": dirichlet_mask, |
88 | 98 | "dirichlet_values": dirichlet_values, |
|
98 | 108 | "vtk_output": "mesh_density.vtk", |
99 | 109 | } |
100 | 110 |
|
101 | | -# cells = np.array([8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15]) |
102 | | -cells = np.concatenate([np.array([[8]] * hex_mesh.n_faces), hex_mesh.faces], 1) |
103 | | -celltypes = np.full(hex_mesh.n_faces, pv.CellType.HEXAHEDRON, dtype=np.uint8) |
104 | | -mesh2 = pv.UnstructuredGrid(cells.ravel(), celltypes, hex_mesh.points) |
105 | | -print(mesh.cell_connectivity) |
106 | | - |
107 | 111 | outputs = tess_simp_compliance.apply(inputs) |
108 | 112 |
|
109 | 113 | # Verify relationship between compliance and strain energy |
|
117 | 121 | print(f"Ratio (should be ~1.0): {total_strain_energy / (0.5 * compliance):.6f}") |
118 | 122 |
|
119 | 123 | # Finite difference check |
120 | | -num_tests = 5 # set to 0 if you don't want to run this check |
| 124 | +num_tests = 0 # set to 0 if you don't want to run this check |
121 | 125 | FD_delta = 1.0e-3 |
122 | 126 | f0 = outputs["compliance"] |
123 | 127 | sensitivity = outputs["sensitivity"] |
|
130 | 134 | # FD_sensitivity[i] = (fupp - f0) / FD_delta |
131 | 135 | # inputs["rho"][i] -= FD_delta |
132 | 136 |
|
133 | | - inputs["rho"][i] -= 2.0*FD_delta |
| 137 | + inputs["rho"][i] -= 2.0 * FD_delta |
134 | 138 | outputs = tess_simp_compliance.apply(inputs) |
135 | 139 | fdown = outputs["compliance"] |
136 | 140 | FD_sensitivity[i] = (fupp - fdown) / FD_delta / 2.0 |
|
0 commit comments