1from mpi4py import MPI
2from petsc4py import PETSc
3from dolfinx import mesh
4from dolfinx import fem
5
6
7domain = mesh.create_unit_square(MPI.COMM_WORLD,
8 nx = 4, ny = 4)
9
10
11
12import ufl
13from dolfinx import default_scalar_type
14from dolfinx.fem.petsc import LinearProblem, assemble_vector, create_vector
15
16
17for i in range(3):
18
19 V = fem.functionspace(domain, ('P', 1))
20
21
22 import numpy as np
23 uD = fem.Function(V)
24 uD.interpolate(lambda x: np.full(x.shape[1], 0.))
25
26 tdim = domain.topology.dim
27 fdim = tdim - 1
28 domain.topology.create_connectivity(fdim, tdim)
29 boundary_facets = mesh.exterior_facet_indices(domain.topology)
30 boundary_dofs = fem.locate_dofs_topological(V, fdim,
31 boundary_facets)
32 bc = fem.dirichletbc(uD, boundary_dofs)
33
34 u = ufl.TrialFunction(V)
35 v = ufl.TestFunction(V)
36
37
38 x = ufl.SpatialCoordinate(domain)
39 f = 2 * ufl.pi**2 * ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
40
41
42 a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx
43
44
45 L = f * v * ufl.dx
46
47
48 problem = LinearProblem(a, L, bcs=[bc],
49 petsc_options_prefix="ex_mef2d_modelo")
50 uh = problem.solve()
51
52
53 import pyvista
54 from dolfinx import plot
55
56
57 topology, cell_types, geometry = plot.vtk_mesh(V)
58 grid_uh = pyvista.UnstructuredGrid(topology, cell_types, geometry)
59 grid_uh.point_data["uh"] = uh.x.array.real
60 grid_uh.set_active_scalars("uh")
61
62
63 p = pyvista.Plotter()
64 p.add_mesh(grid_uh, show_edges=True, scalars="uh", cmap="viridis", label="uh")
65
66
67 p.add_axes()
68 p.add_legend()
69 p.view_xy()
70 p.show()
71
72
73 W0 = fem.functionspace(domain, ("DG", 0))
74 w0 = ufl.TestFunction(W0)
75
76
77 r = f + ufl.div(ufl.grad(uh))
78 r2_form = fem.form((r**2) * w0 * ufl.dx)
79
80 r2_vec = create_vector(fem.extract_function_spaces(r2_form))
81 with r2_vec.localForm() as loc_r2:
82 loc_r2.set(0)
83 assemble_vector(r2_vec, r2_form)
84 r2_vec.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
85 mode=PETSc.ScatterMode.REVERSE)
86 r2_vec.ghostUpdate(addv=PETSc.InsertMode.INSERT_VALUES,
87 mode=PETSc.ScatterMode.FORWARD)
88
89
90
91
92
93
94
95 print(f"Refinement {i}: max cell residual L2 norm = {r2_vec.array.max()}")
96
97
98 topology, cell_types, geometry = plot.vtk_mesh(domain, domain.topology.dim)
99 grid_residual = pyvista.UnstructuredGrid(topology, cell_types, geometry)
100
101 grid_residual.cell_data["cell_residual_l2"] = r2_vec.array.real
102 grid_residual.set_active_scalars("cell_residual_l2")
103
104 pl = pyvista.Plotter()
105 pl.add_mesh(grid_residual, show_edges=True, scalars="cell_residual_l2", cmap="inferno", label="cell_residual_l2")
106 pl.add_axes()
107 pl.add_legend()
108 pl.view_xy()
109 pl.show()
110
111
112
113 tdim = domain.topology.dim
114 num_local_cells = domain.topology.index_map(tdim).size_local
115 local_cells = np.arange(num_local_cells, dtype=np.int32)
116 cell_eta = np.empty(num_local_cells, dtype=np.float64)
117 for c in local_cells:
118 dof = W0.dofmap.cell_dofs(c)[0]
119
120 cell_eta[c] = r2_vec.array[dof].real
121
122 local_max = cell_eta.max() if num_local_cells > 0 else 0.0
123 global_max = domain.comm.allreduce(local_max, op=MPI.MAX)
124 threshold = 0.5 * global_max
125 cells_to_refine = local_cells[cell_eta > threshold]
126 print(f"Refinement {i}: marking {len(cells_to_refine)} cells for refinement")
127
128
129
130
131
132
133
134 from dolfinx.mesh import refine
135 if len(cells_to_refine) > 0:
136 marker_entities = cells_to_refine
137 try:
138
139 marker_entities = mesh.compute_incident_entities(domain.topology,
140 cells_to_refine,
141 tdim, 1)
142 except Exception:
143 pass
144 refine_out = refine(domain, marker_entities)
145 domain = refine_out[0] if isinstance(refine_out, tuple) else refine_out