{"id": "line_smoother_3d", "title": "Line-implicit smoothing in three dimensions", "description": "Steady laminar flow past a sphere (Re = 100, M = 0.2, degree 2) on a cubed-sphere shell whose layers grow by a factor 2.2 from the wall, so that the first layers are several times wider than they are thick. The flow is converged with element-block Jacobi and with line Jacobi as the smoother of the p-multigrid levels 2-1-0; at the converged flow one forward and one transposed system with the same right-hand side are solved to a relative tolerance of 1e-10. The lines run radially through the anisotropic layers of all six blocks of the mesh. The checks require the same drag coefficient with both smoothers, the same adjoint derivatives when the transposed systems are solved to 1e-12 (their difference at 1e-10 is reported), and fewer than half the Krylov iterations with line Jacobi in both linear solves. Wall times are reported without a threshold.", "passed": true, "checks": [{"name": "flow solves converged with both smoothers", "value": true, "expected": "true", "passed": true}, {"name": "lines found on the shell with thin wall layers (elements in lines)", "value": 216, "expected": "> 0", "passed": true}, {"name": "drag coefficient: relative difference between the two smoothers", "value": 6.576539823830864e-11, "expected": "< 1e-6", "passed": true}, {"name": "forward solve to 1e-10, both smoothers reaching the tolerance: Krylov iterations, line Jacobi / block Jacobi", "value": 0.32857142857142857, "expected": "< 0.5", "passed": true}, {"name": "transposed (adjoint) solve to 1e-10, both smoothers reaching the tolerance: Krylov iterations, line Jacobi / block Jacobi", "value": 0.3463687150837989, "expected": "< 0.5", "passed": true}, {"name": "adjoint derivatives of the drag (Mach, Reynolds, angle of attack) from transposed solves that reached 1e-12: largest difference between the two smoothers, relative to the largest derivative", "value": 8.643285635799802e-08, "expected": "< 1e-6", "passed": true}], "charts": [], "tables": [{"id": "linear", "title": "Linear solves at the converged flow (tolerance 1e-10)", "columns": ["preconditioner", "system", "Krylov iterations", "residual reduction", "tolerance reached", "wall time of the Krylov solve, compiled, preconditioner assembled before [s]"], "rows": [["block Jacobi", "forward", 210, 9.25819104857776e-11, true, 7.6814329624176025], ["block Jacobi", "transposed (adjoint)", 179, 9.932805022395086e-11, true, 5.7146055698394775], ["line Jacobi", "forward", 69, 7.657149100202826e-11, true, 1.8611867427825928], ["line Jacobi", "transposed (adjoint)", 62, 7.39255713504308e-11, true, 1.676159381866455]]}, {"id": "assembly", "title": "One assembly of the preconditioner at the converged flow", "columns": ["preconditioner", "wall time, compiled, fastest of five [s]"], "rows": [["block Jacobi", 0.3913838863372803], ["line Jacobi", 1.1759209632873535]]}, {"id": "flow", "title": "Flow solve from the free stream", "columns": ["preconditioner", "levels", "nonlinear steps", "Krylov iterations", "converged", "drag coefficient", "wall time, first solve [s]", "wall time, repeated solve (compiled) [s]", "repeated solve converged"], "rows": [["block Jacobi", "2, 1, 0", 13, 193, true, 1.1354643744345898, 141.42991495132446, 13.85288667678833, true], ["line Jacobi", "2, 1, 0", 13, 123, true, 1.1354643743599155, 109.47519326210022, 19.53579878807068, true]]}, {"id": "derivatives", "title": "Adjoint derivatives of the drag coefficient", "columns": ["input", "block Jacobi (solve to 1e-12)", "line Jacobi (solve to 1e-12)", "difference / largest derivative, solves to 1e-12", "difference / largest derivative, solves to 1e-10", "block Jacobi: change from 1e-10 to 1e-12 / largest derivative"], "rows": [["mach", -0.006352388789843865, -0.0063523882407887575, 8.643285635799802e-08, 2.4226840067433526e-06, 7.4870873304961295e-06], ["re", -0.005524897098230009, -0.005524897097839369, 6.149494157135881e-11, 2.9471877131589726e-10, 2.695549413314763e-10], ["alpha", 2.2761667749233253e-14, -3.477065119124596e-14, 9.056800653080508e-12, 6.368407015676479e-11, 7.274960943606415e-11]]}, {"id": "lines", "title": "Lines of the mesh", "columns": ["lines", "elements in lines", "elements", "longest line", "colours", "stored line slots"], "rows": [[54, 216, 432, 4, 3, 216]]}], "provenance": {"version": "0.4.0", "commit": "39979fcf902ad6116eb550b881b4278d4599c8e2", "dirty": false, "describe": "39979fcf90", "device": {"platform": "gpu", "device": "cuda:0", "device_kind": "NVIDIA GeForce RTX 3060 Ti", "jax": "0.11.2", "x64": true}, "timestamp": "2026-11-12T10:58:47-0500"}, "wall_time": 620.35, "notes": "The mesh has 54 lines holding 216 of its 432 elements (the longest 4 elements, 3 colours); 58320 unknowns. The transposed solve took 62 Krylov iterations with line Jacobi against 179 with block Jacobi (ratio 0.35; compiled wall time, ratio 0.29), the forward solve 69 against 210. The adjoint derivatives of the two smoothers differ by at most 2.4e-06 of the largest derivative when the transposed systems are solved to 1e-10 (in the derivative with respect to 'mach') and by at most 8.6e-08 at 1e-12. Between the two tolerances the block-Jacobi value of that derivative itself moves by 7.5e-06 of the largest derivative (last column of the table): the difference between the smoothers is the linear tolerance, amplified by the conditioning of that derivative. One assembly of the preconditioner took 1.18 s with line Jacobi against 0.39 s with block Jacobi, and a flow solve assembles it at every nonlinear step: the repeated flow solves took 13.9 s (block Jacobi) and 19.5 s (line Jacobi). The mesh is coarse and its layers are thinner than a laminar boundary layer at this Reynolds number needs: the case measures the solver, not the flow. Wall times: the column of the linear table is the Krylov solve alone, with a preconditioner that is already assembled; one assembly is timed separately (table 'assembly'). The first flow solve of a configuration includes the one-off compilation. The suite runs its studies in parallel lanes, so other studies were running while these times were taken; they are measurements of small cases on a machine that was not idle, reported without a threshold. Machine load while the study ran: The timings were taken on a busy machine (other processes used 74 % of the capacity of the 8 CPUs while the study ran; the GPU was 17 % utilized when the study started).", "level": "quick"}