diff --git a/demo/conftest.py b/demo/conftest.py index 66dbb04..87ce4b1 100644 --- a/demo/conftest.py +++ b/demo/conftest.py @@ -2,10 +2,13 @@ def pytest_addoption(parser): - parser.addoption("--mpiexec", action="store", default="mpirun", - help="Name of program to run MPI, e.g. mpiexex") - parser.addoption("--num-proc", action="store", default=1, - help="Number of MPI processes to use") + parser.addoption( + "--mpiexec", + action="store", + default="mpirun", + help="Name of program to run MPI, e.g. mpiexex", + ) + parser.addoption("--num-proc", action="store", default=1, help="Number of MPI processes to use") @pytest.fixture diff --git a/demo/demo_kirchhoff-love-clamped.py b/demo/demo_kirchhoff-love-clamped.py index 956dde7..c02b598 100644 --- a/demo/demo_kirchhoff-love-clamped.py +++ b/demo/demo_kirchhoff-love-clamped.py @@ -65,8 +65,9 @@ # + k = 2 -U_el = mixed_element([element("Lagrange", mesh.basix_cell(), k + 1), - element("HHJ", mesh.basix_cell(), k)]) +U_el = mixed_element( + [element("Lagrange", mesh.basix_cell(), k + 1), element("HHJ", mesh.basix_cell(), k)] +) U = functionspace(mesh, U_el) w, M = ufl.TrialFunctions(U) @@ -148,7 +149,7 @@ def k_theta(theta): def k_M(M): """Bending strain tensor in terms of bending moments""" - return (12.0/(E*t**3))*((1.0 + nu)*M - nu*Identity(2)*tr(M)) + return (12.0 / (E * t**3)) * ((1.0 + nu) * M - nu * Identity(2) * tr(M)) def nn(M): @@ -163,14 +164,16 @@ def inner_divdiv(M, theta): """Discrete div-div inner product""" n = FacetNormal(M.ufl_domain()) M_nn = nn(M) - result = -inner(M, k_theta(theta))*dx + inner(M_nn("+"), - ufl.jump(theta, n))*dS + inner(M_nn, ufl.dot(theta, n))*ds + result = ( + -inner(M, k_theta(theta)) * dx + + inner(M_nn("+"), ufl.jump(theta, n)) * dS + + inner(M_nn, ufl.dot(theta, n)) * ds + ) return result -a = inner(k_M(M), M_t)*dx + inner_divdiv(M_t, theta(w)) + \ - inner_divdiv(M, theta(w_t)) -L = -inner(t**3, w_t)*dx +a = inner(k_M(M), M_t) * dx + inner_divdiv(M_t, theta(w)) + inner_divdiv(M, theta(w_t)) +L = -inner(t**3, w_t) * dx def all_boundary(x): @@ -187,15 +190,14 @@ def all_boundary(x): # TODO: Add table like TDNNS example. # + -boundary_entities = dolfinx.mesh.locate_entities_boundary( - mesh, mesh.topology.dim - 1, all_boundary) +boundary_entities = dolfinx.mesh.locate_entities_boundary(mesh, mesh.topology.dim - 1, all_boundary) bcs = [] # Transverse displacement boundary_dofs_displacement = dolfinx.fem.locate_dofs_topological( - U.sub(0), mesh.topology.dim - 1, boundary_entities) -bcs.append(dirichletbc(np.array(0.0, dtype=np.float64), - boundary_dofs_displacement, U.sub(0))) + U.sub(0), mesh.topology.dim - 1, boundary_entities +) +bcs.append(dirichletbc(np.array(0.0, dtype=np.float64), boundary_dofs_displacement, U.sub(0))) # - @@ -204,15 +206,18 @@ def all_boundary(x): # centre of the plate. # + -problem = LinearProblem(a, L, bcs=bcs, petsc_options={ - "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}) +problem = LinearProblem( + a, + L, + bcs=bcs, + petsc_options={"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}, +) u_h = problem.solve() bb_tree = dolfinx.geometry.bb_tree(mesh, 2) point = np.array([[0.5, 0.5, 0.0]], dtype=np.float64) cell_candidates = dolfinx.geometry.compute_collisions_points(bb_tree, point) -cells = dolfinx.geometry.compute_colliding_cells( - mesh, cell_candidates, point) +cells = dolfinx.geometry.compute_colliding_cells(mesh, cell_candidates, point) w, M = u_h.split() diff --git a/demo/demo_reissner-mindlin-clamped-tdnns.py b/demo/demo_reissner-mindlin-clamped-tdnns.py index 1586d15..7cc3109 100644 --- a/demo/demo_reissner-mindlin-clamped-tdnns.py +++ b/demo/demo_reissner-mindlin-clamped-tdnns.py @@ -75,8 +75,9 @@ # + k = 3 cell = mesh.basix_cell() -U_el = mixed_element([element("N2curl", cell, k), element("Lagrange", cell, k + 1), - element("HHJ", cell, k)]) +U_el = mixed_element( + [element("N2curl", cell, k), element("Lagrange", cell, k + 1), element("HHJ", cell, k)] +) U = functionspace(mesh, U_el) u = ufl.TrialFunction(U) @@ -92,7 +93,7 @@ # + E = 10920.0 nu = 0.3 -kappa = 5.0/6.0 +kappa = 5.0 / 6.0 t = 0.001 # - @@ -144,13 +145,13 @@ def k_theta(theta): def k_M(M): """Bending strain tensor in terms of bending moments""" - return (12.0/(E*t**3))*((1.0 + nu)*M - nu*Identity(2)*tr(M)) + return (12.0 / (E * t**3)) * ((1.0 + nu) * M - nu * Identity(2) * tr(M)) def nn(M): """Normal-normal component of tensor""" n = FacetNormal(M.ufl_domain()) - M_n = M*n + M_n = M * n M_nn = ufl.dot(M_n, n) return M_nn @@ -159,8 +160,11 @@ def inner_divdiv(M, theta): """Discrete div-div inner product""" n = FacetNormal(M.ufl_domain()) M_nn = nn(M) - result = -inner(M, k_theta(theta))*dx + inner(M_nn("+"), - ufl.jump(theta, n))*dS + inner(M_nn, ufl.dot(theta, n))*ds + result = ( + -inner(M, k_theta(theta)) * dx + + inner(M_nn("+"), ufl.jump(theta, n)) * dS + + inner(M_nn, ufl.dot(theta, n)) * ds + ) return result @@ -169,9 +173,13 @@ def gamma(theta, w): return grad(w) - theta -a = inner(k_M(M), M_t)*dx + inner_divdiv(M_t, theta) + inner_divdiv(M, theta_t) - \ - ((E*kappa*t)/(2.0*(1.0 + nu)))*inner(gamma(theta, w), gamma(theta_t, w_t))*dx -L = -inner(1.0*t**3, w_t)*dx +a = ( + inner(k_M(M), M_t) * dx + + inner_divdiv(M_t, theta) + + inner_divdiv(M, theta_t) + - ((E * kappa * t) / (2.0 * (1.0 + nu))) * inner(gamma(theta, w), gamma(theta_t, w_t)) * dx +) +L = -inner(1.0 * t**3, w_t) * dx # - @@ -207,19 +215,20 @@ def all_boundary(x): return np.full(x.shape[1], True, dtype=bool) -boundary_entities = dolfinx.mesh.locate_entities_boundary( - mesh, mesh.topology.dim - 1, all_boundary) +boundary_entities = dolfinx.mesh.locate_entities_boundary(mesh, mesh.topology.dim - 1, all_boundary) bcs = [] # Transverse displacement boundary_dofs = dolfinx.fem.locate_dofs_topological( - U.sub(1), mesh.topology.dim - 1, boundary_entities) + U.sub(1), mesh.topology.dim - 1, boundary_entities +) bcs.append(dirichletbc(np.array(0.0, dtype=np.float64), boundary_dofs, U.sub(1))) # Fix tangential component of rotation R = U.sub(0).collapse()[0] boundary_dofs = dolfinx.fem.locate_dofs_topological( - (U.sub(0), R), mesh.topology.dim - 1, boundary_entities) + (U.sub(0), R), mesh.topology.dim - 1, boundary_entities +) theta_bc = Function(R) bcs.append(dirichletbc(theta_bc, boundary_dofs, U.sub(0))) @@ -230,15 +239,18 @@ def all_boundary(x): # centre of the plate. # + -problem = LinearProblem(a, L, bcs=bcs, petsc_options={ - "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}) +problem = LinearProblem( + a, + L, + bcs=bcs, + petsc_options={"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}, +) u_h = problem.solve() bb_tree = dolfinx.geometry.bb_tree(mesh, 2) point = np.array([[0.5, 0.5, 0.0]], dtype=np.float64) cell_candidates = dolfinx.geometry.compute_collisions_points(bb_tree, point) -cells = dolfinx.geometry.compute_colliding_cells( - mesh, cell_candidates, point) +cells = dolfinx.geometry.compute_colliding_cells(mesh, cell_candidates, point) theta, w, M = u_h.split() diff --git a/demo/demo_reissner-mindlin-clamped.py b/demo/demo_reissner-mindlin-clamped.py index 25c121b..0edb129 100644 --- a/demo/demo_reissner-mindlin-clamped.py +++ b/demo/demo_reissner-mindlin-clamped.py @@ -65,8 +65,14 @@ # + cell = mesh.basix_cell() -U_el = mixed_element([element("Lagrange", cell, 2, shape=(2,)), element("Lagrange", cell, 1), - element("N1curl", cell, 1), element("N1curl", cell, 1)]) +U_el = mixed_element( + [ + element("Lagrange", cell, 2, shape=(2,)), + element("Lagrange", cell, 1), + element("N1curl", cell, 1), + element("N1curl", cell, 1), + ] +) U = functionspace(mesh, U_el) u_ = Function(U) @@ -81,7 +87,7 @@ E = 10920.0 nu = 0.3 -kappa = 5.0/6.0 +kappa = 5.0 / 6.0 t = 0.001 # The bending strain tensor $k$ for the Reissner-Mindlin model can be expressed @@ -101,9 +107,9 @@ # # which can be expressed in UFL as -D = (E*t**3)/(24.0*(1.0 - nu**2)) +D = (E * t**3) / (24.0 * (1.0 - nu**2)) k = sym(grad(theta_)) -psi_b = D*((1.0 - nu)*tr(k*k) + nu*(tr(k))**2) +psi_b = D * ((1.0 - nu) * tr(k * k) + nu * (tr(k)) ** 2) # Because we are using a mixed variational formulation, we choose to write the # shear energy density $\psi_s$ is a function of the reduced shear strain @@ -113,7 +119,7 @@ # # or in UFL: -psi_s = ((E*kappa*t)/(4.0*(1.0 + nu)))*inner(R_gamma_, R_gamma_) +psi_s = ((E * kappa * t) / (4.0 * (1.0 + nu))) * inner(R_gamma_, R_gamma_) # Finally, we can write out external work due to the uniform loading in the out-of-plane direction # @@ -127,7 +133,7 @@ # # In UFL this can be expressed as -W_ext = inner(1.0*t**3, w_)*dx +W_ext = inner(1.0 * t**3, w_) * dx # With all of the standard mechanical terms defined, we can turn to defining # the Duran-Liberman reduction operator. This operator 'ties' our reduced shear @@ -163,16 +169,15 @@ # choose to write this function in full here. # + -dSp = ufl.Measure('dS', metadata={'quadrature_degree': 1}) -dsp = ufl.Measure('ds', metadata={'quadrature_degree': 1}) +dSp = ufl.Measure("dS", metadata={"quadrature_degree": 1}) +dsp = ufl.Measure("ds", metadata={"quadrature_degree": 1}) n = ufl.FacetNormal(mesh) t = ufl.as_vector((-n[1], n[0])) def inner_e(x, y): - return (inner(x, t)*inner(y, t))('+') * \ - dSp + (inner(x, t)*inner(y, t))*dsp + return (inner(x, t) * inner(y, t))("+") * dSp + (inner(x, t) * inner(y, t)) * dsp Pi_R = inner_e(gamma - R_gamma_, p_) @@ -182,7 +187,7 @@ def inner_e(x, y): # residual and Jacobian automatically using the standard UFL `derivative` # function -Pi = psi_b*dx + psi_s*dx + Pi_R - W_ext +Pi = psi_b * dx + psi_s * dx + Pi_R - W_ext F = ufl.derivative(Pi, u_, u_t) J = ufl.derivative(F, u_, u) @@ -207,21 +212,22 @@ def all_boundary(x): u_boundary = Function(U) -boundary_entities = dolfinx.mesh.locate_entities_boundary( - mesh, mesh.topology.dim - 1, all_boundary) -boundary_dofs = dolfinx.fem.locate_dofs_topological( - U, mesh.topology.dim - 1, boundary_entities) +boundary_entities = dolfinx.mesh.locate_entities_boundary(mesh, mesh.topology.dim - 1, all_boundary) +boundary_dofs = dolfinx.fem.locate_dofs_topological(U, mesh.topology.dim - 1, boundary_entities) bcs = [dirichletbc(u_boundary, boundary_dofs)] -problem = LinearProblem(J, -F, bcs=bcs, petsc_options={ - "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}) +problem = LinearProblem( + J, + -F, + bcs=bcs, + petsc_options={"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}, +) u_ = problem.solve() bb_tree = dolfinx.geometry.bb_tree(mesh, 2) point = np.array([[0.5, 0.5, 0.0]], dtype=np.float64) cell_candidates = dolfinx.geometry.compute_collisions_points(bb_tree, point) -cells = dolfinx.geometry.compute_colliding_cells( - mesh, cell_candidates, point) +cells = dolfinx.geometry.compute_colliding_cells(mesh, cell_candidates, point) theta, w, R_gamma, p = u_.split() @@ -233,7 +239,8 @@ def all_boundary(x): # mesh. def test_center_displacement(): - assert np.isclose(value[0], 1.285E-6, atol=1E-3, rtol=1E-3) + assert np.isclose(value[0], 1.285e-6, atol=1e-3, rtol=1e-3) + with XDMFFile(MPI.COMM_WORLD, "w.xdmf", "w") as f: f.write_mesh(mesh) diff --git a/demo/demo_reissner-mindlin-simply-supported.py b/demo/demo_reissner-mindlin-simply-supported.py index 6ebaaca..dd5949a 100644 --- a/demo/demo_reissner-mindlin-simply-supported.py +++ b/demo/demo_reissner-mindlin-simply-supported.py @@ -35,7 +35,7 @@ from dolfinx.fem import Function, functionspace, dirichletbc from dolfinx.fem.petsc import LinearProblem from dolfinx.mesh import CellType, create_unit_square -from ufl import (dx, grad, inner, split, sym, tr) +from ufl import dx, grad, inner, split, sym, tr from mpi4py import MPI @@ -64,8 +64,14 @@ # + cell = mesh.basix_cell() -U_el = mixed_element([element("Lagrange", cell, 1, shape=(2,), element("Lagrange", cell, 1), - element("RTCE", cell, 1), element("RTCE", cell, 1)]) +U_el = mixed_element( + [ + element("Lagrange", cell, 1, shape=(2,)), + element("Lagrange", cell, 1), + element("RTCE", cell, 1), + element("RTCE", cell, 1), + ] +) U = functionspace(mesh, U_el) u_ = Function(U) @@ -80,7 +86,7 @@ E = 10920.0 nu = 0.3 -kappa = 5.0/6.0 +kappa = 5.0 / 6.0 t = 0.001 # The bending strain tensor $k$ for the Reissner-Mindlin model can be expressed @@ -100,9 +106,9 @@ # # which can be expressed in UFL as -D = (E*t**3)/(24.0*(1.0 - nu**2)) +D = (E * t**3) / (24.0 * (1.0 - nu**2)) k = sym(grad(theta_)) -psi_b = D*((1.0 - nu)*tr(k*k) + nu*(tr(k))**2) +psi_b = D * ((1.0 - nu) * tr(k * k) + nu * (tr(k)) ** 2) # Because we are using a mixed variational formulation, we choose to write the # shear energy density $\psi_s$ is a function of the reduced shear strain @@ -112,7 +118,7 @@ # # or in UFL: -psi_s = ((E*kappa*t)/(4.0*(1.0 + nu)))*inner(R_gamma_, R_gamma_) +psi_s = ((E * kappa * t) / (4.0 * (1.0 + nu))) * inner(R_gamma_, R_gamma_) # Finally, we can write out external work due to the uniform loading in the out-of-plane direction # @@ -126,7 +132,7 @@ # # In UFL this can be expressed as -W_ext = inner(1.0*t**3, w_)*dx +W_ext = inner(1.0 * t**3, w_) * dx # With all of the standard mechanical terms defined, we can turn to defining # the Duran-Liberman reduction operator. This operator 'ties' our reduced shear @@ -162,16 +168,15 @@ # choose to write this function in full here. # + -dSp = ufl.Measure('dS', metadata={'quadrature_degree': 1}) -dsp = ufl.Measure('ds', metadata={'quadrature_degree': 1}) +dSp = ufl.Measure("dS", metadata={"quadrature_degree": 1}) +dsp = ufl.Measure("ds", metadata={"quadrature_degree": 1}) n = ufl.FacetNormal(mesh) t = ufl.as_vector((-n[1], n[0])) def inner_e(x, y): - return (inner(x, t)*inner(y, t))('+') * \ - dSp + (inner(x, t)*inner(y, t))*dsp + return (inner(x, t) * inner(y, t))("+") * dSp + (inner(x, t) * inner(y, t)) * dsp Pi_R = inner_e(gamma - R_gamma_, p_) @@ -181,7 +186,7 @@ def inner_e(x, y): # residual and Jacobian automatically using the standard UFL `derivative` # function -Pi = psi_b*dx + psi_s*dx + Pi_R - W_ext +Pi = psi_b * dx + psi_s * dx + Pi_R - W_ext F = ufl.derivative(Pi, u_, u_t) J = ufl.derivative(F, u_, u) @@ -210,9 +215,9 @@ def top_or_bottom(x): def make_bc(value, V, on_boundary): boundary_entities = dolfinx.mesh.locate_entities_boundary( - mesh, mesh.topology.dim - 1, on_boundary) - boundary_dofs = dolfinx.fem.locate_dofs_topological( - V, mesh.topology.dim - 1, boundary_entities) + mesh, mesh.topology.dim - 1, on_boundary + ) + boundary_dofs = dolfinx.fem.locate_dofs_topological(V, mesh.topology.dim - 1, boundary_entities) bc = dirichletbc(value, boundary_dofs, V) return bc @@ -228,15 +233,18 @@ def make_bc(value, V, on_boundary): bcs.append(make_bc(np.array(0.0, dtype=np.float64), U.sub(0).sub(1), left_or_right)) -problem = LinearProblem(J, -F, bcs=bcs, petsc_options={ - "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}) +problem = LinearProblem( + J, + -F, + bcs=bcs, + petsc_options={"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}, +) u_ = problem.solve() bb_tree = dolfinx.geometry.bb_tree(mesh, 2) point = np.array([[0.5, 0.5, 0.0]], dtype=np.float64) cell_candidates = dolfinx.geometry.compute_collisions_points(bb_tree, point) -cells = dolfinx.geometry.compute_colliding_cells( - mesh, cell_candidates, point) +cells = dolfinx.geometry.compute_colliding_cells(mesh, cell_candidates, point) theta, w, R_gamma, p = u_.split() diff --git a/demo/test_demos.py b/demo/test_demos.py index 9be8986..4713d15 100644 --- a/demo/test_demos.py +++ b/demo/test_demos.py @@ -15,7 +15,7 @@ # Build list of demo programs demos = [] -demo_files = list(path.glob('**/demo_*.py')) +demo_files = list(path.glob("**/demo_*.py")) for f in demo_files: demos.append((f.parent, f.name)) diff --git a/doc/source/conf.py b/doc/source/conf.py index 5d8a040..ffe1a0f 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -9,42 +9,51 @@ import os import sys -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath(".")) import jupytext_process jupytext_process.process() -project = 'FEniCSx-Shells' -copyright = '2022, FEniCSx-Shells Authors' -author = 'FEniCSx-Shells Authors' -release = '0.5.0.dev0' +project = "FEniCSx-Shells" +copyright = "2022, FEniCSx-Shells Authors" +author = "FEniCSx-Shells Authors" +release = "0.5.0.dev0" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.mathjax', - 'sphinx.ext.napoleon', - 'sphinx.ext.todo', - 'sphinx.ext.viewcode', - 'myst_parser', ] - -templates_path = ['_templates'] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.mathjax", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "myst_parser", +] + +templates_path = ["_templates"] exclude_patterns = [] -source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] html_theme = "sphinx_rtd_theme" -myst_enable_extensions = ["dollarmath",] +myst_enable_extensions = [ + "dollarmath", +] -autodoc_default_options = {'members': True, 'show-inheritance': True, 'imported-members': True, 'undoc-members': True} +autodoc_default_options = { + "members": True, + "show-inheritance": True, + "imported-members": True, + "undoc-members": True, +} autosummary_generate = True autoclass_content = "both" # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'alabaster' -html_static_path = ['_static'] +html_theme = "alabaster" +html_static_path = ["_static"] diff --git a/doc/source/jupytext_process.py b/doc/source/jupytext_process.py index fad2b3c..bb3221e 100644 --- a/doc/source/jupytext_process.py +++ b/doc/source/jupytext_process.py @@ -21,11 +21,11 @@ def process(): # Iterate over subdirectories containing demos for subdir in subdirs: # Make demo doc directory - demo_dir = pathlib.Path('./demo') + demo_dir = pathlib.Path("./demo") demo_dir.mkdir(parents=True, exist_ok=True) # Process each demo using jupytext/myst - for demo in subdir.glob('**/demo*.py'): + for demo in subdir.glob("**/demo*.py"): # If demo saves matplotlib images, run the demo if "savefig" in demo.read_text(): here = os.getcwd()