[ase-users] Split POSCAR/CONTCAR files

fabian Fabian.T89 at web.de
Thu May 4 09:25:40 CEST 2017


Dear Oscar,

Thank you for your reply! It is really appreciated.
I included your solution into my code:

from  ase.ioimport  read,  write
from  ase.atomsimport  Atoms
from  ase.constraintsimport  FixAtoms


atoms=  read('CONTCAR')

write('POSCAR_slab_molecule',  atoms,  vasp5=True,  sort=True,  direct=True,long_format=True,  format='vasp')
# Specify the Atoms in the slab!
slab_elms=  ['Cu',  'O']  # assuming the adsorbate has no Cu and O

slab_i=  [a.indexfor  ain  atomsif  a.symbolin  slab_elms]
ads_i=  [a.indexfor  ain  atomsif  a.symbolnot  in  slab_elms]

# Use Atoms
slab=  Atoms([afor  ain  atomsif  a.indexin  slab_i])
ads=  Atoms([afor  ain  atomsif  a.indexin  ads_i])
cell=  atoms.get_cell()
slab.set_cell(cell)
ads.set_cell(cell)

# read constraints
fixed_atoms_i=  atoms.contraints[0].index
fix_mask=  {'ads':  [],  'slab':  []}
for  ain  atoms:
     is_fixed=  a.indexin  fixed_atoms_i
     key=  'ads'  if  a.indexin  ads_ielse  '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)


# write

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')

But i still get an error:

*T**raceback (most recent call last):**
**  File "SPLIT_CONTCAR_V6.py", line 23, in <module>**
**    fixed_atoms_i = atoms.contraints[0].index**
**AttributeError: 'Atoms' object has no attribute 'contraints'*

I am running and older Version of ASE ( 3.9.1.4567) . Might this be a 
problem? The package is installed on a windows machine and i am a little 
reluctant to ask the admin to
update it, as i was told it is complicated to install it under Win7.  Is 
there a Tutorial available how to uninstall ASE and reinstall the newest 
Version available under Windows?

Thank you very much for you support!

all the best

Fabian


Am 03.05.2017 um 16:16 schrieb Oscar Xavier Guerrero:
> 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 <mailto: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
>     <mailto: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, write from ase.atoms import Atoms
>         from 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.indexfor  ain  atomsif  a.symbolin  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
>>         <mailto: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
>>>             <mailto: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 lineslab_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 bestfabian
>>>                 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 <http://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
>>>>                 <mailto: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 <http://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/izxle/VaspTools
>>>>                     <https://github.com/izxle/VaspTools>
>>>>                     2017-04-18 2:52 GMT-05:00 fabian via ase-users
>>>>                     <ase-users at listserv.fysik.dtu.dk
>>>>                     <mailto: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
>>>>                         <mailto:ase-users at listserv.fysik.dtu.dk>
>>>>                         https://listserv.fysik.dtu.dk/mailman/listinfo/ase-users
>>>>                         <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/20170504/2c52be02/attachment-0001.html>


More information about the ase-users mailing list