a
    TbP                     @   s  d dl Zd dlZd dlmZ d dlZd dlm	Z
 ejZejZejZejZejZd dlZd dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ ejZejZd
d ZG dd de Z!G dd de Z"dd Z#dd Z$dd Z%dd ZdS )    N)function)MPI)datetime)_swarmvarschema)FeMesh_Cartesian)Swarm)MeshVariable)SwarmVariablec                 C   s   t | tjr| tjj}nt| tj} | j}td|	dd }|dkrVtj
}nV|dkrftj}nF|dkrvtj}n6|dkrtj}n&|dkrtj}n|d	krtj}ntj}| |S 
z. Adjust the units used depending on the value z{0:.3E}E	      r   i
isinstanceuQuantitytoyears	magnitudedimensionaliseintformatsplitgigayearmegayeardayshoursminutessecondsvalmagexponentunits r'   C/scratch/q97/ac9890/MODELS/Models_to_finish_/HighEro_2/addClases.py_adjust_time_units   s&    r)   c                   @   s\   e Zd ZdZdddZdd Zdd Zdd	d
ZdddZdddZ	dddZ
dddZdS )_CheckpointFunctionz3This Class is responsible for Checkpointing a ModelNc                 C   s   || _ || _d | _t|tjr>d| _t|| _|j| j | _	n|rZd| _|| _|j
| | _	|| _|| _|j| _|sv|r~|   d S )Ntimestep)Modeloutput_units	step_typer   r   r   ndcheckpoint_interval_ndtimenext_checkpointstepDonecheckpoint_timesrestart_checkpoint	outputDircheckpoint_all)selfr-   durationr1   r5   r6   r.   r'   r'   r(   __init__9   s     
z_CheckpointFunction.__init__c                 C   s   | j }| jdu r|j| jks2| jdu r|j| jkr| jd7  _| j|jd | j|jd |  j| j7  _t	
  |j| j dkr| j|jd t	
  d S )Nr+   r,      )checkpointIDr   )r-   r/   r2   r3   r4   r=   checkpoint_fieldscheckpoint_tracersr1   commBarrierr6   checkpoint_swarms)r9   r-   r'   r'   r(   
checkpointR   s     


z_CheckpointFunction.checkpointc                    s   | j  d }d }| jdu r$| j j }| jr\ fdd| jD }dd |D }|  |d }|rn|rnt||S |rv|S |r~|S d S d S )Nr+   c                    s   g | ]}| j  qS r'   )r2   .0r#   r-   r'   r(   
<listcomp>u       z@_CheckpointFunction.get_next_checkpoint_time.<locals>.<listcomp>c                 S   s   g | ]}|d kr|qS )r   r'   rD   r'   r'   r(   rG   v   rH   r   )r-   r/   r3   r2   r5   sortmin)r9   dt1dt2tcheckr'   rF   r(   get_next_checkpoint_timej   s"    

z,_CheckpointFunction.get_next_checkpoint_timec                 C   s:   | j }|s|j}tj|s.tdkr.t| t  |S )Nr   )	r-   r7   ospathexistsrankmakedirsr@   rA   )r9   r7   r-   r'   r'   r(   create_output_directory   s    
z+_CheckpointFunction.create_output_directoryc                 C   s<   |  |||| | |||| | |||| t  dS )a   Do a checkpoint (Save fields)
        Parameters:
        -----------
            variables:
                list of fields/variables to save
            checkpointID:
                checkpoint ID.
            outpuDir:
                output directory
        N)r>   rB   r?   r@   rA   )r9   r=   	variablestracersr+   r7   r'   r'   r(   r8      s    z"_CheckpointFunction.checkpoint_allc              	   C   sV  | j }|std }|s|j}| |}|r.|n|j}t|tjrR| jrR|	| j}|j
s^|jrd| }tj||}|jjd| tj|d}n^|jsd}tj||}|jjd| tj|d}d|_n&d}tj||}tj|jd| }tdkr8dt|d	 d
 }	tj||	}	tj }
|
tj|||7 }
t  |D ]}|dkr^|js^qD||j v rt|}zt|d  }W n t y   d}Y n0 t!||}tj||d|  }|jd| ||d}tdkr|
tj"||7 }
t  qDtdkrJ|
tj# 7 }
t$|	d}|%|
 W d   n1 s@0    Y  t  dS )a   Save the mesh and the mesh variables to outputDir
        Parameters
        ----------
        fields : A list of mesh/field variables to be saved.
        checkpointID : Checkpoint ID
        time : Model time at checkpoint
        outputDir : output directory
        zdefault.outputszmesh-%s%s.h5r&   r+   meshTr   zXDMF.fields.   .xmftemperature.SIunitsN-%sw)&r-   rcParamsr=   rT   r+   r   r   r   r.   r   	_advector_freeSurfacerO   rP   joinrY   save
kilometers_mesh_saveduwutilsSavedFileDatarR   strzfill_xdmfheader_spacetimeschemar@   rA   r\   mesh_variableskeysKeyErrorgetattr_fieldschema_xdmffooteropenwrite)r9   fieldsr=   r+   r7   r-   	mesh_namemesh_prefixmHfilenamestringfieldr&   objfile_prefixhandlexdmfFHr'   r'   r(   r>      sr    






*z%_CheckpointFunction.checkpoint_fieldsc              	   C   s  | j }|s|j}|s|j}| |}|r,|n|j}t|tjrP| jrP|	| j}d| }|j
jtj||tj|d}tdkrdt|d d }tj||}tj }	|	tj|||7 }	t  |D ]}
|
|j v rt|
}
zt|
d  }W n ty   d}Y n0 t||
}tj||
d	|  }|jd
| ||d}tdkr\|	t||
7 }	t  qtdkr|	tj 7 }	t |d}|!|	 W d   n1 s0    Y  t  dS )a   Save the swarm and the swarm variables to outputDir
        Parameters
        ----------
        fields : A list of swarm/field variables to be saved.
        checkpointID : Checkpoint ID
        time : Model time at checkpoint
        outputDir : output directory
        swarm-%s.h5rX   r   zXDMF.swarms.rZ   r[   r]   Nr^   rW   r_   )"r-   restart_variablesr=   rT   r+   r   r   r   r.   r   swarmrd   rO   rP   rc   re   rR   rj   rk   rg   rh   rl   _swarmspacetimeschemar@   rA   swarm_variablesro   r`   rp   rq   r   rs   rt   ru   )r9   rv   r=   r+   r7   r-   
swarm_namesHrz   r{   r|   r&   r}   r~   r   r   r'   r'   r(   rB      s\    









*z%_CheckpointFunction.checkpoint_swarmsc                 C   s   | j }|s|j}|r|n|j}t|tjr<| jr<|| j}|sF|j}t	dkrdt
j|sdt
| t  |jr|j D ]\}}|||| q|t  dS )z Checkpoint the tracers
        Parameters
        ----------
        tracers : List of tracers to checkpoint.
        checkpointID : Checkpoint ID.
        time : Model time at checkpoint.
        outputDir : output directory
        r   N)r-   r=   r+   r   r   r   r.   r   r7   rR   rO   rP   rQ   rS   r@   rA   passive_tracersitemsrd   )r9   rV   r=   r+   r7   r-   dumpitemr'   r'   r(   r?   <  s    
z&_CheckpointFunction.checkpoint_tracers)NNNNN)N)NNNNN)NNNN)NNNN)NNNN)__name__
__module____qualname____doc__r;   rC   rN   rT   r8   r>   rB   r?   r'   r'   r'   r(   r*   6   s(      

  
  
T  
F  r*   c                   @   sL   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )_RestartFunctionc                 C   s   || _ || _t  d S )N)r-   
restartDirr@   rA   )r9   r-   r   r'   r'   r(   r;   a  s    z_RestartFunction.__init__c                 C   s  | j }|  }|dk r|| n|}||_||vr8tdtdkrtj| jd| }t	
|d(}tt|jd|_W d   q1 s0    Y  nd|_tj|jdd|_tdkrtd td	||j td
t d d  td tj  t  | | | | |  |  | | !| |j"rX|j"j#}d|_"||j$_#t%|j&t&j't&j(t&j)fr|j&}||_ |j*|_*t%|j&t&j+r| ,| dS )aw  restart
        Parameters
        ----------
        step : int
            Step from which you want to restart the model.
            Must be an int (step number either absolute or relative)
            if step == -1, run the last available step
            if step == -2, run the second last etc.
        Returns
        -------
        This function returns None
        r   z$Cannot find step in specified folderr   rr+   N)rootzQ================================================================================
z-Restarting Model from Step {0} at Time = {1}
(%Y-%m-%d %H:%M:%S))-r-   find_available_stepsr=   
ValueErrorrR   rO   rP   rc   r   h5pyFiler0   r   r   attrsgetr2   r@   bcastprintr   r+   r   nowstrftimesysstdoutflushrA   reload_meshreload_swarm_initializereload_restart_variablesreload_passive_tracers_solveroptionssolverr   surfaceProcessesSedimentationThresholdErosionThreshold ErosionAndSedimentationThreshold	timeFieldBadlandsrestart_badlands)r9   r,   r-   indices
swarm_fileh5fsolver_optionsr}   r'   r'   r(   restarth  sP    8






z_RestartFunction.restartc                 C   s"   dd t | jD }|  |S )Nc                 S   s2   g | ]*}d |v rt tj|d d d qS )-r   r   )r   rO   rP   splitextr   )rE   rz   r'   r'   r(   rG     s   z9_RestartFunction.find_available_steps.<locals>.<listcomp>)rO   listdirr   rI   )r9   r   r'   r'   r(   r     s
    
z%_RestartFunction.find_available_stepsc                 C   sv   | j }|jr*|jtj| jd|  n|jtj| jd tdkrrt	
 d}td| d  tj  d S )Nz
mesh-%s.h5zmesh.h5r   r   zMesh loaded(r   )r-   ra   rY   loadrO   rP   rc   r   rR   r   r   r   r   r   r   r   r9   r,   r-   r   r'   r'   r(   r     s    z_RestartFunction.reload_meshc                 C   sf   | j }t|jdd|_|jtj| jd|  t	dkrbt
 d}td| d  tj  d S )NT)rY   particleEscaper   r   r   zSwarm loaded(r   )r-   r   rY   r   r   rO   rP   rc   r   rR   r   r   r   r   r   r   r   r   r'   r'   r(   r     s    z_RestartFunction.reload_swarmc                 C   s   | j }|jD ]n}t||}tj| j|d|  }|t| t	dkrt
 d}td|d | d  tj  qd S )N-%s.h5r   r   
{0} loadedr   r   )r-   r   rq   rO   rP   rc   r   r   rj   rR   r   r   r   r   r   r   r   r   )r9   r,   r-   r|   r}   rP   r   r'   r'   r(   r     s    

z)_RestartFunction.reload_restart_variablesc                 C   s\  | j }|j D ]D\}}|jd|  }tj| j|}|j}t	|j
|j|jd}|| |jrxtjj|j|dd|_tj| j|jd|  }|j| | D ]N\}	}
|jf |	dd|
}|jd |	 d|  }tj| j|}|| q|j d	 }t||| ||j|< td
krt d}td|jd | d  tj  qd S )Nr   )r      )orderz_global_index-%s.h5T)name	overwrite__tracersr   r   r   r   r   )r-   r   r   r   rO   rP   rc   r   tracked_fieldsPassiveTracersrY   r   r   advectorrg   systemsSwarmAdvectorvelocityFieldglobal_indexadd_tracked_fieldlowersetattrrR   r   r   r   r   r   r   r   r   )r9   r,   r-   keytracerfnamefpathr   r}   r   kwargsr|   
svar_fname
svar_fpath	attr_namer   r'   r'   r(   r     s4    

z'_RestartFunction.reload_passive_tracersc              	   C   s,  | j }|j}|j}|j}|jr&|j}n|j}|jr:|j}n|}ddlm  m} |d t| d }|	|}|
 }	t|	d d d jd }
|jtjj}t|
| dkrtd|
||j}|j}|j}|j}|j}tj|||||||d|_tdkr(td	t  d
 d  t!j"#  dS )z Restart Badlands from step
            Note that step is only used if no restartStep has been
            defined on the badlands_model object r   Nz/xmf/tin.timer[   Valuer<   zTime in Underworld and Badlands outputs
                             differs:

                             Badlands: {0}

                             Underworld: {1})restartFolderrestartStepzBadlands restarted(r   r   )$r-   r   r   r   r7   xml.etree.ElementTreeetreeElementTreerj   parsegetrootfloatattribr+   r   r   r   r   npabsr   r   airIndexsedimentIndexXML
resolutionr1   r   rR   r   r   r   r   r   r   r   )r9   r,   r-   badlands_modelr   r   r   xmftreer   badlands_timeuw_timer   r   r   r   r1   r'   r'   r(   r     sH    

z!_RestartFunction.restart_badlandsN)r   r   r   r;   r   r   r   r   r   r   r   r'   r'   r'   r(   r   _  s   C	%r   c               
   G   s\   ddl m} | D ]B}zt|W   S  t|fy:   Y n0 t|tjr|j  S qtd S )Nr   )UndefinedUnitErrorztime.SIunits)	pintr   r   Unit	TypeErrorr   r   r&   r`   )argsr   argr'   r'   r(   _get_output_units5  s    r   c                 C   sV   i }| j j D ]@\}}t|trDi }|j D ]\}}|||< q0n|}|||< q|S )z-Return a dictionary of all the solver options)r   __dict__r   r   dict)r   ddr   r#   dd2key2val2r'   r'   r(   _solver_options_dictionaryB  s    

r   c                 C   sR   |  D ]D\}}t|tr@|  D ]\}}|| jj| j|< q"q|| jj|< q| S )zPApply options on a solver
    solver: solver
    options: python dictionary
    )r   r   r   r   r   )r   r   r   r#   r   r   r'   r'   r(   _apply_saved_options_on_solverP  s    
r   c                 C   s   t | tjr| tjj}nt| tj} | j}td|	dd }|dkrVtj
}nV|dkrftj}nF|dkrvtj}n6|dkrtj}n&|dkrtj}n|d	krtj}ntj}| |S r
   r   r"   r'   r'   r(   r)   ^  s&    )&UWGeodynamicsGEOnumpyr   
underworldr   fnr   mpi4pyr   _MPIr@   rR   sizeUnitRegistryr   r`   rO   r   rg   r   underworld.utilsr   underworld.meshr   underworld.swarmr   r   r	   r   r0   r)   objectr*   r   r   r   r   r'   r'   r'   r(   <module>   s<     + W