| from dolfinx import fem, io, default_scalar_type, mesh |
| from dolfinx.fem.petsc import LinearProblem |
| from mpi4py import MPI |
| import ufl |
| import meshio |
| import numpy as np |
| import pandas as pd |
| from matplotlib.backends.backend_pdf import PdfPages |
| import gmsh |
| |
|
|
| def observer_operator(mesh_pos, displacement, x0, y0, dx, dy) : |
| subdomain_condition_x = ((mesh_pos[:, 0] >= x0) & (mesh_pos[:, 0] <= (x0 + dx))) |
| subdomain_condition_y = ((mesh_pos[:, 1] >= y0) & (mesh_pos[:, 1] <= (y0 + dy))) |
| subdomain_condition = subdomain_condition_x & subdomain_condition_y |
| observed_mesh_pos = mesh_pos[subdomain_condition] |
| observed_mesh_pos[:, 0] -= x0 |
| observed_mesh_pos[:, 1] -= y0 |
| observed_displacement = displacement[subdomain_condition] |
| return observed_mesh_pos, observed_displacement |
| def get_mesh(msh_data) : |
| domain, _, _ = msh_data |
| fdim = domain.topology.dim - 1 |
| node_dim = 0 |
| domain.topology.create_connectivity(fdim, domain.topology.dim) |
| domain.topology.create_connectivity(node_dim, domain.topology.dim) |
| adj_list = domain.topology.connectivity(domain.topology.dim, node_dim) |
| mesh_pos = domain.geometry.x[:, :] |
| node_connectivity = adj_list.array.reshape(-1, 3) |
| return mesh_pos, node_connectivity |
| def solve_fem(msh_data, G, K, load) : |
| domain, _, facet_tags = msh_data |
| fdim = domain.topology.dim - 1 |
| node_dim = 0 |
| domain.topology.create_connectivity(fdim, domain.topology.dim) |
| domain.topology.create_connectivity(node_dim, domain.topology.dim) |
| adj_list = domain.topology.connectivity(domain.topology.dim, node_dim) |
|
|
| V = fem.functionspace(domain, ("Lagrange", 1, (3,))) |
|
|
| |
|
|
| b_D = fem.locate_dofs_topological(V, fdim, facet_tags.find(2)) |
| u_D = np.array([0, 0, 0], dtype=default_scalar_type) |
| bc_D = fem.dirichletbc(u_D, b_D, V) |
|
|
| |
| T_neuman = fem.Constant(domain, default_scalar_type(load)) |
| ds = ufl.Measure("ds", domain=domain, subdomain_data=facet_tags) |
|
|
| |
| def epsilon(u): |
| return ufl.sym(ufl.grad(u)) |
| |
| def sigma(u): |
| return (-2/3 * G + K) * ufl.nabla_div(u) * ufl.Identity(len(u)) + 2 * G * epsilon(u) |
| |
| |
| u = ufl.TrialFunction(V) |
| v = ufl.TestFunction(V) |
|
|
| |
| f = fem.Constant(domain, default_scalar_type((0, 0, 0))) |
| a = ufl.inner(sigma(u), epsilon(v)) * ufl.dx |
| L = ufl.dot(f, v) * ufl.dx + ufl.dot(T_neuman, v) * ds(3) |
|
|
| |
| problem = LinearProblem(a, L, bcs=[bc_D], petsc_options={"ksp_type": "preonly", "pc_type": "lu"}) |
|
|
| |
| uh = problem.solve() |
|
|
| num_dofs = V.dofmap.index_map.size_local |
| mesh_pos = domain.geometry.x[:, :] |
| node_connectivity = adj_list.array.reshape(-1, 3) |
|
|
| displacement = uh.x.array[:].reshape((num_dofs, -1)) |
|
|
| return displacement |