"""Script for running a tsunami inundation scenario for Cairns, QLD Australia.

Source data such as elevation and boundary data is assumed to be available in
directories specified by project.py
The output sww file is stored in directory named after the scenario, i.e
slide or fixed_wave.

The scenario is defined by a triangular mesh created from project.polygon,
the elevation data and a tsunami wave generated by a submarine mass failure.

Geoscience Australia, 2004-present

This has remained unchanged aside from the parallelism added, the resource statistics
and the output directories, its also been scaled down so it runs faster(in project.py)
"""

#------------------------------------------------------------------------------
# Import necessary modules
#------------------------------------------------------------------------------
# Standard modules
import os
import time
import sysimport anuga
from anuga_parallel import distribute, myid, numprocs
from anuga.abstract_2d_finite_volumes.util import add_directories
from anuga.utilities import log


# Application specific imports
import project                 # Definition of file names and polygons


# set up variables for the correct output directories
home = os.getenv('INUNDATIONHOME')
scenariodirV = add_directories(home, ["data","mem_time_test", "parallel",
                                       "cairns", "parrallel-" + str(numprocs) +"-"+str(myid)])
scenariodir = add_directories(home, ["data","mem_time_test", "parallel",
                                       "cairns"])

h = 'CAIRNS.msh'
file_pathh = os.path.join(scenariodirV, h)
log.log_filename = os.path.join(scenariodirV, "anuga.log")
log._setup = False

log.timingInfo(msg=('numberofcpus,'+str(numprocs))) #write the variable to be measured to file
log.timingInfo(msg=('myid,'+str(myid))) #write the variable to be measured to file

log.timingInfo(msg=('beforetime,'+str(log.TimeStamp()))) #get the time at the beginning of the simulation

log.resource_usage_timing(prefix = 'beforesimulation')#get memory statistics at this point
#------------------------------------------------------------------------------
# Preparation of topographic data
# Convert ASC 2 DEM 2 PTS using source data and store result in source data
#------------------------------------------------------------------------------
# Create DEM from asc data
anuga.asc2dem(os.path.join(scenariodir, 'cairns.asc'), use_cache=True, verbose=True)

# Create pts file for onshore DEM
anuga.dem2pts(os.path.join(scenariodir,'cairns.dem'), use_cache=True, verbose=True)

#------------------------------------------------------------------------------
# Create the triangular mesh and domain based on 
# overall clipping polygon with a tagged
# boundary and interior regions as defined in project.py
# (in serial, so the set up only runs once)
#------------------------------------------------------------------------------
if myid == 0:
    domain = anuga.create_domain_from_regions(project.bounding_polygon,
                                    boundary_tags={'top': [0],
                                                   'ocean_east': [1],
                                                   'bottom': [2],
                                                   'onshore': [3]},
                                    maximum_triangle_area=project.default_res,
                                    mesh_filename=file_pathh,
                                    interior_regions=project.interior_regions,
                                    use_cache=True,
                                    verbose=True)

    # Print some stats about mesh and domain
    print 'Number of triangles = ', len(domain)
    print 'The extent is ', domain.get_extent()
    print domain.statistics()
else:
    domain = None

log.resource_usage_timing(prefix = 'aftermesh')#get memory statistics at this point
log.timingInfo(msg=('aftermeshtime,'+str(log.TimeStamp()))) #get the time at the beginning of the simulation
     
#parallel
domain = distribute(domain)
                               
#------------------------------------------------------------------------------
# Setup parameters of computational domain
#------------------------------------------------------------------------------
domain.set_name('cairns_' + project.scenario) # Name of sww file
domain.set_datadir(scenariodirV)                       # Store sww output here
domain.set_minimum_storable_height(0.01)      # Store only depth > 1cm

#------------------------------------------------------------------------------
# Setup initial conditions
#------------------------------------------------------------------------------

tide = 0.0
domain.set_quantity('stage', tide)
domain.set_quantity('friction', 0.0) 
domain.set_quantity('elevation', 
                    filename=os.path.join(scenariodir, 'cairns.pts'),
                    use_cache=True,
                    verbose=True,
                    alpha=0.1)
log.resource_usage_timing(prefix='afterinitialconditions') #get memory statistics at this point

#------------------------------------------------------------------------------
# Setup information for slide scenario (to be applied 1 min into simulation
#------------------------------------------------------------------------------
if project.scenario == 'slide':
    # Function for submarine slide
    tsunami_source = anuga.slide_tsunami(length=35000.0,
                                   depth=project.slide_depth,
                                   slope=6.0,
                                   thickness=500.0, 
                                   x0=project.slide_origin[0], 
                                   y0=project.slide_origin[1], 
                                   alpha=0.0, 
                                   domain=domain,
                                   verbose=True)

#------------------------------------------------------------------------------
# Setup boundary conditions
#------------------------------------------------------------------------------
print 'Available boundary tags', domain.get_boundary_tags()

Bd = anuga.Dirichlet_boundary([tide, 0, 0]) # Mean water level
Bs = anuga.Transmissive_stage_zero_momentum_boundary(domain) # Neutral boundary

if project.scenario == 'fixed_wave':
    # Huge 50m wave starting after 60 seconds and lasting 1 hour.
    Bw = anuga.Time_boundary(domain=domain,
                       function=lambda t: [(60<t<3660)*50, 0, 0])
    domain.set_boundary({'ocean_east': Bw,
                         'bottom': Bs,
                         'onshore': Bd,
                         'top': Bs})

if project.scenario == 'slide':
    # Boundary conditions for slide scenario
    domain.set_boundary({'ocean_east': Bd,
                         'bottom': Bd,
                         'onshore': Bd,
                         'top': Bd})
log.resource_usage_timing(prefix='afterboundary') #get memory statistics at this point
#------------------------------------------------------------------------------
# Evolve system through time
#------------------------------------------------------------------------------
import time
t0 = time.time()

from numpy import allclose

if project.scenario == 'slide':
    # Initial run without any event
    for t in domain.evolve(yieldstep=2000, finaltime=2000): 
        print domain.timestepping_statistics()
        print domain.boundary_statistics(tags='ocean_east')        
        
    # Add slide to water surface
    if allclose(t, 60):
        domain.add_quantity('stage', tsunami_source)    

    # Continue propagating wave
    for t in domain.evolve(yieldstep=2000, finaltime=2000, 
                           skip_initial_step=True):
        print domain.timestepping_statistics()
        print domain.boundary_statistics(tags='ocean_east')    

if project.scenario == 'fixed_wave':
    # Save every two mins leading up to wave approaching land
    for t in domain.evolve(yieldstep=2000, finaltime=2000): 
        print domain.timestepping_statistics()
        print domain.boundary_statistics(tags='ocean_east')    

    # Save every 30 secs as wave starts inundating ashore
    for t in domain.evolve(yieldstep=2000, finaltime=2000, 
                           skip_initial_step=True):
        print domain.timestepping_statistics()
        print domain.boundary_statistics(tags='ocean_east')
            

print 'That took %.2f seconds' %(time.time()-t0)

log.resource_usage_timing(prefix='aftersimulation') #get memory statistics at this point
log.timingInfo(msg=('aftertime,'+str(log.TimeStamp()))) #get the time at the end of the simulation

