def test1(): print('generating graphene structure') graphene = GrapheneGenerator(armchair_edge_length=5, zigzag_edge_length=5) lattice = graphene.lattice print('graphene.bounds:\n{}'.format(graphene.bounds)) print('graphene.centroid:\n{}'.format(graphene.centroid)) print('graphene.lattice:\n{}'.format(lattice)) print('graphene.lattice.a1:\n{}'.format(lattice.a1)) print('graphene.lattice.a2:\n{}'.format(lattice.a2)) print('graphene.lattice.a3:\n{}'.format(lattice.a3)) print('graphene.lattice.orientation_matrix:\n{}'.format( lattice.orientation_matrix)) print('rotating graphene') graphene.rotate(angle=-np.pi/2, axis='x') print('graphene.bounds:\n{}'.format(graphene.bounds)) print('graphene.centroid:\n{}'.format(graphene.centroid)) print('graphene.lattice:\n{}'.format(lattice)) print('graphene.lattice.a1:\n{}'.format(lattice.a1)) print('graphene.lattice.a2:\n{}'.format(lattice.a2)) print('graphene.lattice.a3:\n{}'.format(lattice.a3)) print('graphene.lattice.orientation_matrix:\n{}'.format( lattice.orientation_matrix)) assert_true(np.allclose(lattice.angles, 3 * [90.0])) lattice_region = Cuboid(pmax=lattice.lengths) # lattice_region = Parallelepiped(u=lattice.a * xhat, # v=lattice.b * yhat, # w=lattice.c * zhat) assert_equal(lattice_region.a, lattice.a) assert_equal(lattice_region.b, lattice.b) assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) print('\nrotating lattice_region') lattice_region.rotate(transform_matrix=lattice.orientation_matrix) # assert_equal(lattice_region.a, lattice.a) # assert_equal(lattice_region.b, lattice.b) # assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) print('\ncentering lattice_region on graphene centroid') tvec = Vector(Point(graphene.centroid) - lattice_region.centroid) lattice_region.translate(tvec) # assert_equal(lattice_region.a, lattice.a) # assert_equal(lattice_region.b, lattice.b) # assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) bounding_box = generate_bounding_box(from_lattice=lattice, center=graphene.centroid, verbose=True) print('bounding_box:\n{}'.format(bounding_box)) assert_equal(bounding_box, lattice_region) print('lattice_region.lengths: {}, {}, {}'.format( lattice_region.a, lattice_region.b, lattice_region.c))
def test1(): print('generating graphene structure') graphene = GrapheneGenerator(armchair_edge_length=5, zigzag_edge_length=5) lattice = graphene.lattice print('graphene.bounds:\n{}'.format(graphene.bounds)) print('graphene.centroid:\n{}'.format(graphene.centroid)) print('graphene.lattice:\n{}'.format(lattice)) print('graphene.lattice.a1:\n{}'.format(lattice.a1)) print('graphene.lattice.a2:\n{}'.format(lattice.a2)) print('graphene.lattice.a3:\n{}'.format(lattice.a3)) print('graphene.lattice.orientation_matrix:\n{}'.format( lattice.orientation_matrix)) print('rotating graphene') graphene.rotate(angle=-np.pi / 2, axis='x') print('graphene.bounds:\n{}'.format(graphene.bounds)) print('graphene.centroid:\n{}'.format(graphene.centroid)) print('graphene.lattice:\n{}'.format(lattice)) print('graphene.lattice.a1:\n{}'.format(lattice.a1)) print('graphene.lattice.a2:\n{}'.format(lattice.a2)) print('graphene.lattice.a3:\n{}'.format(lattice.a3)) print('graphene.lattice.orientation_matrix:\n{}'.format( lattice.orientation_matrix)) assert_true(np.allclose(lattice.angles, 3 * [90.0])) lattice_region = Cuboid(pmax=lattice.lengths) # lattice_region = Parallelepiped(u=lattice.a * xhat, # v=lattice.b * yhat, # w=lattice.c * zhat) assert_equal(lattice_region.a, lattice.a) assert_equal(lattice_region.b, lattice.b) assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) print('\nrotating lattice_region') lattice_region.rotate(transform_matrix=lattice.orientation_matrix) # assert_equal(lattice_region.a, lattice.a) # assert_equal(lattice_region.b, lattice.b) # assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) print('\ncentering lattice_region on graphene centroid') tvec = Vector(Point(graphene.centroid) - lattice_region.centroid) lattice_region.translate(tvec) # assert_equal(lattice_region.a, lattice.a) # assert_equal(lattice_region.b, lattice.b) # assert_equal(lattice_region.c, lattice.c) print('lattice_region:\n{}'.format(lattice_region)) print('lattice_region.centroid:\n{}'.format(lattice_region.centroid)) bounding_box = generate_bounding_box(from_lattice=lattice, center=graphene.centroid, verbose=True) print('bounding_box:\n{}'.format(bounding_box)) assert_equal(bounding_box, lattice_region) print('lattice_region.lengths: {}, {}, {}'.format(lattice_region.a, lattice_region.b, lattice_region.c))
def write(cls, fname=None, outpath=None, fpath=None, structure=None, atoms=None, atom_style='full', bounding_box=None, comment_line=None, assert_unique_ids=False, enforce_consecutive_ids=True, pad_box=False, xpad=10., ypad=10., zpad=10., pad_tol=0.01, verbose=False, **kwargs): """Write structure data to file. Parameters ---------- fname : str, optional Output file name. outpath : str, optional Output file path. fpath : str, optional Full path (directory path + file name) to output data file. atoms : :class:`~sknano.core.atoms.Atoms` An :class:`~sknano.core.atoms.Atoms` instance. bounding_box : dict, optional If `None`, determined automatically from the `atoms` coordinates. comment_line : str, optional A string written to the first line of `data` file. If `None`, then it is set to the full path of the output `data` file. assert_unique_ids : bool, optional Check that each :class:`~sknano.core.atoms.Atom` in `atoms` has a unique :attr:`~sknano.core.atoms.Atom.id`. If the check fails, then assign a unique :attr:`~sknano.core.atoms.Atom.id`. to each :class:`~sknano.core.atoms.Atom`. If `assert_unique_ids` is True, but the id's are not unique, LAMMPS will not be able to read the data file. enforce_consecutive_ids : bool, optional pad_box : bool, optional xpad, ypad, zpad : float, optional pad_tol : float, optional verbose : bool, optional verbose output """ if structure is None and atoms is None: raise ValueError('Expected either `structure` or `atoms` object.') if structure is not None and atoms is None: atoms = structure.atoms if fpath is None: fpath = get_fpath(fname=fname, ext='data', outpath=outpath, overwrite=True, add_fnum=False) if comment_line is None: comment_line = default_comment_line atoms.rezero() atoms.assign_unique_types() typemap = atoms.typemap Natoms = atoms.Natoms Natoms_width = \ 8 if len(str(Natoms)) <= 12 else len(str(Natoms)) + 4 Ntypes = atoms.Ntypes Ntypes_width = Natoms_width id_width = len(str(Natoms)) + 1 type_width = len(str(Ntypes)) + 1 if (enforce_consecutive_ids and atoms.ids.max() != atoms.Natoms) or \ (not assert_unique_ids and len(set(atoms.ids)) != atoms.Natoms): atoms.assign_unique_ids() if bounding_box is None: if structure is not None and structure.lattice is not None: bounding_box = \ generate_bounding_box(from_lattice=structure.lattice, center=atoms.centroid) else: bounding_box = \ generate_bounding_box(from_array=atoms.coords) if pad_box: boxpad = {'x': xpad, 'y': ypad, 'z': zpad} # for dim, pad in boxpad.items(): for i, dim in enumerate(('x', 'y', 'z')): pad = boxpad[dim] dmin = dim + 'min' dmax = dim + 'max' if abs(getattr(bounding_box, dmin) - atoms.coords[:, i].min()) < pad - pad_tol: setattr(bounding_box, dmin, getattr(bounding_box, dmin) - pad) if abs(getattr(bounding_box, dmax) - atoms.coords[:, i].max()) < pad - pad_tol: setattr(bounding_box, dmax, getattr(bounding_box, dmax) + pad) if verbose: print('bounding_box: {}'.format(bounding_box)) lohi_width = 0 for dim in ('x', 'y', 'z'): lohi_width = \ max(lohi_width, len('{:.6f} {:.6f}'.format( getattr(bounding_box, dim + 'min'), getattr(bounding_box, dim + 'max'))) + 4) with zopen(fpath, 'wt') as f: f.write('# {}\n\n'.format(comment_line.lstrip('#').strip())) f.write('{}atoms\n'.format( '{:d}'.format(Natoms).ljust(Natoms_width))) f.write('{}atom types\n\n'.format( '{:d}'.format(Ntypes).ljust(Ntypes_width))) for dim in ('x', 'y', 'z'): f.write('{}{dim}lo {dim}hi\n'.format( '{:.6f} {:.6f}'.format( getattr(bounding_box, dim + 'min'), getattr(bounding_box, dim + 'max')).ljust(lohi_width), dim=dim)) f.write('\nMasses\n\n') for atomtype, properties in list(typemap.items()): f.write('{}{:.4f}\n'.format( '{:d}'.format(atomtype).ljust(Natoms_width), properties['mass'])) f.write('\nAtoms\n\n') for atom in atoms: line = '' line += "{:>{}}".format(atom.id, id_width) line += "{:>{}}".format(atom.mol, 3) line += "{:>{}}".format(atom.type, type_width) line += "{:>{}}".format('{:.1f}'.format(atom.q), 4) line += "{:>{}}".format('{:f}'.format(atom.x), 14) line += "{:>{}}".format('{:f}'.format(atom.y), 14) line += "{:>{}}".format('{:f}'.format(atom.z), 14) line += "{:>{}}".format('{:d}'.format(atom.ix), 3) line += "{:>{}}".format('{:d}'.format(atom.iy), 3) line += "{:>{}}".format('{:d}'.format(atom.iz), 3) line += '\n' f.write(line) f.write('\nVelocities\n\n') for atom in atoms: line = '' line += "{:>{}}".format(atom.id, id_width) line += "{:>{}}".format('{:f}'.format(atom.vx), 14) line += "{:>{}}".format('{:f}'.format(atom.vy), 14) line += "{:>{}}".format('{:f}'.format(atom.vz), 14) line += '\n' f.write(line)
def write(cls, fname=None, outpath=None, fpath=None, structure=None, atoms=None, atom_style='full', bounding_box=None, comment_line=None, assert_unique_ids=False, enforce_consecutive_ids=True, pad_box=False, xpad=10., ypad=10., zpad=10., pad_tol=0.01, verbose=False, **kwargs): """Write structure data to file. Parameters ---------- fname : str, optional Output file name. outpath : str, optional Output file path. fpath : str, optional Full path (directory path + file name) to output data file. atoms : :class:`~sknano.core.atoms.Atoms` An :class:`~sknano.core.atoms.Atoms` instance. bounding_box : dict, optional If `None`, determined automatically from the `atoms` coordinates. comment_line : str, optional A string written to the first line of `data` file. If `None`, then it is set to the full path of the output `data` file. assert_unique_ids : bool, optional Check that each :class:`~sknano.core.atoms.Atom` in `atoms` has a unique :attr:`~sknano.core.atoms.Atom.id`. If the check fails, then assign a unique :attr:`~sknano.core.atoms.Atom.id`. to each :class:`~sknano.core.atoms.Atom`. If `assert_unique_ids` is True, but the id's are not unique, LAMMPS will not be able to read the data file. enforce_consecutive_ids : bool, optional pad_box : bool, optional xpad, ypad, zpad : float, optional pad_tol : float, optional verbose : bool, optional verbose output """ if structure is None and atoms is None: raise ValueError('Expected either `structure` or `atoms` object.') if structure is not None and atoms is None: atoms = structure.atoms if fpath is None: fpath = get_fpath(fname=fname, ext='data', outpath=outpath, overwrite=True, add_fnum=False) if comment_line is None: comment_line = default_comment_line atoms.rezero() atoms.assign_unique_types() typemap = atoms.typemap Natoms = atoms.Natoms Natoms_width = \ 8 if len(str(Natoms)) <= 12 else len(str(Natoms)) + 4 Ntypes = atoms.Ntypes Ntypes_width = Natoms_width id_width = len(str(Natoms)) + 1 type_width = len(str(Ntypes)) + 1 if (enforce_consecutive_ids and atoms.ids.max() != atoms.Natoms) or \ (not assert_unique_ids and len(set(atoms.ids)) != atoms.Natoms): atoms.assign_unique_ids() if bounding_box is None: if structure is not None and structure.lattice is not None: bounding_box = \ generate_bounding_box(from_lattice=structure.lattice, center=atoms.centroid) else: bounding_box = \ generate_bounding_box(from_array=atoms.coords) if pad_box: boxpad = {'x': xpad, 'y': ypad, 'z': zpad} # for dim, pad in boxpad.items(): for i, dim in enumerate(('x', 'y', 'z')): pad = boxpad[dim] dmin = dim + 'min' dmax = dim + 'max' if abs(getattr(bounding_box, dmin) - atoms.coords[:, i].min()) < pad - pad_tol: setattr(bounding_box, dmin, getattr(bounding_box, dmin) - pad) if abs(getattr(bounding_box, dmax) - atoms.coords[:, i].max()) < pad - pad_tol: setattr(bounding_box, dmax, getattr(bounding_box, dmax) + pad) if verbose: print('bounding_box: {}'.format(bounding_box)) lohi_width = 0 for dim in ('x', 'y', 'z'): lohi_width = \ max(lohi_width, len('{:.6f} {:.6f}'.format( getattr(bounding_box, dim + 'min'), getattr(bounding_box, dim + 'max'))) + 4) with zopen(fpath, 'wt') as f: f.write('# {}\n\n'.format(comment_line.lstrip('#').strip())) f.write('{}atoms\n'.format( '{:d}'.format(Natoms).ljust(Natoms_width))) f.write('{}atom types\n\n'.format( '{:d}'.format(Ntypes).ljust(Ntypes_width))) for dim in ('x', 'y', 'z'): f.write('{}{dim}lo {dim}hi\n'.format('{:.6f} {:.6f}'.format( getattr(bounding_box, dim + 'min'), getattr(bounding_box, dim + 'max')).ljust(lohi_width), dim=dim)) f.write('\nMasses\n\n') for atomtype, properties in list(typemap.items()): f.write('{}{:.4f}\n'.format( '{:d}'.format(atomtype).ljust(Natoms_width), properties['mass'])) f.write('\nAtoms\n\n') for atom in atoms: line = '' line += "{:>{}}".format(atom.id, id_width) line += "{:>{}}".format(atom.mol, 3) line += "{:>{}}".format(atom.type, type_width) line += "{:>{}}".format('{:.1f}'.format(atom.q), 4) line += "{:>{}}".format('{:f}'.format(atom.x), 14) line += "{:>{}}".format('{:f}'.format(atom.y), 14) line += "{:>{}}".format('{:f}'.format(atom.z), 14) line += "{:>{}}".format('{:d}'.format(atom.ix), 3) line += "{:>{}}".format('{:d}'.format(atom.iy), 3) line += "{:>{}}".format('{:d}'.format(atom.iz), 3) line += '\n' f.write(line) f.write('\nVelocities\n\n') for atom in atoms: line = '' line += "{:>{}}".format(atom.id, id_width) line += "{:>{}}".format('{:f}'.format(atom.vx), 14) line += "{:>{}}".format('{:f}'.format(atom.vy), 14) line += "{:>{}}".format('{:f}'.format(atom.vz), 14) line += '\n' f.write(line)