dragonfly_sim.utils.derived_fields ================================== .. py:module:: dragonfly_sim.utils.derived_fields .. autoapi-nested-parse:: Derived fields and the chain rule through them. A derived field is a Function the residual (or a force functional) reads that is not one of the unknowns, but is itself a function of the state U, the angle of attack alpha and/or the mesh coordinates x: the Green-Gauss gradient G = M^-1 b(U, alpha, x) (core/reconstruction.py) the cell centres c = C x (core/reconstruction.py) the wall distance d = d(x) (core/wall_distance.py) For R(U, f(U, alpha, x), alpha, x) every total derivative picks up one chain term per field, dR/dU = dR/dU|_f + sum_f (dR/df) (df/dU) dR/dalpha = dR/dalpha|_f + sum_f (dR/df) (df/dalpha) dR/dx = dR/dx|_f + sum_f (dR/df) (df/dx) and the same holds for a scalar functional J. A DerivedField supplies the three right-hand factors; DerivedFieldChainRule assembles the partial derivatives with UFL and combines them. With no derived fields nothing here is used, and the model's derivative assemblers are the plain UFL ones. .. !! processed by numpydoc !! Classes ------- .. autoapisummary:: dragonfly_sim.utils.derived_fields.DerivedField dragonfly_sim.utils.derived_fields.DerivedFieldChainRule dragonfly_sim.utils.derived_fields._ChainedMeshOperator Functions --------- .. autoapisummary:: dragonfly_sim.utils.derived_fields._assemble_mat dragonfly_sim.utils.derived_fields._assemble_vec dragonfly_sim.utils.derived_fields._nonempty dragonfly_sim.utils.derived_fields._shell_matrix dragonfly_sim.utils.derived_fields.destroy_chained_operator dragonfly_sim.utils.derived_fields.destroy_operator dragonfly_sim.utils.derived_fields.diagonal_mass_inverse dragonfly_sim.utils.derived_fields.mesh_coordinate_argument Module Contents --------------- .. py:class:: DerivedField Interface. `function` is the dolfinx Function the forms read. update() recompute the field at the current state and mesh update_geometry() refresh whatever depends on the mesh only (called after mesh motion, before update()) state_jacobian() PETSc Mat d(field)/dU (only if depends_on_state) alpha_vector() PETSc Vec d(field)/dalpha, or None mesh_jacobian() PETSc Mat d(field)/dx, columns in the mesh's coordinate_space, or None .. !! processed by numpydoc !! .. py:method:: alpha_vector() .. py:method:: discard(obj) Free a matrix or vector returned by state_jacobian / alpha_vector / mesh_jacobian once the caller is done with it. A field that caches them keeps its own (override); a python-context operator also frees what its context holds. .. !! processed by numpydoc !! .. py:method:: mesh_jacobian() .. py:method:: release_cache() Free whatever the field caches between calls (nothing by default). .. !! processed by numpydoc !! .. py:method:: state_jacobian() .. py:method:: update() .. py:method:: update_geometry() .. py:attribute:: depends_on_state :value: False .. py:attribute:: function :value: None .. py:class:: DerivedFieldChainRule(mesh_obj, u, fields, alpha_var=None, jit_options=None) Total derivatives of a residual form F (rank 1) or a functional J (rank 0) through a list of DerivedFields. Compiled forms are cached per (form id, field) on this object, so reuse one instance per model. .. !! processed by numpydoc !! .. py:method:: _compiled(key, factory) .. py:method:: _partial_field(form, key, field) dform/dfield: a matrix form (rank-1 form) or a vector form (rank 0). .. !! processed by numpydoc !! .. py:method:: functional_alpha(J, key) dJ/dalpha (total) as a number. Collective. .. !! processed by numpydoc !! .. py:method:: functional_mesh(J, key) dJ/dx (total) as a Vec on the mesh's coordinate_space. .. !! processed by numpydoc !! .. py:method:: functional_state(J, key) dJ/dU (total) as a Vec in the state layout. .. !! processed by numpydoc !! .. py:method:: residual_alpha(F, key, out) out <- dR/dalpha (total); `out` is a Vec in the residual's layout. .. !! processed by numpydoc !! .. py:method:: residual_mesh_operator(F, key) dR/dx (total) as a PETSc python Mat with mult / multTranspose. .. !! processed by numpydoc !! .. py:method:: update() .. py:attribute:: _forms .. py:attribute:: alpha_var :value: None .. py:attribute:: fields .. py:attribute:: jit_options .. py:attribute:: mesh_obj .. py:attribute:: u .. py:class:: _ChainedMeshOperator(A_x, chains) Python-Mat context: y = A_x v + sum_k A_k (X_k v), and its transpose. .. !! processed by numpydoc !! .. py:method:: mult(mat, v, y) .. py:method:: multTranspose(mat, w, y) .. py:attribute:: A_x .. py:attribute:: _work .. py:attribute:: chains .. py:function:: _assemble_mat(form) .. py:function:: _assemble_vec(form) .. py:function:: _nonempty(form) The form with derivatives expanded, or None if it is identically zero. .. !! processed by numpydoc !! .. py:function:: _shell_matrix(A_x, chains) .. py:function:: destroy_chained_operator(M) Free a residual_mesh_operator result and the matrices it holds now. Left to the garbage collector, a parallel petsc4py object is only queued, and freed at the next PETSc.garbage_cleanup; for a 3D RANS operator that is several GB held into the next adjoint. .. !! processed by numpydoc !! .. py:function:: destroy_operator(obj) Destroy a PETSc Mat or Vec. A python-context Mat's context frees what it owns in its destroy(mat) method, which PETSc calls with the Mat. .. !! processed by numpydoc !! .. py:function:: diagonal_mass_inverse(V, dx) 1/|K| per dof of a DG0 (blocked) space V: the inverse of its diagonal mass matrix, as a Vec in V's layout. .. !! processed by numpydoc !! .. py:function:: mesh_coordinate_argument(form, coordinate_space) The Argument a mesh-coordinate derivative of `form` is taken along. .. !! processed by numpydoc !!