コード例 #1
0
    lprint("    {:s}".format(str(Lat_M)))
    lprint("")

    # minimum gamma
    gamma = lambda x: 3 + 2 * np.sqrt(3 * x) + x

    lprint("Searching")
    lprint("=========")

    C1 = np.tensordot(E_A, E_Minv, axes=([], [])).transpose(0, 3, 1, 2)
    C2 = np.tensordot(C1, C1, axes=([1], [1]))\
        .transpose(0, 3, 1, 2, 4, 5)\
        .reshape(dim**2, dim**2, dim**2)
    D = np.tensordot(C2, C2, axes=([0], [0]))
    lprint('finding alpha by quartic minimization ...', 2)
    alpha = quart_min(D)
    lprint('alpha = {:>9.6f}'.format(alpha), 2)

    # start searching
    def add_sol(sol, sols, ext_sols):
        # if can add to the solution list
        if not tuple(sol['l']) in ext_sols:
            # insert the solution and update EXT_SOLS
            idx = np.searchsorted([s['d'] for s in sols], sol['d'])
            if la.det(sol['l'].reshape(dim, dim)) != 0:
                sols.insert(idx, sol)
            ext_sols = ext_sols.union(eqlatcor(sol['l']))
            if len(sols) > nsol:
                while sols[-1]['d'] > sols[nsol-1]['d']:
                    # sols.pop()
                    delSol = sols.pop()
コード例 #2
0
ファイル: main_direct.py プロジェクト: hua2001/PyStrucTrans
def lat_cor(brava, pa, bravm, pm, **kwargs):
    """
    find the optimal lattice invarient shear move E1 as close as possible to E2
    allowed kwargs:
     - dim: dimension of the Bravais lattice, default is 3, the only other option is 2
     - nsol: number of solutions
     - slice_sz: size of each slice of L's for vectorized calculation, default is 1000
     - disp: level of detail of printing, default is 2
             0 => no print
             1 => two lattices and solution
             2 => progress over HNFs
             3 => more info in the lat_opt
             4 => all info in the lat_opt (not implemented)
     - logfile: name of the logfile
     - loglevel: level of the logging
    """
    ''' 
    ===========
    Preparation
    =========== 
    '''
    # start the timer
    t_start = timer()

    # read kwargs
    def readkw(field, default):
        return kwargs[field] if field in kwargs else default

    nsol = readkw('nsol', 1)
    vol_th = readkw('vol_th', 0.1)
    disp = readkw('disp', 1)
    dim = readkw('dim', 3)
    slice_sz = readkw('slice_sz', 100)
    distName = readkw('dist', 'Cauchy')

    def lprint(msg, lev=1):
        # print with level
        if disp >= lev:
            print(msg)
        if lev == 1:
            logger.info(msg)
        elif lev >= 2:
            logger.debug(msg)

    # setup logging
    loglevel = readkw('loglevel', logging.INFO)
    if 'logfile' in kwargs:
        # FORMAT = '[%(levelname)s] %(asctime)-15s %(name)s: %(message)s'
        FORMAT = '%(message)s'
        logfile = readkw('logfile', 'untitled.log')
        logging.basicConfig(filename=logfile,
                            filemode='w',
                            level=loglevel,
                            format=FORMAT)
    ''' 
    ====================
    Preparation - finish
    ====================
    '''
    ''' 
    ============
    Core process
    ============
    '''

    lprint("Input data")
    lprint("==========")

    # construct
    Lat_A = BravaisLattice(brava, pa, dim=dim)
    Lat_M = BravaisLattice(bravm, pm, dim=dim)

    E_A = Lat_A.base()
    E_M = Lat_M.base()

    E_Minv = la.inv(E_M)
    dist = lambda x: Cauchy_dist(x, E_A, E_Minv)
    dist_vec = lambda xs: Cauchy_dist_vec(xs, E_A, E_Minv)

    C_A = Lat_A.conventional_trans()
    C_M = Lat_M.conventional_trans()

    LG_A = Lat_A.lattice_group().matrices()
    LG_M = Lat_M.lattice_group().matrices()

    def eqlatcor(l):
        L = l.reshape(dim, dim)
        return set(
            tuple(M1.dot(L).dot(M2).flatten()) for M1 in LG_A for M2 in LG_M)

    lprint(" - Austenite lattice:")
    lprint("    {:s}".format(str(Lat_A)))
    lprint(" - Martensite lattice:")
    lprint("    {:s}".format(str(Lat_M)))
    lprint("")

    # minimum gamma
    gamma = lambda x: 3 + 2 * np.sqrt(3 * x) + x

    lprint("Searching")
    lprint("=========")

    C1 = np.tensordot(E_A, E_Minv, axes=([], [])).transpose(0, 3, 1, 2)
    C2 = np.tensordot(C1, C1, axes=([1], [1]))\
        .transpose(0, 3, 1, 2, 4, 5)\
        .reshape(dim**2, dim**2, dim**2)
    D = np.tensordot(C2, C2, axes=([0], [0]))
    lprint('finding alpha by quartic minimization ...', 2)
    alpha = quart_min(D)
    lprint('alpha = {:>9.6f}'.format(alpha), 2)

    # start searching
    def add_sol(sol, sols, ext_sols):
        # if can add to the solution list
        if not tuple(sol['l']) in ext_sols:
            # insert the solution and update EXT_SOLS
            idx = np.searchsorted([s['d'] for s in sols], sol['d'])
            if la.det(sol['l'].reshape(dim, dim)) != 0:
                sols.insert(idx, sol)
            ext_sols = ext_sols.union(eqlatcor(sol['l']))
            if len(sols) > nsol:
                while sols[-1]['d'] > sols[nsol - 1]['d']:
                    # sols.pop()
                    delSol = sols.pop()
                    ext_sols = ext_sols.difference(eqlatcor(delSol['l']))
        return sols, ext_sols, sols[-1]['d']

    def update_sol(ls, sols, ext_sols, dmax):
        dmax_ref = dmax
        ds = dist_vec(ls)
        while len(ds) > 0:
            minidx = np.argmin(ds)
            dmin = ds[minidx]
            ds = np.delete(ds, minidx)
            lmin = ls[minidx].reshape(dim**2)
            ls = np.delete(ls, minidx, axis=0)
            if dmin <= dmax:
                sols, ext_sols, dmax = add_sol({
                    'l': lmin,
                    'd': dmin
                }, sols, ext_sols)
            else:
                break
        updated = (dmax < dmax_ref)
        return updated, sols, ext_sols, dmax

    # initialization
    L0 = np.floor(la.inv(E_A).dot(E_M)).astype(np.int)
    SOLS = []
    EXT_SOLS = set()
    DMAX = float('inf')

    for _ in xrange(20 * nsol):
        shift = np.random.random_integers(-1, 1, (dim, dim))
        L = L0 + shift
        l = L.reshape(dim**2)
        while tuple(l) in EXT_SOLS or not (1 - vol_th < la.det(L0 + shift) <
                                           1 + vol_th):
            shift = np.random.random_integers(-1, 1, (dim, dim))
            L = L0 + shift
            l = L.reshape(dim**2)
        sol = {'l': l, 'd': dist(l)}
        SOLS, EXT_SOLS, DMAX = add_sol(sol, SOLS, EXT_SOLS)

    rmax = lambda d: (gamma(d) / alpha)**0.25

    maxRadius = rmax(DMAX)
    lprint('start searching ...')
    updated = True
    checkpoint = np.zeros(dim**2, np.int)

    # iteration
    while updated:
        updated = False
        g = vec_generator(maxRadius, dim**2, checkpoint)
        lprint(
            'searching radius = {:>9.6f}, max distance = {:>9.6f}, starting at {:s}'
            .format(maxRadius, DMAX, str(checkpoint)), 2)
        ary = np.array(list(itertools.islice(g, slice_sz)))
        while len(ary) > 0:
            updated, SOLS, EXT_SOLS, DMAX = update_sol(ary, SOLS, EXT_SOLS,
                                                       DMAX)
            if updated:
                maxRadius = rmax(DMAX)
                checkpoint = np.array(next(g))
                break
            else:
                ary = np.array(list(itertools.islice(g, slice_sz)))

    for sol in SOLS:
        eqls = eqlatcor(sol['l'])
        sol['l'] = sol['l'].reshape(dim, dim)
        for l in eqls:
            L = np.array(l).reshape(dim, dim)
            if la.det(L) > 0:
                sol['l'] = L
                break

        cor = np.dot(np.dot(la.inv(C_A), sol['l']), C_M)
        sol['cor'] = cor[:]
        # Cauchy-Born deformation gradient: F.EA.H.L = EM
        F = np.dot(E_M, la.inv(np.dot(E_A, sol['l'])))
        C = np.dot(F.T, F)
        [lams, V] = la.eig(C)  # spectrum decomposition
        lams = np.sqrt(np.real(lams))
        U = np.dot(np.dot(V, np.diag(lams)), la.inv(V))
        sol['u'] = U[:]
        lams = np.sort(lams)
        sol['lams'] = lams[:]

    lprint("Finally {:d} / {:d} solutions are found.".format(len(SOLS), nsol),
           3)
    lprint("")
    '''
    =====================
    Core process - finish
    =====================
    '''
    '''
    ============
    Print result
    ============
    '''
    # Print and save the results
    lprint('Print and save the results')
    lprint('==========================')

    output = _sols_tostr(SOLS, nsol, dim, distName)
    if disp > 0:
        print(output)
    for line in output.split("\n"):
        logger.info(line)
    '''
    =====================
    Print result - finish
    =====================
    '''

    # timer
    lprint("All done in {:g} secs.".format(timer() - t_start), 1)

    return SOLS
コード例 #3
0
    lprint("    {:s}".format(str(Lat_M)))
    lprint("")

    # minimum gamma
    gamma = lambda x: 3 + 2 * np.sqrt(3 * x) + x

    lprint("Searching")
    lprint("=========")

    C1 = np.tensordot(E_A, E_Minv, axes=([], [])).transpose(0, 3, 1, 2)
    C2 = np.tensordot(C1, C1, axes=([1], [1]))\
        .transpose(0, 3, 1, 2, 4, 5)\
        .reshape(dim**2, dim**2, dim**2)
    D = np.tensordot(C2, C2, axes=([0], [0]))
    lprint('finding alpha by quartic minimization ...', 2)
    alpha = quart_min(D)
    lprint('alpha = {:>9.6f}'.format(alpha), 2)

    # start searching
    def add_sol(sol, sols, ext_sols):
        # if can add to the solution list
        if not tuple(sol['l']) in ext_sols:
            # insert the solution and update EXT_SOLS
            idx = np.searchsorted([s['d'] for s in sols], sol['d'])
            if la.det(sol['l'].reshape(dim, dim)) != 0:
                sols.insert(idx, sol)
            ext_sols = ext_sols.union(eqlatcor(sol['l']))
            if len(sols) > nsol:
                while sols[-1]['d'] > sols[nsol - 1]['d']:
                    # sols.pop()
                    delSol = sols.pop()
コード例 #4
0
ファイル: main_direct.py プロジェクト: hua2001/PyStrucTrans
def lat_cor(brava, pa, bravm, pm, **kwargs):
    """
    find the optimal lattice invarient shear move E1 as close as possible to E2
    allowed kwargs:
     - dim: dimension of the Bravais lattice, default is 3, the only other option is 2
     - nsol: number of solutions
     - slice_sz: size of each slice of L's for vectorized calculation, default is 1000
     - disp: level of detail of printing, default is 2
             0 => no print
             1 => two lattices and solution
             2 => progress over HNFs
             3 => more info in the lat_opt
             4 => all info in the lat_opt (not implemented)
     - logfile: name of the logfile
     - loglevel: level of the logging
    """
    
    ''' 
    ===========
    Preparation
    =========== 
    '''
    # start the timer
    t_start = timer()
    
    # read kwargs
    def readkw(field, default):
        return kwargs[field] if field in kwargs else default

    nsol = readkw('nsol', 1)
    vol_th = readkw('vol_th', 0.1)
    disp = readkw('disp', 1)
    dim = readkw('dim', 3)
    slice_sz = readkw('slice_sz', 100)
    distName = readkw('dist', 'Cauchy')

    def lprint(msg, lev=1):
        # print with level
        if disp >= lev:
            print(msg)
        if lev == 1:
            logger.info(msg)
        elif lev >= 2:
            logger.debug(msg)

    # setup logging
    loglevel =readkw('loglevel', logging.INFO)
    if 'logfile' in kwargs:
        # FORMAT = '[%(levelname)s] %(asctime)-15s %(name)s: %(message)s'
        FORMAT = '%(message)s'
        logfile = readkw('logfile', 'untitled.log')
        logging.basicConfig(filename=logfile, filemode='w', level=loglevel, format=FORMAT)

    ''' 
    ====================
    Preparation - finish
    ====================
    '''
        
    ''' 
    ============
    Core process
    ============
    '''

    lprint("Input data")
    lprint("==========")
    
    # construct
    Lat_A = BravaisLattice(brava, pa, dim=dim)
    Lat_M = BravaisLattice(bravm, pm, dim=dim)
    
    E_A = Lat_A.base()
    E_M = Lat_M.base()

    E_Minv = la.inv(E_M)
    dist = lambda x: Cauchy_dist(x, E_A, E_Minv)
    dist_vec = lambda xs: Cauchy_dist_vec(xs, E_A, E_Minv)

    C_A = Lat_A.conventional_trans()
    C_M = Lat_M.conventional_trans()

    LG_A = Lat_A.lattice_group().matrices()
    LG_M = Lat_M.lattice_group().matrices()

    def eqlatcor(l):
        L = l.reshape(dim, dim)
        return set(tuple(M1.dot(L).dot(M2).flatten()) for M1 in LG_A for M2 in LG_M)

    lprint(" - Austenite lattice:")
    lprint("    {:s}".format(str(Lat_A)))
    lprint(" - Martensite lattice:")
    lprint("    {:s}".format(str(Lat_M)))
    lprint("")

    # minimum gamma
    gamma = lambda x: 3 + 2 * np.sqrt(3 * x) + x

    lprint("Searching")
    lprint("=========")

    C1 = np.tensordot(E_A, E_Minv, axes=([], [])).transpose(0, 3, 1, 2)
    C2 = np.tensordot(C1, C1, axes=([1], [1]))\
        .transpose(0, 3, 1, 2, 4, 5)\
        .reshape(dim**2, dim**2, dim**2)
    D = np.tensordot(C2, C2, axes=([0], [0]))
    lprint('finding alpha by quartic minimization ...', 2)
    alpha = quart_min(D)
    lprint('alpha = {:>9.6f}'.format(alpha), 2)

    # start searching
    def add_sol(sol, sols, ext_sols):
        # if can add to the solution list
        if not tuple(sol['l']) in ext_sols:
            # insert the solution and update EXT_SOLS
            idx = np.searchsorted([s['d'] for s in sols], sol['d'])
            if la.det(sol['l'].reshape(dim, dim)) != 0:
                sols.insert(idx, sol)
            ext_sols = ext_sols.union(eqlatcor(sol['l']))
            if len(sols) > nsol:
                while sols[-1]['d'] > sols[nsol-1]['d']:
                    # sols.pop()
                    delSol = sols.pop()
                    ext_sols = ext_sols.difference(eqlatcor(delSol['l']))
        return sols, ext_sols, sols[-1]['d']

    def update_sol(ls, sols, ext_sols, dmax):
        dmax_ref = dmax
        ds = dist_vec(ls)
        while len(ds) > 0:
            minidx = np.argmin(ds)
            dmin = ds[minidx]
            ds = np.delete(ds, minidx)
            lmin = ls[minidx].reshape(dim**2)
            ls = np.delete(ls, minidx, axis=0)
            if dmin <= dmax:
                sols, ext_sols, dmax = add_sol({'l': lmin, 'd': dmin}, sols, ext_sols)
            else:
                break
        updated = (dmax < dmax_ref)
        return updated, sols, ext_sols, dmax

    # initialization
    L0 = np.floor(la.inv(E_A).dot(E_M)).astype(np.int)
    SOLS = []
    EXT_SOLS = set()
    DMAX = float('inf')

    for _ in xrange(20 * nsol):
        shift = np.random.random_integers(-1, 1, (dim, dim))
        L = L0 + shift
        l = L.reshape(dim**2)
        while tuple(l) in EXT_SOLS or not (1 - vol_th < la.det(L0 + shift) < 1 + vol_th):
            shift = np.random.random_integers(-1, 1, (dim, dim))
            L = L0 + shift
            l = L.reshape(dim**2)
        sol = {'l': l, 'd': dist(l)}
        SOLS, EXT_SOLS, DMAX = add_sol(sol, SOLS, EXT_SOLS)

    rmax = lambda d: (gamma(d) / alpha) ** 0.25

    maxRadius = rmax(DMAX)
    lprint('start searching ...')
    updated = True
    checkpoint = np.zeros(dim**2, np.int)

    # iteration
    while updated:
        updated = False
        g = vec_generator(maxRadius, dim**2, checkpoint)
        lprint('searching radius = {:>9.6f}, max distance = {:>9.6f}, starting at {:s}'.format(
            maxRadius, DMAX, str(checkpoint)
        ), 2)
        ary = np.array(list(itertools.islice(g, slice_sz)))
        while len(ary) > 0:
            updated, SOLS, EXT_SOLS, DMAX = update_sol(ary, SOLS, EXT_SOLS, DMAX)
            if updated:
                maxRadius = rmax(DMAX)
                checkpoint = np.array(next(g))
                break
            else:
                ary = np.array(list(itertools.islice(g, slice_sz)))

    for sol in SOLS:
        eqls = eqlatcor(sol['l'])
        sol['l'] = sol['l'].reshape(dim, dim)
        for l in eqls:
            L = np.array(l).reshape(dim, dim)
            if la.det(L) > 0:
                sol['l'] = L
                break

        cor = np.dot(np.dot(la.inv(C_A), sol['l']), C_M)
        sol['cor'] = cor[:]
        # Cauchy-Born deformation gradient: F.EA.H.L = EM
        F = np.dot(E_M, la.inv(np.dot(E_A, sol['l'])))
        C = np.dot(F.T, F)
        [lams, V] = la.eig(C)  # spectrum decomposition
        lams = np.sqrt(np.real(lams))
        U = np.dot(np.dot(V, np.diag(lams)), la.inv(V))
        sol['u'] = U[:]
        lams = np.sort(lams)
        sol['lams'] = lams[:]

    lprint("Finally {:d} / {:d} solutions are found.".format(len(SOLS), nsol), 3)
    lprint("")

    '''
    =====================
    Core process - finish
    =====================
    '''

    '''
    ============
    Print result
    ============
    '''
    # Print and save the results
    lprint('Print and save the results')
    lprint('==========================')

    output = _sols_tostr(SOLS, nsol, dim, distName)
    if disp > 0:
        print(output)
    for line in output.split("\n"):
        logger.info(line)
    '''
    =====================
    Print result - finish
    =====================
    '''

    # timer
    lprint("All done in {:g} secs.".format(timer()-t_start), 1)

    return SOLS
コード例 #5
0
ファイル: solver.py プロジェクト: hua2001/PyStrucTrans
    def load_input(self):
        self.lprint("Input data")
        self.lprint("==========")

        # construct
        Lat_A = BravaisLattice(self.brava, self.pa, dim=self.dim)
        Lat_M = BravaisLattice(self.bravm, self.pm, dim=self.dim)

        E_A = Lat_A.base()
        E_M = Lat_M.base()
        self.E_A = E_A
        self.E_M = E_M

        E_Minv = la.inv(E_M)
        self.dist = lambda x: Cauchy_dist(x, E_A, E_Minv)
        self.dist_vec = lambda xs: Cauchy_dist_vec(xs, E_A, E_Minv)

        C_A = Lat_A.conventional_trans()
        C_M = Lat_M.conventional_trans()

        LG_A = Lat_A.lattice_group().matrices()
        LG_M = Lat_M.lattice_group().matrices()

        def eqlatcor(l):
            L = l.reshape(self.dim, self.dim)
            return set(tuple(M1.dot(L).dot(M2).flatten()) for M1 in LG_A for M2 in LG_M)

        self.lprint(" - Austenite lattice:")
        self.lprint("    {:s}".format(str(Lat_A)))
        self.lprint(" - Martensite lattice:")
        self.lprint("    {:s}".format(str(Lat_M)))
        self.lprint("")

        # minimum gamma
        self.gamma = lambda x: 3 + 2 * np.sqrt(3 * x) + x

        C1 = np.tensordot(E_A, E_Minv, axes=([], [])).transpose(0, 3, 1, 2)
        C2 = np.tensordot(C1, C1, axes=([1], [1])) \
            .transpose(0, 3, 1, 2, 4, 5) \
            .reshape(self.dim ** 2, self.dim ** 2, self.dim ** 2)
        D = np.tensordot(C2, C2, axes=([0], [0]))
        self.lprint('finding alpha by quartic minimization ...', 2)
        self.alpha = quart_min(D)
        self.lprint('alpha = {:>9.6f}'.format(self.alpha), 2)

        # start searching
        def add_sol(sol, sols, ext_sols):
            # if can add to the solution list
            if not tuple(sol['l']) in ext_sols:
                # insert the solution and update EXT_SOLS
                idx = np.searchsorted([s['d'] for s in sols], sol['d'])
                if la.det(sol['l'].reshape(self.dim, self.dim)) != 0:
                    sols.insert(idx, sol)
                ext_sols = ext_sols.union(eqlatcor(sol['l']))
                if len(sols) > self.nsol:
                    while sols[-1]['d'] > sols[self.nsol - 1]['d']:
                        delSol = sols.pop()
                        ext_sols = ext_sols.difference(eqlatcor(delSol['l']))
            return sols, ext_sols, sols[-1]['d']

        self.add_sol = add_sol

        def update_sol(ls, sols, ext_sols, dmax):
            dmax_ref = dmax
            ds = self.dist_vec(ls)
            while len(ds) > 0:
                minidx = np.argmin(ds)
                dmin = ds[minidx]
                ds = np.delete(ds, minidx)
                lmin = ls[minidx].reshape(self.dim ** 2)
                ls = np.delete(ls, minidx, axis=0)
                if dmin <= dmax:
                    sols, ext_sols, dmax = add_sol({'l': lmin, 'd': dmin}, sols, ext_sols)
                else:
                    break
            updated = (dmax < dmax_ref)
            return updated, sols, ext_sols, dmax

        self.update_sol = update_sol