Input and Basis Set Generation

CRYSTALpytools provides a branch of methods to prepare input files and basis sets interactively. They are kept in the crystal_io module.

‘crystal_io.Crystal_input’ class

NOTE

Though developers are working hard to implement all the keywords, due to the limit of time and developing forces, not all keywords has been implemented. Please confirm that in module-specific documentations or contact developers via GitHub.

Basic file generation

The Crystal_input class accepts keywords and prepare input files for ‘crystal’ calculations of CRYSTAL package. The user can create a crystal input object by directly calling the methods. Both the name and format of methods are consistent with CRYSTAL keywords. The text input in ‘d12’ format is accessible by calling the data property.

[1]:
from CRYSTALpytools.crystal_io import Crystal_input

mgo_input = Crystal_input()
mgo_input.geom.title('MGO BULK - GEOMETRY TEST')
mgo_input.geom.crystal(225, # Space group
                      [4.217], # Minimal set of lattice parameters
                      [[12, 0., 0., 0.], # Atomic labels and coordinates
                       [8, 0.5, 0.5, 0.5]]
                      )
mgo_input.basisset.basisset('POB-DZVP')
mgo_input.scf.dft.xcfunc('B3LYP')
mgo_input.scf.dft.xxlgrid()
mgo_input.scf.tolinteg(7, 7, 7, 7, 14)
mgo_input.scf.shrink(12, 24)
mgo_input.scf.maxcycle(70)
mgo_input.scf.fmixing(70)
mgo_input.scf.diis()

print(mgo_input.data)
MGO BULK - GEOMETRY TEST
CRYSTAL
0   0   0
225
4.217000
2
12     0.00000000   0.00000000   0.00000000
8      0.50000000   0.50000000   0.50000000
BASISSET
POB-DZVP
DFT
B3LYP
XXLGRID
ENDDFT
MAXCYCLE
70
SHRINK
12 24
TOLINTEG
7 7 7 7 14
FMIXING
70
DIIS
ENDSCF

Of course the previous example might look cumbersome. The Crystal_input objects can be generated by ‘block’ texts. ‘Block’ is a multiple-line string closed by the ‘END’ keyword. 3 basic blocks are defined in CRYSTAL d12 format: geometry, basis set and SCF. There are sub-blocks in the 3 major blocks that can be defined in a similar way by calling corresponding keywords. Also the whole file is recognized as a block.

[2]:
geom_block = \
"""MGO BULK - GEOMETRY TEST
CRYSTAL
0 0 0
225
4.217
2
12 0.    0.    0.
8 0.5   0.5   0.5
ENDGEOM
"""

bs_block   = \
"""BASISSET
POB-DZVP
"""
func_block = \
"""DFT
B3LYP
XXLGRID
ENDDFT
"""
scf_block  = \
"""TOLINTEG
7 7 7 7 14
SHRINK
12 24
MAXCYCLE
200
FMIXING
70
DIIS
ENDSCF
"""
mgo_input = Crystal_input()
mgo_input.geom(geom_block)
mgo_input.basisset(bs_block)
mgo_input.scf(scf_block)
mgo_input.scf.dft(func_block) # DFT is a sub-block of SCF block
print(mgo_input.data)
MGO BULK - GEOMETRY TEST
CRYSTAL
0 0 0
225
4.217
2
12 0.    0.    0.
8 0.5   0.5   0.5
BASISSET
POB-DZVP
DFT
B3LYP
XXLGRID
ENDDFT
MAXCYCLE
200
SHRINK
12 24
TOLINTEG
7 7 7 7 14
FMIXING
70
DIIS
ENDSCF

To set value for keywords (not closed by ‘END’), use obj.keyword(value). 3 types of input parameters are allowed.

  1. Normal input: Depending on the requirements of the keyword

  2. Empty: Print the keyword only

  3. ‘None’: Clean the entry and the keyword.

A warning message is printed because the newly added ‘NODIIS’ conflicts with the original ‘DIIS’ keyword. The old entry is removed.

[3]:
mgo_input.scf.fmixing(30) # edit FMIXING keyword
mgo_input.scf.maxcycle(None) # remove MAXCYCLE keyword
mgo_input.scf.nodiis() # add NODIIS keyword
print(mgo_input.scf.data)
DFT
B3LYP
XXLGRID
ENDDFT
SHRINK
12 24
TOLINTEG
7 7 7 7 14
FMIXING
30
NODIIS
ENDSCF

/home/huanyu/apps/anaconda3/envs/crystal_py3.9/lib/python3.9/site-packages/CRYSTALpytools/base/crysd12.py:1231: UserWarning: 'NODIIS' conflicts with the existing 'DIIS'. The old one is deleted.
  super().assign_keyword('NODIIS', [], nodiis); return self

The user can also use an existing file as a template. In a similar way one can change, delete and substitute keywords. Here a ‘keyword-only’ OPTGEOM block is defined.

[4]:
mgo_opt = Crystal_input('crysinp_mgo.d12')
mgo_opt.geom.optgeom()
print(mgo_opt.geom.data)
MGO BULK - GEOMETRY TEST
CRYSTAL
0 0 0
225
4.217
2
12 0.    0.    0.
8 0.5   0.5   0.5
OPTGEOM
ENDOPT
ENDGEOM

Sub-blocks can be automatically added by calling keywords defined within. The object can also be instantiated by calling the classmethod read_file().

[5]:
mgo_opt = Crystal_input.read_file('crysinp_mgo.d12')
mgo_opt.geom.title('Generated by CRYSTALpytools')
mgo_opt.geom.optgeom.toldex(0.0012)
mgo_opt.geom.optgeom.toldeg(0.0003)
print(mgo_opt.geom.data)
Generated by CRYSTALpytools
CRYSTAL
0 0 0
225
4.217
2
12 0.    0.    0.
8 0.5   0.5   0.5
OPTGEOM
TOLDEG
0.0003
TOLDEX
0.0012
ENDOPT
ENDGEOM

Eventually an input file can be written.

[6]:
mgo_opt.write_file('crysinp_mgo_opt.d12')
[6]:
<CRYSTALpytools.crystal_io.Crystal_input at 0x7fdb6d111370>

Set geometry

Geometry input can be set by a CIF file or a pymatgen structure when needed. There are 2 available options:

  1. Set keyword='EXTERNAL' (default) and Crystal_input object automatically convert the geometry entry to a gui file with default settings. Recommended.

[7]:
para = Crystal_input().geom_from_cif('crysinp_para.cif',
                                     gui_name='crysinp_para.gui')
print(para.geom.data)
Generated by CRYSTALpytools
EXTERNAL
ENDGEOM

/home/huanyu/apps/anaconda3/envs/crystal_py3.9/lib/python3.9/site-packages/pymatgen/io/cif.py:1287: UserWarning: Issues encountered while parsing CIF: Skipping relative stoichiometry check because CIF does not contain formula keys.
  warnings.warn("Issues encountered while parsing CIF: " + "\n".join(self.warnings))
  1. Set keyword=CRYSTAL, the input block will be automatically generated. 3D structures only.

[8]:
para = Crystal_input().geom_from_cif('crysinp_para.cif',
                                     keyword='CRYSTAL')
print(para.geom.data)
Generated by CRYSTALpytools
CRYSTAL
0   0   0
14
7.073000     9.166000     12.667000    115.510000
20
1      0.37160000   0.92980000   0.49880000
1      0.24220000   0.76340000   0.33040000
1      0.77660000   0.60000000   0.43090000
1      0.90770000   0.76640000   0.60050000
1      0.79990000   0.53530000   0.25760000
1      0.10820000   0.95930000   0.69510000
1      0.56840000   0.08530000   0.89610000
1      0.29390000   0.07980000   0.85010000
1      0.40860000   0.21910000   0.80230000
6      0.14960000   0.85790000   0.56187000
6      0.24320000   0.85758000   0.48526000
6      0.17040000   0.76206000   0.39004000
6      0.00430000   0.66838000   0.37078000
6      0.90790000   0.67092000   0.44601000
6      0.98060000   0.76560000   0.54106000
6      0.39830000   0.01599000   0.71975000
6      0.41680000   0.10369000   0.82440000
7      0.21229000   0.94984000   0.66089000
8      0.94130000   0.57511000   0.27811000
8      0.54450000   0.00741000   0.69146000
ENDGEOM

It should be noted that sequences of atoms of the input geometry are different from d12 blocks. The coordinates might also change during the standarization of unit cell. In ordinary scenarios it would not affect the outcomes.

However, extra care must be taken when conventional atomic numbers are set (i.e., when using peudopotentials or different basis sets for the same element). Though zconv can be set for geom_from_cif() and geom_from_pmg() methods, they are not recommended unless the user is very sure about the output indices of atoms with conventional atomic numbers. The developers are working actively for better solutions.

Set basis set

The user can set basis set by string (as shown before), a text file or downloading it from Basis Set Exchange (BSE). Besides, a built-in BS can be called by keyword ‘BASISSET’.

To download BSs from BSE, the name of basis set and conventional atomic numbers of elements are needed.

Note

In BSE, the charge information is missing. A neutral atom is always assumed by default, which works well in most cases. To modify the initial charge guess, see below.

Automatic assignment of charges is available only for all-electron BSs.

Call the wrapper method bs_user(), which is equivalent to basisset.from_bse(). The downloaded BS is written as user-defined basis sets.

[9]:
mgo_input = Crystal_input.read_file('crysinp_mgo.d12')

mgo_input.bs_user('6-31G*', z=[12, 8])
print(mgo_input.basisset.data)
12 5
0 0 6 2.00 1.00
  11722.8000000000      0.0019778293
   1759.9300000000      0.0151139948
    400.8460000000      0.0739107745
    112.8070000000      0.2491909140
     35.9997000000      0.4879278316
     12.1828000000      0.3196618896
0 1 6 8.00 1.00
    189.1800000000     -0.0032371705      0.0049281299
     45.2119000000     -0.0410079060      0.0349887994
     14.3563000000     -0.1126000164      0.1407249977
      5.1388600000      0.1486330216      0.3336419947
      1.9065200000      0.6164970898      0.4449399929
      0.7058870000      0.3648290531      0.2692539957
0 1 3 2.00 1.00
      0.9293400000     -0.2122908985     -0.0224191812
      0.2690350000     -0.1079854570      0.1922708390
      0.1173790000      1.1758449770      0.8461802916
0 1 1 0.00 1.00
      0.0421061000      1.0000000000      1.0000000000
0 3 1 0.00 1.00
      0.1750000000      1.0000000000
8 4
0 0 6 2.00 1.00
   5484.6716600000      0.0018310744
    825.2349460000      0.0139501722
    188.0469580000      0.0684450781
     52.9645000000      0.2327143360
     16.8975704000      0.4701928980
      5.7996353400      0.3585208530
0 1 3 6.00 1.00
     15.5396162500     -0.1107775495      0.0708742682
      3.5999335860     -0.1480262627      0.3397528391
      1.0137617500      1.1307670150      0.7271585773
0 1 1 0.00 1.00
      0.2700058226      1.0000000000      1.0000000000
0 3 1 0.00 1.00
      0.8000000000      1.0000000000
99 0
ENDBS

The same method can be used to interprete basis set files, equivalent to the basisset.from_file() method. Format string is consistent with BSE python API.

[10]:
mgo_input.bs_user('bs_mgo.gbs', fmt='gaussian94')
print(mgo_input.basisset.data)
8 2
0 0 3 2.00 1.00
    130.7093214000      0.1543289673
     23.8088660500      0.5353281423
      6.4436083130      0.4446345422
0 1 3 6.00 1.00
      5.0331513190     -0.0999672292      0.1559162750
      1.1695961250      0.3995128261      0.6076837186
      0.3803889600      0.7001154689      0.3919573931
12 3
0 0 3 2.00 1.00
    299.2374137000      0.1543289673
     54.5064684500      0.5353281423
     14.7515775200      0.4446345422
0 1 3 8.00 1.00
     15.1218235200     -0.0999672292      0.1559162750
      3.5139865790      0.3995128261      0.6076837186
      1.1428574980      0.7001154689      0.3919573931
0 1 3 2.00 1.00
      1.3954482930     -0.2196203690      0.0105876043
      0.3893265318      0.2255954336      0.5951670053
      0.1523797659      0.9003984260      0.4620010120
99 0
ENDBS

In some rare cases, the user might want to change the charge of BS shells to get ions and a better initial guess of charge density. A dictionary is used to define the charge.

  • Key: Conventional atomic number

  • Value: nshell*1 list of charges. Must be consistent with BS definitions.

Define Mg\(^{2+}\) and O\(^{2-}\) ions:

[11]:
chg = {8  : [2.0, 8.0],
       12 : [2.0, 8.0, 0.0]}
mgo_input.bs_user('bs_mgo.gbs', fmt='gaussian94', charge=chg)
print(mgo_input.basisset.data)
8 2
0 0 3 2.00 1.00
    130.7093214000      0.1543289673
     23.8088660500      0.5353281423
      6.4436083130      0.4446345422
0 1 3 8.00 1.00
      5.0331513190     -0.0999672292      0.1559162750
      1.1695961250      0.3995128261      0.6076837186
      0.3803889600      0.7001154689      0.3919573931
12 3
0 0 3 2.00 1.00
    299.2374137000      0.1543289673
     54.5064684500      0.5353281423
     14.7515775200      0.4446345422
0 1 3 8.00 1.00
     15.1218235200     -0.0999672292      0.1559162750
      3.5139865790      0.3995128261      0.6076837186
      1.1428574980      0.7001154689      0.3919573931
0 1 3 0.00 1.00
      1.3954482930     -0.2196203690      0.0105876043
      0.3893265318      0.2255954336      0.5951670053
      0.1523797659      0.9003984260      0.4620010120
99 0
ENDBS

Convert the Gaussian-formatted basis set collection and write them into the external ‘crysinp_BASISSETS.DAT’ file in CRYSTAL format, with the title ‘STO-3G from BSE’.

[12]:
chg = {8  : [2.0, 8.0],
       12 : [2.0, 8.0, 0.0]}
mgo_input.bs_user('bs_mgo.gbs', fmt='gaussian94', charge=chg,
                  BSfile='crysinp_BASISSETS.DAT', title='STO-3G from BSE')
[12]:
<CRYSTALpytools.crystal_io.Crystal_input at 0x7fdbc938ff70>

The input keywords are changed accordingly.

[13]:
print(mgo_input.basisset.data)
BASISSET
STO-3G from BSE

Similarly, effective core pseudopotential can be defined. The automatic charge assignment of atomic charge is also available for ECP BSs.

Defining BaO basis set with Stuttgart ECP (Only Ba, O is not supported in CRYSTAL and causes error). Use append=True to attach new entries.

[14]:
bao_input = Crystal_input()
bao_input.bs_user('Stuttgart RSC 1997', z=[356],
                  ECP={356 : 'STUTSC'})
bao_input.bs_user('6-31G*', z=[8], append=True)
print(bao_input.basisset.data)
356 11
STUTSC
0 0 3 2.00 1.00
      2.3961900000     -5.9288950000
      2.2433050000      6.6469340000
      0.7174020000     -0.5514370000
0 0 1 2.00 1.00
      0.2784460000      1.0000000000
0 0 1 0.00 1.00
      0.0431880000      1.0000000000
0 0 1 0.00 1.00
      0.0197980000      1.0000000000
0 2 3 6.00 1.00
      2.9267420000      0.7633590000
      2.5207180000     -1.0220140000
      0.5240950000      0.6498360000
0 2 1 0.00 1.00
      0.2034280000      1.0000000000
0 2 1 0.00 1.00
      0.0479960000      1.0000000000
0 2 1 0.00 1.00
      0.0200950000      1.0000000000
0 3 3 0.00 1.00
      0.9663150000     -0.9089380000
      0.8938280000      0.9472400000
      0.2731950000      0.3220570000
0 3 2 0.00 1.00
      0.1038910000      0.4732600000
      0.0355780000      0.3659770000
0 4 1 0.00 1.00
      0.6970000000      1.0000000000
8 4
0 0 6 2.00 1.00
   5484.6716600000      0.0018310744
    825.2349460000      0.0139501722
    188.0469580000      0.0684450781
     52.9645000000      0.2327143360
     16.8975704000      0.4701928980
      5.7996353400      0.3585208530
0 1 3 6.00 1.00
     15.5396162500     -0.1107775495      0.0708742682
      3.5999335860     -0.1480262627      0.3397528391
      1.0137617500      1.1307670150      0.7271585773
0 1 1 0.00 1.00
      0.2700058226      1.0000000000      1.0000000000
0 3 1 0.00 1.00
      0.8000000000      1.0000000000
99 0
ENDBS

To set conventional atomic numbers for basis sets, the user can use bs_user() twice with append=True. Here a ‘def2-SVP’ basis set is defined for H atom with atomic number 101.

[15]:
obj = Crystal_input()
obj.bs_user('6-31G*', [6, 1])
obj.bs_user('def2-SVP', [101], append=True)
print(obj.basisset.data)
6 4
0 0 6 2.00 1.00
   3047.5248800000      0.0018347371
    457.3695180000      0.0140373228
    103.9486850000      0.0688426223
     29.2101553000      0.2321844432
      9.2866629600      0.4679413484
      3.1639269600      0.3623119853
0 1 3 4.00 1.00
      7.8682723500     -0.1193324198      0.0689990666
      1.8812885400     -0.1608541517      0.3164239610
      0.5442492580      1.1434564380      0.7443082909
0 1 1 0.00 1.00
      0.1687144782      1.0000000000      1.0000000000
0 3 1 0.00 1.00
      0.8000000000      1.0000000000
1 2
0 0 3 1.00 1.00
     18.7311369600      0.0334946043
      2.8253943650      0.2347269535
      0.6401216923      0.8137573261
0 0 1 0.00 1.00
      0.1612777588      1.0000000000
101 3
0 0 3 1.00 1.00
     13.0107010000      0.0196821580
      1.9622572000      0.1379652400
      0.4445379600      0.4783193500
0 0 1 0.00 1.00
      0.1219496200      1.0000000000
0 2 1 0.00 1.00
      0.8000000000      1.0000000000
99 0
ENDBS

In principle, to use ‘BASISSET’ keyword, the basisset.basisset() should be called. A shortcut bs_keyword is added. A warning message is triggered because of the old definition of basis sets.

[16]:
mgo_input = Crystal_input.read_file('crysinp_mgo.d12')
mgo_input.bs_keyword('pob-DZVP')
print(mgo_input.data)
MGO BULK - GEOMETRY TEST
CRYSTAL
0 0 0
225
4.217
2
12 0.    0.    0.
8 0.5   0.5   0.5
BASISSET
pob-DZVP
DFT
B3LYP
XXLGRID
ENDDFT
MAXCYCLE
200
SHRINK
12 24
TOLINTEG
7 7 7 7 14
FMIXING
70
DIIS
ENDSCF

/home/huanyu/apps/anaconda3/envs/crystal_py3.9/lib/python3.9/site-packages/CRYSTALpytools/crystal_io.py:229: UserWarning: User's definition of baisis set is not empty. It will be covered by 'BASISSET' keyword.
  self.basisset.basisset(keyword)

‘crystal_io.Properties_input’ class

NOTE

Though developers are working hard to implement all the keywords, due to the limit of time and developing forces, not all keywords has been implemented. Please confirm that in module-specific documentations or contact developers via GitHub.

Basic file generation

The Properties_input class is developed in a similar style as the Crystal_input class. It prepares input ‘d3’ files for ‘properties’ calculations of CRYSTAL package.

An instance is generated by manually calling keywords ‘NEWK’, ‘ECHG’, ‘DOSS’ and ‘BAND’ for charge density, DOS and band calculations. As pointed out in CRYSTAL user manual, ‘BAND’ must be put before ‘NEWK’, while in the following code, newk() is called first. The generated output automatically corrects this issue.

[17]:
from CRYSTALpytools.crystal_io import Properties_input

inp = Properties_input()
# NEWK
inp.newk(12, 24, 1, 0)
# ECHG
inp.echg(0, 95) # N point of MAPNET set to 95. Default 100
inp.echg.coordina([-4., -4., 0.], [4, -4, 0.], [4., 4., 0.])
inp.echg.margins(1.5, 1.5, 1.5, 1.5)
inp.echg.rectangu()
# DOSS
inp.doss(0, 600, 203, 224, 1, 12, 0)
# BAND
inp.band('Band structure', 3, 4, 200, 1, 26, 1, 0,
         [[[0, 0, 0], [2, 0, 0]],
          [[2, 0, 0], [2, 2, 2]],
          [[2, 2, 2], [1, 0, 2]]])

# Write the input
inp.write_file('propinp_1.d3')
[17]:
<CRYSTALpytools.crystal_io.Properties_input at 0x7fdb64540910>

The Properties_input class can be instantiated from file or text in the same way as Crystal_input. Please refer to the examples above.

‘make_band_block’ short cut method

It is a shortcut method parameterized for quick generations of band structure block. It accepts either list definition or pymatgen HighSymmKpath object.

The following example shows how to prepare band structure plot from geometry optimization output of diamond.

[18]:
from pymatgen.symmetry.bandstructure import HighSymmKpath
from CRYSTALpytools.crystal_io import Crystal_output, Properties_input

dia = Crystal_output('propinp_diamondcrys.out').get_geometry(initial=False)
k_path = HighSymmKpath(dia.get_pcel([[-1, 1, 1], [1, -1, 1], [1, 1, -1]]))

inp = Properties_input().make_band_block(k_path, 200, 1, 26)
print(inp.data)
BAND
BAND STRUCTURE CALCULATION
10 8 200 1 26 1 0
0  0  0    4  0  4
4  0  4    4  2  6
4  2  6    3  3  6
3  3  6    0  0  0
0  0  0    4  4  4
4  4  4    5  2  5
5  2  5    4  2  6
4  2  6    4  4  4
4  4  4    3  3  6
3  3  6    5  2  5
END

‘make_doss_block’ shortcut method

make_doss_block is also a shortcut method with parameters set. It allows specification of projected elements with projections entry, when output file of ‘crystal’ calculation is available. Useful for big systems.

[19]:
inp = Properties_input()

inp.newk(12, 24, 1, 0)
inp.make_doss_block(band_range=[1, 26], projections=['O'],
                    output_file='propinp_Mg2O2crys.out')
print(inp.data)
NEWK
12 24
1 0
DOSS
1 200 1 26 2 12 1
-4 3 4 5 6
END

Advanced: Repeated keywords and ‘append’ property

Both Crystal_input and Properties_input classes are inherited from the same BlockBASE object defined in ‘base.inputbase’ script. Keywords are protected by block objects and repeating the same keyword in the same block overwrites the previous entry. Therefore, in principle, all the keywords should appear only once in the same block.

So far as the developers have been aware of, that causes 2 issues:

  1. In Crystal_input.geom block, the keyword ‘MOLECULE’ refers to both the modelling keyword for 0D systems and editing keyword to substracte molecules from molecular crystal. The method of the latter one should be called as molecule2() but the original keyword is recognized for file I/O.

[20]:
from CRYSTALpytools.crystal_io import Crystal_input

inp = Crystal_input().geom_from_cif('crysinp_para.cif', keyword='CRYSTAL')
inp.geom.atomorde()
inp.geom.molecule2(1, [[1 ,0, 0, 0]])
inp.write_file('adv_molecule2.d12')

inp = Crystal_input.read_file('adv_molecule2.d12')
inp.geom.molecule2(None)
print(inp.geom.data)
Generated by CRYSTALpytools
CRYSTAL
0   0   0
14
7.073000     9.166000     12.667000    115.510000
20
1      0.37160000   0.92980000   0.49880000
1      0.24220000   0.76340000   0.33040000
1      0.77660000   0.60000000   0.43090000
1      0.90770000   0.76640000   0.60050000
1      0.79990000   0.53530000   0.25760000
1      0.10820000   0.95930000   0.69510000
1      0.56840000   0.08530000   0.89610000
1      0.29390000   0.07980000   0.85010000
1      0.40860000   0.21910000   0.80230000
6      0.14960000   0.85790000   0.56187000
6      0.24320000   0.85758000   0.48526000
6      0.17040000   0.76206000   0.39004000
6      0.00430000   0.66838000   0.37078000
6      0.90790000   0.67092000   0.44601000
6      0.98060000   0.76560000   0.54106000
6      0.39830000   0.01599000   0.71975000
6      0.41680000   0.10369000   0.82440000
7      0.21229000   0.94984000   0.66089000
8      0.94130000   0.57511000   0.27811000
8      0.54450000   0.00741000   0.69146000
ATOMORDE
ENDGEOM

/home/huanyu/apps/anaconda3/envs/crystal_py3.9/lib/python3.9/site-packages/pymatgen/io/cif.py:1287: UserWarning: Issues encountered while parsing CIF: Skipping relative stoichiometry check because CIF does not contain formula keys.
  warnings.warn("Issues encountered while parsing CIF: " + "\n".join(self.warnings))
  1. For charge difference maps, ‘ECHG’ keyword is defined twice to get charge differences. The user can run 2 separate calculations and call electronics.ChargeDensity class to get difference maps, or define then Properties_input object with ‘append’ subblocks, which can be set just as Properties_input objects. The Properties_input object allows 5 ‘append’ blocks, i.e., append1 to append5.

[21]:
from CRYSTALpytools.crystal_io import Properties_input

inp = Properties_input()
inp.echg(0, 100)
inp.echg.coordina([-4., -4., 0.], [4, -4, 0.], [4., 4., 0.])
inp.echg.margins(1.5, 1.5, 1.5, 1.5)
inp.echg.rectangu()

inp.append1.pato(0, 0)
inp.append1.echg(0, 100)
inp.append1.echg.coordina([-4., -4., 0.], [4, -4, 0.], [4., 4., 0.])
inp.append1.echg.margins(1.5, 1.5, 1.5, 1.5)
inp.append1.echg.rectangu()

inp.write_file('adv_dCHG.d3')
print(inp.data)
ECHG
0
100
COORDINA
-4.000000 -4.000000  0.000000
 4.000000 -4.000000  0.000000
 4.000000  4.000000  0.000000
RECTANGU
MARGINS
1.5 1.5 1.5 1.5
END
PATO
0 0
ECHG
0
100
COORDINA
-4.000000 -4.000000  0.000000
 4.000000 -4.000000  0.000000
 4.000000  4.000000  0.000000
RECTANGU
MARGINS
1.5 1.5 1.5 1.5
END
END

For more details, please refer to the API documentations and the developer’s documentation of InputBASE, Crystal_inputBASE and Properties_inputBASE classes. For more information about basis sets, also check the Basis Set: Advanced example book.