def create_simulation(destDir,
                      inputPath,
                      bf_layer_option=False,
                      nb_tiles_option=[1,1],
                      nameRun_suffix=''):
    '''
    @description
    create the executable corresponding to the inputPath, save it
    to the destDir, create the PBS script to run the simulation
    and save it in the destDir
    '''

    #0) check that destDir exists
    if(not os.path.isdir(destDir)):
        print 'library_sm_lg_results'
        print 'create_simulation'
        sys.exit('***directory '+destDir+' does not exist***')

    
    #1) create the executable corresponding to the inputPath
    exePath = generate_exe(inputPath,
                           bf_layer_option=bf_layer_option,
                           nb_tiles_option=nb_tiles_option)


    #2) move the executable to destDir
    if(not os.path.isfile(exePath)):
        print 'library_sm_lg_results'
        print 'create_simulation'
        sys.exit('***exe file'+exePath+' does not exist***')

    newExePath = destDir
    newExePath+='/'+os.path.basename(exePath)
    shutil.move(exePath,newExePath)


    #3) create the PBS script
    temperature   = float(get_parameter('temperature',inputPath))
    flow_velocity = float(get_parameter('flow_velocity',inputPath))
    nameRun = get_name_run(temperature,flow_velocity)
    nameRun+= nameRun_suffix
    simulation_duration = estimate_simulation_duration(inputPath)
    walltime = estimate_wall_time(simulation_duration,
                                  safety_ratio=2.0,
                                  nb_tiles_option=nb_tiles_option)

    pbsScriptPath = destDir+'/run_sim.job'

    create_pbs_script(
        pbsScriptPath,
        newExePath,
        nameRun=nameRun,
        walltime=walltime,
        nb_tiles_option=nb_tiles_option)

    return [pbsScriptPath,nameRun]
def create_simulation(destDir,
                      inputPath):
    '''
    @description
    create the executable corresponding to the inputPath, save it
    to the destDir, create the PBS script to run the simulation
    and save it in the destDir
    '''

    #0) check that destDir exists
    if(not os.path.isdir(destDir)):
        print 'library_wall_st_results'
        print 'create_simulation'
        sys.exit('***directory '+destDir+' does not exist***')

    
    #1) create the executable corresponding to the inputPath
    exePath = generate_exe(inputPath)


    #2) move the executable to destDir
    if(not os.path.isfile(exePath)):
        print 'library_wall_st_results'
        print 'create_simulation'
        sys.exit('***exe file'+exePath+' does not exist***')

    newExePath = destDir
    newExePath+='/'+os.path.basename(exePath)
    shutil.move(exePath,newExePath)


    #3) create the PBS script
    temperature         = float(get_parameter('temperature',inputPath))
    micro_contact_angle = float(get_parameter('wall_micro_contact_angle',inputPath))
    nameRun = get_name_run(temperature,micro_contact_angle)
    simulation_duration = 12.0*60.0*60.0 #estimate_simulation_duration(inputPath)
    walltime = estimate_wall_time(simulation_duration,
                                  safety_ratio=6.0)

    pbsScriptPath = destDir+'/run_sim.job'

    create_pbs_script(
        pbsScriptPath,
        newExePath,
        nameRun=nameRun,
        walltime=walltime)

    return [pbsScriptPath,nameRun]
def estimate_simulation_duration(inputPath):
    '''
    @description:
    estimate the simulation duration based on the
    grid size in x- and y-directions and the total
    number of time steps (in seconds)
    '''

    #1) verify that the file 'inputPath' exists
    if(os.path.isfile(inputPath)):


        #2) extract the following parameters
        #   [dt,t_max,dx,x_min,x_max,dy,y_min,y_max]
        #   from 'inputPath'
        dt    = float(get_parameter('dt',inputPath))
        t_max = float(get_parameter('t_max',inputPath))
        dx    = float(get_parameter('dx',inputPath))
        x_min = float(get_parameter('x_min',inputPath))
        x_max = float(get_parameter('x_max',inputPath))
        dy    = float(get_parameter('dy',inputPath))
        y_min = float(get_parameter('y_min',inputPath))
        y_max = float(get_parameter('y_max',inputPath))


        #3) determine nx,ny,nt, the number of space steps
        #   in the x- and y-directions and the total number
        #   of time steps in the simulation
        nx = math.ceil((x_max-x_min)/dx) + 2*bc_size
        ny = math.ceil((y_max-y_min)/dy) + 2*bc_size
        nt = math.ceil(t_max/dt)


        #4) we know that for 104*104 grid size and 4000 time steps
        #   the simulation lasts around 5.0min
        #   for each time step, the RK scheme takes 3 steps
        #   so the average time spent computing each grid point at
        #   each intermediate time step is (in seconds):
        dt = 5.0*60.0/(3.0*4000.0*104*104)
        
        
        #5) for [nx*ny] grid size and 3*nt intermediate time steps
        #   the simulation will approximately lasts:
        time = dt*nx*ny*3*nt

        return time

    else:
        print 'library_sm_lg_results'
        print 'estimate_simulation_duration'
        sys.exit('*** '+inputPath+' does not exist***')
def extract_interface_length(dim2dParamPath,temperature):
    '''
    @description: extract the interface length from the 
                  parameters in dim2d_parameters and the
                  temperature for the initial conditions
    '''

    if(os.path.isfile(dim2dParamPath)):
        length_c  = float(get_parameter('length_c', dim2dParamPath))
        dim2d_a   = float(get_parameter( 'dim2d_a', dim2dParamPath))
        dim2d_b   = float(get_parameter( 'dim2d_b', dim2dParamPath))
        dim2d_M   = float(get_parameter( 'dim2d_M', dim2dParamPath))
        dim2d_K   = float(get_parameter( 'dim2d_K', dim2dParamPath))

    else:
        sys.exit('*** '+dim2dParamPath+' does not exist***')

    # compute the Weber number
    we = get_we(length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_K)

    # compute the interface length from the temperature
    interface_lgh = get_interface_length(we,temperature)

    return interface_lgh
def get_inputsToBeModified(steady_state_ac,
                           temperature,
                           micro_contact_angle,
                           phase_at_center,
                           gravity_ac,
                           gravity_amp,
                           nb_pts_in_interface,
                           ratio_bubble_interface,
                           ratio_eq_length_domain,
                           ratio_drop_length_domain,
                           CFL_constant,
                           total_nb_files,
                           spherical_cap=False):

    '''
    @description
    determine the inputs to be modified in the template.txt
    template input file to run the DIM2D simulation for a steady
    state of a drop/bubble on a wall
    '''

    # extract length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_cv, dim2d_R
    # and dim2d_K from the dim2d_parameters.f fortran file
    dim2dParamPath = os.path.join(os.getenv('augeanstables'),
                                  'src',
                                  'physical_models',
                                  'dim2d',
                                  'dim2d_parameters.f')

    if(os.path.isfile(dim2dParamPath)):
        length_c  = float(get_parameter('length_c', dim2dParamPath))
        dim2d_a   = float(get_parameter( 'dim2d_a', dim2dParamPath))
        dim2d_b   = float(get_parameter( 'dim2d_b', dim2dParamPath))
        dim2d_M   = float(get_parameter( 'dim2d_M', dim2dParamPath))
        dim2d_cv  = float(get_parameter('dim2d_cv', dim2dParamPath))
        dim2d_R   = float(get_parameter( 'dim2d_R', dim2dParamPath))
        dim2d_K   = float(get_parameter( 'dim2d_K', dim2dParamPath))

    else:
        sys.exit('*** '+dim2dParamPath+' does not exist***')


    # compute the Weber number
    we = get_we(length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_K)
    if(debug): print 'we: ', we

    # compute the interface length from the temperature
    interface_lgh = get_interface_length(we,temperature)
    if(debug): print 'interface_length: ', interface_lgh

    # compute the bubble diameter from the interface length
    bubble_diameter = 3.0*interface_lgh*sqrt(2.0) #get_bubble_diameter(interface_lgh,
                                        #  ratio_bubble_interface)
    if(debug): print 'bubble_diameter: ', bubble_diameter
    

    # compute the x_max of the domain
    eq_length = get_equilibrium_length(micro_contact_angle,bubble_diameter)
    x_max     = get_x_max(bubble_diameter,eq_length,ratio_eq_length_domain)
    if(debug): print 'x_max: ', x_max

    # compute the y_max of the domain
    y_max     = x_max #get_y_max(bubble_diameter,ratio_drop_length_domain)
    if(debug): print 'y_max: ', y_max

    # compute the maximum space step from the interface length
    dx_max = get_interface_space_step(interface_lgh,
                                      nb_pts_in_interface)
    if(debug): print 'dx_max: ', dx_max

    # compute the extent of the domain as a matrix
    # x_min : domain_extent[0][0]
    # x_max : domain_extent[1][0]
    # y_min : domain_extent[0][1]
    # y_max : domain_extent[1][1]
    domain_extent = get_wall_domain_extent(x_max,y_max,dx_max)
    if(debug): print 'domain_extent: ', domain_extent

    # compute the reduced heat capacity
    cv_r = get_cv_r(dim2d_M,dim2d_cv,dim2d_R)

    # compute the maximum speed of sound in the flow
    speed_of_sound = get_max_speed_of_sound(temperature,cv_r)

    # compute the maximum time step ensuring numerical stability
    flow_velocity = 0.0
    speed_max     = speed_of_sound
    if(debug): print 'speed_of_sound: ', speed_of_sound

    dt_max        = get_dt_max(dx_max,speed_max,CFL_constant,precision_c=6)
    if(debug): print 'dt_max: ', dt_max

    # determine the maximum simulation time
    simulation_time = 200.0

    # determine the detail print
    detail_print = get_detail_print(total_nb_files,
                                    simulation_time,
                                    dt_max)
    if(debug): print 'detail_print: ', detail_print

    # initial conditions:
    # either half sphere with 90 contact angle
    # or spherical cap constrained by contact angle
    if(spherical_cap):
        ic_choice = spherical_cap_ic_choice
    else:
        ic_choice = half_sphere_ic_choice


    # gather the inputs to be modified in a dictionnary
    inputsToBeModified = {
        'detail_print'                : detail_print,
        'dt'                          : dt_max,
        't_max'                       : simulation_time,
        'steady_state_ac'             : steady_state_ac,
        'dx'                          : dx_max,
        'x_min'                       : domain_extent[0][0],
        'x_max'                       : domain_extent[1][0],
        'dy'                          : dx_max,
        'y_min'                       : domain_extent[0][1],
        'y_max'                       : domain_extent[1][1],
        'ic_choice'                   : ic_choice,
        'flow_velocity'               : flow_velocity,
        'temperature'                 : temperature,
        'wall_micro_contact_angle'    : micro_contact_angle,
        'phase_at_center'             : phase_at_center,
        'gravity_ac'                  : gravity_ac,
        'gravity_amp'                 : gravity_amp}

    return inputsToBeModified
def compute_inputsToBeModified(temperature,
                               flow_velocity,
                               nb_pts_in_interface,
                               ratio_interface_separation,
                               ratio_bubble_interface,
                               ratio_interface_influence,
                               CFL_constant,
                               total_nb_files,
                               dct_distance,
                               md_threshold_ac,
                               md_threshold,
                               flow_direction='x'):

    """Determine the inputs to be modified in the input.txt
    file for the simulation with two bubbles transported by the
    mean flow

    Args:
        temperature (double) : mean flow temperature
        flow_velocity (double) : mean flow velocity
        nb_pts_in_interface (int) : number of grid-points needed
            to resolve the interface profile
        ratio_interface_separation (double) : length (expressed as
            a fraction of the width of the interface) separating the
           two bubbles
        ratio_bubble_interface (double) : ratio between bubble
           diameter and interface width
        ratio_interface_influence (double) : length threshold
           (expressed as a fraction of the width of the interface)
           above which the interface is not supposed to interact
           with the border
        CFL_constant (double) : CFL threshold (0-1)
        total_nb_files (int) : total nb of files written
        dct_distance (int) : distance between the detectors and
           the boundary expressed as a number of gridpoints
        md_threshold_ac (int) : activate the increase of the computational
           domain with a mass density threshold
        md_threshold (double) : mass density threshold to activate the
           increase of the computational domain (between 0 and 1)

    Returns:
        inputsToBeModified (dict) :
           - dict[key] : name of the input to be modified
           - dict[value] : value of the input to be modified
    """

    # extract length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_cv, dim2d_R
    # and dim2d_K from the dim2d_parameters.f fortran file
    dim2dParamPath = os.path.join(os.getenv('augeanstables'),
                                  'src',
                                  'physical_models',
                                  'dim2d',
                                  'dim2d_parameters.f')

    if(os.path.isfile(dim2dParamPath)):
        length_c  = float(get_parameter('length_c', dim2dParamPath))
        dim2d_a   = float(get_parameter( 'dim2d_a', dim2dParamPath))
        dim2d_b   = float(get_parameter( 'dim2d_b', dim2dParamPath))
        dim2d_M   = float(get_parameter( 'dim2d_M', dim2dParamPath))
        dim2d_cv  = float(get_parameter('dim2d_cv', dim2dParamPath))
        dim2d_R   = float(get_parameter( 'dim2d_R', dim2dParamPath))
        dim2d_K   = float(get_parameter( 'dim2d_K', dim2dParamPath))

    else:
        sys.exit('*** '+dim2dParamPath+' does not exist***')


    # compute the Weber number
    we = get_we(length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_K)


    # compute the interface length from the temperature
    interface_length = get_interface_length(we,temperature)

    
    # compute the bubble diameter
    bubble_diameter = interface_length*ratio_bubble_interface

    
    # compute the extent of the domain
    [Lx,Ly] = get_domain_sizes(bubble_diameter,
                               interface_length,
                               ratio_interface_influence,
                               ratio_interface_separation)


    # compute the maximum space step from the interface length
    dx_max = get_interface_space_step(interface_length,
                                      nb_pts_in_interface)


    # get the extent of the domain
    # x_min : domain_extent[0][0]
    # x_max : domain_extent[1][0]
    # y_min : domain_extent[0][1]
    # y_max : domain_extent[1][1]
    domain_extent = get_domain_extent(Lx,Ly,dx_max,dx_max)

    
    # compute the reduced heat capacity
    cv_r = get_cv_r(dim2d_M,dim2d_cv,dim2d_R)


    # compute the maximum speed of sound in the flow
    speed_of_sound = get_max_speed_of_sound(temperature,cv_r)


    # compute the maximum time step ensuring numerical stability
    speed_max = speed_of_sound + abs(flow_velocity)
    dt_max    = get_dt_max(dx_max,speed_max,CFL_constant)


    # determine the simulation time needed to let the two bubbles
    # leave the computational domain
    simulation_time = get_simulation_time(Lx,
                                          bubble_diameter,
                                          ratio_interface_separation*interface_length,
                                          ratio_interface_influence*interface_length,
                                          flow_velocity)


    # determine the detail print
    detail_print = get_detail_print(total_nb_files,
                                    simulation_time,
                                    dt_max)


    # gather the inputs to be modified in a dictionnary
    inputsToBeModified = {
        'detail_print'                : detail_print,
        'dt'                          : dt_max,
        't_max'                       : simulation_time,
        'dx'                          : dx_max,
        'dy'                          : dx_max,
        'flow_velocity'               : flow_velocity,
        'temperature'                 : temperature,
        'li_separation'               : ratio_interface_separation,
        'openbc_detector_distance'    : dct_distance,
        'openbc_md_threshold_ac'      : md_threshold_ac,
        'openbc_md_threshold'         : md_threshold}

    if(flow_direction=='x'):

        inputsToBeModified.update({'x_min'          : domain_extent[0][0],
                                   'x_max'          : domain_extent[1][0],
                                   'y_min'          : domain_extent[0][1],
                                   'y_max'          : domain_extent[1][1],
                                   'flow_direction' : 'E'})
    else:

        if(flow_direction!='y'):
            sys.exit('create_bb_tr_input: '+
                     'compute_inputsToBeModified: '+
                     'flow_direction not recognized')
            sys.exit(2)

        inputsToBeModified.update({'x_min'          : domain_extent[0][1],
                                   'x_max'          : domain_extent[1][1],
                                   'y_min'          : domain_extent[0][0],
                                   'y_max'          : domain_extent[1][0],
                                   'flow_direction' : 'N'})

    return inputsToBeModified
    inspect.getfile( inspect.currentframe() ))[0],"../../../sm_lg_domain_automatization")))
if cmd_subfolder not in sys.path:
    sys.path.insert(0, cmd_subfolder)

from create_sm_lg_inputs import get_parameter

from library_sm_lg_inputs import (get_we,
                                  get_cv_r)

# extract length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_cv, dim2d_R
# and dim2d_K from the dim2d_parameters.f fortran file
dim2dParamPath = os.path.join(os.getenv('augeanstables'),
                              'src',
                              'physical_models',
                              'dim2d',
                              'dim2d_parameters.f')

length_c  = float(get_parameter('length_c', dim2dParamPath))
dim2d_a   = float(get_parameter( 'dim2d_a', dim2dParamPath))
dim2d_b   = float(get_parameter( 'dim2d_b', dim2dParamPath))
dim2d_M   = float(get_parameter( 'dim2d_M', dim2dParamPath))
dim2d_cv  = float(get_parameter('dim2d_cv', dim2dParamPath))
dim2d_R   = float(get_parameter( 'dim2d_R', dim2dParamPath))
dim2d_K   = float(get_parameter( 'dim2d_K', dim2dParamPath))

# compute the reduced cv_r
cv_r = get_cv_r(dim2d_M,dim2d_cv,dim2d_R)

# compute the Weber number
we = get_we(length_c, dim2d_a, dim2d_b, dim2d_M, dim2d_K)