Fourier Neural Operator
Spectral convolution architecture that learns mappings between function spaces in Fourier domain.
Variants
FNO3D
20.1M3D Fourier Neural Operator for volumetric reservoir datasets. Uses 3D FFT for spectral convolutions.
FNO2D
2.4M2D Fourier Neural Operator for Cartesian grid datasets. Uses 2D FFT.
Training Provenance
These values are read from the generated benchmark result metadata, not from static method-page copy. When a model is retrained and the website data is regenerated, this section updates with the result records.
Arena training recipe
Arena feature sets
Flow Arena input channels vary by fault complexity. Current result records for this method include 3 feature-set definitions.
Strengths & Weaknesses
Strengths
- Global receptive field from the first layer — captures long-range pressure communication naturally
- Resolution-invariant in principle — can generalize across grid sizes
- Very compact model (0.8M params for 2D, 8.9M for 3D) compared to convolutional alternatives
- Strong theoretical foundation in operator learning and function space approximation
- Spectral bias provides implicit regularization for smooth fields like pressure
Weaknesses
- Spectral truncation can blur sharp discontinuities (saturation fronts, fault boundaries)
- Assumes periodic boundary conditions implicitly — may introduce artifacts near domain boundaries
- Requires uniform Cartesian grids for standard FFT — not directly applicable to unstructured meshes
- Performance degrades on datasets with highly localized features that need many Fourier modes
- Checkpoint saving/loading requires special handling (state_dict extraction) unlike standard PyTorch models
Results Across Benchmarks
All results for Fourier Neural Operator variants across all benchmark families. Sorted by the first field's rel-L² error by default.
Two-Phase Oil-Water
| Pres (bar) | Sat (frac) | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| # | Target | Model | Loss | Epochs | rel-L²▲ | MRE | MAE | rel-L² | MRE | MAE | Params |
| 1 | pressure | FNO3D | BadawiSingleField | 200 | 0.0344 | 0.0300 | 5.154885 | - | - | - | 5.6M |
| 2 | combined | FNO3D | BadawiCombined | 200 | 0.0415 | 0.0357 | 6.102467 | 0.0532 | 0.0423 | 0.014022 | 5.6M |
| 3 | combined | FNO2D | RelLp | 200 | 0.0434 | 0.0375 | 6.469421 | 0.0504 | 0.0379 | 0.012490 | 14.7M |
| 4 | combined | FNO2D | RelLp | 200 | 0.0555 | 0.0482 | 8.634762 | 0.0539 | 0.0414 | 0.013596 | 2.4M |
| 5 | pressure | FNO2D | RelLp | 200 | 0.0581 | 0.0521 | 8.838425 | - | - | - | 14.6M |
| 6 | pressure | FNO2D | RelLp | 200 | 0.0596 | 0.0528 | 9.173145 | - | - | - | 2.4M |
| 7 | saturation | FNO2D | RelLp | 200 | - | - | - | 0.0617 | 0.0465 | 0.015350 | 2.4M |
| 8 | saturation | FNO2D | RelLp | 200 | - | - | - | 0.0565 | 0.0426 | 0.014027 | 14.6M |
| 9 | saturation | FNO3D | BadawiSingleField | 200 | - | - | - | 0.0555 | 0.0431 | 0.014490 | 5.6M |
CO2 Radial
| Pres (bar) | Sat (frac) | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| # | Target | Model | Loss | Epochs | rel-L²▲ | MRE | MAE | rel-L² | MRE | MAE | Params |
| 1 | pressure | FNO2D | UFNODerivLoss | 500 | 0.0057 | 0.0015 | 0.350251 | - | - | - | 20.2M |
| 2 | pressure | FNO2D | RelLp | 500 | 0.0064 | 0.0015 | 0.376695 | - | - | - | 9.0M |
| 3 | combined | FNO2D | RelLp | 500 | 0.0068 | 0.0019 | 0.433446 | 0.1152 | 9.9045 | 0.003185 | 9.0M |
| 4 | saturation | FNO2D | UFNODerivLoss | 500 | - | - | - | 0.1197 | 9.9107 | 0.003067 | 20.2M |
| 5 | saturation | FNO2D | RelLp | 500 | - | - | - | 0.1067 | 8.7535 | 0.002723 | 9.0M |
Flow Arena
| Sat (frac) | Pres (bar) | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| # | Dataset | Model | Loss | Epochs | rel-L²▲ | MRE | MAE | rel-L² | MRE | MAE | Params |
| 1 | geostat_nf_rate | FNO3D | AbsLp(p=2) | 200 | 0.2176 | 0.4239 | 0.050780 | 0.0422 | 0.0361 | 7.765929 | 20.1M |
| 2 | geostat_nf_bhp | FNO3D | AbsLp(p=2) | 200 | 0.2207 | 0.4422 | 0.051482 | 0.0371 | 0.0320 | 8.007223 | 20.1M |
| 3 | geostat_nf_bhp | FNO3D | MSE | 200 | 0.2345 | 0.4861 | 0.054643 | 0.0392 | 0.0337 | 8.408319 | 20.1M |
| 4 | geostat_nf_rate | FNO3D | MSE | 200 | 0.2413 | 0.4747 | 0.051482 | 0.0472 | 0.0398 | 8.519495 | 20.1M |
| 5 | channels_nf_bhp | FNO3D | AbsLp(p=2) | 200 | 0.3062 | 0.6482 | 0.081473 | 0.0630 | 0.0522 | 13.104323 | 20.1M |
| 6 | geostat_zt_bhp | FNO3D | AbsLp(p=2) | 200 | 0.3079 | 0.5782 | 0.069802 | 0.0604 | 0.0490 | 12.343442 | 20.1M |
| 7 | geostat_zt_bhp | FNO3D | MSE | 200 | 0.3101 | 0.5740 | 0.067988 | 0.0616 | 0.0500 | 12.460086 | 20.1M |
| 8 | channels_nf_bhp | FNO3D | MSE | 200 | 0.3125 | 0.7185 | 0.082872 | 0.0630 | 0.0519 | 13.005433 | 20.1M |
| 9 | geostat_zt_rate | FNO3D | MSE | 200 | 0.3215 | 0.5966 | 0.072588 | 0.0999 | 0.0760 | 17.914213 | 20.1M |
| 10 | geostat_zt_rate | FNO3D | AbsLp(p=2) | 200 | 0.3224 | 0.6041 | 0.075425 | 0.0993 | 0.0763 | 18.035299 | 20.1M |
| 11 | channels_nf_rate | FNO3D | AbsLp(p=2) | 200 | 0.3508 | 0.6550 | 0.080835 | 0.0766 | 0.0612 | 13.280948 | 20.1M |
| 12 | channels_nf_rate | FNO3D | MSE | 200 | 0.3562 | 0.7176 | 0.080030 | 0.0801 | 0.0639 | 13.712110 | 20.1M |
| 13 | geostat_vt_bhp | FNO3D | MSE | 200 | 0.3630 | 0.6794 | 0.083388 | 0.0810 | 0.0665 | 16.656662 | 35.7M |
| 14 | geostat_vt_bhp | FNO3D | AbsLp(p=2) | 200 | 0.3636 | 0.7398 | 0.093502 | 0.0778 | 0.0636 | 16.000710 | 35.7M |
| 15 | geostat_vt_rate | FNO3D | AbsLp(p=2) | 200 | 0.3744 | 0.7287 | 0.098138 | 0.1098 | 0.0830 | 20.213245 | 35.7M |
| 16 | geostat_vt_rate | FNO3D | MSE | 200 | 0.3791 | 0.7203 | 0.084728 | 0.1190 | 0.0903 | 21.365623 | 35.7M |
| 17 | channels_zt_bhp | FNO3D | AbsLp(p=2) | 200 | 0.4080 | 0.7672 | 0.089509 | 0.0860 | 0.0697 | 17.261770 | 20.1M |
| 18 | channels_zt_bhp | FNO3D | MSE | 200 | 0.4119 | 0.8244 | 0.090742 | 0.0856 | 0.0688 | 17.075972 | 20.1M |
| 19 | channels_zt_rate | FNO3D | MSE | 200 | 0.4301 | 0.8042 | 0.091805 | 0.1241 | 0.0950 | 22.028023 | 20.1M |
| 20 | channels_zt_rate | FNO3D | AbsLp(p=2) | 200 | 0.4328 | 0.7792 | 0.094815 | 0.1227 | 0.0940 | 21.869766 | 20.1M |
| 21 | channels_vt_bhp | FNO3D | AbsLp(p=2) | 200 | 0.4708 | 0.9126 | 0.105809 | 0.1008 | 0.0799 | 20.026644 | 35.7M |
| 22 | channels_vt_bhp | FNO3D | MSE | 200 | 0.4785 | 0.9393 | 0.102066 | 0.1039 | 0.0824 | 20.654514 | 35.7M |
| 23 | channels_vt_rate | FNO3D | AbsLp(p=2) | 200 | 0.4823 | 0.9359 | 0.109471 | 0.1458 | 0.1106 | 26.306049 | 35.7M |
| 24 | channels_vt_rate | FNO3D | MSE | 200 | 0.4886 | 0.9646 | 0.111228 | 0.1505 | 0.1138 | 26.803350 | 35.7M |
CO2 Nested
| Pres (bar) | |||||||
|---|---|---|---|---|---|---|---|
| # | Model | Loss | Epochs | rel-L²▲ | MRE | MAE | Params |
| 1 | FNO3D | RelLp | 200 | 0.0003 | 8.79e-5 | 0.020232 | 13.2M |
Two-Phase 3D Channels
| Pres (bar) | Sat (frac) | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| # | Target | Model | Loss | Epochs | rel-L²▲ | MRE | MAE | rel-L² | MRE | MAE | Params |
| 1 | pressure | FNO3D | RelLp | 500 | 0.0021 | 0.0015 | 0.491382 | - | - | - | 9.0M |
| 2 | combined | FNO3D | RelLp | 500 | 0.0022 | 0.0017 | 0.539620 | 0.2223 | 0.1442 | 0.031166 | 9.0M |
| 3 | pressure | FNO3D | RelLp | 200 | 0.0024 | 0.0018 | 0.582078 | - | - | - | 9.0M |
| 4 | combined | FNO3D | RelLp | 200 | 0.0026 | 0.0020 | 0.640025 | 0.2308 | 0.1786 | 0.036466 | 9.0M |
| 5 | saturation | FNO3D | RelLp | 200 | - | - | - | 0.2312 | 0.1648 | 0.034480 | 9.0M |
| 6 | saturation | FNO3D | RelLp | 500 | - | - | - | 0.2310 | 0.1571 | 0.033396 | 9.0M |
Training Curves
FNO2D - Two-Phase Oil-Water (combined)
FNO2D - Two-Phase Oil-Water (combined)
FNO2D - Two-Phase Oil-Water (pressure)
FNO2D - Two-Phase Oil-Water (pressure)
FNO2D - Two-Phase Oil-Water (saturation)
FNO2D - Two-Phase Oil-Water (saturation)
FNO2D - CO2 Radial (pressure)
FNO2D - CO2 Radial (saturation)
Architecture
The Fourier Neural Operator (FNO), introduced by Li et al. (2021), represents a fundamentally different approach to learning PDE surrogates. Instead of operating directly in physical space like convolutional networks, FNO performs convolutions in Fourier space via the Fast Fourier Transform (FFT). This spectral approach enables global receptive fields at every layer — each Fourier mode interacts with the entire spatial domain — making FNO naturally suited for problems with long-range spatial correlations like pressure diffusion.
The architecture consists of a lifting layer (projecting inputs to a higher-dimensional channel space), a sequence of Fourier layers (each performing spectral convolution followed by a local linear transform and nonlinearity), and a projection layer mapping back to the output space. The spectral convolutions truncate high-frequency modes, acting as a learned low-pass filter that implicitly regularizes the solution.
FNO has a key theoretical advantage: it is resolution-invariant in principle, meaning a model trained on one grid resolution can be evaluated on another without retraining. In practice, this property is approximate and works best when the underlying physics is smooth.
We use the NVIDIA NeuralOperator library implementation, which provides optimized 2D and 3D variants. The 3D version (FNO3D) treats the spatial domain as a 3D volume, while the 2D version (FNO2D) is used for Cartesian 2D datasets.
Model Summary
FNO2D
FNO2DWrapper(
(model): FNO(
(positional_embedding): GridEmbeddingND()
(fno_blocks): FNOBlocks(
(convs): ModuleList(
(0-3): 4 x SpectralConv(
(weight): DenseTensor(shape=torch.Size([64, 64, 16, 9]), rank=None)
)
)
(fno_skips): ModuleList(
(0-3): 4 x Flattened1dConv(
(conv): Conv1d(64, 64, kernel_size=(1,), stride=(1,), bias=False)
)
)
(channel_mlp): ModuleList(
(0-3): 4 x ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(64, 32, kernel_size=(1,), stride=(1,))
(1): Conv1d(32, 64, kernel_size=(1,), stride=(1,))
)
)
)
(channel_mlp_skips): ModuleList(
(0-3): 4 x SoftGating()
)
)
(lifting): ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(86, 128, kernel_size=(1,), stride=(1,))
(1): Conv1d(128, 64, kernel_size=(1,), stride=(1,))
)
)
(projection): ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(64, 128, kernel_size=(1,), stride=(1,))
(1): Conv1d(128, 80, kernel_size=(1,), stride=(1,))
)
)
)
) FNO3D
FNO3DWrapper(
(model): FNO(
(positional_embedding): GridEmbeddingND()
(fno_blocks): FNOBlocks(
(convs): ModuleList(
(0-3): 4 x SpectralConv(
(weight): DenseTensor(shape=torch.Size([48, 48, 4, 32, 17]), rank=None)
)
)
(fno_skips): ModuleList(
(0-3): 4 x Flattened1dConv(
(conv): Conv1d(48, 48, kernel_size=(1,), stride=(1,), bias=False)
)
)
(channel_mlp): ModuleList(
(0-3): 4 x ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(48, 24, kernel_size=(1,), stride=(1,))
(1): Conv1d(24, 48, kernel_size=(1,), stride=(1,))
)
)
)
(channel_mlp_skips): ModuleList(
(0-3): 4 x SoftGating()
)
)
(lifting): ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(8, 96, kernel_size=(1,), stride=(1,))
(1): Conv1d(96, 48, kernel_size=(1,), stride=(1,))
)
)
(projection): ChannelMLP(
(fcs): ModuleList(
(0): Conv1d(48, 96, kernel_size=(1,), stride=(1,))
(1): Conv1d(96, 40, kernel_size=(1,), stride=(1,))
)
)
)
)