[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