def make_bc_fig(inputs_file, ndim=2):

    inputs = read_inputs(inputs_file)


    n_cells = string_to_array(inputs['main.num_cells'])
    nx = n_cells[0]
    ny = n_cells[1]

    max_dom_length = max(nx, ny)
    scaled_nx = nx / max_dom_length
    scaled_ny = ny / max_dom_length

    # Start making figure
    window_width = 9.0
    window_height = window_width *0.9* scaled_ny / scaled_nx
    # window_height=12.0
    latexify(fig_width=window_width, fig_height=window_height)
    fig = plt.figure()


    # Add domain rectangle
    ax_width = 0.5
    ax_height = ax_width*(scaled_ny/scaled_nx)*(window_width/window_height)
    ax = fig.add_axes([(1-ax_width)/2.0, 0.25, ax_width, ax_height])
    ax.set_axis_off()


    domain_box = patches.Rectangle((0, 0), 1, 1, fill=False, transform = ax.transAxes, clip_on=False )

    ax.add_patch(domain_box)

    # Add BCs to each side
    padding = 0.02
    for dim in range(0, ndim):
        for side in range(0, 2):

            # Defaults
            horiz_align = 'center'
            vert_align = 'top'
            rotate = 0

            plus_minus = 1
            if side == 0:
                plus_minus = -1


            if dim == 0:
                # X direction bcs (left/right)
                # rotate = 90
                # ypos = 0.0


                rotate = 0
                ypos = scaled_ny/2.0
                vert_align = 'bottom'

                if side == 0:
                    horiz_align = 'right'
                else:
                    horiz_align = 'left'
            else:
                ypos = side + padding*plus_minus

            if dim == 1:
                # Y direction bcs (top/bottom)
                xpos = scaled_nx/2.0

                rotate = 0
                horiz_align = 'center'

                if side == 0:
                    vert_align = 'top'
                else:
                    vert_align = 'bottom'

            else:
                xpos = side + padding*plus_minus


            bc_text = make_bc_text(inputs, dim, side)

            ax.text(xpos, ypos, bc_text, horizontalalignment=horiz_align, verticalalignment=vert_align,
                    rotation = rotate, transform=ax.transAxes)

    # TODO: label axis extents and add num cells label (e.g 64x64)

    # Also add dimensionless parameters to the middle of the domain
    dim_params = 'Dynamics: $Rm_S = %g, Rm_T = %g$ \n     $\Pi_H = %g, Da = %g, Pr=%g$, \n ' \
                 'Material properties: $Le = %g, c_p = %g, k = %g$, \n' \
                 'Thermodynamics: $\mathscr{C}=%g, \mathscr{S}=%g,$ \n'\
                 'Phase diagram: $\Gamma=%g, C_i = %g,$ \n     $C_e = %g, T_e=%g$ \n' % (
                                                                                  inputs['parameters.rayleighComp'],
                                                                                  inputs['parameters.rayleighTemp'],
                                                                                  1.0/inputs['parameters.nonDimReluctance'],
                                                                                  inputs['parameters.darcy'],
                                                                                  inputs['parameters.prandtl'],
                                                 inputs['parameters.lewis'],
                                                 inputs['parameters.specificHeatRatio'],
                                                 inputs['parameters.heatConductivityRatio'],

                                                                    inputs['parameters.compositionRatio'],
                                                                                  inputs['parameters.stefan'],
                                                                                  inputs['parameters.liquidusSlope'],
                                                              inputs['parameters.initialComposition'],
                                                              inputs['parameters.eutecticComposition'],
                                                              inputs['parameters.eutecticTemp']
                                                 )

    if 'heatSource.size' in inputs:
        dim_params = dim_params + '+ heat source $Q = \\frac{Q_0}{\sigma \sqrt{2 \pi}} \exp\left[ - 0.5 \left( \\frac{x-x_c}{\sigma} \\right)^2 \\right]  0.5 \left( 1 + \\tanh\left[10 (z-(H-h)) \\right]) \\right)$, \n' \
                'where $Q_0=%s,\sigma=%s,x_c=%s,h=%s$' % (inputs['heatSource.size'], inputs['heatSource.width'], inputs['heatSource.xpos'], inputs['heatSource.depth'])

    ax.text(0.5, 0.4, dim_params, horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)

    dom_height = float(inputs['main.domain_height'])
    dom_width = dom_height * n_cells[0]/n_cells[1]
    ax.text(0.5, 0.85, 'Domain: [%g, %g] with %d x %d cells' % (dom_width, dom_height, n_cells[0], n_cells[1]), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)

    figure_full_path = inputs_file + '-auto-generated-visualisation.pdf'
    print('Saved to %s' % figure_full_path)
    plt.savefig(figure_full_path, format='pdf')

    plt.show()
Пример #2
0
def runTest(base_dir,
            physical_problem,
            resolution_specific_params,
            AMRSetup,
            num_procs,
            analysis_command='',
            extra_params={},
            numRestarts=0,
            params_file='',
            restart_from_low_res=False):

    # base_dir should be e.g.
    # '/network/group/aopp/oceans/AW002_PARKINSON_MUSH/Test/AMRConvergenceTestNoFlow'

    mushyLayerBaseDir = os.path.abspath(os.pardir)

    all_params = []

    job_ids = []

    for setup in AMRSetup:
        max_level = setup['max_level']
        ref_rat = max(setup['ref_rat'], 1)
        Nzs = setup['Nzs']

        runTypes = ['uniform']
        if 'run_types' in setup:
            runTypes = setup['run_types']

        # finestRefinement = pow(ref_rat, max_level)
        maxRefinement = ref_rat**max_level
        # output_dir = ''
        Nz_i = -1

        # Construct the params files
        for nz_coarse in Nzs:

            Nz_i = Nz_i + 1

            # Some default options

            # Use same aspect ratio as already defined
            # nx_coarse = -1  # if this isn't changed, we'll eventually just use the predetermined aspect ratio
            # gridFile = ''

            # defaultParamsFile = os.path.join(mushyLayerBaseDir, '/params/convergenceTest/' + physical_problem + '.parameters')
            # if os.path.exists(defaultParamsFile):
            #    params = read_inputs(defaultParamsFile)

            output_dir = ''

            nx_coarse, params, gridFile = resolution_specific_params(
                nz_coarse, ref_rat, max_level, maxRefinement)

            # Default options
            if nx_coarse == -1:
                print('Trying to convert to an array: ' +
                      str(params['main.num_cells']))
                gridPts = string_to_array(params['main.num_cells'])

                aspectRatio = gridPts[0] / gridPts[1]
                nx_coarse = aspectRatio * nz_coarse

            if not gridFile:
                gridFile = mushyLayerBaseDir + '/grids/middle/' + str(
                    nz_coarse) + 'x' + str(nz_coarse)

            # Turn slope limiting off unless we've requested it
            if 'main.use_limiting' not in params:
                params['main.use_limiting'] = 'false'

            # also turn off debug to save disk space, unless we've explicitly asked for it
            if 'main.debug' not in params:
                params['main.debug'] = 'false'

            # Any extra params we may have
            for k, v in extra_params.iteritems():
                params[k] = v

            #numCellsAMR = str(nx_coarse) + ' ' + str(nz_coarse) + '  8'
            numCellsAMR = [int(nx_coarse), int(nz_coarse), 8]

            gridFileQuarter = mushyLayerBaseDir + '/grids/rightQuarter/' + str(
                nx_coarse) + 'x' + str(nz_coarse)
            gridFileThreeLevels = mushyLayerBaseDir + '/grids/rightHalfThreeLevel/' + str(
                nx_coarse) + 'x' + str(nz_coarse)
            # numCellsUniform = str(nx_coarse * finestRefinement) + ' ' + str(nz_coarse * finestRefinement) + '  8'
            # numCellsUniform = str(nx_coarse) + ' ' + str(nz_coarse) + '  8'
            numCellsUniform = [int(nx_coarse), int(nz_coarse), 8]

            # params['main.gridfile'] = gridFile
            params['main.num_cells'] = numCellsAMR
            params['main.max_level'] = str(max_level)
            params['main.ref_ratio'] = str(ref_rat) + ' ' + str(
                ref_rat) + ' ' + str(ref_rat)

            num_proc = num_procs[Nz_i]
            params['num_proc'] = num_proc

            if num_proc > 1:
                optimalGrid = float(nx_coarse) / (float(num_proc) / 2.0)

                # print('Initial optimal grid guess: %d' % optimalGrid)

                # increase to next power of 2
                while not is_power_of_two(optimalGrid):
                    optimalGrid = optimalGrid + 1

                # print('Final optimal grid guess: %d' % optimalGrid)

                maxGrid = max(16, optimalGrid)
                # grid size must be greater than the blocking factor
                maxGrid = max(maxGrid, 2 * int(params['main.block_factor']))
                params['main.max_grid_size'] = str(int(maxGrid))

            # Now construct vector different param sets
            param_sets = []

            # Run 1: uniform mesh
            if 'uniform' in runTypes:
                p0 = dict(params)
                p0['main.max_level'] = '0'
                p0['main.num_cells'] = numCellsUniform
                p0['run_name'] = 'Uniform'
                p0['concise_run_name'] = 'Uniform'
                p0['projection.eta'] = 0.0

                param_sets.append(p0)

            # This should do the job for AMR simulations
            if 'amr' in runTypes:
                p1 = dict(params)
                p1['main.reflux_scalar'] = '1'
                p1['main.use_subcycling'] = '1'
                p1['main.refluxType'] = '2'
                p1['projection.eta'] = '0.99'

                p1['run_name'] = 'AMR-Subcycle-Reflux-Freestream' + str(
                    p1['projection.eta']) + '-MaxLevel' + str(max_level)
                p1['concise_run_name'] = 'AMR'
                # p13['main.initialize_VD_corr'] = 'true' # true by default

                param_sets.append(p1)

            # Variable mesh
            if 'variable' in runTypes and max_level == 1:
                p2 = dict(params)
                p2['main.reflux_scalar'] = '1'
                p2['main.use_subcycling'] = '1'
                p2['main.refluxType'] = '2'
                p2['projection.eta'] = '0.95'

                p2['main.gridfile'] = gridFile
                p2['run_name'] = 'VM-Subcycle-Reflux-Freestream' + str(
                    p2['projection.eta']) + '-MaxLevel' + str(max_level)
                p2['concise_run_name'] = 'VM'

                param_sets.append(p2)

            if 'variable' in runTypes and max_level == 2:
                p3 = dict(params)
                p3['main.reflux_scalar'] = '1'
                p3['main.use_subcycling'] = '1'
                p3['main.refluxType'] = '2'
                p3['projection.eta'] = '0.95'

                p3['main.gridfile'] = gridFileThreeLevels
                p3['run_name'] = 'VM-Subcycle-Reflux-Freestream' + str(
                    p3['projection.eta']) + '-MaxLevel' + str(max_level)
                p3['concise_run_name'] = 'VM'

                param_sets.append(p3)

            # Do this for all the param sets just made:
            for p in param_sets:

                # if num_proc > 1:
                #    p['run_name'] = 'p' + p['run_name']

                run_name = p['run_name']
                run_name = run_name
                if int(p['main.max_level']) > 0:
                    run_name = run_name + '-ref' + str(ref_rat)

                run_name = run_name + '-' + physical_problem + '-' + str(
                    nz_coarse)

                p['concise_run_name'] = p['concise_run_name'] + str(
                    nz_coarse) + physical_problem
                p['main.plot_prefix'] = run_name + '-'
                p['main.chk_prefix'] = 'chk' + p['main.plot_prefix']

                # Now add to the full list of param sets
                all_params.append(p)

        # Actually run the convergence test
        #full_output_dir = os.path.join(base_dir, output_dir)
        full_output_dir = base_dir

        these_job_ids = amr_convergence_test(all_params, full_output_dir,
                                             physical_problem, Nzs, num_procs,
                                             numRestarts, analysis_command,
                                             restart_from_low_res)

        # Concatenate lists
        job_ids = job_ids + these_job_ids

    # Once all these runs have been submitted, submit the analysis job
    print('analysis command: %s' % analysis_command)
    if analysis_command:
        runAnalysisName = 'runAnalysis.sh'

        # Don't redo analysis - we may be waiting on runs to finish
        if os.path.exists(os.path.join(base_dir, runAnalysisName)):
            print(Fore.YELLOW + 'Analysis job already submitted \n' +
                  Fore.RESET)
        else:
            jobName = physical_problem + '-analysis'

            s = BatchJob(base_dir, jobName, '', 4)

            s.set_dependency(job_ids)
            s.set_custom_command(analysis_command)

            # s.write_slurm_file(runAnalysisName)
            s.run_task(runAnalysisName)
            print(Fore.GREEN + 'Submitted analysis job \n' + Fore.RESET)

    return job_ids
def make_bc_text(inputs, directory, side):
    scalar_options = ['Dirichlet', 'Neumann', 'InflowOutflow', 'OnlyInflow', 'Robin', 'VariableFlux', 'FixedTemperature', 'TemperatureFlux', 'TemperatureFluxRadation']
    scalars = {'enthalpy': 'H', 'bulkConcentration': '\Theta', 'vel': '\mathbf{U}'}
    BC_TYPES = {'bulkConcentration': scalar_options,
                'enthalpy': scalar_options,
                'vel': ['$\mathbf{U} = 0$', 'Inflow',
		'Outflow',
		'OutflowNormal', # only a normal velocity
		'InflowOutflow', # both inflow and outflow possible
		'noShear',
		'Symmetry ($\mathbf{U} \cdot \mathbf{n} = 0$) ',
		'Plume inflow',
		'Outflow with enforced pressure gradient',
		'Pressure head']}


    sides = ['Lo', 'Hi']
    dirs = ['x', 'y']

    side_text = sides[side]

    #bc_text = dirs[dir] + sides[side]

    variables = ['bulkConcentration', 'enthalpy', 'vel']

    var_texts = []

    for v in variables:
        this_var_text = ''

        bc_type_name = 'bc.%s%s' % (v, side_text)
        bc_val_name = 'bc.%s%sVal' % (v, side_text)

        bc_type = string_to_array(inputs[bc_type_name])
        bc_type_this_dir = bc_type[directory]

        bc_type_description = BC_TYPES[v][bc_type_this_dir]

        # Now we know what the BC is, need to display it sensibly

        # Default:
        this_var_text = bc_type_description

        if v == 'vel':
            this_var_text = bc_type_description

        else:

            bc_val = string_to_array(inputs[bc_val_name], conversion=lambda x: float(x))[directory]

            perp_dir = directory + 1
            if perp_dir > 1:
                perp_dir = 0
            perp_dir_string = dirs[perp_dir]

            if bc_type_description == 'Dirichlet':
                this_var_text = 'Fixed: $%s = %.2g$' % (scalars[v], bc_val)
            elif bc_type_description == 'Neumann':
                this_var_text = 'No flux: $\mathbf{n} \cdot \\nabla %s = 0$' % scalars[v]
            elif bc_type_description == 'VariableFlux':

                this_var_text = 'Variable flux: $\mathbf{n} \cdot \\nabla %s = $ \n $%g (1+\\textrm{tanh}(50(%s-0.75)))$' % (scalars[v], bc_val*0.5, perp_dir_string)

            elif bc_type_description == 'FixedTemperature':
                no_flux_limit = string_to_array(inputs['bc.NoFluxLimit%s' % side_text], conversion=lambda x: float(x))[directory]
                this_var_text = '$ T = %g \; (%s > %g),$ \n $ \mathbf{n} \cdot \\nabla T = 0 \; (%s < %g)$' % (
                                                                                                                bc_val,
                                                                                                                perp_dir_string,
                                                                                                                no_flux_limit,
                                                                                                                perp_dir_string,
                                                                                                                no_flux_limit)

            elif bc_type_description == 'TemperatureFlux':
                no_flux_limit = string_to_array(inputs['bc.NoFluxLimit%s' % side_text], conversion=lambda x: float(x))[directory]
                this_var_text = '$ \mathbf{n} \cdot \\nabla  T = %g \; (%s > %g),$ \n $ \mathbf{n} \cdot \\nabla T = 0 \; (%s < %g)$' % (
                                                                                                                bc_val,
                                                                                                                perp_dir_string,
                                                                                                                no_flux_limit,
                                                                                                                perp_dir_string,
                                                                                                                no_flux_limit)


        var_texts.append(this_var_text)

    bc_text = ', \n'.join(var_texts)


    return bc_text