dragonfly_sim.utils.pod_utils ============================= .. py:module:: dragonfly_sim.utils.pod_utils .. autoapi-nested-parse:: Helpers for core/pod.py: PETSc dense-matrix plumbing for the distributed snapshot SVD, and the compact-support cubic weight function of the local_weighted basis. Also the distributed thin QR (tsqr) of the reduced adjoint in core/reduced_order_model.py. Storage convention (see core/pod.py:SnapshotMatrix): - Q (the basis), distributed MATDENSE with the row layout of the state vector; its column count (the rank) is the same on every rank. - R, Sigma, VT, small PETSc objects on PETSc.COMM_SELF, one identical copy per rank. Their size scales with the number of snapshots, not with the mesh, so there is nothing to gain from distributing them. Rank-sized quantities such as Q^T W x are formed as a local dense product on each rank's row block followed by one Allreduce, which keeps them available as replicated numpy arrays. .. !! processed by numpydoc !! Classes ------- .. autoapisummary:: dragonfly_sim.utils.pod_utils.DiagonalWeight Functions --------- .. autoapisummary:: dragonfly_sim.utils.pod_utils.basis_size_floor dragonfly_sim.utils.pod_utils.cubic_dist_hat dragonfly_sim.utils.pod_utils.cubic_dist_hat_fixed dragonfly_sim.utils.pod_utils.cubic_weights dragonfly_sim.utils.pod_utils.petsc_append_dense_column dragonfly_sim.utils.pod_utils.petsc_dense_from_local_block dragonfly_sim.utils.pod_utils.petsc_small_mat_from_numpy dragonfly_sim.utils.pod_utils.petsc_small_mat_to_numpy dragonfly_sim.utils.pod_utils.petsc_small_vec_from_numpy dragonfly_sim.utils.pod_utils.replicated_transpose_product dragonfly_sim.utils.pod_utils.tsqr Module Contents --------------- .. py:class:: DiagonalWeight(w) A diagonal inner-product weight W = diag(w) with the `.mult(x, y)` that core/pod.py:SnapshotMatrix calls, w a Vec in the state layout. .. !! processed by numpydoc !! .. py:method:: destroy() .. py:method:: mult(x, y) .. py:attribute:: w .. py:function:: basis_size_floor(accepted_distnorm, rb_size, spread, margin_scale=0.001) The smallest cubic support radius that leaves the rb_size snapshots nearest the query point (among `accepted_distnorm`, the snapshots that carry a basis column) with a nonzero weight. The cubic weight vanishes AT its support radius, so the radius has to lie strictly beyond d_k, the k-th smallest distance (k = min(rb_size, number of snapshots)): it is the next larger distance (that snapshot gets zero weight), but at least d_k + margin_scale * spread, with `spread` the spread of all distances (max - min). The margin keeps the k-th weight clear of the 1e-10 pruning threshold when the next distance is barely larger, and places the radius beyond d_k when no larger distance exists. Snapshots tied with d_k all stay inside. .. !! processed by numpydoc !! .. py:function:: cubic_dist_hat(parameter_distnorm, min_dist, max_dist, n_nonzero_weights, tail_eps_scale=0.001, tie_rtol=1e-09) The cubic weight's support radius dist_hat such that exactly the k = min(n_nonzero_weights, n_snapshots) snapshots nearest the query point get a nonzero weight and the (k+1)-th nearest gets zero. k >= n_snapshots: there is no (k+1)-th neighbour to cut at, so dist_hat is pushed a small relative distance beyond max_dist (tail_eps_scale keeps the farthest snapshot's weight above the 1e-10 pruning threshold in PODBasis.construct_basis). k or more snapshots tied at min_dist (e.g. a symmetric pair of design perturbations) would put dist_hat at min_dist; k is walked forward past the tie first. Ties exactly at the (k+1)-th boundary need no handling: both snapshots land on dist_hat and both get zero. .. !! processed by numpydoc !! .. py:function:: cubic_dist_hat_fixed(min_dist, max_dist, c) The cubic weight's support radius from a user-set c in [0, 1): dist_hat = c min_dist + (1 - c) max_dist. c = 0 puts dist_hat at the farthest snapshot (only it gets zero weight); larger c narrows the support towards the nearest snapshot. .. !! processed by numpydoc !! .. py:function:: cubic_weights(parameter_distnorm, min_dist, dist_hat) The cubic Hermite weight with w(min_dist) = 1, w(dist_hat) = 0 and zero slope at both ends, zero beyond dist_hat: w = 2 t^3 - 3 t^2 + 1, t = (d - min_dist) / (dist_hat - min_dist). This closed form is the exact solution of the 4x4 monomial interpolation system, without that system's ill-conditioning at large absolute distances. The zeroing beyond dist_hat is required: the polynomial turns back up for t > 1. .. !! processed by numpydoc !! .. py:function:: petsc_append_dense_column(comm, old_mat, new_col_local) A new distributed MATDENSE with one column more than `old_mat` (None for a fresh single-column matrix): its data, then `new_col_local` (this rank's slice of the new column) as the last column. .. !! processed by numpydoc !! .. py:function:: petsc_dense_from_local_block(comm, local_block, M_global=None) A distributed MATDENSE whose local row block is `local_block` (shape (m_local, ncols)). .. !! processed by numpydoc !! .. py:function:: petsc_small_mat_from_numpy(arr) A small numpy array as a PETSc.COMM_SELF MATDENSE (the caller builds `arr` identically on every rank). .. !! processed by numpydoc !! .. py:function:: petsc_small_mat_to_numpy(mat) .. py:function:: petsc_small_vec_from_numpy(arr) A small 1D numpy array as a PETSc.COMM_SELF Vec (replicated). .. !! processed by numpydoc !! .. py:function:: replicated_transpose_product(comm, V, x_local) V^T x as a numpy array on every rank, for a distributed MATDENSE V and this rank's owned entries x_local of a vector in V's row layout. .. !! processed by numpydoc !! .. py:function:: tsqr(comm, X_local) Thin QR, X = Q R, of a tall matrix X (N x k) distributed by rows, X_local being this rank's rows (TSQR): each rank factors its block, the k x k factors are gathered in rank order and factored once more. Returns (Q_local, R): this rank's rows of Q (Q^T Q = I) and the k x k upper-triangular R, identical on every rank (every rank factors the same gathered stack). A rank with fewer than k rows (or none) pads its factor with zero rows. .. !! processed by numpydoc !!