Skip to content

Commit 339fb11

Browse files
committed
add annotations
1 parent cd4c43d commit 339fb11

File tree

1 file changed

+215
-1
lines changed

1 file changed

+215
-1
lines changed

source/module_hamilt_general/module_vdw/dftd3_xc_name.h

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,218 @@ namespace DFTD3 {
345345
}
346346
return xcname;
347347
}
348-
}
348+
}
349+
350+
/**
351+
import os
352+
import re
353+
def read_xc_func_h(fn):
354+
with open(fn) as f:
355+
lines = f.readlines()
356+
out = {}
357+
for line in lines:
358+
words = line.strip().split()
359+
xc, xcid = words[1], int(words[2])
360+
xc_annos = ' '.join(words[4:-1])
361+
out[xc] = {'id': xcid, 'annos': xc_annos}
362+
return out
363+
364+
def sort_xc(xc_data):
365+
'''Sort the xc functionals into x, c, xc, k functionals.
366+
367+
Parameters
368+
----------
369+
xc_data : dict
370+
from function read_xc_func_h
371+
372+
Returns
373+
-------
374+
dict, dict, dict, dict
375+
The dictionaries of x, c, xc, k functionals, whose keys are the
376+
like LDA, GGA, MGGA, HYB, HYB_LDA, HYB_GGA, HYB_MGGA, values are
377+
the dictionaries of the functionals, whose keys are the conventional
378+
xc name, values include approx, annos, id, full.
379+
'''
380+
x, c, xc, k = {}, {}, {}, {}
381+
dictmap = {'X': x, 'C': c, 'XC': xc, 'K': k}
382+
xcpat = r'XC_(LDA|GGA|MGGA|HYB|HYB_LDA|HYB_GGA|HYB_MGGA)_(X|C|XC|K)_(.*)'
383+
for xc_name, data in xc_data.items():
384+
m = re.match(xcpat, xc_name)
385+
if m is None:
386+
print('Warning: cannot match', xc_name)
387+
continue
388+
approx, type_, name = m.groups()
389+
dictmap[type_][name] = {'approx': approx, 'annos': data['annos'],
390+
'id': data['id'], 'full': xc_name}
391+
return x, c, xc, k
392+
393+
def pair_xc(x, c):
394+
'''
395+
Pair the x and c functionals.
396+
397+
Parameters
398+
----------
399+
x : dict
400+
The dictionary of x functionals, whose keys are the conventional
401+
xc name, values include approx, annos, id, full.
402+
403+
c : dict
404+
the same as x
405+
406+
Returns
407+
-------
408+
dict, dict
409+
The dictionary of paired and unpaired x and c functionals, whose keys are the
410+
conventional xc name, values are the dictionary of x and c functionals.
411+
'''
412+
paired, unpaired = {}, {}
413+
for xc_name, data in x.items():
414+
if xc_name in c:
415+
paired[xc_name] = {'x': data, 'c': c[xc_name]}
416+
else:
417+
unpaired[xc_name] = data
418+
return paired, unpaired
419+
420+
def xc_to_stdmap(xc, conventional_lower=True):
421+
'''print the xc in the way of c++ std::map<std::string, std::string>.
422+
423+
Parameters
424+
----------
425+
xc : dict
426+
The dictionary of xc functionals, whose keys are the conventional
427+
xc name, values include approx, annos, id, full.
428+
conventional_lower : bool
429+
Whether to convert the conventional name to lower case.
430+
431+
Returns
432+
-------
433+
str
434+
The string of c++ code, std::map<std::string, std::string> mapping
435+
the full name of xc to its conventional name.
436+
'''
437+
out = 'const std::map<std::string, std::string> xcname_libxc_xc_ = {\n'
438+
for name, data in xc.items():
439+
name = name.lower() if conventional_lower else name
440+
out += ' {"%s", "%s"},\n' % (data['full'], name)
441+
out += '};\n'
442+
return out
443+
444+
def paired_xc_to_stdmap(pairs, conventional_lower=True):
445+
'''print the xc in the way of c++ std::map<std::string, std::string>.
446+
447+
Parameters
448+
----------
449+
pairs : dict
450+
The dictionary of xc functionals, whose keys are the conventional
451+
xc name, values include approx, annos, id, full.
452+
conventional_lower : bool
453+
Whether to convert the conventional name to lower case.
454+
455+
Returns
456+
-------
457+
str
458+
The string of c++ code, std::map<std::string, std::string> mapping
459+
the full name of xc to its conventional name.
460+
'''
461+
out = 'const std::map<std::string, std::string> xcname_libxc_xplusc_ = {\n'
462+
for name, data in pairs.items():
463+
name = name.lower() if conventional_lower else name
464+
plus = f'{data["x"]["full"]}+{data["c"]["full"]}'
465+
out += ' {"%s", "%s"},\n' % (plus, name)
466+
# sulp = f'{data["c"]["full"]}+{data["x"]["full"]}'
467+
# out += ' {"%s", "%s"},\n' % (sulp, name)
468+
out += '};\n'
469+
return out
470+
471+
def special_x_and_c(x, c):
472+
'''Special pairings of x and c functionals. The following data sheet is
473+
from Pyscf:
474+
https://github.com/pyscf/pyscf/blob/master/pyscf/dft/xcfun.py
475+
Thanks for pointing out the bug by @QuantumMiska and the help from wsr (@hebrewsnabla)
476+
477+
478+
Parameters
479+
----------
480+
x : dict
481+
The dictionary of x functionals, whose keys are the conventional
482+
xc name, values include approx, annos, id, full.
483+
484+
c : dict
485+
the same as x
486+
487+
Returns
488+
-------
489+
dict
490+
The dictionary of special pairings of x and c functionals.
491+
'''
492+
DATA = {
493+
'BLYP' : 'B88,LYP',
494+
'BP86' : 'B88,P86',
495+
'PW91' : 'PW91,PW91',
496+
'PBE' : 'PBE,PBE',
497+
'REVPBE' : 'REVPBE,PBE',
498+
'PBESOL' : 'PBE_SOL,PBE_SOL',
499+
'PKZB' : 'PKZB,PKZB',
500+
'TPSS' : 'TPSS,TPSS',
501+
'REVTPSS' : 'REVTPSS,REVTPSS',
502+
'SCAN' : 'SCAN,SCAN',
503+
'SOGGA' : 'SOGGA,PBE',
504+
'BLOC' : 'BLOC,TPSSLOC',
505+
'OLYP' : 'OPTX,LYP',
506+
'RPBE' : 'RPBE,PBE',
507+
'BPBE' : 'B88,PBE',
508+
'MPW91' : 'MPW91,PW91',
509+
'HFLYP' : 'HF,LYP',
510+
'HFPW92' : 'HF,PWMOD',
511+
'SPW92' : 'SLATER,PWMOD',
512+
'SVWN' : 'SLATER,VWN',
513+
'MS0' : 'MS0,REGTPSS',
514+
'MS1' : 'MS1,REGTPSS',
515+
'MS2' : 'MS2,REGTPSS',
516+
'MS2H' : 'MS2H,REGTPSS',
517+
'MVS' : 'MVS,REGTPSS',
518+
'MVSH' : 'MVSH,REGTPSS',
519+
'SOGGA11' : 'SOGGA11,SOGGA11',
520+
'SOGGA11-X': 'SOGGA11_X,SOGGA11_X',
521+
'KT1' : 'KT1X,VWN',
522+
'DLDF' : 'DLDF,DLDF',
523+
'GAM' : 'GAM,GAM',
524+
'M06-L' : 'M06_L,M06_L',
525+
'M11-L' : 'M11_L,M11_L',
526+
'MN12-L' : 'MN12_L,MN12_L',
527+
'MN15-L' : 'MN15_L,MN15_L',
528+
'N12' : 'N12,N12',
529+
'N12-SX' : 'N12_SX,N12_SX',
530+
'MN12-SX' : 'MN12_SX,MN12_SX',
531+
'MN15' : 'MN15,MN15',
532+
'MBEEF' : 'MBEEF,PBE_SOL',
533+
'SCAN0' : 'SCAN0,SCAN',
534+
'PBEOP' : 'PBE,OP_PBE',
535+
'BOP' : 'B88,OP_B88',
536+
}
537+
paired = {}
538+
for name, data in DATA.items():
539+
xname, cname = data.split(',')
540+
if xname in x and cname in c:
541+
paired[name] = {'x': x[xname], 'c': c[cname]}
542+
else:
543+
print(f'Warning: {name} not found in x or c: {xname}, {cname}')
544+
return paired
545+
546+
def print_xc(xc):
547+
print(f'{"Name":20s} {"Full":30s} {"Appr":10s} {"Annos"}')
548+
for name, data in xc.items():
549+
print(f'{name:20s} {data["full"]:30s} {data["approx"]:10s} {data["annos"]}')
550+
551+
if __name__ == '__main__':
552+
libxc = '/root/soft/libxc/libxc-6.2.2'
553+
f = 'src/xc_funcs.h'
554+
xc_data = read_xc_func_h(os.path.join(libxc, f))
555+
x, c, xc, k = sort_xc(xc_data)
556+
pairs, others = pair_xc(x, c)
557+
special = special_x_and_c(x, c)
558+
# print(xc_to_stdmap(xc))
559+
# print(paired_xc_to_stdmap(pairs))
560+
# print_xc(others)
561+
print(paired_xc_to_stdmap(special))
562+
*/

0 commit comments

Comments
 (0)