Ë
    :ƒ§jL3  ã                  ó0  — d Z ddlmZ ddlmZ ddlZddlmZmZ ddlmc m	Z
 dd„Z G d„ dej                  «      Zdd	„Z G d
„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Zd d„Z G d„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Z G d„ dej                  «      Zy)!zÃSmall PyTorch implementations of the POC model families.

These are deliberately dependency-light baselines, not claims of a production
architecture or of material/defect predictive performance.
é    )Úannotations)ÚOptionalN)ÚTensorÚnnc                ó   — t        j                  t        j                  | |dd¬«      t        j                  d|«      t        j                  «       t        j                  ||dd¬«      t        j                  «       «      S ©Né   é   ©Úpadding)r   Ú
SequentialÚConv2dÚ	GroupNormÚGELU©ÚcinÚcouts     úmodels/architectures.pyÚ_conv2r      ó{   € Ü�=‰=œŸ™ 3¨¨a¸Ô;¼R¿\¹\È!ÈTÓ=RÔTV×T[ÑT[ÓT]Ô_a×_hÑ_hÐimÐosÐuvð  ABô  `Cô  EG÷  ELñ  ELó  ENó  Oð  Oó    c                  ó0   ‡ — e Zd ZdZddˆ fd„Zddd„Zˆ xZS )Ú	CNN2DUNetzA2D CNN/U-Net for multi-view raster channels; output is per-pixel.c                ó¤  •— t         ‰| �  «        t        ||«      t        ||dz  «      c| _        | _        t        j                  d«      | _        t        j                  |dz  |dd¬«      | _	        t        |dz  |«      t        j                  ||d«      c| _        | _        || _        |rt        j                  ||dz  «      | _        y d | _        y )Né   )Ústrider
   é   )ÚsuperÚ__init__r   Úenc1Úenc2r   Ú	MaxPool2dÚpoolÚConvTranspose2dÚupr   ÚdecÚheadÚ
global_dimÚLinearÚfilm©ÚselfÚin_channelsÚout_channelsÚwidthr(   Ú	__class__s        €r   r   zCNN2DUNet.__init__   sª   ø€ Ü‰ÑÔÜ% k°5Ó9¼6À%ÈÐQRÉÓ;SÐˆŒ	�4”9Ü—L‘L “OˆŒ	Ü×$Ñ$ U¨Q¡Y°°qÀÔCˆŒÜ$ U¨Q¡Y°Ó6¼¿	¹	À%ÈÐWXÓ8YÐˆŒ�$”)Ø$ˆŒÙ8B”B—I‘I˜j¨%°!©)Ó4ˆ�	Èˆ�	r   c                óŠ  — | j                  |«      }| j                  | j                  |«      «      }| j                  �z|�(|j                  |j                  d   | j
                  fk7  rt        d«      ‚| j                  |«      j                  dd«      \  }}|d|d d …d d …d d f   z   z  |d d …d d …d d f   z   }| j                  |«      }|j                  dd  |j                  dd  k7  r&t        j                  ||j                  dd  dd¬«      }| j                  | j                  t        j                  ||gd¬	«      «      «      S )
Nr   zCCNN2DUNet requires one [B,global_dim] process+mask vector per imager   r
   éþÿÿÿÚbilinearF©ÚsizeÚmodeÚalign_corners)Údim)r    r!   r#   r*   Úshaper(   Ú
ValueErrorÚchunkr%   ÚFÚinterpolater'   r&   ÚtorchÚcat)r,   ÚxÚprocessÚaÚbÚscaleÚbiasÚus           r   ÚforwardzCNN2DUNet.forward   s  € Ø�I‰I�a‹Lˆ˜dŸi™i¨¯	©	°!«Ó5˜!Ø�9‰9Ð Øˆ '§-¡-°A·G±G¸A±JÀÇÁÐ3PÒ"PÜ Ð!fÓgÐgØŸ)™) GÓ,×2Ñ2°1°aÓ8‰KˆE�4Ø�Q˜šq¢! T¨4Ð/Ñ0Ñ0Ñ1°DººA¸tÀTÐ9IÑ4JÑJˆAØ�G‰G�A‹JˆØ�7‰7�2�3ˆ<˜1Ÿ7™7 2 3˜<Ò'¬Q¯]©]¸1À1Ç7Á7È2È3À<ÐV`ÐpuÔ-v¨Ø�y‰y˜Ÿ™¤%§)¡)¨Q°¨F¸Ô":Ó;Ó<Ð<r   )r
   é   r   ©r-   Úintr.   rJ   r/   rJ   r(   rJ   ©N©r@   r   rA   úOptional[Tensor]Úreturnr   ©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rG   Ú__classcell__©r0   s   @r   r   r      s   ø„ ÙKöM÷	=ð 	=r   r   c                ó   — t        j                  t        j                  | |dd¬«      t        j                  d|«      t        j                  «       t        j                  ||dd¬«      t        j                  «       «      S r   )r   r   ÚConv3dr   r   r   s     r   Ú_conv3rX   )   r   r   c                  ó0   ‡ — e Zd ZdZddˆ fd„Zddd„Zˆ xZS )ÚUNet3Dz?Dense 3D U-Net; only use bounded dense occupancy/field tensors.c                ó¢  •— t         ‰| �  «        t        ||«      t        ||dz  «      c| _        | _        t        j                  d«      | _        t        j                  |dz  |dd«      | _	        t        |dz  |«      t        j                  ||d«      c| _        | _        || _        |rt        j                  ||dz  «      | _        y d | _        y )Nr   r
   r   )r   r   rX   r    r!   r   Ú	MaxPool3dr#   ÚConvTranspose3dr%   rW   r&   r'   r(   r)   r*   r+   s        €r   r   zUNet3D.__init__/   s­   ø€ Ü‰ÑÔÜ% k°5Ó9¼6À%ÈÐQRÉÓ;SÐˆŒ	�4”9Ü—L‘L “OˆŒ	¬r×/AÑ/AÀ%È!Á)ÈUÐTUÐWXÓ/Y T¤WÜ$ U¨Q¡Y°Ó6¼¿	¹	À%ÈÐWXÓ8YÐˆŒ�$”)Ø$ˆŒÑV`´"·)±)¸JÈÐPQÉ	Ó2R d¥iÐfj d¥ir   c                ó®  — | j                  |«      }| j                  | j                  |«      «      }| j                  |«      }| j                  ��|�(|j
                  |j
                  d   | j                  fk7  rt        d«      ‚| j	                  |«      j                  dd«      \  }}|d|d d …d d …d d d f   z   z  |d d …d d …d d d f   z   }| j                  |«      }|j
                  dd  |j
                  dd  k7  r&t        j                  ||j
                  dd  dd¬«      }| j                  | j                  t        j                  ||gd«      «      «      S )	Nr   zAUNet3D requires one [B,global_dim] process+mask vector per volumer   r
   éýÿÿÿÚ	trilinearFr4   )r    r!   r#   r%   r*   r9   r(   r:   r;   r<   r=   r'   r&   r>   r?   )r,   r@   rA   rB   rC   rF   rD   rE   s           r   rG   zUNet3D.forward6   sM  € Ø�I‰I�a‹Lˆ˜dŸi™i¨¯	©	°!«Ó5˜!¸4¿7¹7À1»:°qØ�9‰9Ð Øˆ '§-¡-°A·G±G¸A±JÀÇÁÐ3PÒ"PÔXbð  dgó  Yhð  ShØŸ)™) GÓ,×2Ñ2°1°aÓ8‰KˆE�4¸aÀ1ÀuÊQÒPQÐSWÐY]Ð_cÐMcÑGdÑCdÑ>eÐhlÒmnÒpqÐswÐy}ð  @Dð  nDñ  iEñ  ?E¸!Ø—‘˜“
ˆAØ�7‰7�2�3ˆ<˜1Ÿ7™7 2 3˜<Ò'¬Q¯]©]¸1À1Ç7Á7È2È3À<ÐVaÐqvÔ-w¨Ø�y‰y˜Ÿ™¤%§)¡)¨Q°¨F°AÓ"6Ó7Ó8Ð8r   )r
   é   r   rI   rK   rL   rO   rU   s   @r   rZ   rZ   -   s   ø„ ÙIök÷9ð 9r   rZ   c                  ó2   ‡ — e Zd ZdZdZddˆ fd„Zdd„Zˆ xZS )ÚSparseUNetOptionalzNTrue sparse U-Net, available only with MinkowskiEngine (never dense fallback).ÚMinkowskiEnginec           	     ó6  •— t         ‰| �  «        	 dd l}|| _        t        j                  |j                  ||dd¬«      |j                  |«      |j                  «       «      | _        t        j                  |j                  ||dz  ddd¬«      |j                  |dz  «      |j                  «       «      | _        t        j                  |j                  |dz  |dz  dd¬«      |j                  |dz  «      |j                  «       «      | _        t        j                  |j                  |dz  |ddd¬«      |j                  |«      |j                  «       «      | _        |j                  |dz  |dd¬«      | _        y # t        $ r}t	        d«      |‚d }~ww xY w)Nr   zfSparse U-Net unavailable: install optional MinkowskiEngine; dense tensors are not a sparse substitute.r	   )Ú	dimensionr   )r   rf   r
   )r   r   rd   ÚImportErrorÚRuntimeErrorÚ_MEr   r   ÚMinkowskiConvolutionÚMinkowskiBatchNormÚMinkowskiReLUÚstemÚdownÚmidÚMinkowskiConvolutionTransposer%   r'   )r,   r-   r.   r/   ÚMEÚexcr0   s         €r   r   zSparseUNetOptional.__init__C   sÿ  ø€ Ü‰ÑÔð	RÛ(ð ˆŒÜ—M‘M "×"9Ñ"9¸+ÀuÈaÐ[\Ð"9Ó"]Ð_a×_tÑ_tÐuzÓ_{Ð}÷  ~Nñ  ~Nó  ~Pó  QˆŒ	Ü—M‘M "×"9Ñ"9¸%ÀÈÁÈAÐVWÐcdÐ"9Ó"eÐgi×g|Ñg|ð  ~Cð  FGñ  ~Gó  hHð  JL÷  JZñ  JZó  J\ó  ]ˆŒ	Ü—=‘= ×!8Ñ!8¸À¹ÀEÈAÁIÈqÐ\]Ð!8Ó!^Ð`b×`uÑ`uÐv{Ð~Ñvó  aAð  CE÷  CSñ  CSó  CUó  VˆŒÜ—-‘- × @Ñ @ÀÈÁÈEÐSTÐ]^ÐjkÐ @Ó lÐnp÷  oDñ  oDð  EJó  oKð  MO÷  M]ñ  M]ó  M_ó  `ˆŒØ×+Ñ+¨E°A©I°|ÀQÐRSÐ+ÓTˆ�	øô ò 	RÜð   Hó  Ið  ORð  Rûð	Rús   ‘E> Å>	FÆFÆFc                óÔ   — | j                  |«      }| j                  | j                  j                  || j	                  | j                  | j                  |«      «      «      «      «      S rK   )rm   r'   ri   r?   r%   ro   rn   )r,   r@   Úskips      r   rG   zSparseUNetOptional.forwardP   sK   € Ø�y‰y˜‹|ˆ D§I¡I¨d¯h©h¯l©l¸4ÀÇÁÈÏÉÐRV×R[ÑR[Ð\`ÓRaÓIbÓAcÓ.dÓ$eÐer   )r
   rH   ©r-   rJ   r.   rJ   r/   rJ   ©r@   r   rN   r   )rP   rQ   rR   rS   Úbackendr   rG   rT   rU   s   @r   rc   rc   @   s   ø„ ÙXØ€GöU÷fr   rc   c                  ó.   ‡ — e Zd ZdZddˆ fd„Zdd„Zˆ xZS )ÚPointNetSegz3PointNet segmentation baseline, [B,N,C] -> [B,N,O].c           	     ó´  •— t         ‰| �  «        t        j                  t        j                  ||d«      t        j
                  «       t        j                  ||dz  d«      t        j
                  «       «      | _        t        j                  t        j                  |dz  |d«      t        j
                  «       t        j                  ||d«      «      | _        y )Nr
   r   r   )r   r   r   r   ÚConv1dr   Úlocalr'   ©r,   r-   r.   r/   r0   s       €r   r   zPointNetSeg.__init__V   s•   ø€ Ü‰ÑÔÜ—]‘]¤2§9¡9¨[¸%ÀÓ#CÄRÇWÁWÃYÔPR×PYÑPYÐZ_ÐafÐijÑajÐlmÓPnÔpr×pwÑpwÓpyÓzˆŒ
Ü—M‘M¤"§)¡)¨E°A©I°u¸aÓ"@Ä"Ç'Á'Ã)ÌRÏYÉYÐW\Ð^jÐlmÓMnÓoˆ�	r   c                ó
  — | j                  |j                  dd«      «      }|j                  dd¬«      j                  j	                  |«      }| j                  t        j                  ||gd«      «      j                  dd«      S )Nr
   r   éÿÿÿÿT)r8   Úkeepdim)r|   Ú	transposeÚmaxÚvaluesÚ	expand_asr'   r>   r?   )r,   r@   ÚhÚgs       r   rG   zPointNetSeg.forward[   si   € Ø�J‰J�q—{‘{ 1 aÓ(Ó)ˆ¨q¯u©u¸ÀT¨uÓ/J×/QÑ/Q×/[Ñ/[Ð\]Ó/^¨1Ø�y‰yœŸ™ A q 6¨1Ó-Ó.×8Ñ8¸¸AÓ>Ð>r   ©r
   é@   ru   rv   rO   rU   s   @r   ry   ry   T   s   ø„ Ù=öp÷
?r   ry   c                ó°  — | j                   d   }|dk(  rt        d«      ‚|dk(  rEt        j                  | dd…dd…ddd…f   t        j                  | dd…dd…ddd…f   «      gd«      S t        ||dz
  «      }t        j                  | | «      }|j                  dd¬«      j                  t        d«      «       |j                  |d	¬
«      j                  }t        j                  | j                   d   | j                  ¬«      dd…ddf   }| ||f   }t        j                  | dd…dd…ddd…f   j                  |«      || dd…dd…ddd…f   z
  gd«      S )zLDynamic feature-space kNN, bounded by caller supplied N (DGCNN smoke <=512).r
   r   zDGCNN needs at least one pointNr   r   )Údim1Údim2ÚinfF)Úlargest)Údevice)r9   r:   r>   r?   Ú
zeros_likeÚminÚcdistÚdiagonalÚfill_ÚfloatÚtopkÚindicesÚarangerŽ   r„   )r@   ÚkÚnÚdistÚidxrC   Únbrs          r   Ú_knn_featuresr�   `   s/  € à	�‰�‰
€AØˆA‚v”ZÐ @ÓAÐAØˆA‚vÜ�y‰y˜!šAšq $ª˜MÑ*¬E×,<Ñ,<¸QºqÂ!ÀTÊ1¸}Ñ=MÓ,NÐOÐQSÓTÐTÜˆAˆq�1‰u‹€AÜ�;‰;�q˜!Ó€DØ‡M�M�q˜q€MÓ!×'Ñ'¬¨e«Ô5Ø
�)‰)�A˜uˆ)Ó
%×
-Ñ
-€CÜ�‰�Q—W‘W˜Q‘Z¨¯©Ô1²!°T¸4°-Ñ@€AØ
ˆAˆsˆF‰)€CÜ�9‰9�ašš1˜d¢A˜Ñ&×0Ñ0°Ó5°s¸QºqÂ!ÀTÊ1¸}Ñ=MÑ7MÐNÐPRÓSÐSr   c                  ó6   ‡ — e Zd ZdZddˆ fd„Zdd„Zdd„Zˆ xZS )	ÚDGCNNSegzFDGCNN with recomputed feature-neighbor graphs at both EdgeConv stages.c                ó’  •— t         ‰| �  «        || _        t        j                  t        j
                  |dz  |«      t        j                  «       t        j
                  ||«      t        j                  «       «      | _        t        j                  t        j
                  |dz  |«      t        j                  «       t        j
                  ||«      t        j                  «       «      | _        t        j                  t        j
                  |dz  |«      t        j                  «       t        j
                  ||«      «      | _	        y )Nr   r	   )
r   r   r˜   r   r   r)   r   Úe1Úe2r'   )r,   r-   r.   r/   r˜   r0   s        €r   r   zDGCNNSeg.__init__q   sÎ   ø€ Ü‰ÑÔ Q˜DœFÜ—-‘-¤§	¡	¨+¸©/¸5Ó AÄ2Ç7Á7Ã9ÌbÏiÉiÐX]Ð_dÓNeÔgi×gnÑgnÓgpÓqˆŒÜ—-‘-¤§	¡	¨%°!©)°UÓ ;¼R¿W¹W»YÌÏ	É	ÐRWÐY^ÓH_Ôac×ahÑahÓajÓkˆŒÜ—M‘M¤"§)¡)¨E°A©I°uÓ"=¼r¿w¹w»yÌ"Ï)É)ÐTYÐ[gÓJhÓiˆ�	r   c                ól   —  |t        || j                  «      «      j                  d«      j                  S ©Nr   )r�   r˜   r‚   rƒ   )r,   r@   Únets      r   Ú_edgezDGCNNSeg._edgew   s)   € Ù”=  D§F¡FÓ+Ó,×0Ñ0°Ó3×:Ñ:Ð:r   c                ó  — | j                  || j                  «      }| j                  || j                  «      }|j                  dd¬«      j                  j                  |«      }| j                  t        j                  |||gd«      «      S )Nr
   T)r€   r   )	r¦   r¡   r¢   r‚   rƒ   r„   r'   r>   r?   )r,   r@   rB   rC   r†   s        r   rG   zDGCNNSeg.forwardz   sl   € Ø�J‰J�q˜$Ÿ'™'Ó"ˆ¨¯
©
°1°d·g±gÓ(> AØ�E‰E�!˜TˆEÓ"×)Ñ)×3Ñ3°AÓ6ˆØ�y‰yœŸ™ A q¨! 9¨bÓ1Ó2Ð2r   )r
   é    rH   )r-   rJ   r.   rJ   r/   rJ   r˜   rJ   )r@   r   r¥   z	nn.ModulerN   r   rv   )rP   rQ   rR   rS   r   r¦   rG   rT   rU   s   @r   rŸ   rŸ   o   s   ø„ ÙPöjó;÷3r   rŸ   c                  ó0   ‡ — e Zd ZdZddˆ fd„Zddd„Zˆ xZS )ÚMeshGraphProcessorzLEdge-conditioned message passing with per-graph global process conditioning.c                óŠ  •— t         ‰| �  «        || _        t        j                  t        j
                  ||«      t        j                  «       «      | _        t        j                  t        j
                  ||«      t        j                  «       «      | _        t        j                  t        j
                  |dz  |z   |z   |«      t        j                  «       t        j
                  ||«      t        j                  «       «      | _	        t        j                  |dz  |«      | _        t        j
                  ||«      | _        y r¤   )r   r   Ústepsr   r   r)   r   ÚnodeÚ
global_encÚedgeÚGRUCellÚupdater'   )r,   Únode_dimÚedge_dimr(   r.   r/   r¬   r0   s          €r   r   zMeshGraphProcessor.__init__‚   sØ   ø€ Ü‰ÑÔ¨˜DœJÜ—M‘M¤"§)¡)¨H°eÓ"<¼b¿g¹g»iÓHˆŒ	ÜŸ-™-¬¯	©	°*¸eÓ(DÄbÇgÁgÃiÓPˆŒÜ—M‘M¤"§)¡)¨E°A©I¸Ñ,@À5Ñ,HÈ%Ó"PÔRT×RYÑRYÓR[Ô]_×]fÑ]fÐglÐnsÓ]tÔvx×v}Ñv}Óvó  AˆŒ	Ü—j‘j ¨¡¨EÓ2ˆŒÄÇ	Á	È%ÐQ]Ó@^°DµIr   c           
     ó  — |€.|j                  |j                  d   t        j                  ¬«      }| j	                  |«      }| j                  |«      |   }|\  }}	t        | j                  «      D ]‚  }
| j                  t        j                  ||   ||	   |||   gd«      «      }t        j                  |«      j                  d|	|«      }| j                  t        j                  ||gd«      |«      }Œ„ | j                  |«      S )Nr   ©Údtyper
   )Ú	new_zerosr9   r>   Úlongr­   r®   Úranger¬   r¯   r?   r�   Ú
index_add_r±   r'   )r,   Únode_xÚ
edge_indexÚ	edge_attrÚglobal_xÚbatchr…   r†   ÚsrcÚdstÚ_ÚmÚaggs                r   rG   zMeshGraphProcessor.forward‰   sß   € Øˆ= &×"2Ñ"2°6·<±<À±?Ì%Ï*É*Ð"2Ó"U˜%Ø�I‰I�fÓˆ 4§?¡?°8Ó#<¸UÑ#C˜qØ‰ˆˆSÜ�t—z‘zÖ"ˆAØ—	‘	œ%Ÿ)™) Q s¡V¨Q¨s©V°YÀÀ#ÁÐ$GÈÓKÓLˆAÜ×"Ñ" 1Ó%×0Ñ0°°C¸Ó;ˆCØ—‘œEŸI™I q¨# h°Ó2°AÓ6‰Að #ð �y‰y˜‹|Ðr   )r
   é0   r	   )r²   rJ   r³   rJ   r(   rJ   r.   rJ   r/   rJ   r¬   rJ   rK   )r»   r   r¼   r   r½   r   r¾   r   r¿   rM   rN   r   rO   rU   s   @r   rª   rª   €   s   ø„ ÙVö_÷ð r   rª   c                  óF   ‡ — e Zd ZdZ	 d	 	 	 	 	 dˆ fd„Z	 	 	 	 	 	 dd„Zˆ xZS )ÚPhysicsConstrainedRiskGNNzÛNode-wise risk/deformation heads with a hard magnitude constraint.

    ``deformation_magnitude >= abs(signed_normal_deformation)`` is enforced by
    construction. Defect-type logits are pooled once per graph/run.
    c                ó‚   •— t         ‰| �  «        |dk  rt        d«      ‚|| _        t	        |||d|z   ||¬«      | _        y )Nr
   z!defect_types must be at least oner	   )r.   r/   r¬   )r   r   r:   Údefect_typesrª   Ú	processor)r,   r²   r³   r(   rÉ   r/   r¬   r0   s          €r   r   z"PhysicsConstrainedRiskGNN.__init__š   sI   ø€ ä‰ÑÔØ˜!ÒÜÐ@ÓAÐAØ(ˆÔÜ+Ø�h 
¸¸\Ñ9IØ˜uô&ˆ�r   c                óÖ  — | j                  |||||«      }|d d …df   }|j                  «       t        j                  |d d …df   «      z   }|d d …dd …f   }	|j                  d   }
|	j                  |
| j                  f«      j                  d||	«      }t        j                  ||
¬«      j                  d«      j                  |	j                  «      d d …d f   }|d d …df   ||||z  dœS )Nr
   r   r	   r   )Ú	minlength)Ú
risk_logitÚsigned_normal_deformationÚdeformation_magnitudeÚdefect_type_logits)rÊ   Úabsr<   Úsoftplusr9   r·   rÉ   rº   r>   ÚbincountÚ	clamp_minÚtor¶   )r,   r»   r¼   r½   r¾   r¿   ÚrawÚsignedÚ	magnitudeÚ	node_typeÚgraph_countÚtype_sumÚcounts                r   rG   z!PhysicsConstrainedRiskGNN.forward¤   sé   € à�n‰n˜V Z°¸HÀeÓLˆØ’Q˜�T‘ˆØ—J‘J“L¤1§:¡:¨c²!°Q°$©iÓ#8Ñ8ˆ	Øš˜1™2˜‘Jˆ	Ø—n‘n QÑ'ˆØ×&Ñ&¨°T×5FÑ5FÐ'GÓH×SÑSÐTUÐW\Ð^gÓhˆÜ—‘˜u°Ô<×FÑFÀqÓI×LÑLÈYÏ_É_Ó]Ò^_ÐaeÐ^eÑfˆàša ˜d™)Ø)/Ø%.Ø"*¨UÑ"2ñ	
ð 	
r   )r¨   r   )r²   rJ   r³   rJ   r(   rJ   rÉ   rJ   r/   rJ   r¬   rJ   )r»   r   r¼   r   r½   r   r¾   r   r¿   r   rN   zdict[str, Tensor]rO   rU   s   @r   rÇ   rÇ   ”   sI   ø„ ñð CDð&Ø"ð&Ø+.ð&Ø<?õ&ð
Ø ð
Ø)/ð
Ø4E÷
r   rÇ   c                  ó.   ‡ — e Zd ZdZddˆ fd„Zdd„Zˆ xZS )ÚUVNetFaceModelzJUV-Net-style face-grid encoder followed by face adjacency message passing.c           
     ó¾  •— t         ‰| �  «        t        j                  t        j                  ||dd¬«      t        j
                  «       t        j                  ||dd¬«      t        j
                  «       «      | _        t        j                  t        j                  |dz  |«      t        j
                  «       «      | _        t        j                  ||«      | _	        y )Nr	   r
   r   r   )
r   r   r   r   r   r   Úgridr)   Úmsgr'   )r,   ÚchannelsÚface_dimr.   r0   s       €r   r   zUVNetFaceModel.__init__·   sÄ   ø€ Ü‰ÑÔ¬¯©´b·i±iÀÈ(ÐTUÐ_`Ô6aÔce×cjÑcjÓclÔnp×nwÑnwð  yAð  CKð  MNð  XYô  oZô  \^÷  \cñ  \có  \eó  )f˜DœIÜ—=‘=¤§¡¨8°a©<¸Ó!BÄBÇGÁGÃIÓNˆŒÔ\^×\eÑ\eÐfnÐp|Ó\}ÐPTÕPYr   c                ó  — | j                  |«      j                  d«      }|\  }}| j                  t        j                  ||   ||   gd«      «      }t        j
                  |«      j                  d||«      }| j                  ||z   «      S )N)r   r2   r
   r   )rà   Úmeanrá   r>   r?   r�   rº   r'   )r,   ÚgridsÚ	adjacencyr…   rÀ   rÁ   rÃ   rÄ   s           r   rG   zUVNetFaceModel.forward»   s}   € à�I‰I�eÓ×!Ñ! (Ó+ˆ¸	©X¨S°#Ø�H‰H”U—Y‘Y  #¡¨¨#©Ð/°Ó3Ó4ˆ¼E×<LÑ<LÈQÓ<O×<ZÑ<ZÐ[\Ð^aÐcdÓ<e°cØ�y‰y˜˜S™Ó!Ð!r   )ra   r
   )râ   rJ   rã   rJ   r.   rJ   )ræ   r   rç   r   rN   r   rO   rU   s   @r   rÞ   rÞ   µ   s   ø„ ÙTö~÷"r   rÞ   c                  ó*   ‡ — e Zd Zddˆ fd„Zdd„Zˆ xZS )ÚSpectralConv2dc           	     óZ  •— t         ‰| �  «        |||c| _        | _        | _        t        j                  t        j                  ||||t        j                  ¬«      dz  «      | _
        t        j                  t        j                  ||||t        j                  ¬«      dz  «      | _        y )Nrµ   g{®Gáz”?)r   r   r   r   Úmodesr   Ú	Parameterr>   ÚrandnÚcfloatÚ
weight_posÚ
weight_neg)r,   r   r   rë   r0   s       €r   r   zSpectralConv2d.__init__Ã   s   ø€ Ü‰ÑÔ¸cÀ4ÈÐ;˜DœH d¤i°´ÜŸ,™,¤u§{¡{°3¸¸eÀUÔRW×R^ÑR^Ô'_ÐbfÑ'fÓgˆŒÜŸ,™,¤u§{¡{°3¸¸eÀUÔRW×R^ÑR^Ô'_ÐbfÑ'fÓgˆ�r   c           
     óœ  — t         j                  j                  |«      }t        j                  |j                  d   | j
                  |j                  d   |j                  d   dz  dz   |j                  t         j                  ¬«      }t        | j                  |j                  d   «      }t        | j                  |j                  d   «      }t        | j                  t        d|j                  d   |z
  «      «      }t        j                  d|d d …d d …d |…d |…f   | j                  d d …d d …d |…d |…f   «      |d d …d d …d |…d |…f<   |rPt        j                  d|d d …d d …| d …d |…f   | j                  d d …d d …d |…d |…f   «      |d d …d d …| d …d |…f<   t         j                  j                  ||j                  dd  ¬«      S )	Nr   r2   r   r   r
   )rŽ   r¶   zbixy,ioxy->boxy)Ús)r>   ÚfftÚrfft2Úzerosr9   r   rŽ   rî   r�   rë   r‚   Úeinsumrï   rð   Úirfft2)r,   r@   ÚxfÚoutÚm2ÚposÚnegs          r   rG   zSpectralConv2d.forwardÇ   sÉ  € Ü�Y‰Y�_‰_˜QÓˆ¤u§{¡{°1·7±7¸1±:¸t¿y¹yÈ!Ï'É'ÐRTÉ+ÐWX×W^ÑW^Ð_aÑWbÐfgÑWgÐjkÑWkÐtu×t|Ñt|ô  EJ÷  EQñ  EQô  (R Ü�—‘˜RŸX™X b™\Ó*ˆ´#°d·j±jÀ!Ç'Á'È"Á+Ó2N¨CÔVYÐZ^×ZdÑZdÔfiÐjkÐmn×mtÑmtÐuwÑmxÐ{~Ñm~Ófó  WAÐPSÜ$Ÿ|™|Ð,=¸rÂ!ÂQÈÈÈÈcÈrÈcÀ/Ñ?RÐTX×TcÑTcÒdeÒghÐjnÐknÐjnÐpsÐqsÐpsÐdsÑTtÓuˆŠAŠq�$�3�$˜˜˜ˆOÑÙÜ$)§L¡LÐ1BÀBÂqÊ!ÈcÈTÉUÐTWÐUWÐTWÐGWÑDXÐZ^×ZiÑZiÒjkÒmnÐptÐqtÐptÐvyÐwyÐvyÐjyÑZzÓ${ˆC’’1�s�d‘e˜S˜b˜SÐ Ñ!Ü�y‰y×Ñ  q§w¡w¨r¨s |ÐÓ4Ð4r   )ra   )r   rJ   r   rJ   rë   rJ   rv   )rP   rQ   rR   r   rG   rT   rU   s   @r   ré   ré   Â   s   ø„ öh÷5r   ré   c                  ó0   ‡ — e Zd ZdZddˆ fd„Zddd„Zˆ xZS )ÚFNO2dzFFourier neural operator baseline for gridded thermal/field surrogates.c           
     ó  •— t         ‰| �  «        t        j                  ||d«      | _        t        j
                  t        d«      D �cg c]  }t        |||«      ‘Œ c}«      | _        t        j
                  t        d«      D �cg c]  }t        j                  ||d«      ‘Œ c}«      | _	        t        j                  ||d«      | _
        || _        |rt        j                  ||dz  «      | _        y d | _        y c c}w c c}w )Nr
   r	   r   )r   r   r   r   ÚliftÚ
ModuleListr¹   ré   Úspecrt   rù   r(   r)   r*   )r,   r-   r.   r/   rë   r(   rÂ   r0   s          €r   r   zFNO2d.__init__Ò   sÍ   ø€ Ü‰ÑÔ¬¯	©	°+¸uÀaÓ(H˜DœIÜ—M‘MÔPUÐVWÔPXÓ"YÑPXÈ1¤>°%¸ÀÕ#FÐPXÑ"YÓZˆŒ	Ü—M‘MÄuÈQÄxÓ"PÁxÀ!¤2§9¡9¨U°E¸1Õ#=ÀxÑ"PÓQˆŒ	Ô^`×^gÑ^gÐhmÐo{Ð}~Ó^ÐSWÔS[Ø$ˆŒÑV`´"·)±)¸JÈÐPQÉ	Ó2R d¥iÐfj d¥iùò #ZùÚ"Ps   ÁC:ÂC?c                óê  — | j                  |«      }| j                  �z|�(|j                  |j                  d   | j                  fk7  rt	        d«      ‚| j                  |«      j                  dd«      \  }}|d|d d …d d …d d f   z   z  |d d …d d …d d f   z   }t        | j                  | j                  «      D ])  \  }}t        j                   ||«       ||«      z   «      }Œ+ | j                  |«      S )Nr   z?FNO2d requires one [B,global_dim] process+mask vector per fieldr   r
   )r   r*   r9   r(   r:   r;   Úzipr  rt   r<   Úgelurù   )r,   r@   rA   r…   rò   rC   Úps          r   rG   zFNO2d.forward×   sç   € Ø�I‰I�a‹LˆØ�9‰9Ð Øˆ '§-¡-°A·G±G¸A±JÀÇÁÐ3PÒ"PÔXbð  deó  Yfð  SfØ—9‘9˜WÓ%×+Ñ+¨A¨qÓ1‰DˆAˆq°q¸AÀÂ!ÂQÈÈdÐBRÑ@SÑ<SÑ7TÐWXÒYZÒ\]Ð_cÐeiÐYiÑWjÑ7j°1Ü˜Ÿ	™	 4§9¡9Ö-‰DˆAˆq´1·6±6¹!¸A»$ÁÀ1Ã¹+Ó3F©qÐ-Ø�x‰x˜‹{Ðr   )r
   é   ra   r   )
r-   rJ   r.   rJ   r/   rJ   rë   rJ   r(   rJ   rK   rL   rO   rU   s   @r   rþ   rþ   Ð   s   ø„ ÙPök÷
ð r   rþ   c                  ó.   ‡ — e Zd ZdZddˆ fd„Zdd„Zˆ xZS )ÚTabularSurrogatez]Small mask-aware tabular surrogate; feature values and masks are concatenated by the adapter.c           
     ó  •— t         ‰| �  «        t        j                  t        j                  ||«      t        j
                  «       t        j                  ||«      t        j
                  «       t        j                  ||«      «      | _        y rK   )r   r   r   r   r)   r   r¥   r}   s       €r   r   zTabularSurrogate.__init__â   si   ø€ Ü‰ÑÔÜ—=‘=¤§¡¨;¸Ó!>ÄÇÁÃ	Ì2Ï9É9ÐUZÐ\aÓKbÔdf×dkÑdkÓdmÔoq×oxÑoxÐy~ð  AMó  pNó  Oˆ�r   c                ó$   — | j                  |«      S rK   )r¥   )r,   r@   s     r   rG   zTabularSurrogate.forwardå   s   € °4·8±8¸A³;Ð,>r   r‡   ru   rv   rO   rU   s   @r   r	  r	  à   s   ø„ ÙgöO÷ ?r   r	  )r   rJ   r   rJ   rN   znn.Sequential)r@   r   r˜   rJ   rN   r   )rS   Ú
__future__r   Útypingr   r>   r   r   Útorch.nn.functionalÚ
functionalr<   r   ÚModuler   rX   rZ   rc   ry   r�   rŸ   rª   rÇ   rÞ   ré   rþ   r	  © r   r   Ú<module>r     sã   ðñõ
 #å Û ß ß Ð óOô=�—	‘	ô =ó.Oô9ˆR�Y‰Yô 9ô&f˜Ÿ™ô fô(	?�"—)‘)ô 	?óTô3ˆr�y‰yô 3ô"˜Ÿ™ô ô(
 §	¡	ô 
ôB
"�R—Y‘Yô 
"ô5�R—Y‘Yô 5ôˆB�I‰Iô ô ?�r—y‘yõ ?r   