"""
This script is designed to run the parametric studies with Spindle FEA. You can change ``nsamples`` variable
to control the number of jobs with identical parameters. ``Spring`` variable is the governing parameter of the study.
Its values are given in the corresponding list in this script. One can run parametric studies with any variable in
``kwargs`` by altering this script accordingly.
"""


def generateKwargs(spring, jobname, modelname):
    """
    Function that generates kwargs for parametric analysis

    :param spring: Spring stiffness parameter

    :type spring: float

    :param jobname: Name of the current job

    :type jobname: str

    :param modelname: Name of the current model

    :type modelname: str

    :return: kwargs

    :rtype: object
    """
    kwargs = {'x'               : 0,
              'y'               : 0,
              'index'           : 0,
              'modelname'       : modelname,
              'assembly'        : 0,
              'CentrosomeRadius': 0.20,
              'CentrosomeLength': 0.40,
              'CentrosomeE'     : 1500000000.0,
              'CentrosomeNu'    : 0.3,
              'ipMTnumber'      : 6,
              'lengthInterval'  : [2, 5],
              'separation'      : [0.02876, 0.0414],
              'angle'           : [96.39, 11.12],
              'd'               : 0.015,
              'D'               : 0.025,
              'ElasticModulus'  : 1500000000.0,
              'PoissonRatio'    : 0.3,
              'spindleLength'   : 10,
              'Nconnectors'     : 20,
              'connectorRadius' : 0.001,
              'connectorE'      : 1500000000.,
              'connectorNu'     : 0.3,
              'aMTnumber'       : 40,
              'aMTlength'       : 2,
              'aMTsSpring'      : spring,
              'groundSpring'    : spring,
              'StepName'        : 'Standard_Buckling',
              'NumberOfEigs'    : 5,
              'CompressiveLoad' : 1,
              'JobName'         : jobname}
    return kwargs


def jobSubmit(**kwargs):
    """
    Function to submit the job to Abaqus solver

    :param kwargs: model parameters

    :type kwargs: object

    :return: Null

    :rtype: Null
    """
    name = kwargs['JobName']
    modelname = kwargs['modelname']
    mdb.Job(name=name, model=modelname, description='', type=ANALYSIS, atTime=None,
            waitMinutes=0, waitHours=0, queue=None, memory=90,
            memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True,
            explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, echoPrint=OFF,
            modelPrint=OFF, contactPrint=OFF, historyPrint=OFF, userSubroutine='',
            scratch='', resultsFormat=ODB, multiprocessingMode=DEFAULT, numCpus=1,
            numGPUs=0)
    mdb.jobs[name].submit(consistencyChecking=OFF)
    mdb.jobs[name].waitForCompletion()


if __name__ == '__main__':
    from abaqus import *
    from abaqusConstants import *
    from LoadCase import Interaction
    from LoadCase import Step
    from LoadCase import LoadsAndBCs
    from SpindleMesh import generate_mesh
    import numpy as np
    ''' Governing parameters '''
    spring = [1, 2, 5, 10, 15, 20, 40, 80, 100, 150, 200]
    nsamples = 5
    modelname = [['spring_%s_%s' % (i, j) for j in range(nsamples)] for i in spring]
    jobname = [['job_%s_%s' % (i, j) for j in range(nsamples)] for i in spring]
    ''' Loop over parameters '''
    for i in range(np.shape(jobname)[1]):
        for j in range(np.shape(jobname)[0]):
            kwargs = generateKwargs(spring=spring[j],
                                    modelname=modelname[j][i],
                                    jobname=jobname[j][i])
            ''' Call modules '''
            kwargs, data = Interaction.create_interactions(**kwargs)
            Step.Step(**kwargs)
            LoadsAndBCs.create_load(data, **kwargs)
            LoadsAndBCs.create_bc(**kwargs)
            generate_mesh.standard_mesh(**kwargs)
            ''' Create and submit a job '''
            jobSubmit(**kwargs)

