Beispiel #1
0
    def stage4(self):
        """
        Depolarize.

        Provided variables:
        spacegraph: depolarized network with node positions.
        yapresult:  Animation of the depolarization process in YaPlot format.
        """
        self.logger.info("Stage4: Depolarization.")
        if not self.depolarize or self.asis:
            self.logger.info("  Skip depolarization by request.")
            self.yapresult = ""
            self.spacegraph = dg.SpaceIceGraph(self.graph,
                                               coord=self.reppositions,
                                               ignores=self.graph.ignores)
        else:
            if self.double_network:
                if (self.rep[0] % 2 == 0) and (self.rep[1] % 2 == 0) and (self.rep[2] % 2 == 0):
                    pass
                else:
                    self.logger.error(
                        "In making the ice structure having the double network (e.g. ices 6 and 7), all the repetition numbers (--rep) must be even.")
                    sys.exit(1)
            self.spacegraph = dg.SpaceIceGraph(self.graph,
                                               coord=self.reppositions,
                                               ignores=self.graph.ignores)
            draw = dg.YaplotDraw(
                self.reppositions, self.repcell.mat, data=self.spacegraph)
            self.yapresult = dg.depolarize(
                self.spacegraph, self.repcell.mat, draw=draw)
        self.logger.info("Stage4: end.")
Beispiel #2
0
    def stage4_analice(self):
        """
        Depolarize.

        Provided variables:
        spacegraph: depolarized network with node positions.
        yapresult:  Animation of the depolarization process in YaPlot format.
        """
        self.logger.info("Stage4: (...)")
        self.yapresult = ""
        self.spacegraph = dg.SpaceIceGraph(self.graph,
                                           coord=self.reppositions,
                                           ignores=self.graph.ignores)
        self.logger.info("Stage4: end.")
Beispiel #3
0
def generate_ice(lattice_type, density=-1, seed=1000, rep=(1, 1, 1), stage=3):
    logger = logging.getLogger()
    logger.info("Ice type: {0}".format(lattice_type))
    lat = safe_import("lattice", lattice_type)
    #Show the document of the module
    try:
        for line in lat.__doc__.splitlines():
            logger.info("!!! {0}".format(line))
    except:
        pass
    lat.waters = load_numbers(lat.waters)
    logger.debug("Waters: {0}".format(len(lat.waters)))
    lat.waters = lat.waters.reshape((lat.waters.size // 3, 3))
    #prepare cell transformation matrix
    if lat.celltype == "rect":
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        lat.cell = np.diag(lat.cell)
    elif lat.celltype == "monoclinic":
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        beta = lat.cell[3] * math.pi / 180.
        lat.cell = np.array(
            ((lat.cell[0] * 1.0, lat.cell[1] * 0.0,
              lat.cell[2] * math.cos(beta)),
             (lat.cell[0] * 0.0, lat.cell[1] * 1.0,
              lat.cell[2] * 0.0), (lat.cell[0] * 0.0, lat.cell[1] * 0.0,
                                   lat.cell[2] * math.sin(beta))))
        lat.cell = lat.cell.transpose(
        )  #all the vector calculations are done in transposed manner.
    elif lat.celltype == "triclinic":
        """
        Put the vectors like following:
        cell = "ax 0 0 bx by 0 cx cy cz"
        when you define a unit cell in Lattice/
        
        """
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
            logger.debug(lat.cell)
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        lat.cell = np.reshape(lat.cell, (3, 3))
        #assert lat.cell[0,1] == 0 and lat.cell[0,2] == 0 and lat.cell[1,2] == 0
    else:
        logger.error("unknown cell type: {0}".format(lat.celltype))
        sys.exit(1)

    #express molecular positions in the coordinate relative to the cell
    if lat.coord == "absolute":
        lat.waters = np.dot(
            lat.waters,
            np.linalg.inv(lat.cell),
        )
        lat.waters = np.array(lat.waters)
    random.seed(seed)
    np.random.seed(seed)

    #Prearranged network topology information (if available)
    pairs = None
    bondlen = None
    try:
        if type(lat.pairs) is str:
            lines = lat.pairs.split("\n")
            pairs = set()
            for line in lines:
                columns = line.split()
                if len(columns) == 2:
                    i, j = [int(x) for x in columns]
                    pairs.add(frozenset([i, j]))
        elif type(lat.pairs) is list:
            pairs = set()
            for pair in pairs:
                pairs.add(frozenset(pair))
    except AttributeError:
        logger.info("Graph is not defined.")

    #Bond length threshold
    try:
        bondlen = lat.bondlen
    except AttributeError:
        logger.info("Bond length is not defined.")

    #set density
    if density < 0:
        density = lat.density

    #scale the cell according to the (specified) density
    mass = 18  #water
    NB = 6.022e23
    nmol = lat.waters.shape[0]  #nmol in a unit cell
    volume = np.linalg.det(lat.cell)  #volume of a unit cell in nm**3
    d = mass * nmol / (NB * volume * 1e-21)
    ratio = (d / density)**(1.0 / 3.0)
    lat.cell *= ratio
    if bondlen is not None:
        bondlen *= ratio

    if True:
        logger.info("Start placing the bonds.")
        if pairs is None:
            logger.info("  Pairs are not given explicitly.")
            logger.info(
                "  Start estimating the bonds according to the pair distances."
            )
            #make bonded pairs according to the pair distance.
            #make before replicating them.
            grid = pl.determine_grid(lat.cell, bondlen)
            pairs = pl.pairlist_fine(lat.waters,
                                     bondlen,
                                     lat.cell,
                                     grid,
                                     distance=False)
            if logger.level <= logging.DEBUG:
                pairs2 = pl.pairlist_crude(lat.waters,
                                           bondlen,
                                           lat.cell,
                                           distance=False)
                logger.debug("pairs: {0}".format(len(pairs)))
                logger.debug("pairs2: {0}".format(len(pairs2)))
                for pair in pairs:
                    i, j = pair
                    assert (i, j) in pairs2 or (j, i) in pairs2
                for pair in pairs2:
                    i, j = pair
                    assert (i, j) in pairs or (j, i) in pairs
            logger.info("  End estimating the bonds.")

        shuffled_pairs = []
        for pair in pairs:
            i, j = pair
            if random.randint(0, 1) == 0:
                i, j = j, i
            shuffled_pairs.append((i, j))

        graph = dg.IceGraph()
        graph.register_pairs(shuffled_pairs)
        logger.info("End placing the bonds.")

    #replicate water molecules to make a repeated cell
    reppositions = replicate(lat.waters, rep)

    #scale the cell
    for d in range(3):
        lat.cell[:, d] *= rep[d]

    result = {
        "positions": reppositions,
        "cell": lat.cell,
        "celltype": lat.celltype,
        "bondlen": bondlen
    }
    if stage == 0:
        return result
        #return reppositions, None, None, lat.cell, lat.celltype, bondlen

    #replicate the graph
    #This also shuffles the bond directions
    graph = replicate_graph(graph, lat.waters, rep)

    result["graph"] = graph
    if stage == 1:
        return result

    #Test
    undir = graph.to_undirected()
    for node in range(undir.number_of_nodes()):
        if node not in undir:
            logger.debug("z=0 at {0}".format(node))
        else:
            z = len(undir.neighbors(node))
            if z != 4:
                logger.debug("z={0} at {1}".format(z, node))

    if graph.number_of_edges() != len(reppositions) * 2:
        logger.info(
            "Inconsistent number of HBs {0} for number of molecules {1}.".
            format(graph.number_of_edges(), len(reppositions)))
        return result

    #make them obey the ice rule
    logger.info("Start making the bonds obey the ice rules.")
    graph.purge_ice_defects()
    logger.info("End making the bonds obey the ice rules.")
    if stage == 2:
        result["graph"] = graph
        return result

    #Rearrange HBs to purge the total dipole moment.
    logger.info("Start depolarization.")
    double_net_test = True
    try:
        if lat.double_network:
            double_net_test = (rep[0] % 2 == 0) and (rep[1] % 2
                                                     == 0) and (rep[2] % 2
                                                                == 0)
    except:
        pass  #just ignore.
    if not double_net_test:
        logger.error(
            "In making the ice structure having the double network (e.g. ices 6 and 7), all the repetition numbers (--rep) must be even."
        )
        sys.exit(1)
    spacegraph = dg.SpaceIceGraph(graph, coord=reppositions)
    draw = dg.YaplotDraw(reppositions, lat.cell, data=spacegraph)
    yapresult = dg.depolarize(spacegraph, lat.cell, draw=draw)
    logger.info("End depolarization.")
    #determine the orientations of the water molecules based on edge directions.
    rotmatrices = orientations(reppositions, spacegraph, lat.cell)
    result["rotmatrices"] = rotmatrices
    result["graph"] = spacegraph
    result["yaplot"] = yapresult
    if stage == 3:
        return result