def merit( g0 ) :
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.  
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True, select='htse' )
    
            etaFstar = penalty( lda0.etaF_star , 5 ) 
            if 'Number' in kwargs.keys():
                return  etaFstar * Npenalty( lda0.Number) 
            else:
                return  etaFstar
        except Exception as e :
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100= 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e4 # this is caused by too much green 
                           # return large value to asign penalty
            elif posslope in e.message:
                return 1e4 # this is caused by too much green
                           # as the chemical potential comes to close
                           # to the threshold and atoms accumulate on 
                           # the beams 
                           # return large value to asign penalty
            elif threshol in e.message:
                return 1e4 # this is caused by too much green
                           # the chemical potential is above the evap th. 
                           # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e4 # this is caused by too much green
                           # the chemical potential is above the bottom of 
                           # the band along 100 
                           # return large value to asign penalty
                              
 
            elif 'vanish' in e.message : 
                # this is is caused by insufficient extents
                print "extents = %.1f"%  extents  
                raise 
            else:
                raise 
    def merit(g0):
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True, select='htse' )

            etaFstar = penalty(lda0.etaF_star, 5)
            if 'Number' in kwargs.keys():
                return etaFstar * Npenalty(lda0.Number)
            else:
                return etaFstar
        except Exception as e:
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100 = 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e4  # this is caused by too much green
                # return large value to asign penalty
            elif posslope in e.message:
                return 1e4  # this is caused by too much green
                # as the chemical potential comes to close
                # to the threshold and atoms accumulate on
                # the beams
                # return large value to asign penalty
            elif threshol in e.message:
                return 1e4  # this is caused by too much green
                # the chemical potential is above the evap th.
                # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e4  # this is caused by too much green
                # the chemical potential is above the bottom of
                # the band along 100
                # return large value to asign penalty

            elif 'vanish' in e.message:
                # this is is caused by insufficient extents
                print "extents = %.1f" % extents
                raise
            else:
                raise
def get_trap_results( **kwargs  ):
    """
    If the parameters for the trap are known, the trap results can be obtained 
    directly with this function 
    """
    s0 = kwargs.get('s0', 7. ) 
    wL = kwargs.get('wL', 47. )
    wC = kwargs.get('wC', 40. )
    alpha = wL/wC
    a_s = kwargs.get('a_s', 650. )
    T_Er= kwargs.get('T_Er', 0.2 )
    extents = kwargs.get('extents', 40.)
  
    gOptimal = kwargs.get('g0',4.304)
    
    potOpt = scubic.sc( allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC ) 
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)  
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL,  ldaOpt.DeltaEvap ]
def get_trap_results(**kwargs):
    """
    If the parameters for the trap are known, the trap results can be obtained 
    directly with this function 
    """
    s0 = kwargs.get('s0', 7.)
    wL = kwargs.get('wL', 47.)
    wC = kwargs.get('wC', 40.)
    alpha = wL / wC
    a_s = kwargs.get('a_s', 650.)
    T_Er = kwargs.get('T_Er', 0.2)
    extents = kwargs.get('extents', 40.)

    gOptimal = kwargs.get('g0', 4.304)

    potOpt = scubic.sc(allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC)
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL,  ldaOpt.DeltaEvap ]
Example #5
0
def single_spi(**kwargs):

    savedir = kwargs.pop('savedir', None)
    numlist = kwargs.pop('numlist', [1.2e5, 1.3e5, 1.4e5, 1.5e5, 1.6e5])
    mulist = kwargs.pop('mulist',  [-0.15, -0.075, 0., 0.10, 0.18])
    bestForce = kwargs.pop('bestForce', -1)

    s = kwargs.pop('params_s', 7.)
    g = kwargs.pop('params_g', 3.666)
    wIR = kwargs.pop('params_wIR', 47.)
    wGR = kwargs.pop('params_wGR', 47./1.175)
    direc = '111'
    mu0 = 'halfMott'

    aS = kwargs.pop('params_aS', 300.)
    Tdens = kwargs.pop('params_Tdens', 0.6)
    Tspi = kwargs.pop('params_Tspi',  0.6)

    extents = kwargs.pop('extents', 30.)
    spiextents = kwargs.pop('spiextents', 25.)
    sthextents = kwargs.pop('sthextents', 30.)
    entextents = kwargs.pop('entextents', 25.)
    finegrid = kwargs.pop('finegrid', False)

    sarr = np.array([[s], [s], [s]])
    bands = scubic.bands3dvec(sarr, NBand=0)
    t0 = np.mean((bands[1] - bands[0])/12.)  # tunneling 0 in recoils

    Tdens_Er = Tdens*t0
    Tspi_Er = Tspi*t0

    print "========================================"
    print " Single Spi"
    print " gr={:0.3f}, aS={:03d}".format(g, int(aS))
    print " Tdens={:0.2f}, Tspi={:0.2f}".format(Tdens, Tspi)

    select = 'qmc'
    spis = []

    for tag, muPlus in enumerate(mulist):
        numgoal = numlist[tag]
        print
        print "num = %.3g, muPlus = %.3f" % (numgoal, muPlus)
        pot = scubic.sc(allIR=s, allGR=g, allIRw=wIR, allGRw=wGR)

        lda0 = lda.lda(potential=pot, Temperature=Tdens_Er, a_s=aS,
                       extents=extents,
                       Natoms=numgoal, halfMottPlus=muPlus,\
                       #                       globalMu=mu0, halfMottPlus=muPlus,\
                       verbose=True, \
                       select=select,\
                       ignoreExtents=False, ignoreSlopeErrors=True, \
                       ignoreMuThreshold=True)

        spibulk, spi, sthbulk, sth, r111, n111, U111, t111, mut111, \
            entrbulk, entr111,\
            lda_num, density111, k111, k111htse_list = \
            lda0.getBulkSpi(Tspi=Tspi, inhomog=True,
                            spiextents=spiextents, sthextents=sthextents,
                            entextents=entextents, do_k111=False)

        if finegrid:
            r111_fine, spi111_fine, n111_fine, k111_fine, mu111_Er = \
                lda0.getSpiFineGrid(Tspi=Tspi, numpoints=320,
                                    inhomog=True, spiextents=spiextents,
                                    entextents=entextents)
        else:
            r111_fine, spi111_fine, n111_fine, k111_fine, mu111_Er = \
                 None, None, None, None, None

        spis.append({
                      'gr': g,
                      'muPlus': muPlus,
                      'SpiBulk': spibulk,
                      'spi111': spi,
                      'SthBulk': sthbulk,
                      'sth111': sth,
                      'r111': r111,
                      'n111': n111,
                      'U111': U111,
                      'mut111': mut111,
                      't111': t111,
                      'entrbulk': entrbulk,
                      'entr111': entr111,
                      'k111': k111,
                      'k111htse_list': k111htse_list,
                      'Number': lda0.Number,
                      'ldanum': lda_num,\
                      # dens111 is the one obtained from QMC
                      'dens111': density111,\
                      'Tdens': Tdens,\
                      'Tspi': Tspi,\
                      'aS': aS,\
                      'savedir': savedir,\
                      'r111_fine': r111_fine,\
                      'spi111_fine': spi111_fine,\
                      'n111_fine': n111_fine,\
                      'k111_fine': k111_fine,\
                      'mu111_Er': mu111_Er,\
                      'v0111': lda0.pot.S0(lda0.X111, lda0.Y111, lda0.Z111)[0]
                      })

        # Figure to check inhomogeneity only run if temperature is high
        if Tspi > 0.85 and Tdens > 0.85:
            fig111, binresult, peak_dens, radius1e, peak_t, output = \
                lda.CheckInhomog(lda0, closefig=True, n_ylim=(-0.1, 2.0))

            figfname = savedir + 'Inhomog/{:0.3f}gr_{:03d}_{}_T{:0.4f}Er.png'.\
                format(g, tag, select, Tspi)

            figfname = kwargs.pop('params_figfname', figfname)

            fig111.savefig(figfname, dpi=300)

    print
    print "Atom number = {:5.3g}".format(spis[0]['Number'])
    print "Entropy     = {:0.2f}".format(spis[0]['entrbulk'])

    plot_spis( spis, bestForce=bestForce, \
               # kwargs
               **kwargs)

    return spis[bestForce]
def dmu_dr( rpoints, **kwargs ):
    s       = kwargs.pop('params_s', 7.) 
    g       = kwargs.pop('params_g', 3.666)
    wIR     = kwargs.pop('params_wIR', 47.) 
    wGR     = kwargs.pop('params_wGR', 47./1.175) 
    extents = kwargs.pop('params_extents', 31.)
    direc   = '111'
    mu0     = 'halfMott'
    muBrent = kwargs.pop('params_muBrent',(-0.2,0.3)) 
    muBrentShift = kwargs.pop('params_muBrentShift', 0.)



    aS     = kwargs.pop('params_aS', 300.) 
    muPlus = kwargs.pop('params_muPlus', 0.00 )
    Natoms = kwargs.pop('params_Natoms', None)
    

    select = 'nlce'
    #print 
    #print "muPlus = ", muPlus
    pot = scubic.sc(allIR=s, allGR=g, allIRw=wIR, allGRw=wGR)

    Tlist = kwargs.pop('Tlist', [0.036])
    outdict = {} 
    for TT, Tval in enumerate(Tlist):
        print TT,
        sys.stdout.flush()
        logger.warning('working on Tval = {:0.4f}'.format(Tval) )
        if Natoms is None:
            lda0 = lda.lda(potential = pot, Temperature=Tval, a_s=aS, \
                           override_npoints = 240,\
                           extents=extents, \
                           globalMu=mu0, halfMottPlus=muPlus,\
                           verbose=False, \
                           select = select,\
                           ignoreExtents=False, ignoreSlopeErrors=True, \
                           ignoreMuThreshold=True)
        else:
            lda0 = lda.lda(potential = pot, Temperature=Tval, a_s=aS, \
                           override_npoints = 240,\
                           extents=extents, \
                           Natoms = Natoms,\
                           muBrent=muBrent, muBrentShift=muBrentShift,\
                           verbose=False, \
                           select = select,\
                           ignoreExtents=False, ignoreSlopeErrors=True, \
                           ignoreMuThreshold=True)
    
        r111, n111 = lda0.getDensity( lda0.globalMu, lda0.T)  
        localMu_t = lda0.get_localMu_t( lda0.globalMu )
    
        localMu_t_f = extrap1d( interp1d( r111, localMu_t ) )
        dmu_dr = deriv( rpoints, localMu_t_f )
        dmu_dr111 = deriv( r111, localMu_t_f ) 
    
        t0 = lda0.tunneling_111.min()
        # Need to also get the value of T/t0 and the overall S/N 
        _spibulk, _spi, _r111, _n111, _U111, _t111, _entrbulk, _entr111,\
        _lda_num, _density111, _k111, _k111htse_list = \
            lda0.getBulkSpi(Tspi=Tval/t0, inhomog=True, \
               spiextents=extents, entextents=extents, do_k111=False) 
    
        Tdict = {
                   'r111':r111 ,\
                   'n111':n111 ,\
                   'Ut111':lda0.onsite_111 / lda0.tunneling_111 ,\
                   'localMu_t':localMu_t ,\
                   'dmu_dr': dmu_dr ,\
                   'dmu_dr111': dmu_dr111 ,\
                   'num':lda0.Number,\
                   'T/t0': Tval/t0 ,\
                   'S/N':_entrbulk ,\
                          } 
        outdict[ Tval ] = Tdict

    return outdict 
Example #7
0
def Spi_vs_N( aS=200., Spi_inhomog=False, Tspi=0.9, \
              savedir='dataplots/VaryN_Spi', \
              mulist =[-0.15, -0.075, 0., 0.10, 0.18], 
              bestForce = -1 ,
              spiextents = 25., 
              entextents = 25., 
              finegrid = False, 
              ):

    s       = 7.
    g       = 3.666
    wIR     = 47.
    wGR     = 47./1.175
    T       = 0.035
    extents = 30.
    direc   = '111'
    mu0     = 'halfMott'

    spis = [] 
    select = 'nlce'

    for tag, muPlus in enumerate(mulist):
        print 
        print "muPlus = ", muPlus
        pot = scubic.sc(allIR=s, allGR=g, allIRw=wIR, allGRw=wGR)

        lda0 = lda.lda(potential = pot, Temperature=T, a_s=aS, \
                       extents=extents, \
                       globalMu=mu0, halfMottPlus=muPlus,\
                       verbose=True, \
                       select = select,\
                       ignoreExtents=False, ignoreSlopeErrors=True, \
                       ignoreMuThreshold=True)

        spibulk, spi, r111, n111, U111, t111, entrbulk, entr111,\
        lda_num, density111  = \
            lda0.getBulkSpi(Tspi=Tspi, inhomog=Spi_inhomog, \
               spiextents=spiextents, entextents=entextents)
    
        if finegrid: 
            r111_fine, spi111_fine, n111_fine = lda0.getSpiFineGrid( Tspi=Tspi, numpoints=320,\
                inhomog=Spi_inhomog, spiextents=spiextents, entextents=entextents )
        else:
            r111_fine, spi111_fine, n111_fine = None, None, None


        spis.append( {'SpiBulk':spibulk,\
                      'spi111':spi,\
                      'r111':r111,\
                      'n111':n111,\
                      'U111':U111,\
                      't111':t111,\
                      'entrbulk':entrbulk,\
                      'entr111':entr111,\
                      'Number':lda0.Number,\
                      'ldanum':lda_num,\
                      'dens111':density111,\
                      'Tn':T,\
                      'Tspi':Tspi,\
                      'aS':aS,\
                      'savedir':savedir,\
                      'r111_fine':r111_fine,\
                      'spi111_fine':spi111_fine,\
                      'n111_fine':n111_fine,\
                      } ) 

        # Figure to check inhomogeneity
        fig111, binresult, peak_dens, radius1e, peak_t, output = \
            lda.CheckInhomog( lda0, closefig = True, n_ylim=(-0.1,2.0) ) ;

        figfname = savedir + 'Inhomog/{:0.3f}gr_{:03d}_{}_T{:0.4f}Er.png'.\
                   format(g,tag,select,T)

        fig111.savefig(figfname, dpi=300)

    plot_spis( spis, inhomog=Spi_inhomog, bestForce=bestForce)
    
    return spis[bestForce] 
def optimal_FixedRadius( **kwargs ) :
    """ 
    This function takes fixed values of s0, wL, wC and finds the value of
    green that would be required to make a sample with a radius that is
    a fixed fraction of the lattice beam waist. 
 
    The value of the fraction is hardcoded in the function
    """
    fraction = 0.32

    s0 = kwargs.get('s0', 7. ) 
    wL = kwargs.get('wL', 47. )
    wC = kwargs.get('wC', 40. )
    alpha = wL/wC
    a_s = kwargs.get('a_s', 650. )
    T_Er= kwargs.get('T_Er', 0.2 )
    extents = kwargs.get('extents', 40.)

    def merit( g0 ) :
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.  
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True )

            return   (fraction*wL -   lda0.getRadius())**2.
            #return   fraction -   lda0.getRadius()/wL
        except Exception as e :
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100= 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e6 # this is caused by too much green 
                           # return large value to asign penalty
            elif posslope in e.message:
                return 1e6 # this is caused by too much green
                           # as the chemical potential comes to close
                           # to the threshold and atoms accumulate on 
                           # the beams 
                           # return large value to asign penalty
            elif threshol in e.message:
                return 1e6 # this is caused by too much green
                           # the chemical potential is above the evap th. 
                           # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e6 # this is caused by too much green
                           # the chemical potential is above the bottom of 
                           # the band along 100 
                           # return large value to asign penalty
                              
 
            elif 'vanish' in e.message : 
                # this is is caused by insufficient extents
                print "extents = %.1f"%  extents  
                raise 
            else:
                raise 
            #print "Fail at g0=%.2f"% g0 
            #raise

    g0bounds =  (1., min(s0, (4.*s0-2.*np.sqrt(s0))/(4.*(alpha**2.)) ) ) 
 

    
    #(x, res) = brentq( merit, g0bounds[0], g0bounds[1] )  
    #gOptimal =  x
 
    res = minimize_scalar( merit, bounds=g0bounds, tol=1e-4, \
              method='bounded' )
    gOptimal =  res.x 

    #print "gOpt=%.2f"%gOptimal

    potOpt = scubic.sc( allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC ) 
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)  
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL ]
def optimal( **kwargs ) :
    """ 
    This function takes fixed values of s0, wL, wC and optimizes the 
    evaporation figure of merit, eta_F,  by using the green compensation
    as a variable. 
    """

    s0 = kwargs.get('s0', 7. ) 
    wL = kwargs.get('wL', 47. )
    wC = kwargs.get('wC', 40. )
    alpha = wL/wC
    a_s = kwargs.get('a_s', 650. )
    T_Er= kwargs.get('T_Er', 0.2 )
    extents = kwargs.get('extents', 40.)

    if 'Number' in kwargs.keys():  
        N0 = kwargs['Number']  

    def Npenalty( Num ):
        p = 4.
        if Num > N0: 
            return np.exp( (Num - N0)/1e5 )**p 
        else:
            return 1. 

    def penalty(x,p):
        """
        This function is used to penalyze  EtaF < 1 , which amounts to 
        spilling out along the lattice beams.
        """ 
        if x < 1.:
            return np.exp(-(x-1.))**p
        else:
            return x 
    
        #return np.piecewise(x, [x < 1., x >= 1.], \
        #           [lambda x: , lambda x: x])        

    def merit( g0 ) :
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.  
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True, select='htse' )
    
            etaFstar = penalty( lda0.etaF_star , 5 ) 
            if 'Number' in kwargs.keys():
                return  etaFstar * Npenalty( lda0.Number) 
            else:
                return  etaFstar
        except Exception as e :
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100= 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e4 # this is caused by too much green 
                           # return large value to asign penalty
            elif posslope in e.message:
                return 1e4 # this is caused by too much green
                           # as the chemical potential comes to close
                           # to the threshold and atoms accumulate on 
                           # the beams 
                           # return large value to asign penalty
            elif threshol in e.message:
                return 1e4 # this is caused by too much green
                           # the chemical potential is above the evap th. 
                           # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e4 # this is caused by too much green
                           # the chemical potential is above the bottom of 
                           # the band along 100 
                           # return large value to asign penalty
                              
 
            elif 'vanish' in e.message : 
                # this is is caused by insufficient extents
                print "extents = %.1f"%  extents  
                raise 
            else:
                raise 
            #print "Fail at g0=%.2f"% g0 
            #raise

    g0bounds =  (0., min(s0,s0/(alpha**2.)))   
    res = minimize_scalar( merit, bounds=g0bounds, tol=4e-2, \
              method='bounded' )
    gOptimal =  res.x 

    #print "gOpt=%.2f"%gOptimal

    potOpt = scubic.sc( allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC ) 
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)  
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL,  ldaOpt.DeltaEvap ]
def optimal_FixedRadius(**kwargs):
    """ 
    This function takes fixed values of s0, wL, wC and finds the value of
    green that would be required to make a sample with a radius that is
    a fixed fraction of the lattice beam waist. 
 
    The value of the fraction is hardcoded in the function
    """
    fraction = 0.32

    s0 = kwargs.get('s0', 7.)
    wL = kwargs.get('wL', 47.)
    wC = kwargs.get('wC', 40.)
    alpha = wL / wC
    a_s = kwargs.get('a_s', 650.)
    T_Er = kwargs.get('T_Er', 0.2)
    extents = kwargs.get('extents', 40.)

    def merit(g0):
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True )

            return (fraction * wL - lda0.getRadius())**2.
            #return   fraction -   lda0.getRadius()/wL
        except Exception as e:
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100 = 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e6  # this is caused by too much green
                # return large value to asign penalty
            elif posslope in e.message:
                return 1e6  # this is caused by too much green
                # as the chemical potential comes to close
                # to the threshold and atoms accumulate on
                # the beams
                # return large value to asign penalty
            elif threshol in e.message:
                return 1e6  # this is caused by too much green
                # the chemical potential is above the evap th.
                # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e6  # this is caused by too much green
                # the chemical potential is above the bottom of
                # the band along 100
                # return large value to asign penalty

            elif 'vanish' in e.message:
                # this is is caused by insufficient extents
                print "extents = %.1f" % extents
                raise
            else:
                raise
            #print "Fail at g0=%.2f"% g0
            #raise

    g0bounds = (1., min(s0, (4. * s0 - 2. * np.sqrt(s0)) / (4. * (alpha**2.))))

    #(x, res) = brentq( merit, g0bounds[0], g0bounds[1] )
    #gOptimal =  x

    res = minimize_scalar( merit, bounds=g0bounds, tol=1e-4, \
              method='bounded' )
    gOptimal = res.x

    #print "gOpt=%.2f"%gOptimal

    potOpt = scubic.sc(allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC)
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL ]
def optimal(**kwargs):
    """ 
    This function takes fixed values of s0, wL, wC and optimizes the 
    evaporation figure of merit, eta_F,  by using the green compensation
    as a variable. 
    """

    s0 = kwargs.get('s0', 7.)
    wL = kwargs.get('wL', 47.)
    wC = kwargs.get('wC', 40.)
    alpha = wL / wC
    a_s = kwargs.get('a_s', 650.)
    T_Er = kwargs.get('T_Er', 0.2)
    extents = kwargs.get('extents', 40.)

    if 'Number' in kwargs.keys():
        N0 = kwargs['Number']

    def Npenalty(Num):
        p = 4.
        if Num > N0:
            return np.exp((Num - N0) / 1e5)**p
        else:
            return 1.

    def penalty(x, p):
        """
        This function is used to penalyze  EtaF < 1 , which amounts to 
        spilling out along the lattice beams.
        """
        if x < 1.:
            return np.exp(-(x - 1.))**p
        else:
            return x

        #return np.piecewise(x, [x < 1., x >= 1.], \
        #           [lambda x: , lambda x: x])

    def merit(g0):
        try:
            pot = scubic.sc(allIR  = s0, \
                        allGR  = g0, \
                        allIRw = wL, \
                        allGRw = wC )

            # The lda within the optimization loop is told to ignore errors
            # of the density distribution going beyond the extents.
            # This will be checked after the optmization is done.
            lda0 = lda.lda(potential = pot, Temperature = T_Er,\
                            a_s=a_s, globalMu='halfMott', extents=extents,\
                            ignoreExtents=True, select='htse' )

            etaFstar = penalty(lda0.etaF_star, 5)
            if 'Number' in kwargs.keys():
                return etaFstar * Npenalty(lda0.Number)
            else:
                return etaFstar
        except Exception as e:
            negslope = 'Bottom of the band has a negative slope'
            posslope = 'Radial density profile along 111 has a positive slope'
            threshol = 'Chemical potential exceeds the evaporation threshold'
            thresh100 = 'Chemical potential exceeds the bottom of the band along 100'

            if negslope in e.message:
                return 1e4  # this is caused by too much green
                # return large value to asign penalty
            elif posslope in e.message:
                return 1e4  # this is caused by too much green
                # as the chemical potential comes to close
                # to the threshold and atoms accumulate on
                # the beams
                # return large value to asign penalty
            elif threshol in e.message:
                return 1e4  # this is caused by too much green
                # the chemical potential is above the evap th.
                # return large value to asign penalty
            elif thresh100 in e.message:
                return 1e4  # this is caused by too much green
                # the chemical potential is above the bottom of
                # the band along 100
                # return large value to asign penalty

            elif 'vanish' in e.message:
                # this is is caused by insufficient extents
                print "extents = %.1f" % extents
                raise
            else:
                raise
            #print "Fail at g0=%.2f"% g0
            #raise

    g0bounds = (0., min(s0, s0 / (alpha**2.)))
    res = minimize_scalar( merit, bounds=g0bounds, tol=4e-2, \
              method='bounded' )
    gOptimal = res.x

    #print "gOpt=%.2f"%gOptimal

    potOpt = scubic.sc(allIR=s0, allGR=gOptimal, allIRw=wL, allGRw=wC)
    ldaOpt = lda.lda( potential = potOpt, Temperature=T_Er, \
                      a_s=a_s, globalMu='halfMott', extents=extents)
    return [ gOptimal, ldaOpt.EtaEvap, ldaOpt.Number, \
             ldaOpt.Entropy/ldaOpt.Number, ldaOpt.getRadius(), ldaOpt.getRadius()/wL,  ldaOpt.DeltaEvap ]