{"id": "mixed_precision", "title": "Single-precision blocks in the preconditioner", "description": "Each case is solved twice from the free stream, with the blocks of the smoother in double and in single precision (solver.precond_precision), and 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. A rounded preconditioner must change neither the answers nor, to speak of, the work: the checks require the same drag coefficient, the same solutions of the linear systems, at most a tenth more Krylov iterations, and half the memory for the stored blocks. The cases cover turbulent flow, whose blocks are the worst conditioned, with both smoothers, and laminar flow in three dimensions.", "passed": true, "checks": [{"name": "every flow solve and every linear solve converged, in both precisions", "value": true, "expected": "true", "passed": true}, {"name": "drag coefficient: largest relative difference between the precisions", "value": 2.2461733956287898e-14, "expected": "< 1e-08", "passed": true}, {"name": "solutions of the linear systems (tolerance 1e-10): largest relative difference between the precisions", "value": 4.465041854283483e-11, "expected": "< 1e-07", "passed": true}, {"name": "Krylov iterations of the flow solve, single / double: largest ratio", "value": 1.0, "expected": "< 1.1", "passed": true}, {"name": "Krylov iterations of the linear solves, single / double: largest ratio", "value": 1.0, "expected": "< 1.1", "passed": true}, {"name": "memory of the stored blocks, single / double: largest ratio", "value": 0.5, "expected": "< 0.51", "passed": true}], "charts": [], "tables": [{"id": "comparison", "title": "Double against single precision of the smoother's blocks", "columns": ["case", "blocks", "unknowns", "nonlinear steps", "Krylov iterations, flow solve", "drag coefficient", "Krylov iterations, forward solve", "Krylov iterations, transposed solve", "linear solutions: relative difference to double", "stored blocks [MB]"], "rows": [["turbulent flat plate (SA)", "double", 6750, 35, 540, 0.005753647480878753, 238, 249, null, 2.94], ["turbulent flat plate (SA)", "single", 6750, 35, 540, 0.005753647480878731, 238, 249, 1.707535781808483e-11, 1.47], ["turbulent flat plate (SA), line smoother", "double", 6750, 35, 267, 0.005753647479387662, 66, 63, null, 8.8984], ["turbulent flat plate (SA), line smoother", "single", 6750, 35, 267, 0.005753647479387533, 66, 63, 4.465041854283483e-11, 4.4492], ["laminar sphere (3-D), Re = 100, degree 1", "double", 3840, 14, 79, 2.1348552042817577, 46, 43, null, 1.248], ["laminar sphere (3-D), Re = 100, degree 1", "single", 3840, 14, 79, 2.134855204281754, 46, 43, 4.1034163558300646e-14, 0.624]]}], "provenance": {"version": "0.4.0", "commit": "39979fcf902ad6116eb550b881b4278d4599c8e2", "dirty": false, "describe": "39979fcf90", "device": {"platform": "cpu", "device": "cpu:0", "device_kind": "cpu", "jax": "0.11.2", "x64": true}, "timestamp": "2026-11-12T11:27:02-0500"}, "wall_time": 2648.96, "notes": "With solver.precond_precision 'single' the columns of the element blocks (and of the coupling blocks of the line smoother) are cast to float32 as they are computed, the inverses and the factorisation of the line systems are computed in float64 from them and rounded, and the blocks are applied in float32. The residual, its Jacobian products and the Krylov vectors are float64 throughout, so the converged flow and the solutions of the linear systems are those of the same equations: the differences in the table are the tolerances of the solves. The cases are small; what the option is for, a problem that does not fit the device otherwise, is in the study scale_3d.", "level": "quick"}