Strategy API¶
flowdesign.strategy
¶
Generative modeling utilities for FlowDesign.
EnergyBasedStrategy
¶
Bases: IntermediateStrategy
Energy-based physics injection from Fig. 2b/2c.
Use t_cut=0.0 in run(...) for full-trajectory injection, or t_cut>0.0 for an unconditional prefix followed by physics-guided injection.
Source code in flowdesign/strategy/intermediate.py
EnergyFullStrategy
¶
Bases: EnergyBasedStrategy
Energy-based strategy with physics injection from t=0.
Source code in flowdesign/strategy/intermediate.py
IntermediateStrategy
¶
Generic intermediate strategy for a pre-trained flow-matching model.
It is agnostic to the exact physical quantities:
everything is delegated to physics_fn and loss_fn.
Pipeline: 1) (Optional) Unconditional rollout from t = 0 -> t_cut using flow matching only. 2) Physics-guided drift from t = t_cut -> 1.0 using gradients from loss_fn(physics_fn(x)).
Parameters¶
wrapped_vf : callable Velocity field wrapper, callable as wrapped_vf(x, t) -> [B, D]. physics_fn : callable Function mapping x -> AeroCoeffs, typically a WingPhysics instance. loss_fn : callable Function mapping AeroCoeffs -> (loss, metrics_dict). dim : int Dimensionality of the design variables (e.g., 16 for CST). device : torch.device or str, optional Device for computation. If None, automatically selects CUDA if available. lambda_guidance : float, optional Scaling factor for the physics gradient guidance term. base_output_dir : str or None, optional Directory for saving CSV outputs. If None, no files are written.
Source code in flowdesign/strategy/intermediate.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
run(n_steps, batch_size, t_cut, save_tag=None, save_csv=True)
¶
Run the intermediate strategy.
Parameters¶
n_steps : int Total number of steps (unconditional + physics-guided). batch_size : int Number of samples to generate. t_cut : float Cutoff time for switching from unconditional rollout to physics-guided drift. 0 <= t_cut <= 1.0. save_tag : str, optional Extra tag for filenames (e.g. "_tc0.60_run0"). save_csv : bool, optional If True, save a summary CSV of metrics.
Returns¶
result_dict : dict Contains: - "x_out" : [B, 1, D] final design variables - "loss" : list of physics-guided losses - "alignment_history" - "total_time" - "avg_time_per_sample" - "metrics_last_step" : dict of metrics from the final step - "diversity_std" - "strategy" : "intermediate" - "x_trajectory" : [T, B, D] full trajectory - "trajectory_semantics": dict explaining the single inference time axis used by intermediate/energy guidance.
Source code in flowdesign/strategy/intermediate.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
MultipleShootingFlowStrategy
dataclass
¶
Multiple-shooting guided generation in DFlow source space.
The interval [t0, t1] is split into shooting segments. The optimization variables are the node states z_0 ... z_M. Terminal design loss is applied at z_M, while segment defects penalize violations of z_{i+1} = Phi_i(z_i). The returned designs are generated by reintegrating from the optimized source node z_0.
Source code in flowdesign/strategy/multiple_shooting.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
PostOptStrategy
¶
Post-Optimization strategy for a pre-trained flow-matching model.
Pipeline: 1) Sample initial designs x0 by rolling out the flow model from t = 1 -> 0. 2) For each sample, run local gradient-based optimization (Adam) on the physical loss starting from x0[i]. 3) Collect per-sample loss curves and final metrics.
This class is agnostic to the exact physical quantities:
- physics_fn maps x -> AeroCoeffs (CL, CD, CM, ...)
- loss_fn maps AeroCoeffs -> (loss, metrics_dict)
Parameters¶
wrapped_vf : callable Velocity field wrapper, callable as wrapped_vf(x, t) -> [B, D]. (e.g. flowdesign.utils.dflow_utils.WrappedModel) physics_fn : AeroPhysics (or compatible) Callable mapping x -> AeroCoeffs (CL, CD, CM). loss_fn : PhysicalLoss (or compatible) Callable mapping AeroCoeffs -> (loss, metrics_dict). dim : int Dimensionality of the design variables (e.g., 16 for CST). device : str or torch.device, optional Device for computation. If None, automatically selects CUDA if available. base_output_dir : str or None, optional Directory for saving optional outputs. If None, no files are written.
Source code in flowdesign/strategy/postopt.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | |
run(n_flow_steps, batch_size, max_opt_steps=200, lr=0.01, early_stop_patience=100, early_stop_thresh=0.0001, thresholds=(0.01, 0.001, 0.0001), save_tag=None, save_csv=True)
¶
Run the Post-Optimization strategy.
Parameters¶
n_flow_steps : int Number of steps for the flow rollout (t=1->0) to get x0. batch_size : int Number of samples to generate and optimize. max_opt_steps : int, optional Maximum number of local optimization steps per sample. lr : float, optional Learning rate for Adam optimizer. early_stop_patience : int, optional Early stopping patience on loss (no significant improvement). early_stop_thresh : float, optional Early stopping threshold on best loss achieved. thresholds : tuple of float, optional Thresholds at which we record the step index (e.g., 1e-2, 1e-3, 1e-4). save_tag : str, optional Extra tag for filenames (e.g. "_flow1000"). save_csv : bool, optional If True, save a summary CSV with aggregate metrics.
Returns¶
result_dict : dict Contains: - "x_out" : [B, 1, D] final optimized designs - "loss" : list of per-sample loss curves (length B) - "steps_to_thresholds": dict mapping threshold -> avg step index - "total_time" - "avg_time_per_sample" - "mean_cl_error", "std_cl_error" - "mean_cm_error", "std_cm_error" - "mean_cd_violation", "max_cd_violation" - "diversity_std" - "strategy" : "postopt" - "x0_from_flow" : initial designs x0 [B, D]
Source code in flowdesign/strategy/postopt.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | |
ShootingFlowStrategy
dataclass
¶
Single-shooting guided generation in DFlow source space.
The strategy solves the inference-time boundary-value problem by optimizing a source state z0 and differentiating through the flow map Phi(z0). If no flow/vector-field model is supplied, Phi is the identity map; this preserves the current package examples where strategies optimize design variables directly.
Source code in flowdesign/strategy/shooting.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
SolverGuidedDFlowStrategy
dataclass
¶
DFlow-style generation guided by solver-estimated losses.
This strategy is intended for non-autograd evaluators such as XFoil. It samples candidates from the geometry prior or sampler, assembles the standard DesignProblem loss, estimates gradients by central finite differences, and updates the design variables.
Source code in flowdesign/strategy/solver_guided.py
get_init_x(x_dims, ode_func, y, H, init_method='random', ode_opts={}, blend_coef=1.0, init_t=0.0, final_t=1.0)
¶
Gets the initial state of the ODE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_dims
|
Size
|
The dimensions of the initial state. |
required |
ode_func
|
Callable
|
model wraper to use for the ODE. Expected API: ode_func(t, x) -> torch.Tensor |
required |
y
|
Tensor
|
observed signal / control value |
required |
H
|
Callable
|
forward operator |
required |
init_method
|
Any
|
The method to use to initialize the initial state. (default: 'random') 'random' - init_x ~ N(0,I) 'backward' - init_x = ODEsolve(y, [1,0]) 'backward_blend'- init_x = H(ODEsolve(y, [1,0]))sqrt(blend_coef) + zsqrt(1-blend_coef) , z~N(0,I) int - init_x = torch.randn(x_dims) with seed = init_method |
'random'
|
ode_opts
|
Dict
|
A dictionary of options for the ODE solver. |
{}
|
blend_coef
|
float
|
The blend coefficient for the initial state. |
1.0
|
init_t
|
float
|
The initial time. (default: 0.) |
0.0
|
final_t
|
float
|
The final time. (default: 1.) |
1.0
|
Returns:
| Type | Description |
|---|---|
Tensor
|
The initial state of the ODE. |
Source code in flowdesign/strategy/dflow.py
ode_integrate(ode_func, init_x, ode_opts={}, t_eps=0, init_t=0.0, final_t=1.0, t_arr=None, intermediate_points=False)
¶
Integrates an ODE using the given ode_func.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ode_func
|
Callable
|
model wraper to use for the ODE. Expected API: ode_func(t, x) -> torch.Tensor |
required |
init_x
|
Tensor
|
The initial state of the ODE. |
required |
ode_opts
|
Dict
|
A dictionary of options for the ODE solver. |
{}
|
t_eps
|
float
|
A small value to add to the initial time. |
0
|
init_t
|
float
|
The initial time. |
0.0
|
final_t
|
float
|
The final time. |
1.0
|
t_arr
|
Optional[List[float]]
|
An optional array of times to evaluate the ODE at. |
None
|
intermediate_points
|
bool
|
Whether to return the intermediate points. |
False
|
Returns:
| Type | Description |
|---|---|
Tensor
|
The solution to the ODE at the final time. (or at intermediate points if intermediate_points=True) |
Source code in flowdesign/strategy/dflow.py
flow_map(vector_field, x, flow_steps=8, t0=0.0, t1=1.0, integrator='rk4')
¶
Differentiable fixed-step flow map used by shooting strategies.
Source code in flowdesign/strategy/shooting.py
flow_trajectory(vector_field, x, flow_steps=8, t0=0.0, t1=1.0, integrator='rk4')
¶
Return inference-time states [T+1, B, D] from source to terminal.