|
14 | 14 | #include <sstream> |
15 | 15 | #include <vector> |
16 | 16 |
|
17 | | -// local inline helpers for eigenvalue calculation (mirrors dftu_io.cpp) |
18 | | -inline void JacobiRotate(std::vector<std::vector<double>>& A, int p, int q, int n) |
19 | | -{ |
20 | | - if (std::abs(A[p][q]) > 1e-10) |
21 | | - { |
22 | | - double r = (A[q][q] - A[p][p]) / (2.0 * A[p][q]); |
23 | | - double t = 0.0; |
24 | | - if (r >= 0) |
25 | | - { |
26 | | - t = 1.0 / (r + sqrt(1.0 + r * r)); |
27 | | - } |
28 | | - else |
29 | | - { |
30 | | - t = -1.0 / (-r + sqrt(1.0 + r * r)); |
31 | | - } |
32 | | - double c = 1.0 / sqrt(1.0 + t * t); |
33 | | - double s = t * c; |
34 | | - |
35 | | - A[p][p] -= t * A[p][q]; |
36 | | - A[q][q] += t * A[p][q]; |
37 | | - A[p][q] = A[q][p] = 0.0; |
38 | | - |
39 | | - for (int k = 0; k < n; k++) |
40 | | - { |
41 | | - if (k != p && k != q) |
42 | | - { |
43 | | - double Akp = c * A[k][p] - s * A[k][q]; |
44 | | - double Akq = s * A[k][p] + c * A[k][q]; |
45 | | - A[k][p] = A[p][k] = Akp; |
46 | | - A[k][q] = A[q][k] = Akq; |
47 | | - } |
48 | | - } |
49 | | - } |
50 | | -} |
51 | | - |
52 | | -inline std::vector<double> CalculateEigenvalues(std::vector<std::vector<double>>& A, int n) |
53 | | -{ |
54 | | - std::vector<double> eigenvalues(n); |
55 | | - while (true) |
56 | | - { |
57 | | - int p = 0, q = 1; |
58 | | - for (int i = 0; i < n; i++) |
59 | | - { |
60 | | - for (int j = i + 1; j < n; j++) |
61 | | - { |
62 | | - if (std::abs(A[i][j]) > std::abs(A[p][q])) |
63 | | - { |
64 | | - p = i; |
65 | | - q = j; |
66 | | - } |
67 | | - } |
68 | | - } |
69 | | - |
70 | | - if (std::abs(A[p][q]) < 1e-10) |
71 | | - { |
72 | | - for (int i = 0; i < n; i++) |
73 | | - { |
74 | | - eigenvalues[i] = A[i][i]; |
75 | | - } |
76 | | - break; |
77 | | - } |
78 | | - |
79 | | - JacobiRotate(A, p, q, n); |
80 | | - } |
81 | | - return eigenvalues; |
82 | | -} |
| 17 | +// local inline helpers for eigenvalue calculation (JacobiRotate, CalculateEigenvalues) |
| 18 | +// have been migrated to dftu_output.cpp, where they are used by dftu_io::write_occup_m. |
| 19 | +// mohan refactored 2025-11-08 |
83 | 20 |
|
84 | 21 | // static member definitions (mohan add 2025-11-06) |
85 | 22 | double Plus_U_Base::energy_u = 0.0; |
@@ -584,237 +521,6 @@ void Plus_U_Base::set_locale_flat(const int iat, const int l, const int spin, |
584 | 521 | } |
585 | 522 |
|
586 | 523 |
|
587 | | -void Plus_U_Base::output(const UnitCell& ucell, |
588 | | - bool out_chg, |
589 | | - const std::string& global_out_dir, |
590 | | - int nspin, |
591 | | - int npol) |
592 | | -{ |
593 | | - ModuleBase::TITLE("Plus_U_Base", "output"); |
594 | | - |
595 | | - GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>" << std::endl; |
596 | | - GlobalV::ofs_running << " | #DFT+U INFORMATION# |" << std::endl; |
597 | | - GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>" << std::endl; |
598 | | - |
599 | | - for (int T = 0; T < ucell.ntype; T++) |
600 | | - { |
601 | | - const int NL = ucell.atoms[T].nwl + 1; |
602 | | - |
603 | | - for (int L = 0; L < NL; L++) |
604 | | - { |
605 | | - const int N = ucell.atoms[T].l_nchi[L]; |
606 | | - |
607 | | - if (L >= get_orbital_corr(T) && has_correlated_orbital(T)) |
608 | | - { |
609 | | - if (L != get_orbital_corr(T)) |
610 | | - { |
611 | | - continue; |
612 | | - } |
613 | | - |
614 | | - if (!Yukawa) |
615 | | - { |
616 | | - GlobalV::ofs_running << " Type=" << T+1 << " L=" << L << " ORBITAL=" << 0 |
617 | | - << " U=" << this->U[T] * ModuleBase::Ry_to_eV << " eV" << std::endl; |
618 | | - } |
619 | | - else |
620 | | - { |
621 | | - for (int n = 0; n < N; n++) |
622 | | - { |
623 | | - if (n != 0) |
624 | | - { |
625 | | - continue; |
626 | | - } |
627 | | - double Ueff = (this->U_Yukawa[T][L][n] - this->J_Yukawa[T][L][n]) * ModuleBase::Ry_to_eV; |
628 | | - GlobalV::ofs_running << " Type=" << T+1 << " L=" << L << " ORBITAL=" << n |
629 | | - << " U=" << this->U_Yukawa[T][L][n] * ModuleBase::Ry_to_eV << " eV" |
630 | | - << " J=" << this->J_Yukawa[T][L][n] * ModuleBase::Ry_to_eV << " eV" |
631 | | - << std::endl; |
632 | | - } |
633 | | - } |
634 | | - } |
635 | | - } |
636 | | - } |
637 | | - |
638 | | - GlobalV::ofs_running << " Local Occupation Matrices for each atom" << std::endl; |
639 | | - this->write_occup_m(ucell, GlobalV::ofs_running, true, nspin, npol); |
640 | | - |
641 | | - // Write dm_onsite.txt |
642 | | - if (out_chg && GlobalV::MY_RANK == 0) |
643 | | - { |
644 | | - std::ofstream ofdftu; |
645 | | - ofdftu.open(global_out_dir + "dm_onsite.txt"); |
646 | | - if (!ofdftu) |
647 | | - { |
648 | | - ModuleBase::WARNING_QUIT("Plus_U_Base::output", "Can't create file dm_onsite.txt"); |
649 | | - } |
650 | | - this->write_occup_m(ucell, ofdftu, false, nspin, npol); |
651 | | - ofdftu.close(); |
652 | | - } |
653 | | - |
654 | | - GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>" << std::endl; |
655 | | - GlobalV::ofs_running << " | # END DFT+U INFO |" << std::endl; |
656 | | - GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>" << std::endl << std::endl; |
657 | | - |
658 | | - return; |
659 | | -} |
660 | | - |
661 | | - |
662 | | -void Plus_U_Base::write_occup_m(const UnitCell& ucell, |
663 | | - std::ofstream& ofs, |
664 | | - bool diag, |
665 | | - int nspin, |
666 | | - int npol) |
667 | | -{ |
668 | | - ModuleBase::TITLE("Plus_U_Base", "write_occup_m"); |
669 | | - |
670 | | - if (GlobalV::MY_RANK != 0) |
671 | | - { |
672 | | - return; |
673 | | - } |
674 | | - |
675 | | - for (int T = 0; T < ucell.ntype; T++) |
676 | | - { |
677 | | - if (!has_correlated_orbital(T)) |
678 | | - { |
679 | | - continue; |
680 | | - } |
681 | | - const int NL = ucell.atoms[T].nwl + 1; |
682 | | - const int LC = get_orbital_corr(T); |
683 | | - |
684 | | - for (int I = 0; I < ucell.atoms[T].na; I++) |
685 | | - { |
686 | | - const int iat = ucell.itia2iat(T, I); |
687 | | - |
688 | | - for (int l = 0; l < NL; l++) |
689 | | - { |
690 | | - if (l != get_orbital_corr(T)) |
691 | | - { |
692 | | - continue; |
693 | | - } |
694 | | - |
695 | | - const int N = ucell.atoms[T].l_nchi[l]; |
696 | | - |
697 | | - for (int n = 0; n < N; n++) |
698 | | - { |
699 | | - if (n != 0) |
700 | | - { |
701 | | - continue; |
702 | | - } |
703 | | - |
704 | | - ofs << "\n Atom= " << iat+1; |
705 | | - ofs << " L= " << l; |
706 | | - ofs << " ORBITAL= " << n << std::endl; |
707 | | - |
708 | | - if (nspin == 1 || nspin == 2) |
709 | | - { |
710 | | - double sum0[2]; |
711 | | - for (int is = 0; is < 2; is++) |
712 | | - { |
713 | | - if (diag) |
714 | | - { |
715 | | - std::vector<std::vector<double>> A(2 * l + 1, std::vector<double>(2 * l + 1)); |
716 | | - for (int m0 = 0; m0 < 2 * l + 1; m0++) |
717 | | - { |
718 | | - for (int m1 = 0; m1 < 2 * l + 1; m1++) |
719 | | - { |
720 | | - A[m0][m1] = locale[iat][l][n][is](m0, m1); |
721 | | - } |
722 | | - } |
723 | | - std::vector<double> eigenvalues = CalculateEigenvalues(A, 2 * l + 1); |
724 | | - sum0[is] = 0.0; |
725 | | - ofs << " Eigenvalues for spin=" << is+1 << std::endl; |
726 | | - ofs << std::setprecision(8) << std::fixed; |
727 | | - for (int i = 0; i < 2 * l + 1; i++) |
728 | | - { |
729 | | - ofs << std::setw(12) << eigenvalues[i]; |
730 | | - sum0[is] += eigenvalues[i]; |
731 | | - } |
732 | | - ofs << std::endl; |
733 | | - ofs << " sum is " << std::setw(12) << sum0[is] << std::endl; |
734 | | - } |
735 | | - ofs << " spin= " << is+1 << std::endl; |
736 | | - ofs << std::setprecision(8) << std::fixed; |
737 | | - for (int m0 = 0; m0 < 2 * l + 1; m0++) |
738 | | - { |
739 | | - for (int m1 = 0; m1 < 2 * l + 1; m1++) |
740 | | - { |
741 | | - ofs << std::setw(12) |
742 | | - << locale[iat][l][n][is](m0, m1); |
743 | | - } |
744 | | - ofs << std::endl; |
745 | | - } |
746 | | - } |
747 | | - if (diag) |
748 | | - { |
749 | | - ofs << std::setw(12) << std::setprecision(8) |
750 | | - << std::fixed << " Magnetism for atom " << iat+1 << ": " << sum0[0] - sum0[1] |
751 | | - << std::endl; |
752 | | - } |
753 | | - } |
754 | | - else if (nspin == 4) // SOC |
755 | | - { |
756 | | - if (diag) |
757 | | - { |
758 | | - double sum0[4]; |
759 | | - std::vector<std::vector<double>> A(2 * l + 1, std::vector<double>(2 * l + 1)); |
760 | | - int index = 0; |
761 | | - for (int is = 0; is < 4; is++) |
762 | | - { |
763 | | - for (int m0 = 0; m0 < 2 * l + 1; m0++) |
764 | | - { |
765 | | - for (int m1 = 0; m1 < 2 * l + 1; m1++) |
766 | | - { |
767 | | - A[m0][m1] = locale[iat][l][n][0].c[index]; |
768 | | - index++; |
769 | | - } |
770 | | - } |
771 | | - std::vector<double> eigenvalues = CalculateEigenvalues(A, 2 * l + 1); |
772 | | - sum0[is] = 0.0; |
773 | | - ofs << " Eigenvalues for is=" << is << std::endl; |
774 | | - ofs << std::setprecision(8) << std::fixed; |
775 | | - for (int i = 0; i < 2 * l + 1; i++) |
776 | | - { |
777 | | - ofs << std::setw(12) << eigenvalues[i]; |
778 | | - sum0[is] += eigenvalues[i]; |
779 | | - } |
780 | | - ofs << std::endl; |
781 | | - ofs << " sum is " << std::setw(12) << sum0[is] << std::endl; |
782 | | - } |
783 | | - ofs << std::setw(12) << std::setprecision(8) |
784 | | - << std::fixed << " Magnetism for atom " << iat + 1 << ": " |
785 | | - << sum0[1] << " " << sum0[2] << " " << sum0[3] << std::endl; |
786 | | - } |
787 | | - else |
788 | | - { |
789 | | - for (int m0 = 0; m0 < 2 * l + 1; m0++) |
790 | | - { |
791 | | - for (int ipol0 = 0; ipol0 < npol; ipol0++) |
792 | | - { |
793 | | - const int m0_all = m0 + (2 * l + 1) * ipol0; |
794 | | - |
795 | | - for (int m1 = 0; m1 < 2 * l + 1; m1++) |
796 | | - { |
797 | | - for (int ipol1 = 0; ipol1 < npol; ipol1++) |
798 | | - { |
799 | | - int m1_all = m1 + (2 * l + 1) * ipol1; |
800 | | - ofs << std::setw(12) << std::setprecision(8) << std::fixed |
801 | | - << locale[iat][l][n][0](m0_all, m1_all); |
802 | | - } |
803 | | - } |
804 | | - ofs << std::endl; |
805 | | - } |
806 | | - } |
807 | | - } |
808 | | - } |
809 | | - } // n |
810 | | - } // l |
811 | | - } // I |
812 | | - } // T |
813 | | - |
814 | | - return; |
815 | | -} |
816 | | - |
817 | | - |
818 | 524 | void Plus_U_Base::read_occup_m(const UnitCell& ucell, |
819 | 525 | const std::string& fn, |
820 | 526 | const std::string& init_chg, |
|
0 commit comments