@@ -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