@@ -1441,13 +1441,34 @@ impl Grid {
14411441
14421442 /// Fix one of the convolutions in the Grid and return a new Grid with lower convolution dimension.
14431443 ///
1444+ /// This function integrates out one of the convolution dimensions of the grid by convolving it
1445+ /// with the provided function `xfx`.
1446+ ///
1447+ /// The `conv_idx` parameter specifies which convolution to fix. The `xfx` function provides
1448+ /// the values of the parton distribution function or fragmentation function for a given parton
1449+ /// ID, `x` value, and scale `mu2`. The `xi` parameter is a scale factor for the factorization
1450+ /// or fragmentation scale.
1451+ ///
1452+ /// # Special handling of fragmentation functions
1453+ ///
1454+ /// If the convolution being fixed is a fragmentation function, the dependency on the
1455+ /// fragmentation scale is removed from the grid. This has a direct impact on the perturbative
1456+ /// orders (`Order`). Specifically, the `logxia` of each `Order` is set to zero.
1457+ ///
1458+ /// As a result, multiple original orders might collapse into a single new order. When this
1459+ /// happens, the corresponding subgrids are merged together, ensuring that the total
1460+ /// contribution is preserved. The final grid is then optimized to remove any empty or
1461+ /// duplicate structures.
1462+ ///
14441463 /// # Panics
14451464 ///
1446- /// TODO
1465+ /// This function panics if internal invariants are violated, which typically indicates a bug in
1466+ /// the library.
14471467 ///
14481468 /// # Errors
14491469 ///
1450- /// Returns an error if the Grid has only one single convolution.
1470+ /// Returns an error if `conv_idx` is out of bounds or if the grid has only one convolution,
1471+ /// as the last convolution cannot be fixed.
14511472 pub fn fix_convolution (
14521473 & self ,
14531474 conv_idx : usize ,
@@ -1507,17 +1528,41 @@ impl Grid {
15071528 . collect ( ) ;
15081529 let new_channel_pids: Vec < _ > = new_channel_map. keys ( ) . cloned ( ) . collect ( ) ;
15091530
1510- let mut new_subgrids = Array3 :: from_shape_simple_fn (
1511- ( self . orders . len ( ) , self . bwfl . len ( ) , new_channels. len ( ) ) ,
1531+ let conv_to_fix = & self . convolutions [ conv_idx] ;
1532+ let ( new_orders, order_map) = if conv_to_fix. conv_type ( ) . is_pdf ( ) {
1533+ ( self . orders . clone ( ) , ( 0 ..self . orders . len ( ) ) . collect ( ) )
1534+ } else {
1535+ let mut unique_orders = Vec :: new ( ) ;
1536+ let map: Vec < usize > = self
1537+ . orders
1538+ . iter ( )
1539+ . map ( |o| {
1540+ let mut new_o = o. clone ( ) ;
1541+ new_o. logxia = 0 ;
1542+ unique_orders
1543+ . iter ( )
1544+ . position ( |uo| uo == & new_o)
1545+ . map_or_else (
1546+ || {
1547+ unique_orders. push ( new_o) ;
1548+ unique_orders. len ( ) - 1
1549+ } ,
1550+ |pos| pos,
1551+ )
1552+ } )
1553+ . collect ( ) ;
1554+ ( unique_orders, map)
1555+ } ;
1556+
1557+ let mut new_subgrids: Array3 < SubgridEnum > = Array3 :: from_shape_simple_fn (
1558+ ( new_orders. len ( ) , self . bwfl . len ( ) , new_channels. len ( ) ) ,
15121559 || EmptySubgridV1 . into ( ) ,
15131560 ) ;
15141561
1515- let conv_to_fix = & self . convolutions [ conv_idx] ;
1516-
15171562 for ( inew_chan, new_pids) in new_channel_pids. iter ( ) . enumerate ( ) {
15181563 let origins = & new_channel_map[ new_pids] ;
15191564
1520- for iord in 0 ..self . orders ( ) . len ( ) {
1565+ ( 0 ..self . orders ( ) . len ( ) ) . for_each ( |iord| {
15211566 for ibin in 0 ..self . bwfl ( ) . bins ( ) . len ( ) {
15221567 let mut intermediate_sg: Option < SubgridEnum > = None ;
15231568
@@ -1576,15 +1621,16 @@ impl Grid {
15761621 }
15771622
15781623 if let Some ( sg) = intermediate_sg {
1579- new_subgrids[ [ iord, ibin, inew_chan] ] = sg;
1624+ let new_iord = order_map[ iord] ;
1625+ new_subgrids[ [ new_iord, ibin, inew_chan] ] . merge ( & sg, None ) ;
15801626 }
15811627 }
1582- }
1628+ } ) ;
15831629 }
15841630
15851631 let mut new_grid = Self :: new (
15861632 self . bwfl . clone ( ) ,
1587- self . orders . clone ( ) ,
1633+ new_orders ,
15881634 new_channels,
15891635 * self . pid_basis ( ) ,
15901636 new_convolutions,
0 commit comments