A FEniCS Tutorial - FEniCS Project
A FEniCS Tutorial - FEniCS Project A FEniCS Tutorial - FEniCS Project
problem = NonlinearVariationalProblem(F, u, bcs, J) solver = NonlinearVariationalSolver(problem) solver.solve() where F corresponds to the nonlinear form F(u;v), u is the unknown Function object, bcs represents the essential boundary conditions (in general a list of DirichletBC objects), and J is a variational form for the Jacobian of F. Let us explain in detail how to use the built-in tools for nonlinear variational problems and their solution. The F form corresponding to (41) is straightforwardly defined as follows, assuming q(u) is coded as a Python function: u_ = Function(V) # most recently computed solution v = TestFunction(V) F = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx Note here that u_ is a Function (not a TrialFunction). An alternative and perhaps more intuitive formula for F is to define F(u;v) directly in terms of a trial function for u and a test function for v, and then create the proper F by u = TrialFunction(V) v = TestFunction(V) F = inner(q(u)*nabla_grad(u), nabla_grad(v))*dx u_ = Function(V) # the most recently computed solution F = action(F, u_) The latter statement is equivalent to F(u = u − ;v), where u − is an existing finite element function representing the most recently computed approximation to the solution. (Note that u k and u k+1 in the previous notation correspond to u − and u in the present notation. We have changed notation to better align the mathematics with the associated UFL code.) ThederivativeJ (J)ofF (F)isformallytheGateauxderivativeDF(u k ;δu,v) of F(u;v) at u = u − in the direction of δu. Technically, this Gateaux derivative is derived by computing lim ǫ→0 d dǫ F i(u − +ǫδu;v). (62) The δu is now the trial function and u − is the previous approximation to the solution u. We start with ∫ d ∇v ·(q(u − +ǫδu)∇(u − +ǫδu)) dx dǫ Ω and obtain ∫ ∇v ·[q ′ (u − +ǫδu)δu∇(u − +ǫδu)+q(u − +ǫδu)∇δu] dx, Ω which leads to ∫ Ω ∇v ·[q ′ (u − )δu∇(u − )+q(u − )∇δu] dx, (63) 56
as ǫ → 0. This last expression is the Gateaux derivative of F. We may use J or a(δu,v) for this derivative, the latter having the advantage that we easily recognize the expression as a bilinear form. However, in the forthcoming code examples J is used as variable name for the Jacobian. The specification of J goes as follows if du is the TrialFunction: du = TrialFunction(V) v = TestFunction(V) u_ = Function(V) # the most recently computed solution F = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx J = inner(q(u_)*nabla_grad(du), nabla_grad(v))*dx + \ inner(Dq(u_)*du*nabla_grad(u_), nabla_grad(v))*dx The alternative specification of F, with u as TrialFunction, leads to u = TrialFunction(V) v = TestFunction(V) u_ = Function(V) # the most recently computed solution F = inner(q(u)*nabla_grad(u), nabla_grad(v))*dx F = action(F, u_) J = inner(q(u_)*nabla_grad(u), nabla_grad(v))*dx + \ inner(Dq(u_)*u*nabla_grad(u_), nabla_grad(v))*dx The UFL language, used to specify weak forms, supports differentiation of forms. Thisfeaturefacilitatesautomaticsymbolic computationoftheJacobianJ by calling the function derivative with F, the most recently computed solution (Function), and the unknown (TrialFunction) as parameters: du = TrialFunction(V) v = TestFunction(V) u_ = Function(V) # the most recently computed solution F = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx J = derivative(F, u_, du) # Gateaux derivative in dir. of du or u = TrialFunction(V) v = TestFunction(V) u_ = Function(V) # the most recently computed solution F = inner(q(u)*nabla_grad(u), nabla_grad(v))*dx F = action(F, u_) J = derivative(F, u_, u) # Gateaux derivative in dir. of u The derivative function is obviously very convenient in problems where differentiating F by hand implies lengthy calculations. ThepreferredimplementationofFandJ,dependingonwhetherduoruisthe TrialFunction object, is a matter of personal taste. Derivation of the Gateaux derivative by hand, as shown above, is most naturally matched by an implementation where du is the TrialFunction, while use of automatic symbolic differentiation with the aid of the derivative function is most naturally matched by 57
- Page 5 and 6: that changing the PDE and boundary
- Page 7 and 8: The proper statement of our variati
- Page 9 and 10: """ FEniCS tutorial demo program: P
- Page 11 and 12: polynomial approximations over each
- Page 13 and 14: Instead of nabla_grad we could also
- Page 15 and 16: solution during program development
- Page 17 and 18: The demo program d2_p2D.py in the s
- Page 19 and 20: All mesh objects are of type Mesh s
- Page 21 and 22: Here, T is the tension in the membr
- Page 23 and 24: """ FEniCS program for the deflecti
- Page 25 and 26: Figure 3: Plot of the deflection of
- Page 27 and 28: Figure 4: Example of visualizing th
- Page 29 and 30: Let us continue to use our favorite
- Page 31 and 32: 1.11 Computing Functionals After th
- Page 33 and 34: e_Ve.vector()[:] = u_e_Ve.vector().
- Page 35 and 36: It is possible to restrict the inte
- Page 37 and 38: Other functions for visualizing 2D
- Page 39 and 40: 1 0.8 Contour plot of u 4 3.5 3 2.5
- Page 41 and 42: accordingly: f = −6, { −4, y =
- Page 43 and 44: Here, Γ 0 is the boundary x = 0, w
- Page 45 and 46: The object A is of type Matrix, whi
- Page 47 and 48: with exact solution u(x) = x 2 . Ou
- Page 49 and 50: The variational formulation of our
- Page 51 and 52: iter += 1 solve(a == L, u, bcs) dif
- Page 53 and 54: tol = 1E-14 def left_boundary(x, on
- Page 55: We may collect the terms with the u
- Page 59 and 60: 3.1 A Diffusion Problem and Its Dis
- Page 61 and 62: • if u 1 is to be computed by pro
- Page 63 and 64: while t 1, but for the values of N
- Page 65 and 66: if we identify the matrix M with en
- Page 67 and 68: y T 0 (t) = T R + T A sin(ωt) x D
- Page 69 and 70: straightforward approach is to defi
- Page 71 and 72: def T_exact(x): a = sqrt(omega*rho*
- Page 73 and 74: Theta = pi/2 a, b = 1, 5.0 nr = 10
- Page 75 and 76: y ✻ u = 1 Ω 1 ∂u ∂n = 0 ∂u
- Page 77 and 78: subdomain1 = Omega1() subdomain1.ma
- Page 79 and 80: The weak form then becomes ∫ ∫
- Page 81 and 82: A = assemble(a, exterior_facet_doma
- Page 83 and 84: 7.2 Overview of Objects and Functio
- Page 85 and 86: Parameters in expression strings mu
- Page 87 and 88: } "smoother: type" : "ML symmetric
- Page 89 and 90: 2. forgetting that the spatial coor
- Page 91 and 92: Applied Mathematics (SIAM), Philade
- Page 93 and 94: Index alg newton np.py, 52 assemble
as ǫ → 0. This last expression is the Gateaux derivative of F. We may use<br />
J or a(δu,v) for this derivative, the latter having the advantage that we easily<br />
recognize the expression as a bilinear form. However, in the forthcoming code<br />
examples J is used as variable name for the Jacobian.<br />
The specification of J goes as follows if du is the TrialFunction:<br />
du = TrialFunction(V)<br />
v = TestFunction(V)<br />
u_ = Function(V) # the most recently computed solution<br />
F = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx<br />
J = inner(q(u_)*nabla_grad(du), nabla_grad(v))*dx + \<br />
inner(Dq(u_)*du*nabla_grad(u_), nabla_grad(v))*dx<br />
The alternative specification of F, with u as TrialFunction, leads to<br />
u = TrialFunction(V)<br />
v = TestFunction(V)<br />
u_ = Function(V) # the most recently computed solution<br />
F = inner(q(u)*nabla_grad(u), nabla_grad(v))*dx<br />
F = action(F, u_)<br />
J = inner(q(u_)*nabla_grad(u), nabla_grad(v))*dx + \<br />
inner(Dq(u_)*u*nabla_grad(u_), nabla_grad(v))*dx<br />
The UFL language, used to specify weak forms, supports differentiation of<br />
forms. Thisfeaturefacilitatesautomaticsymbolic computationoftheJacobianJ<br />
by calling the function derivative with F, the most recently computed solution<br />
(Function), and the unknown (TrialFunction) as parameters:<br />
du = TrialFunction(V)<br />
v = TestFunction(V)<br />
u_ = Function(V) # the most recently computed solution<br />
F = inner(q(u_)*nabla_grad(u_), nabla_grad(v))*dx<br />
J = derivative(F, u_, du) # Gateaux derivative in dir. of du<br />
or<br />
u = TrialFunction(V)<br />
v = TestFunction(V)<br />
u_ = Function(V) # the most recently computed solution<br />
F = inner(q(u)*nabla_grad(u), nabla_grad(v))*dx<br />
F = action(F, u_)<br />
J = derivative(F, u_, u) # Gateaux derivative in dir. of u<br />
The derivative function is obviously very convenient in problems where differentiating<br />
F by hand implies lengthy calculations.<br />
ThepreferredimplementationofFandJ,dependingonwhetherduoruisthe<br />
TrialFunction object, is a matter of personal taste. Derivation of the Gateaux<br />
derivative by hand, as shown above, is most naturally matched by an implementation<br />
where du is the TrialFunction, while use of automatic symbolic differentiation<br />
with the aid of the derivative function is most naturally matched by<br />
57