siman 1.2.4__tar.gz → 1.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {siman-1.2.4/siman.egg-info → siman-1.2.6}/PKG-INFO +1 -1
- {siman-1.2.4 → siman-1.2.6}/setup.py +1 -1
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/vasp.py +61 -31
- {siman-1.2.4 → siman-1.2.6}/siman/core/structure.py +50 -25
- {siman-1.2.4 → siman-1.2.6}/siman/geo.py +19 -6
- {siman-1.2.4 → siman-1.2.6/siman.egg-info}/PKG-INFO +1 -1
- {siman-1.2.4 → siman-1.2.6}/LICENSE +0 -0
- {siman-1.2.4 → siman-1.2.6}/MANIFEST.in +0 -0
- {siman-1.2.4 → siman-1.2.6}/README.md +0 -0
- {siman-1.2.4 → siman-1.2.6}/setup.cfg +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/3d_plot.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/SSHTools.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/analysis.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/analysis_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/analyze/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/analyze/segregation.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/approximation.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/bands.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calc_manage.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calcul.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/aims.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/gaussian.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/qe.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/calculators/vasp_old.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/chg/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/chg/chg_func.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/chg/vasputil_chgarith_module.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/classes.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/calculation.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/calculation_old.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/cluster_batch_script.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/cluster_run_script.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/core/molecule.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/database.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/default_project_conf.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/dev_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/dos_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/fit_hex.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/header.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/helper_for_writing_beatiful_code.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/impurity.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/inout.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/kpoints_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/mat_prop/__init__.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/mat_prop/mat_prop.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/matproj_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/monte.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/monte_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/neb.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/pairs.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/picture_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/plot_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/polaron.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/polaron_hop.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/polaron_mod.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/project_funcs.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/properties_2d.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/properties_energy.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/properties_lattice.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/set_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/simanrc.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/small_classes.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/small_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/structure_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/table_functions.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/thermo.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman/workflow_utilities.py +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman.egg-info/SOURCES.txt +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman.egg-info/dependency_links.txt +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman.egg-info/requires.txt +0 -0
- {siman-1.2.4 → siman-1.2.6}/siman.egg-info/top_level.txt +0 -0
|
@@ -487,13 +487,17 @@ class CalculationVasp(Calculation):
|
|
|
487
487
|
def actualize_set(self, curset = None, params = None):
|
|
488
488
|
"""
|
|
489
489
|
Makes additional processing of set parameters, which also depends on calculation
|
|
490
|
-
|
|
491
|
-
|
|
490
|
+
e.g. adding parameters for atat, etc.
|
|
491
|
+
|
|
492
|
+
INPUT:
|
|
493
|
+
|
|
494
|
+
- curset (str) - name of the current set
|
|
495
|
+
- params (dict) - dictionary with additional parameters from add_loop()
|
|
492
496
|
|
|
493
497
|
|
|
494
498
|
TODO:
|
|
495
499
|
|
|
496
|
-
if number is used after element, then it should be considered as separate type
|
|
500
|
+
if number is used after element, then it should be considered as a separate type
|
|
497
501
|
|
|
498
502
|
RETURN:
|
|
499
503
|
|
|
@@ -512,6 +516,9 @@ class CalculationVasp(Calculation):
|
|
|
512
516
|
#make element list
|
|
513
517
|
el_list = [element_name_inv(el) for el in self.init.znucl] # length is equal to number of elements
|
|
514
518
|
ldau = False
|
|
519
|
+
default_symprec = params.get('symprec') or 0.1
|
|
520
|
+
# print('default_symprec', default_symprec)
|
|
521
|
+
# default_symprec = 0.1
|
|
515
522
|
if 'LDAUL' in vp and vp['LDAUL'] is not None:
|
|
516
523
|
ldau = True
|
|
517
524
|
|
|
@@ -519,23 +526,27 @@ class CalculationVasp(Calculation):
|
|
|
519
526
|
'This block checks if more types for one element should be added to structure'
|
|
520
527
|
uels_set = vp['LDAUL'].keys()
|
|
521
528
|
# print(uels_set)
|
|
522
|
-
uels = [] # list of elements provided by set relevant for the given structure
|
|
529
|
+
uels = [] # list of elements provided by set relevant for the given structure depending on anion
|
|
523
530
|
uelntypat = {} # number of types for each element from the structure, for which U should be used
|
|
531
|
+
nslashes = 0
|
|
524
532
|
for el in set(el_list):
|
|
525
533
|
for el_set in uels_set:
|
|
534
|
+
if '/' in el_set:
|
|
535
|
+
nslashes+=1
|
|
526
536
|
if el == el_set.split('/')[0]: # after slash the required coordination is given.
|
|
527
537
|
uels.append(el_set)
|
|
528
538
|
if el not in uelntypat:
|
|
529
539
|
uelntypat[el] = 0
|
|
530
540
|
uelntypat[el] +=1
|
|
531
|
-
# print(uels, uelntypat)
|
|
541
|
+
# print('uels, uelntypat', uels, uelntypat)
|
|
542
|
+
# sys.exit()
|
|
532
543
|
anions_set = []
|
|
533
544
|
for el in uelntypat.keys(): #
|
|
534
545
|
if uelntypat[el] > 1: # this condition shows that multitype regime was asked for
|
|
535
546
|
printlog('LDAUL are given for the following multitype elements: ',uels, imp = 'y')
|
|
536
547
|
for el_set in uels:
|
|
537
548
|
if el in el_set and '/' not in el_set: # check that correct format is used
|
|
538
|
-
printlog('
|
|
549
|
+
printlog('Warning! Element', el, f'has several types. LDAUL values should be given in format {el}/A but mixture of {el}/A and {el} was detected. Please check that U are assigned as you intend')
|
|
539
550
|
#check that required anions are present
|
|
540
551
|
A = el_set.split('/')[1]
|
|
541
552
|
anions_set.append(A)
|
|
@@ -544,17 +555,17 @@ class CalculationVasp(Calculation):
|
|
|
544
555
|
printlog(f'Warning! Anion {A} is absent in your structure but present in your set')
|
|
545
556
|
|
|
546
557
|
printlog(f'Checking if more types for {el} should be added ... ', imp = 'y')
|
|
547
|
-
self.init, cords = self.init.add_types_for_el(el)
|
|
558
|
+
self.init, cords = self.init.add_types_for_el(el, symprec = default_symprec)
|
|
548
559
|
if len(cords) == 1:
|
|
549
|
-
printlog(f'
|
|
560
|
+
printlog(f'Warning! This structure has only one symmetry non-equivalent position for {el} and may be incompatible with the chosen set that have several definitions for {el}' )
|
|
550
561
|
|
|
551
|
-
if len(cords)
|
|
562
|
+
if len(cords) > uelntypat[el]:
|
|
552
563
|
# print( len(cords), uelntypat[el] )
|
|
553
|
-
printlog(f'
|
|
564
|
+
printlog(f'Warning! The number of non-equivalent position for {el} is {len(cords)}, which is more than the {uelntypat[el]} coordinations provided the chosen set' )
|
|
554
565
|
|
|
555
566
|
inter = list(set([item for sublist in cords for item in sublist]).intersection(set(anions_set)) )
|
|
556
567
|
if len(anions_set) != len(inter):
|
|
557
|
-
printlog('Warning!
|
|
568
|
+
printlog('Warning! Number of coordinations in your structure and provided LDAUL are different. This should not be a problem, but be carefull')
|
|
558
569
|
# sys.exit()
|
|
559
570
|
# for A in anions_set:
|
|
560
571
|
# for cord in cords:
|
|
@@ -562,37 +573,49 @@ class CalculationVasp(Calculation):
|
|
|
562
573
|
# if A in cords:
|
|
563
574
|
# break
|
|
564
575
|
# else:
|
|
576
|
+
|
|
577
|
+
if nslashes > 0:
|
|
578
|
+
el_list = self.init.get_unique_type_els(True, symprec = default_symprec) # new list of elements in M/A format for multielement regime
|
|
565
579
|
|
|
566
580
|
|
|
567
|
-
aniels = [invert(a) for a in header.ANION_ELEMENTS]
|
|
581
|
+
# aniels = [invert(a) for a in header.ANION_ELEMENTS]
|
|
568
582
|
# set(aniels)
|
|
569
|
-
nintersections = len(set(aniels).intersection(el_list))
|
|
583
|
+
# nintersections = len(set(aniels).intersection(el_list)) #
|
|
570
584
|
# print(nintersections, aniels, el_list)
|
|
571
585
|
|
|
572
|
-
el_list = self.init.get_unique_type_els(True) # new list after adding
|
|
573
|
-
# sys.exit()
|
|
574
586
|
|
|
587
|
+
# print(el_list)
|
|
588
|
+
# sys.exit()
|
|
575
589
|
for key in ['LDAUL', 'LDAUU', 'LDAUJ']:
|
|
576
590
|
# print( vp[key])
|
|
591
|
+
set_els = vp[key].keys()
|
|
592
|
+
# print(set_els)
|
|
593
|
+
|
|
577
594
|
try:
|
|
578
|
-
if set(
|
|
579
|
-
printlog('\n\n\
|
|
595
|
+
if set(set_els).isdisjoint(set(el_list)): #no common elements at all
|
|
596
|
+
printlog('\n\n\nWarning! The '+str(key)+f'={set_els} doesnt not contain explicit entries for any of your {set(el_list)} elements! Setting to zero or assigning implicitly\n\n\n')
|
|
580
597
|
# raise RuntimeError
|
|
581
598
|
|
|
582
599
|
new = []
|
|
583
600
|
for el in el_list:
|
|
584
601
|
|
|
602
|
+
el_bare = el.split('/')[0]
|
|
585
603
|
if el in vp[key]:
|
|
586
604
|
val = vp[key][el]
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
605
|
+
elif el_bare in vp[key]:
|
|
606
|
+
val = vp[key][el_bare]
|
|
607
|
+
printlog(f'Warning! I assign {key} of {el_bare} to {el}')
|
|
608
|
+
|
|
609
|
+
# print(aniels)
|
|
610
|
+
# sys.exit()
|
|
611
|
+
# for A in aniels:
|
|
612
|
+
# if A in el_list: # use another U value for other anions, provided like Fe/S - commented from April 1st 2023
|
|
613
|
+
# kk = el+'/'+A
|
|
614
|
+
# if kk in vp[key]:
|
|
615
|
+
# if nintersections == 1:
|
|
616
|
+
# val = vp[key][kk]
|
|
617
|
+
# else:
|
|
618
|
+
# printlog(f'Warning! The chosen structure has more than one anion. The given U values {el}/{A} will be used for all {el} atoms')
|
|
596
619
|
|
|
597
620
|
|
|
598
621
|
|
|
@@ -604,8 +627,10 @@ class CalculationVasp(Calculation):
|
|
|
604
627
|
val = -1
|
|
605
628
|
else:
|
|
606
629
|
val = 0
|
|
607
|
-
|
|
608
|
-
|
|
630
|
+
for set_el in set_els:
|
|
631
|
+
# print(el, set_el)
|
|
632
|
+
if el == set_el or el == set_el.split('/')[0]:
|
|
633
|
+
printlog(f'Warning! no value is given in {key} for element {el}')
|
|
609
634
|
|
|
610
635
|
new.append(val)
|
|
611
636
|
|
|
@@ -640,18 +665,23 @@ class CalculationVasp(Calculation):
|
|
|
640
665
|
# if ldau is true and multitype regime is true then everything is updated above
|
|
641
666
|
# if ldau is true and multitype is false than we cant use multitype here because LDAUL will become incompatible with POSCAR
|
|
642
667
|
self.init, cords = self.init.add_types_for_el(el.split('/')[0])
|
|
643
|
-
el_list = self.init.get_unique_type_els(True) # new list after adding
|
|
668
|
+
el_list = self.init.get_unique_type_els(True, symprec = default_symprec) # new list after adding
|
|
644
669
|
else:
|
|
645
670
|
''
|
|
646
671
|
|
|
647
672
|
for iat in range(self.init.natom):
|
|
648
673
|
typ = self.init.typat[iat]
|
|
649
674
|
el = el_list[typ-1]
|
|
675
|
+
el_bare = el.split('/')[0]
|
|
676
|
+
|
|
650
677
|
if el in curset.magnetic_moments:
|
|
651
678
|
magmom.append(curset.magnetic_moments[el])
|
|
679
|
+
elif el_bare in curset.magnetic_moments:
|
|
680
|
+
magmom.append(curset.magnetic_moments[el])
|
|
681
|
+
printlog(f'Warning! {el} was not found in your set, I use magmom={curset.magnetic_moments[el]} from {el_bare} for it')
|
|
652
682
|
else:
|
|
653
|
-
if '/' in el:
|
|
654
|
-
|
|
683
|
+
# if '/' in el:
|
|
684
|
+
printlog(f'{el} was not found in your set, I use magmom={mag_mom_other} for it', imp = 'n')
|
|
655
685
|
magmom.append(mag_mom_other)
|
|
656
686
|
|
|
657
687
|
|
|
@@ -375,16 +375,16 @@ class Structure():
|
|
|
375
375
|
return int(sum(zvals))
|
|
376
376
|
|
|
377
377
|
|
|
378
|
-
def determine_symmetry_positions(self,
|
|
378
|
+
def determine_symmetry_positions(self, *args, **kwargs):
|
|
379
379
|
from siman.geo import determine_symmetry_positions
|
|
380
380
|
|
|
381
|
-
return determine_symmetry_positions(self,
|
|
381
|
+
return determine_symmetry_positions(self, *args, **kwargs)
|
|
382
382
|
|
|
383
|
-
def get_symmetry_positions(self,
|
|
383
|
+
def get_symmetry_positions(self, *args, **kwargs):
|
|
384
384
|
#just another name
|
|
385
385
|
from siman.geo import determine_symmetry_positions
|
|
386
386
|
|
|
387
|
-
return determine_symmetry_positions(self,
|
|
387
|
+
return determine_symmetry_positions(self, *args, **kwargs)
|
|
388
388
|
|
|
389
389
|
|
|
390
390
|
def get_maglist(self):
|
|
@@ -2703,6 +2703,8 @@ class Structure():
|
|
|
2703
2703
|
RETURN
|
|
2704
2704
|
dict with the following keys:
|
|
2705
2705
|
'av(A-O,F)'
|
|
2706
|
+
'av' - average distance to surrounding atoms
|
|
2707
|
+
'el' - list of surrounding elements
|
|
2706
2708
|
'numbers'
|
|
2707
2709
|
'dist'
|
|
2708
2710
|
'xcart'
|
|
@@ -2788,8 +2790,9 @@ class Structure():
|
|
|
2788
2790
|
el = st.get_elements()
|
|
2789
2791
|
info['el'] = [el[i] for i in out_or[2]]
|
|
2790
2792
|
info['av(A-O,F)'] = local_surrounding(x, st, n, 'av', True, only_elements = [8,9], round_flag = 0)
|
|
2793
|
+
info['av'] = local_surrounding(x, st, n, 'av', True, round_flag = 0)
|
|
2791
2794
|
|
|
2792
|
-
print
|
|
2795
|
+
# print
|
|
2793
2796
|
|
|
2794
2797
|
if more_info:
|
|
2795
2798
|
info['avsq(A-O,F)'] = local_surrounding2(x, st, n, 'avsq', True, only_elements = [8,9])
|
|
@@ -3017,13 +3020,23 @@ class Structure():
|
|
|
3017
3020
|
|
|
3018
3021
|
def localize_polaron(self, i, d, nn = 6):
|
|
3019
3022
|
"""
|
|
3020
|
-
Localize small polaron at transition metal by adjusting TM-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3023
|
+
Localize small polaron at transition metal by adjusting TM-A distances
|
|
3024
|
+
|
|
3025
|
+
INPUT:
|
|
3026
|
+
- i (int) - number of transition atom, from 0
|
|
3027
|
+
- d (float) - shift in angstrom; positive increase TM-O, negative reduce TM-O distance
|
|
3028
|
+
- nn (int) - number of neigbours
|
|
3029
|
+
|
|
3030
|
+
RETURN:
|
|
3031
|
+
|
|
3032
|
+
- st (Structure) - structure with localized polaron at atom i
|
|
3033
|
+
|
|
3034
|
+
AUTHOR:
|
|
3035
|
+
|
|
3036
|
+
Aksyonov DA
|
|
3037
|
+
|
|
3024
3038
|
|
|
3025
3039
|
"""
|
|
3026
|
-
# nn
|
|
3027
3040
|
|
|
3028
3041
|
st = copy.deepcopy(self)
|
|
3029
3042
|
TM = st.get_el_z(i)
|
|
@@ -3034,11 +3047,17 @@ class Structure():
|
|
|
3034
3047
|
silent = 1
|
|
3035
3048
|
if 'n' in header.warnings or 'e' in header.warnings:
|
|
3036
3049
|
silent = 0
|
|
3037
|
-
# silent = 0
|
|
3038
3050
|
|
|
3051
|
+
dic = st.nn(i, nn, from_one = 0, silent = silent)
|
|
3052
|
+
els = dic['el'][1:]
|
|
3053
|
+
unique_neighbours_els = set(els)
|
|
3054
|
+
for A in unique_neighbours_els:
|
|
3055
|
+
z = invert(A)
|
|
3056
|
+
if z not in header.ANION_ELEMENTS:
|
|
3057
|
+
printlog('Warning! provided element ', z, 'is not an anion element, I hope you know what you are doing. ')
|
|
3039
3058
|
|
|
3040
|
-
|
|
3041
|
-
printlog('Average
|
|
3059
|
+
# print(els)
|
|
3060
|
+
printlog('Average '+TM_name+'-'+str(unique_neighbours_els)+' distance before localization is {:.2f} A'.format(dic['av']), imp = 'n')
|
|
3042
3061
|
|
|
3043
3062
|
#updated xcart
|
|
3044
3063
|
xc = st.xcart[i]
|
|
@@ -3058,8 +3077,8 @@ class Structure():
|
|
|
3058
3077
|
|
|
3059
3078
|
st.update_xred()
|
|
3060
3079
|
|
|
3061
|
-
dic = st.nn(i, nn, from_one = 0, silent = silent
|
|
3062
|
-
printlog('Average
|
|
3080
|
+
dic = st.nn(i, nn, from_one = 0, silent = silent)
|
|
3081
|
+
printlog('Average '+TM_name+'-'+str(unique_neighbours_els)+' distance after localization is {:.2f} A'.format(dic['av']), imp = 'n')
|
|
3063
3082
|
|
|
3064
3083
|
st.name+='pol'+str(i+1)
|
|
3065
3084
|
|
|
@@ -3285,13 +3304,16 @@ class Structure():
|
|
|
3285
3304
|
|
|
3286
3305
|
return st
|
|
3287
3306
|
|
|
3288
|
-
def get_coordination(self, el, silent = 1):
|
|
3307
|
+
def get_coordination(self, el, silent = 1, symprec = 0.1):
|
|
3289
3308
|
"""
|
|
3290
3309
|
Get coordination for atom *el* for all non-equivalent types
|
|
3291
3310
|
|
|
3292
3311
|
INPUT:
|
|
3293
3312
|
|
|
3294
3313
|
- el (str) - element name
|
|
3314
|
+
- silent (bool)
|
|
3315
|
+
- symprec (float) - tolerance for symmetry finding, here a more crude value of 0.1 is used
|
|
3316
|
+
|
|
3295
3317
|
|
|
3296
3318
|
|
|
3297
3319
|
RETURN:
|
|
@@ -3304,7 +3326,7 @@ class Structure():
|
|
|
3304
3326
|
"""
|
|
3305
3327
|
|
|
3306
3328
|
st = self
|
|
3307
|
-
numbers = st.determine_symmetry_positions(el, silent = 1)
|
|
3329
|
+
numbers = st.determine_symmetry_positions(el, silent = 1, symprec = symprec)
|
|
3308
3330
|
i = 1
|
|
3309
3331
|
els = st.get_elements()
|
|
3310
3332
|
coords = []
|
|
@@ -3318,7 +3340,7 @@ class Structure():
|
|
|
3318
3340
|
return coords
|
|
3319
3341
|
|
|
3320
3342
|
|
|
3321
|
-
def add_types_for_el(self, el):
|
|
3343
|
+
def add_types_for_el(self, el, symprec = None):
|
|
3322
3344
|
"""
|
|
3323
3345
|
Make several types for the same element. Needed to set different U and magnetic moments
|
|
3324
3346
|
Currently new types are created based on symmetry. New types are added at the end of typat list
|
|
@@ -3326,6 +3348,7 @@ class Structure():
|
|
|
3326
3348
|
INPUT:
|
|
3327
3349
|
|
|
3328
3350
|
- el (str) - element name for which new types should be created
|
|
3351
|
+
- symprec (float) - tolerance for symmetry finding, default is 0.01
|
|
3329
3352
|
|
|
3330
3353
|
RETURN:
|
|
3331
3354
|
|
|
@@ -3343,7 +3366,7 @@ class Structure():
|
|
|
3343
3366
|
|
|
3344
3367
|
st = self.copy()
|
|
3345
3368
|
|
|
3346
|
-
numbers = st.determine_symmetry_positions(el, silent = 1)
|
|
3369
|
+
numbers = st.determine_symmetry_positions(el, silent = 1, symprec = symprec)
|
|
3347
3370
|
ntn = len(numbers) # new number of types for el
|
|
3348
3371
|
z = invert(el)
|
|
3349
3372
|
ntc = st.znucl.count(z) #current number of types for el
|
|
@@ -3351,7 +3374,7 @@ class Structure():
|
|
|
3351
3374
|
# print(numbers)
|
|
3352
3375
|
nt_add = ntn-ntc
|
|
3353
3376
|
# coords = None
|
|
3354
|
-
coords = self.get_coordination(el, silent = 0)
|
|
3377
|
+
coords = self.get_coordination(el, silent = 0, symprec = symprec)
|
|
3355
3378
|
if nt_add > 0:
|
|
3356
3379
|
printlog('Current number of types=', ntc, 'is smaller than the number of non-equivalent positions=', ntn, '; Additional', nt_add, 'types will be added', imp = 'y')
|
|
3357
3380
|
|
|
@@ -3378,14 +3401,15 @@ class Structure():
|
|
|
3378
3401
|
|
|
3379
3402
|
|
|
3380
3403
|
|
|
3381
|
-
def get_unique_type_els(self, coordination = False):
|
|
3404
|
+
def get_unique_type_els(self, coordination = False, symprec = 0.1):
|
|
3382
3405
|
"""
|
|
3383
3406
|
Get list of unique type elements
|
|
3384
3407
|
|
|
3385
3408
|
INPUT:
|
|
3386
3409
|
|
|
3387
3410
|
- coordination (bool) - if true than the coordination of the element is given in format 'el/el_coord', where
|
|
3388
|
-
el_cood is the closest-lying coordinating element. It is done
|
|
3411
|
+
el_cood is the closest-lying coordinating element. It is done for all elements
|
|
3412
|
+
- symprec (float) - tolerance for symmetry finding, here a more crude symprec of 0.1 is used
|
|
3389
3413
|
|
|
3390
3414
|
RETURN:
|
|
3391
3415
|
|
|
@@ -3403,13 +3427,14 @@ class Structure():
|
|
|
3403
3427
|
|
|
3404
3428
|
els_typen = {}
|
|
3405
3429
|
|
|
3430
|
+
els_typec = els_type.copy()
|
|
3406
3431
|
if coordination:
|
|
3407
|
-
els_typec = els_type.copy()
|
|
3408
3432
|
for i, el in enumerate(els_type):
|
|
3409
|
-
if els_type.count(el) > 1:
|
|
3433
|
+
# if els_type.count(el) > 1:
|
|
3434
|
+
if True: # now for all elements it is given in the form el/A
|
|
3410
3435
|
if el not in els_typen:
|
|
3411
3436
|
els_typen[el] = 0
|
|
3412
|
-
coords = self.get_coordination(el, silent = 1)
|
|
3437
|
+
coords = self.get_coordination(el, silent = 1, symprec = symprec)
|
|
3413
3438
|
coord_el = coords[els_typen[el]][0] #currently only first element is used
|
|
3414
3439
|
els_typec[i] = els_type[i]+f'/{coord_el}'
|
|
3415
3440
|
els_typen[el] +=1
|
|
@@ -1147,21 +1147,34 @@ def cubic_supercell(st, ortho_sizes):
|
|
|
1147
1147
|
return create_supercell(st, mul_matrix)
|
|
1148
1148
|
|
|
1149
1149
|
|
|
1150
|
-
def determine_symmetry_positions(st, element, silent = 0):
|
|
1150
|
+
def determine_symmetry_positions(st, element, silent = 0, symprec = 0.01, angle_tolerance = 5.0):
|
|
1151
1151
|
"""
|
|
1152
|
-
|
|
1152
|
+
Determine non-equivalent positions for atoms of type *element* using pymatgen library
|
|
1153
1153
|
|
|
1154
|
-
|
|
1154
|
+
INPUT:
|
|
1155
|
+
|
|
1156
|
+
- st (Structure)
|
|
1157
|
+
- element (str) - name of element, for example Li
|
|
1158
|
+
- silent (bool)
|
|
1159
|
+
- symprec (float) - tolerance for symmetry finding
|
|
1160
|
+
- angle_tolerance - Angle tolerance for symmetry finding
|
|
1161
|
+
|
|
1162
|
+
RETURN:
|
|
1163
|
+
|
|
1164
|
+
- list of lists - atom numbers for each non-equivalent position
|
|
1155
1165
|
|
|
1156
|
-
|
|
1166
|
+
AUTHOR:
|
|
1167
|
+
|
|
1168
|
+
D. Aksyonov
|
|
1157
1169
|
"""
|
|
1158
1170
|
|
|
1159
1171
|
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
|
|
1160
1172
|
|
|
1161
1173
|
|
|
1162
1174
|
stp = st.convert2pymatgen()
|
|
1163
|
-
|
|
1164
|
-
|
|
1175
|
+
# print(st, symprec, angle_tolerance)
|
|
1176
|
+
# sys.exit()
|
|
1177
|
+
spg = SpacegroupAnalyzer(stp, symprec, angle_tolerance)
|
|
1165
1178
|
|
|
1166
1179
|
info = spg.get_symmetry_dataset()
|
|
1167
1180
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|