[ase-users] Split POSCAR/CONTCAR files

Oscar Xavier Guerrero oscarxavier.ox at gmail.com
Wed May 3 16:16:13 CEST 2017


Forgot to include the ase-users to the recipients.

2017-05-03 9:11 GMT-05:00 Oscar Xavier Guerrero <oscarxavier.ox at gmail.com>:

> Hello,
>
> For the formatting of the code, it depends on your e-mail client. Gmail
> has the formatting tools to do it, it can also keep the format if you paste
> it from somewhere else like a python code editor that formats the text
> automatically.
>
> It crashes because you're setting a constraint for atoms that don't exist,
> I'm sure you're getting an IndexError. One way of fixing it is by remapping
> the constraints with something like I write down here. Also, constraints is
> a list of FixAtoms objects so you have to ask for the first one to get the
> correct indices:
>
> fixed_atoms_i = atoms.contraints[0].index
> fix_mask = {'ads': [], 'slab': []}
> for a in atoms:
>     is_fixed = a.index in fixed_atoms_i
>     key = 'ads' if a.index in ads_i else 'slab'
>     fix_mask[key].append(is_fixed)
> fix_ads = FixAtoms(mask=fix_mask['ads'])
> fix_slab = FixAtoms(mask=fix_mask['slab'])
> ads.set_constraint(fix_ads)
> slab.set_constraint(fix_slab)
>
> Whenever the program crashes take a look at the error ir raises, it will
> most of the times point you to the cause. The  error will also help other
> people understand what went wrong.
>
>
>
>
>
>
>
> 2017-05-03 3:25 GMT-05:00 fabian <Fabian.T89 at web.de>:
>
>> Dear Oscar ,
>>
>>
>> I am sorry to bug you again with this, but in my environment i am the
>> only one using ASE so far. I could get my code to write tags to the POSCAR
>> files, but they are all T T T wich is obviously wrong.
>>
>>
>> from ase.io import read, writefrom ase.atoms import Atomsfrom ase.constraints import FixAtoms
>>
>>
>> atoms = read('CONTCAR')
>>
>> write('POSCAR_slab_molecule', atoms, vasp5=True, sort=True, direct=True,long_format=True, format='vasp')# assuming the adsorbate has no Cu and O
>> slab_elms = ['Cu', 'O'] # Specify the Atoms in the slab!
>>
>> # read constraints#constraint_slab = [atoms.constraints.index for a in atoms if a.symbol in slab_elms]#constraint_ads = [atoms.constraints.index for a in atoms if a.symbol not in slab_elms]
>>
>> constraint_slab = atoms.constraints.index
>> constraint_ads = atoms.constraints.index
>>
>>
>> slab_i = [a.index for a in atoms if a.symbol in slab_elms]
>>
>> ads_i = [a.index for a in atoms if a.symbol not in slab_elms]
>> # Use Atoms
>> slab = Atoms([a for a in atoms if a.index in slab_i])
>> ads = Atoms([a for a in atoms if a.index in ads_i])
>> cell = atoms.get_cell()
>> slab.set_cell(cell)
>> ads.set_cell(cell)#Slab
>> slab.set_constraint(constraint_slab)
>> ads.set_constraint(constraint_ads)
>>
>>
>>
>> write('POSCAR_slab', slab, vasp5=True, sort=True, direct=True,long_format=True, format='vasp')
>> write('POSCAR_molecule', ads, vasp5=True, sort=True, direct=True,long_format=True, format='vasp'
>>
>> I guess i am using the atoms.constraints  command wrong? The line
>>
>> write('POSCAR_slab_molecule', atoms, vasp5=True, sort=True, direct=True,long_format=True, format='vasp')
>>
>> does result in a File with the constraints correctly written, though.
>>
>>
>> All the best
>>
>>
>> Fabian
>> Am 02.05.2017 um 16:47 schrieb Oscar Xavier Guerrero:
>>
>> Hello,
>>
>> The constraints are read from the CONTCAR, they are stored in
>> atoms.constraints and you can access the indices of the fixed atoms with
>> atoms.constraints.index, you can then use that information to add that
>> constraint to the new atoms object you created with slab.set_contraint()
>> .
>>
>> The tags are not stored in the Vasp file format, so if you want to use
>> them you would have to assign them yourself. If you want to set tags to the
>> atoms you can use the atoms.set_tags() function. I'm assuming you want
>> to filter the atoms by layer in the slab, here's a function I wrote that
>> assigns tags to fix some layers in a slab.
>>
>> def fix_layers(atoms, fix, n_layers):
>>     '''
>>     fix: number of layers to fix
>>     n_layers: total number of layers in slab
>>     '''
>>     from ase.constraints import FixAtoms
>>     factor = float(fix) / n_layers
>>     max_z = max([a.z for a in atoms])
>>     th = max_z * factor
>>     constraint = FixAtoms(mask=[a.z <= th for a in atoms])
>>     atoms.set_constraint(constraint)
>>     return atoms
>>
>> I would strongly recommend you store files and directories in separate
>> directories, having a dedicated directory to store files.
>>
>> To create a new directory you can use:
>>
>> import os
>> directory = 'path/to/New_Folder'
>> if not os.path.exists(directory)
>>     os.makedirs(directory)
>>
>>
>>
>>
>> 2017-05-02 5:21 GMT-05:00 fabian <Fabian.T89 at web.de>:
>>
>>> Dear Oscar,
>>>
>>>
>>> I have an additional requtest.
>>>
>>> Is it possible to read the constraints from the CONTCAR file and write
>>> them to the split files for the slab and the adsorbate?
>>>
>>>
>>> At the moment i am using this code based on your supplied solution, but
>>> there are no selective dynamics constraints written to the new Files.
>>> Ideally i would like to write them
>>> directly just as they are written in the CONTCAR file without the need
>>> to rewrite them.
>>>
>>> *from ase.io <http://ase.io> import read, write*
>>> *from ase.atoms import Atoms*
>>> *from ase.constraints import FixAtoms*
>>> *atoms = read('CONTCAR')*
>>> *# assuming the adsorbate has no Cu and O*
>>>
>>> *slab_elms = ['Cu', 'O']*
>>> *slab_i = [a.index for a in atoms if a.symbol in slab_elms]*
>>>
>>> *ads_i = [a.index for a in atoms if a.symbol not in slab_elms]*
>>>
>>> *# Use Atoms*
>>> *slab = Atoms([a for a in atoms if a.index in slab_i])*
>>> *ads = Atoms([a for a in atoms if a.index in ads_i])*
>>> *cell = atoms.get_cell()*
>>> *slab.set_cell(cell)*
>>> *ads.set_cell(cell)*
>>> *#Slab*
>>> *c = FixAtoms(indices=[atom.index for atom in slab if atom.tag > 2])*
>>> *slab.set_constraint(c)*
>>> *print slab.get_cell()*
>>> *ns = [x.index for x in sorted(slab, key=lambda x: [ 'Cu',
>>> 'O'].index(x.symbol))]*
>>> *slab = slab[ns]*
>>> *print slab.get_cell()*
>>> *#Ads*
>>> *#print ads.get_cell()*
>>> *#na = [y.index for y in sorted(ads, key=lambda y: [ 'C',
>>> 'H'].index(y.symbol))]*
>>> *#ads = ads[na]*
>>> *#print ads.get_cell()*
>>>
>>> *write('POSCAR', slab, vasp5=True, sort=True,
>>> direct=False,long_format=True, format='vasp')*
>>> *write('POSCAR_2', ads, vasp5=True, sort=True, direct=False,
>>> format='vasp')*
>>>
>>> Is this possible?In the code above the  line *if atom.tag > 2 *the
>>> seems to be ignored? Is it possible to write each new POSCAR file into a
>>> new Folder which is also created by the script directly?
>>>
>>>
>>> Thanks in advance
>>>
>>>
>>> Fabian
>>> Am 19.04.2017 um 18:11 schrieb Oscar Xavier Guerrero:
>>>
>>> No, you would have to use in:
>>>
>>> slab_elms = ['Cu', 'O']
>>> slab_i = [a.index for a in atoms if a.symbol *in slab_elms*]
>>>
>>> This is correct only if you have no O in your adsorbate. Otherwise, it
>>> would be better to use height to separate.
>>>
>>>
>>> 2017-04-19 2:56 GMT-05:00 fabian <Fabian.T89 at web.de>:
>>>
>>>> Dear Oscar,
>>>> Thank you very much for your fast reply! This is exactly what i want to
>>>> do!
>>>>
>>>>
>>>> If my slab consist of different species , for example Cu and O atoms,
>>>> is it correct to change this line
>>>>
>>>>
>>>> slab_i = [a.index for a in atoms if a.symbol == 'Cu']
>>>>
>>>>
>>>> to
>>>>
>>>>
>>>>
>>>> slab_i = [a.index for a in atoms if a.symbol == 'Cu','O'] ?
>>>>
>>>>
>>>> All the best
>>>>
>>>>
>>>> fabian
>>>>
>>>>
>>>> Am 18.04.2017 um 23:25 schrieb Oscar Xavier Guerrero:
>>>>
>>>> Sorry, in the previous example I forgot to convert from list to an
>>>> atoms object.
>>>>
>>>> This should work:
>>>>
>>>> from ase.io import read, write
>>>> from ase.atoms import Atoms
>>>> atoms = read('CONTCAR')
>>>> # assuming the slab is only composed of Cu and the adsorbate has no Cu
>>>> slab_i = [a.index for a in atoms if a.symbol == 'Cu']
>>>> ads_i = [a.index for a in atoms if a.symbol != 'Cu']
>>>> # you could also use height as the threshold
>>>> th = max(a.z for a in atoms if a.symbol == 'Cu')
>>>> # you can also use constraints to set the th
>>>> slb = {atoms[i].symbol for i in atoms.constraints[0].index}
>>>> th = max(a.z for a in atoms if a.symbol in alb)
>>>>
>>>> slab_i = [a.index for a in atoms if a.z <= th]
>>>> ads_i = [a.index for a in atoms if a.z > th]
>>>>
>>>> # this is a quick fix, maybe there's a better method
>>>> slab = atoms.copy()
>>>> for i in sorted(ads_i, reverse=True):
>>>>     del slab[i]
>>>> ads = atoms.copy()
>>>> for i in sorted(slab_i, reverse=True):
>>>>     del ads[i]
>>>>
>>>> # or you could use Atoms
>>>> slab = Atoms([a for a in atoms if a.index in slab_i])
>>>> ads = Atoms([a for a in atoms if a.index in ads_i])
>>>> cell = atoms.get_cell()
>>>> slab.set_cell(cell)
>>>> ads.set_cell(cell)
>>>> constraint = atoms.constraints[0]
>>>> slab.set_constraints(constraint)
>>>> ads.set_constraints(constraint)
>>>>
>>>> write('slab.vasp', slab, vasp5=True, sort=True, direct=True,
>>>> format='vasp')
>>>> write('ads.vasp', ads, vasp5=True, sort=True, direct=True,
>>>> format='vasp')
>>>>
>>>> If you have any questions I'm happy to help.
>>>>
>>>>
>>>> 2017-04-18 15:53 GMT-05:00 Oscar Xavier Guerrero <
>>>> oscarxavier.ox at gmail.com>:
>>>>
>>>>> Hello Fabian,
>>>>>
>>>>> You can read POSCAR/CONTCAR files with ase.io.read, you get an atoms
>>>>> object with all the information the file had. Then you can copy parts of
>>>>> that atoms object into other atoms object. Then use the ase.io.write
>>>>> function to write POSCAR files for each of the new atoms objects. Since you
>>>>> have a slab and an adsorbate, you can use the height as a threshold. It
>>>>> really depends on your systems.
>>>>>
>>>>> Here's an example:
>>>>>
>>>>> from ase.io import read, write
>>>>> atoms = read('CONTCAR')
>>>>> # assuming the slab is only composed of Cu and the adsorbate has no Cu
>>>>> slab = [a for a in atoms if a.symbol == 'Cu']
>>>>> ads = [a for a in atoms if a.symbol != 'Cu']
>>>>> # you could also use height as the threshold
>>>>> th = max(a.z for a in atoms if a.symbol == 'Cu')
>>>>> # you can also use constraints to set the th
>>>>> slb = {atoms[i].symbol for i in atoms.constraints[0].index}
>>>>> th = max(a.z for a in atoms if a.symbol in alb)
>>>>>
>>>>> slab = [a for a in atoms if a.z <= th]
>>>>> ads = [a for a in atoms if a.z > th]
>>>>>
>>>>> write('slab.vasp', slab, vasp5=True, sort=True, direct=True,
>>>>> format='vasp')
>>>>> write('ads.vasp', ads, vasp5=True, sort=True, direct=True,
>>>>> format='vasp')
>>>>>
>>>>> If you have any questions I'm happy to help.
>>>>>
>>>>> P.S. heres my github with some of my scripts. https://github.com/iz
>>>>> xle/VaspTools
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 2017-04-18 2:52 GMT-05:00 fabian via ase-users <
>>>>> ase-users at listserv.fysik.dtu.dk>:
>>>>>
>>>>>> Dear all,
>>>>>>
>>>>>> I want to perform a series of charge density difference calculations. Therefore i want to split the geometry optimised CONTCAR file
>>>>>> containing the coordinates from the slab and the Molecule into tow files containing only slab or Molecule coordinates. At the moment i am doing this
>>>>>> manually. Can someone give me a hint how to read positions and constraints as well as atom types from the POSCAR/CONTCAR files and later write them into two new POSCAR Files?
>>>>>> I would like to be able to either fix all atomic coordinates or leave the as they are.
>>>>>> Atom types could also be extracted from OUTCAR or POTCAR files. For now it is sufficient to perform the split based on the ATOM tag.
>>>>>> Unfortunately i am completely stuck.
>>>>>>
>>>>>> All the best
>>>>>>
>>>>>> fabian
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> ase-users mailing list
>>>>>> ase-users at listserv.fysik.dtu.dk
>>>>>> https://listserv.fysik.dtu.dk/mailman/listinfo/ase-users
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listserv.fysik.dtu.dk/pipermail/ase-users/attachments/20170503/e53ace98/attachment-0001.html>


More information about the ase-users mailing list