@@ -201,8 +201,6 @@ def plot_mesh(mesh: dolfinx.mesh.Mesh, tags: dolfinx.mesh.MeshTags = None, style
201201# ```
202202
203203# As discussed in the previous chapter, we need to choose a mesh to integrate over.
204- # As we would like to exploit the definition of the `n=ufl.FacetNormal(\Omega)` in our
205- # variational problem, we choose the integration domain to be $\Omega$.
206204
207205dx = ufl .Measure ("dx" , domain = omega )
208206ds = ufl .Measure ("ds" , domain = omega , subdomain_data = ft , subdomain_id = potential_contact_marker )
@@ -228,7 +226,6 @@ def plot_mesh(mesh: dolfinx.mesh.Mesh, tags: dolfinx.mesh.MeshTags = None, style
228226
229227# Similarly, we have that $\hat n = (0, -1)$
230228
231- n = ufl .FacetNormal (omega )
232229n_g = dolfinx .fem .Constant (omega , np .zeros (gdim , dtype = dolfinx .default_scalar_type ))
233230n_g .value [- 1 ] = - 1
234231f = dolfinx .fem .Constant (omega , np .zeros (gdim , dtype = dolfinx .default_scalar_type ))
@@ -257,7 +254,7 @@ def sigma(w, mu, lmbda):
257254
258255F = alpha * ufl .inner (sigma (u , mu , lmbda ), epsilon (v )) * dx
259256F -= alpha * ufl .inner (f , v ) * dx
260- F += - ufl .inner (psi - psi_k , ufl .dot (v , n )) * ds
257+ F += - ufl .inner (psi - psi_k , ufl .dot (v , n_g )) * ds
261258F += ufl .inner (ufl .dot (u , n_g ), w ) * ds
262259F += ufl .inner (ufl .exp (psi ), w ) * ds - ufl .inner (g , w ) * ds
263260residual = ufl .extract_blocks (F )
@@ -293,6 +290,7 @@ def disp_func(x):
293290bc = dolfinx .fem .dirichletbc (u_bc , dolfinx .fem .locate_dofs_topological (V , fdim , ft .find (displacement_marker )))
294291bcs = [bc ]
295292
293+ # -
296294
297295# We want to consider the Von-Mises stresses in post-processing, and
298296# use DOLFINx Expression to interpolate the stresses into an appropriate
@@ -331,13 +329,34 @@ def disp_func(x):
331329# In this problem, we measure the norm of the change in the primal space,
332330# rather than the for the mixed function.
333331
332+ # +
333+
334334max_iterations = 25
335335normed_diff = 0
336- tol = 1e-5
336+ tol = 1e-10
337+
338+ u_prev = dolfinx .fem .Function (V )
339+ diff = dolfinx .fem .Function (V )
340+ for it in range (max_iterations ):
341+ print (f"{ it = } /{ max_iterations } { normed_diff :.2e} " )
342+ # Solve the first iterations inaccurately
343+ solver_tol = 100 * tol if it < 3 else tol
344+ solver .solver .setTolerances (rtol = solver_tol , atol = solver_tol , stol = solver_tol )
345+ solver .solve ()
346+
347+ diff .x .array [:] = u .x .array - u_prev .x .array
348+ diff .x .petsc_vec .normBegin (2 )
349+ normed_diff = diff .x .petsc_vec .normEnd (2 )
350+ if normed_diff <= tol and it >= 3 :
351+ print (f"Converged at { it = } with increment norm { normed_diff :.2e} <{ tol :.2e} " )
352+ break
353+ u_prev .x .array [:] = u .x .array
354+ psi_k .x .array [:] = psi .x .array
355+
356+ if it == max_iterations - 1 :
357+ print (f"Did not converge within { max_iterations } iterations" )
337358
338- solver .solve ()
339- iterations = solver .solver .getIterationNumber ()
340- print (f"Converged in { iterations } iterations" )
359+ # -
341360
342361# We compute the von-Mises stresses for the final solution
343362
@@ -348,9 +367,6 @@ def disp_func(x):
348367
349368u_dg .interpolate (u )
350369
351-
352- # -
353-
354370# + tags=["hide-input"]
355371
356372grid = dolfinx .plot .vtk_mesh (u_dg .function_space )
0 commit comments