7 """Fit ``force ~= a*u_mean + b*u_mean**2`` in a least-squares sense."""
8 u_mean_samples = np.asarray(u_mean_samples, dtype=np.float64)
9 force_samples = np.asarray(force_samples, dtype=np.float64)
10 design = np.column_stack([u_mean_samples, u_mean_samples ** 2])
11 coeffs, *_ = np.linalg.lstsq(design, force_samples, rcond=
None)
12 return float(coeffs[0]), float(coeffs[1])
16 """Invert ``force = a*u_mean + b*u_mean**2`` for the positive root."""
18 linear_coeff = float(linear_coeff)
19 quadratic_coeff = float(quadratic_coeff)
20 if abs(quadratic_coeff) < 1e-14:
21 if abs(linear_coeff) < 1e-14:
22 raise ValueError(
"force law is degenerate")
23 return force / linear_coeff
24 disc = linear_coeff ** 2 + 4.0 * quadratic_coeff * force
26 raise ValueError(
"force law has no real solution for the requested force")
27 return (-linear_coeff + np.sqrt(disc)) / (2.0 * quadratic_coeff)
31 """Scale an already converged solver state in place for continuation."""
32 if abs(previous_u_mean) < 1e-14:
33 raise ValueError(
"previous_u_mean must be non-zero")
34 if abs(previous_force) < 1e-14:
35 raise ValueError(
"previous_force must be non-zero")
37 float(target_u_mean) / float(previous_u_mean),
38 float(target_force) / float(previous_force),
43 """Copy ``u``, ``v``, ``w`` and ``p`` from a solver into NumPy arrays."""
45 "u": np.asarray(solver.get_u(), dtype=np.float64),
46 "v": np.asarray(solver.get_v(), dtype=np.float64),
47 "w": np.asarray(solver.get_w(), dtype=np.float64),
48 "p": np.asarray(solver.get_p(), dtype=np.float64),
63 """Periodically resample one axis of a structured field."""
64 source_coords = np.linspace(0.0, 1.0, field.shape[axis], endpoint=
False)
65 field = np.moveaxis(field, axis, 0)
66 resampled = np.empty((target_coords.size,) + field.shape[1:], dtype=np.float64)
67 for index
in np.ndindex(field.shape[1:]):
68 resampled[(slice(
None),) + index] = np.interp(
71 field[(slice(
None),) + index],
74 return np.moveaxis(resampled, 0, axis)
78 """Periodically resample a scalar field to a new ``(nz, ny, nx)`` shape."""
79 field = np.asarray(field, dtype=np.float64)
81 raise ValueError(
"field must have shape (nz, ny, nx)")
82 target_shape = tuple(int(v)
for v
in target_shape)
83 if len(target_shape) != 3:
84 raise ValueError(
"target_shape must have length 3")
86 target_z = np.linspace(0.0, 1.0, target_shape[0], endpoint=
False)
87 target_y = np.linspace(0.0, 1.0, target_shape[1], endpoint=
False)
88 target_x = np.linspace(0.0, 1.0, target_shape[2], endpoint=
False)