o
    Míhé  ã                   @   s8   d dl Zd dlZd dlZd dlmZ G dd„ deƒZdS )é    N)Úget_dir_pathc                   @   s<   e Zd ZdZdd„ Zedd„ ƒZdd„ Zdd	„ Zd
d„ Z	dS )Ú
gen_exodusz‘
    Class for generating an Exodus mesh optimized for Python
    Original C++ codebase: https://github.com/ClimateGlobalChange/tempestremap
    c                 K   s@   || _ | dd¡| _| dd¡| _t tt| jƒƒd ¡| _dS )aF  
        Initializes the gen_exodus object.

        Args:
            nResolution (int): The resolution of the mesh.
            nc (bool, optional): Indicates whether to save the mesh as a netCDF file. Defaults to False.
            path (str, optional): The path to save the mesh file. Defaults to an empty string.
        ÚncFÚpathÚ z	/log.ggenN)	ÚnResolutionÚgetr   r   ÚloggingÚ	getLoggerÚstrr   Úlogger)Úselfr   Úkwargs© r   úX/global/cfs/cdirs/e3sm/www/hass877/share/emis_processing/FlexEmis/src/ggen/gen_exodus.pyÚ__init__   s   	zgen_exodus.__init__c                 C   s’   ||  \}}}|| \}}}	||| |  }
||| |  }||	| |  }t j |
||g¡}|
| }
|| }|| }| |
||g¡ t|ƒd S )a‰  
        Inserts a subnode between two nodes along a common edge.

        Args:
            ix0 (int): Index of the first node.
            ix1 (int): Index of the second node.
            alpha (float): Parameter determining the position of the subnode between the two nodes.
            nodes (list): List of nodes.

        Returns:
            int: Index of the inserted subnode.
        é   )ÚnpÚlinalgÚnormÚappendÚlen)Úix0Úix1ÚalphaÚnodesZx0Zy0Zz0Úx1Úy1Zz1ÚdXÚdYÚdZZdRadiusr   r   r   Úinsert_cs_subnode   s   zgen_exodus.insert_cs_subnodec           	      C   sz   |  ¡  | |¡ td| jƒD ]&}|| j }dt dtj d| d  ¡d  }|  ||||¡}| |¡ q| |¡ |S )ac  
        Generates multiple edge vertices between two nodes.

        Args:
            ix0 (int): Index of the first node.
            ix1 (int): Index of the second node.
            nodes (list): List of nodes.
            edge (list): List to store the generated edge vertices.

        Returns:
            list: The generated edge vertices.
        r   g      à?g      Ð?g       @ç      ð?)Úclearr   Úranger   r   ÚtanÚpir!   )	r   r   r   r   ÚedgeÚiZ	alpha_tmpr   Zix_noder   r   r   Úgenerate_cs_multi_edge_vertices6   s   

$
z*gen_exodus.generate_cs_multi_edge_verticesc              	   C   s–   |}t | jƒD ]A}|| jd kr%||d  }	||d  }
|  |	|
|g ¡}n|}t | jƒD ]}| ||d  ||d  || || g¡ q,| ¡ }q|S )a¦  
        Generates faces from a quadrilateral.

        Args:
            edge0 (list): First edge vertices.
            edge1 (list): Second edge vertices.
            edge2 (list): Third edge vertices.
            edge3 (list): Fourth edge vertices.
            nodes (list): List of nodes.
            vecFaces (list): List to store the generated faces.

        Returns:
            list: The generated faces.
        r   )r$   r   r)   r   Úcopy)r   Zedge0Zedge1Zedge2Zedge3r   ZvecFacesZedge_botÚjr   r   Zedge_topr(   r   r   r   Úgenerate_faces_from_quadM   s   ,
z#gen_exodus.generate_faces_from_quadc                 C   sV  dt  d¡ }|| | g||| g| || g| | | g|| |g|||g| ||g| | |gg}g gd }tg d¢g d¢tdƒƒD ]\}}}|  |||g ¡||< qFg }| |  |d |d |d |d	 |g ¡¡ | |  |d
 |d |d |d |g ¡¡ | |  |d |d |d |d |g ¡¡ | |  |d |d |d |d |g ¡¡ | |  |d ddd… |d |d
 ddd… |d |g ¡¡ | |  |d	 |d ddd… |d |d ddd… |g ¡¡ t  |¡d
  ¡ }tt	|ƒƒD ]&}|| dd… || dd…  ||< || dd… || dd…  ||< qùdd„ t|Ž D ƒ}	t  |	¡}
| j
dkr ddg|
fddg|fdœ}dgt  t  |¡jd ¡fdgt  d¡fdgt  d¡fdgt  |
jd
 ¡fdœ}tj||d}t| jƒ}| j dtdt| jƒ d  ƒ d! t|ƒ ¡ | ¡  |tdt| jƒ d  ƒ ¡ dS | j d"¡ |
||fS )#a  
        Generates the CS mesh using the specified resolution.
    
        Returns:
            tuple or None: If `nc` is True, returns None. Otherwise, returns a tuple containing the coordinate
            array, the fixed faces, and the original faces.
        r"   g      @é   )r   r   é   é   r   r   r.   r/   é   é   é   é   )r   r.   r/   r   r0   r1   r2   r3   r1   r2   r3   r0   r   r0   r1   é   r   r2   é	   r.   r3   é
   r/   é   Néÿÿÿÿc                 S   s   g | ]}t |ƒ‘qS r   )Úlist)Ú.0r(   r   r   r   Ú
<listcomp>Ž   s    z*gen_exodus.gen_cs_mesh.<locals>.<listcomp>TÚnum_dimÚ	num_nodesÚnum_el_in_blk1Únum_nod_per_el1)ÚcoordÚconnect1)r>   r?   r<   r=   )Ú	data_varsÚcoordsz
Creating exodus file Únez.gz in z
Generating exodus metadata)r   ÚsqrtÚzipr$   r)   Úextendr,   ÚarrayÚtolistr   r   ÚarangeÚshapeÚxrÚDatasetr   r   r   Úinfor   r   ÚloadÚ	to_netcdf)r   Z
dInvDeltaXr   ZvecMultiEdgesr(   r+   ÚkÚfacesÚ
FixedfacesZtransposed_listr@   rB   rC   ÚdsÚdir_pathr   r   r   Úgen_cs_meshi   sR   	


ø
"****>>$&


þü
.(
zgen_exodus.gen_cs_meshN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ústaticmethodr!   r)   r,   rV   r   r   r   r   r      s    
r   )	Únumpyr   ÚxarrayrL   r	   Úsrc.ggen.utilsr   Úobjectr   r   r   r   r   Ú<module>   s
    