<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://yxli8023.github.io//feed.xml" rel="self" type="application/atom+xml" /><link href="https://yxli8023.github.io//" rel="alternate" type="text/html" hreflang="zh-Hans" /><updated>2026-05-30T00:37:52+08:00</updated><id>https://yxli8023.github.io//feed.xml</id><title type="html">Yu-Xuan Blog</title><subtitle>整理平时学习到的方法和代码实现。
</subtitle><author><name>YuXuan</name><email>yxli406@gmail.com</email></author><entry><title type="html">严格物理常数单位换算器</title><link href="https://yxli8023.github.io//2025/10/31/strict-physical-constants-converter.html" rel="alternate" type="text/html" title="严格物理常数单位换算器" /><published>2025-10-31T00:00:00+08:00</published><updated>2025-10-31T00:00:00+08:00</updated><id>https://yxli8023.github.io//2025/10/31/strict-physical-constants-converter</id><content type="html" xml:base="https://yxli8023.github.io//2025/10/31/strict-physical-constants-converter.html"><![CDATA[<h1 id="严格物理常数单位换算器含常数与公式显示">严格物理常数单位换算器（含常数与公式显示）</h1>

<blockquote>
  <p>输入任意一项后按 <strong>Enter</strong> 或 <strong>空格键</strong>计算。<br />
支持波长 λ (nm)、能量 E (eV / a.u.)、周期 T (fs)、频率 ν (THz)、波数 ν̃ (cm⁻¹) 之间的精确换算。</p>
</blockquote>

<hr />

<h2 id="输入与计算">输入与计算</h2>

<table>
<tr><th>量</th><th>符号</th><th>输入 / 输出</th></tr>
<tr><td>波长</td><td>λ (nm)</td>
    <td><input id="lambda" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('lambda')" /></td></tr>
<tr><td>能量</td><td>E (eV)</td>
    <td><input id="energy" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('energy')" /></td></tr>
<tr><td>周期</td><td>T (fs)</td>
    <td><input id="period" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('period')" /></td></tr>
<tr><td>频率</td><td>ν (THz)</td>
    <td><input id="freq" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('freq')" /></td></tr>
<tr><td>波数</td><td>ν̃ (cm⁻¹)</td>
    <td><input id="wavenum" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('wavenum')" /></td></tr>
<tr><td>能量</td><td>E (a.u.)</td>
    <td><input id="eau" onkeypress="if(event.key==='Enter'||event.key===' ') convertFrom('eau')" /></td></tr>
</table>

<hr />

<h2 id="常数与换算">常数与换算</h2>

<pre id="constants"></pre>

<hr />

<h2 id="换算公式">换算公式</h2>

<pre>
E = hc / λ
T = h / E
ν = 1 / T
ν̃ = 1 / λ
E(a.u.) = E(eV) / 27.211386
1 eV = 8065.544 cm⁻¹ = 241.799 THz = 0.0367493 a.u.
hc = 1239.841984 eV·nm
</pre>

<hr />

<script>
// ======== 常数 ========
const _PLANCK   = 0.6626075540000000E-33;     // h [J·s]
const _CLIGHT   = 29979245800.00000;         // c [cm/s]
const _JOULE    = 0.4359748200000000E-17;    // J per Hartree
const _TOEV     = 27.21138505000000;         // eV per Hartree
const _TOHERTZ  = 6579683920729000.0;        // Hz per Hartree
const _EV_HARTREE = 0.3674932379085202E-01;  // Hartree per eV

// ======== 派生常数 ========
const hc_J_cm = _PLANCK * _CLIGHT;
const hc_eV_nm = hc_J_cm * (_TOEV / _JOULE) * 1e7;
const eV_to_Hz = _TOHERTZ * _EV_HARTREE;
const eV_to_THz = eV_to_Hz / 1e12;
const J_per_eV = _JOULE / _TOEV;
const h_eV_fs = _PLANCK / J_per_eV * 1e15;
const eV_to_cm1 = 1e7 / hc_eV_nm;

// ======== 格式化输出 ========
function fmt(x,n=6){return (isFinite(x)? x.toExponential(n): '');}

// ======== 转换函数 ========
function convertFrom(type){
  const v = parseFloat(document.getElementById(type).value);
  if (!isFinite(v)) return;

  let lambda_nm, E_eV, T_fs, nu_THz, wavenum_cm1, E_au;

  if (type === 'lambda'){
    lambda_nm = v;
    E_eV = hc_eV_nm / lambda_nm;
  } else if (type === 'energy'){
    E_eV = v;
    lambda_nm = hc_eV_nm / E_eV;
  } else if (type === 'period'){
    T_fs = v;
    E_eV = h_eV_fs / T_fs;
    lambda_nm = hc_eV_nm / E_eV;
  } else if (type === 'freq'){
    nu_THz = v;
    E_eV = (nu_THz * 1e12) / eV_to_Hz;
    lambda_nm = hc_eV_nm / E_eV;
  } else if (type === 'wavenum'){
    wavenum_cm1 = v;
    E_eV = wavenum_cm1 / eV_to_cm1;
    lambda_nm = hc_eV_nm / E_eV;
  } else if (type === 'eau'){
    E_au = v;
    E_eV = E_au * _TOEV;
    lambda_nm = hc_eV_nm / E_eV;
  }

  // 衍生计算
  nu_THz = E_eV * eV_to_THz;
  T_fs = h_eV_fs / E_eV;
  wavenum_cm1 = E_eV * eV_to_cm1;
  E_au = E_eV / _TOEV;

  // 输出更新
  document.getElementById('lambda').value  = lambda_nm.toFixed(6);
  document.getElementById('energy').value  = E_eV.toFixed(9);
  document.getElementById('period').value  = T_fs.toFixed(6);
  document.getElementById('freq').value    = nu_THz.toFixed(6);
  document.getElementById('wavenum').value = wavenum_cm1.toFixed(6);
  document.getElementById('eau').value     = E_au.toFixed(9);
}

// ======== 显示常数 ========
document.getElementById("constants").innerText =
`h  = ${fmt(_PLANCK)} J·s
c  = ${fmt(_CLIGHT)} cm/s
1 Hartree = ${_TOEV} eV = ${(1/_EV_HARTREE).toFixed(6)} eV
1 eV = ${fmt(eV_to_cm1,3)} cm⁻¹ = ${fmt(eV_to_THz,3)} THz = ${(1/_TOEV).toFixed(8)} a.u.
hc = ${hc_eV_nm.toFixed(6)} eV·nm
h  = ${(h_eV_fs).toFixed(6)} eV·fs`;
</script>]]></content><author><name>YuXuan</name><email>yxli406@gmail.com</email></author><summary type="html"><![CDATA[严格物理常数单位换算器（含常数与公式显示） 输入任意一项后按 Enter 或 空格键计算。 支持波长 λ (nm)、能量 E (eV / a.u.)、周期 T (fs)、频率 ν (THz)、波数 ν̃ (cm⁻¹) 之间的精确换算。 输入与计算 量符号输入 / 输出 波长λ (nm) 能量E (eV) 周期T (fs) 频率ν (THz) 波数ν̃ (cm⁻¹) 能量E (a.u.) 常数与换算 换算公式 E = hc / λ T = h / E ν = 1 / T ν̃ = 1 / λ E(a.u.) = E(eV) / 27.211386 1 eV = 8065.544 cm⁻¹ = 241.799 THz = 0.0367493 a.u. hc = 1239.841984 eV·nm]]></summary></entry><entry><title type="html">使用Fortran计算Hall电导</title><link href="https://yxli8023.github.io//2024/11/03/Fortran-Hall-conductance.html" rel="alternate" type="text/html" title="使用Fortran计算Hall电导" /><published>2024-11-03T00:00:00+08:00</published><updated>2024-11-03T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/11/03/Fortran-Hall-conductance</id><content type="html" xml:base="https://yxli8023.github.io//2024/11/03/Fortran-Hall-conductance.html"><![CDATA[<p class="info">整理用Fortran计算某一条能带的Hall电导，这里使用的QWZ模型。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>这里使用的是最简单的QWZ模型，其哈密顿量为</p>

\[H = (m_0 - t_x \cos(k_x) - t_y \cos(k_y))\sigma_z + a_x \sin(k_x) \sigma_x + a_y * \sin(k_y) * sigma_y\]

<p>程序实现上目前是分别计算每一条能带的Hall电导，而不是计算费米面以下电子贡献的电导。当化学势落在能隙中的时候，这里计算的Hall电导就是单独一条能带贡献，如果化学势与能带有交点，那么Hall电导的计算应该是考虑所有费米面以下的贡献，这里先不考虑这件事情。</p>

<h1 id="代码">代码</h1>
<h2 id="串行版">串行版</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">  </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">acos</span><span class="p">(</span><span class="mf">-1.0_dp</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w">                 </span><span class="c1">!   Imagine unit  </span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">Nk</span><span class="p">,</span><span class="n">numk_bz</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">BZklist</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">m0</span><span class="p">,</span><span class="n">t1</span><span class="p">,</span><span class="n">ax</span><span class="p">,</span><span class="n">ay</span><span class="p">,</span><span class="n">mu</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">omega</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">m0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">t1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">ax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">ay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e2</span><span class="p">,</span><span class="w"> </span><span class="n">mu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="n">omega</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-8</span><span class="p">)</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">chern_insulator_hall_conductance</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ik0</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="p">,</span><span class="w"> </span><span class="n">hall_conductance</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">calculate_berry_curvature</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">  </span><span class="c1">! 构建布里渊区</span><span class="w">

    </span><span class="n">hall_conductance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

    </span><span class="c1">! 遍历 k 空间，计算 Berry 曲率并积分</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ik0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="nb">size</span><span class="p">(</span><span class="n">BZklist</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w">
        </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="n">hall_conductance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hall_conductance</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">calculate_berry_curvature</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">pi</span><span class="p">/</span><span class="n">Nk</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

    </span><span class="c1">! 输出结果</span><span class="w">
    </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="s2">"(A50,F15.6)"</span><span class="p">)</span><span class="s2">"Hall Conductance (in units of e^2/h): "</span><span class="p">,</span><span class="w"> </span><span class="n">hall_conductance</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="p">)</span><span class="w">

</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">chern_insulator_hall_conductance</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
    </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">ind_band</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算某一条能带的 Berry 曲率的子程序</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w">  </span><span class="c1">! 哈密顿量维度</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ie1</span><span class="p">,</span><span class="n">ie2</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ind_band</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">calculate_berry_curvature</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">Ave_Ham</span><span class="w">

    </span><span class="c1">! H = (m0 - tx cos(kx) - ty cos(ky))\sigma_z + ax sin(kx) \sigma_x + ay * sin(ky) * sigma_y</span><span class="w">
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="p">(</span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    
    </span><span class="c1">! 计算哈密顿量的特征值和特征向量</span><span class="w">
    </span><span class="n">eigvecs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">eigvals</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_hermitian_matrix</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">Ham</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">,</span><span class="w"> </span><span class="n">eigvals</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 构建哈密顿量对 kx 和 ky 的导数矩阵</span><span class="w">
    </span><span class="n">dHdkx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">dHdky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

    </span><span class="c1">!  DH_x</span><span class="w">
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">

    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> 
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">
    
    </span><span class="c1">!  DH_y</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">

    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 计算 Berry 曲率</span><span class="w">
    </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">   </span><span class="c1">! 索引能带</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">
        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ie2</span><span class="w"> </span><span class="p">/</span><span class="o">=</span><span class="w"> </span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
            </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">)))</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="p">((</span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie2</span><span class="p">))</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">omega</span><span class="p">)</span><span class="w">  </span><span class="c1">! 添加正则项防止除零</span><span class="w">
        </span><span class="k">endif</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">calculate_berry_curvature</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">aimag</span><span class="p">(</span><span class="n">re1</span><span class="p">(</span><span class="n">ind_band</span><span class="p">))</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">psi1</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">psi2</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算  &lt;psi_1|Ham|psi_2&gt;</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i0</span><span class="p">,</span><span class="n">j0</span><span class="p">,</span><span class="n">matdim</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ave_Ham</span><span class="p">,</span><span class="n">expectation</span><span class="p">,</span><span class="n">Ham</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">temp</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">psi1</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">psi2</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="n">expectation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">j0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
            </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">i0</span><span class="p">,</span><span class="w"> </span><span class="n">j0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">psi2</span><span class="p">(</span><span class="n">j0</span><span class="p">)</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">expectation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">expectation</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">psi1</span><span class="p">(</span><span class="n">i0</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">Ave_Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">expectation</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> 
</span><span class="c1">!============================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">
    </span><span class="c1">! 构建四方BZ</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">i0</span><span class="w">
    </span><span class="c1">! 对于四方点阵,BZ的点数可以直接确定</span><span class="w">
    </span><span class="n">numk_bz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">   
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">))</span><span class="w">
    </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k">open</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"BZ.dat"</span><span class="p">)</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">Nk</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">Nk</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="w"> 
            </span><span class="k">write</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="s2">"(4F15.8)"</span><span class="p">)</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">),</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">close</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">  
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵, matout 本征矢量, mateigval 本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">  </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">lwmax0</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">

    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">

    </span><span class="c1">! 初次调用 zheevd 获取最佳工作空间大小</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 根据第一次调用的返回值重新调整工作空间大小</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 重新分配工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">work</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="n">lrwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="n">liwork</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 第二次调用 zheevd 计算本征值和本征矢量</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 错误处理</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="并行版">并行版</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">  </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">acos</span><span class="p">(</span><span class="mf">-1.0_dp</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w">                 </span><span class="c1">!   Imagine unit  </span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">e0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.602176634e-19_dp</span><span class="w">   </span><span class="c1">! 电子电荷 (C)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">hbar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0545718e-34_dp</span><span class="w">  </span><span class="c1">! 约化普朗克常数 (J·s)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">Nk</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">,</span><span class="n">num_mu</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">BZklist</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">m0</span><span class="p">,</span><span class="n">t1</span><span class="p">,</span><span class="n">ax</span><span class="p">,</span><span class="n">ay</span><span class="p">,</span><span class="n">mu</span><span class="p">,</span><span class="n">mu_Max</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">omega</span><span class="p">,</span><span class="n">delta_k</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">t1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">ax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">mu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="n">ay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e3</span><span class="p">,</span><span class="w"> </span><span class="n">omega</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-8</span><span class="p">,</span><span class="w"> </span><span class="n">delta_k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-5</span><span class="p">,</span><span class="n">num_mu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="n">mu_max</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">mpi</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="n">indcore</span><span class="p">,</span><span class="n">ierr</span><span class="p">,</span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">   </span><span class="c1">! Parameter for MPI</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i0</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">temp</span><span class="p">,</span><span class="n">hall_conductance</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">calculate_Hall_conductance</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">da_mpi</span><span class="p">(</span><span class="n">num_mu</span><span class="p">),</span><span class="n">da_list</span><span class="p">(</span><span class="n">num_mu</span><span class="p">),</span><span class="n">hall_mpi</span><span class="p">(</span><span class="n">num_mu</span><span class="p">),</span><span class="n">hall_list</span><span class="p">(</span><span class="n">num_mu</span><span class="p">)</span><span class="w">
    </span><span class="c1">!#######################################         并行计算设置      #######################################</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_INIT</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">     </span><span class="c1">! 初始化进程</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_RANK</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">indcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">! 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该indcore为0到numcore-1间的整数,相当于进程的ID。)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_SIZE</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">!获得进程数量,用numcoer保存</span><span class="w">
    </span><span class="c1">! 并行循环分拆</span><span class="w">
    </span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num_mu</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">num_mu</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w">
    </span><span class="c1">!#######################################         并行计算设置      #######################################</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">  </span><span class="c1">! 构建布里渊区</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
        </span><span class="n">m0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">mu_max</span><span class="p">/</span><span class="n">num_mu</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu_max</span><span class="w">
        </span><span class="n">da_mpi</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m0</span><span class="w">
        </span><span class="n">hall_mpi</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">calculate_Hall_conductance</span><span class="p">()</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">   </span><span class="c1">! 等所有核心都计算完成</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">da_mpi</span><span class="p">,</span><span class="w"> </span><span class="n">da_list</span><span class="p">,</span><span class="w"> </span><span class="n">num_mu</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_DOUBLE_PRECISION</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">hall_mpi</span><span class="p">,</span><span class="w"> </span><span class="n">hall_list</span><span class="p">,</span><span class="w"> </span><span class="n">num_mu</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_DOUBLE_PRECISION</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">

    </span><span class="k">if</span><span class="p">(</span><span class="n">indcore</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="c1">! 数据读写</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Hall-mu.dat"</span><span class="p">)</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_mu</span><span class="w">
            </span><span class="k">write</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="s2">"(9F20.10)"</span><span class="p">)</span><span class="n">da_list</span><span class="p">(</span><span class="n">i0</span><span class="p">),</span><span class="n">hall_list</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w">
        </span><span class="k">enddo</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span><span class="w">
    </span><span class="k">endif</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Finalize</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">

    </span><span class="c1">! hall_conductance = calculate_Hall_conductance()</span><span class="w">
    </span><span class="c1">! 输出结果</span><span class="w">
    </span><span class="c1">! write(*,"(A50,F15.6)")"Hall Conductance (in units of e^2/h): ", hall_conductance</span><span class="w">

</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">calculate_Hall_conductance</span><span class="p">()</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ik0</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="p">,</span><span class="w"> </span><span class="n">re1</span><span class="p">,</span><span class="w"> </span><span class="n">re2</span><span class="p">,</span><span class="w"> </span><span class="n">calculate_Hall_conductance</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">calculate_berry_curvature_v1</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">calculate_berry_curvature_v2</span><span class="w">

    </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">re2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

    </span><span class="c1">! 遍历 k 空间，计算 Berry 曲率并积分</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ik0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="nb">size</span><span class="p">(</span><span class="n">BZklist</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w">
        </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="c1">! re2 = re2 + calculate_berry_curvature_v1(kx,ky,1) * (pi/Nk)**2   !  我这里的步长上是  pi/Nk</span><span class="w">
        </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">calculate_berry_curvature_v2</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">pi</span><span class="p">/</span><span class="n">Nk</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">   </span><span class="c1">!  我这里的步长上是  pi/Nk</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">calculate_Hall_conductance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">/(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 输出结果</span><span class="w">
    </span><span class="c1">! write(*,"(A50,F15.6)")"Hall Conductance (in units of e^2/h): ", re1/(2 * pi)</span><span class="w">

</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_Hall_conductance</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
    </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature_v1</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">ind_band</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算某一条能带的 Berry 曲率的子程序</span><span class="w">
    </span><span class="c1">! 解析给出哈密顿量偏导</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w">  </span><span class="c1">! 哈密顿量维度</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ie1</span><span class="p">,</span><span class="n">ie2</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ind_band</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">calculate_berry_curvature_v1</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">Ave_Ham</span><span class="w">

    </span><span class="c1">! H = (m0 - tx cos(kx) - ty cos(ky))\sigma_z + ax sin(kx) \sigma_x + ay * sin(ky) * sigma_y</span><span class="w">
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="p">(</span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    
    </span><span class="c1">! 计算哈密顿量的特征值和特征向量</span><span class="w">
    </span><span class="n">eigvecs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">eigvals</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_hermitian_matrix</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">Ham</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">,</span><span class="w"> </span><span class="n">eigvals</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 构建哈密顿量对 kx 和 ky 的导数矩阵</span><span class="w">
    </span><span class="n">dHdkx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">dHdky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

    </span><span class="c1">!  DH_x</span><span class="w">
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">

    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> 
    </span><span class="n">dHdkx</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">
    
    </span><span class="c1">!  DH_y</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">

    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">dHdky</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 计算 Berry 曲率</span><span class="w">
    </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">   </span><span class="c1">! 索引能带</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">
        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ie2</span><span class="w"> </span><span class="p">/</span><span class="o">=</span><span class="w"> </span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
            </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">)))</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="p">((</span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie2</span><span class="p">))</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">omega</span><span class="p">)</span><span class="w">  </span><span class="c1">! 添加正则项防止除零</span><span class="w">
        </span><span class="k">endif</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">calculate_berry_curvature_v1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">aimag</span><span class="p">(</span><span class="n">re1</span><span class="p">(</span><span class="n">ind_band</span><span class="p">))</span><span class="w">

</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature_v1</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature_v2</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">ind_band</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算某一条能带的 Berry 曲率的子程序</span><span class="w">
    </span><span class="c1">! 数值差分计算哈密顿量偏导</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w">  </span><span class="c1">! 哈密顿量维度</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ie1</span><span class="p">,</span><span class="n">ie2</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ind_band</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">calculate_berry_curvature_v2</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">Ave_Ham</span><span class="w">

    </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">DH_kxky</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">dHdkx</span><span class="p">,</span><span class="n">dHdky</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算哈密顿量的特征值和特征向量</span><span class="w">
    </span><span class="n">eigvecs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">eigvals</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_hermitian_matrix</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">Ham</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">,</span><span class="w"> </span><span class="n">eigvals</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 计算 Berry 曲率</span><span class="w">
    </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">   </span><span class="c1">! 索引能带</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ie2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="w">
        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ie2</span><span class="w"> </span><span class="p">/</span><span class="o">=</span><span class="w"> </span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
            </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">),</span><span class="w"> </span><span class="n">dHdkx</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie2</span><span class="p">),</span><span class="w"> </span><span class="n">dHdky</span><span class="p">,</span><span class="w"> </span><span class="n">eigvecs</span><span class="p">(:,</span><span class="w"> </span><span class="n">ie1</span><span class="p">)))</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
                            </span><span class="p">((</span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">eigvals</span><span class="p">(</span><span class="n">ie2</span><span class="p">))</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">omega</span><span class="p">)</span><span class="w">  </span><span class="c1">! 添加正则项防止除零</span><span class="w">
        </span><span class="k">endif</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">calculate_berry_curvature_v2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">aimag</span><span class="p">(</span><span class="n">re1</span><span class="p">(</span><span class="n">ind_band</span><span class="p">))</span><span class="w">

</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">calculate_berry_curvature_v2</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham</span><span class="p">)</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w">  </span><span class="c1">! 哈密顿量维度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="c1">! H = (m0 - tx cos(kx) - ty cos(ky))\sigma_z + ax sin(kx) \sigma_x + ay * sin(ky) * sigma_y</span><span class="w">
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="p">(</span><span class="n">m0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ax</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">DH_kxky</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham_dkx</span><span class="p">,</span><span class="n">Ham_dky</span><span class="p">)</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w">  </span><span class="c1">! 哈密顿量维度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">Ham_pk</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">Ham_mk</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">Ham_dkx</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">Ham_dky</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">delta_k</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham_pk</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">delta_k</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham_mk</span><span class="p">)</span><span class="w">
    </span><span class="n">Ham_dkx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Ham_pk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">Ham_mk</span><span class="p">)/(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">delta_k</span><span class="p">)</span><span class="w">

    </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">delta_k</span><span class="p">,</span><span class="n">Ham_pk</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">delta_k</span><span class="p">,</span><span class="n">Ham_mk</span><span class="p">)</span><span class="w">
    </span><span class="n">Ham_dky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Ham_pk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">Ham_mk</span><span class="p">)/(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">delta_k</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">Ave_Ham</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">psi1</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">psi2</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算  &lt;psi_1|Ham|psi_2&gt;</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i0</span><span class="p">,</span><span class="n">j0</span><span class="p">,</span><span class="n">matdim</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ave_Ham</span><span class="p">,</span><span class="n">expectation</span><span class="p">,</span><span class="n">Ham</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">temp</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">psi1</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">psi2</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="n">expectation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">j0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
            </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">i0</span><span class="p">,</span><span class="w"> </span><span class="n">j0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">psi2</span><span class="p">(</span><span class="n">j0</span><span class="p">)</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">expectation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">expectation</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">psi1</span><span class="p">(</span><span class="n">i0</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">temp</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">Ave_Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">expectation</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> 
</span><span class="c1">!============================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">
    </span><span class="c1">! 构建四方BZ</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">i0</span><span class="w">
    </span><span class="c1">! 对于四方点阵,BZ的点数可以直接确定</span><span class="w">
    </span><span class="n">numk_bz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">   
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">))</span><span class="w">
    </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k">open</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"BZ.dat"</span><span class="p">)</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">Nk</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">Nk</span><span class="p">,</span><span class="n">Nk</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Nk</span><span class="p">)</span><span class="w"> 
            </span><span class="k">write</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="s2">"(4F15.8)"</span><span class="p">)</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">),</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">close</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">  
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵, matout 本征矢量, mateigval 本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">  </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">lwmax0</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">

    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">

    </span><span class="c1">! 初次调用 zheevd 获取最佳工作空间大小</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 根据第一次调用的返回值重新调整工作空间大小</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 重新分配工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">work</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="n">lrwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="n">liwork</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 第二次调用 zheevd 计算本征值和本征矢量</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 错误处理</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span></code></pre></div></div>
<p><img src="/assets/images/Fortran/Hall-mu.png" alt="png" /></p>

<h2 id="绘图代码">绘图代码</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">rcParams</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">matplotlib.gridspec</span> <span class="k">as</span> <span class="n">gridspec</span>

<span class="n">plt</span><span class="p">.</span><span class="n">rc</span><span class="p">(</span><span class="s">'font'</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"font.size"</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
<span class="s">"mathtext.fontset"</span><span class="p">:</span><span class="s">'stix'</span><span class="p">,</span>
<span class="s">"font.serif"</span><span class="p">:</span> <span class="p">[</span><span class="s">'SimSun'</span><span class="p">],</span>
<span class="p">}</span>
<span class="n">rcParams</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">config</span><span class="p">)</span> <span class="c1"># Latex 字体设置
#----------------------------------------------------------
</span><span class="k">def</span> <span class="nf">plot_hall</span><span class="p">():</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"Hall-mu.dat"</span>
    <span class="n">picname</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">dataname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">".png"</span>
    <span class="n">da</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">dataname</span><span class="p">)</span> 
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">da</span><span class="p">[:,</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"b"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$m_0$"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\sigma_{xy}(e^2/\hbar)$"</span><span class="p">)</span>
    <span class="c1"># plt.xlim(0,Umax)
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    
    <span class="c1"># plt.axis('scaled')
</span>    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># x 轴最多显示 3 个刻度
</span>    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># y 轴最多显示 3 个刻度
</span>    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1">#------------------------------------------------------------
</span><span class="k">if</span> <span class="n">__name__</span><span class="o">==</span><span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">plot_hall</span><span class="p">()</span>
</code></pre></div></div>

<p>所有文件可以<a href="/assets/data/QWZ-hall.zip">点击这里下载</a>.</p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<table>
  <tr>
    <!-- 图片单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; border: 1px solid #ccc; border-radius: 8px;">
      <img src="/assets/images/qrcode.jpg" alt="QR Code" width="300px" height="300px" style="border-radius: 8px;" />
    </td>
    <!-- 文字单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; padding-left: 20px; border: 1px solid #ccc; border-radius: 8px;">
      <div>
        <h4 style="margin: 0;">Email</h4>
        <p style="margin: 5px 0;">yxli406@gmail.com</p>
      </div>
    </td>
  </tr>
</table>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><category term="Topology" /><summary type="html"><![CDATA[整理用Fortran计算某一条能带的Hall电导，这里使用的QWZ模型。]]></summary></entry><entry><title type="html">适用Fortran读取Wannier90拟合的hr</title><link href="https://yxli8023.github.io//2024/11/02/Fortran-Wannier-Hr.html" rel="alternate" type="text/html" title="适用Fortran读取Wannier90拟合的hr" /><published>2024-11-02T00:00:00+08:00</published><updated>2024-11-02T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/11/02/Fortran-Wannier-Hr</id><content type="html" xml:base="https://yxli8023.github.io//2024/11/02/Fortran-Wannier-Hr.html"><![CDATA[<p class="info">整理用Fortran读取Wannier90拟合的hr数据，后续设计到极化率以及响应之类的计算还是用Fortran的计算速度是最快的。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>在之前博客<a href="https://yxli8023.github.io/2021/12/07/HRToHK.html">利用Wannier90的hr数据构建动量空间能带并计算高对称点宇称</a>中用Python实现过读取Wannier90_hr.dat这个数据，当时只是涉及到计算一下能带以及拓扑不变量，此时不会遇到一些计算瓶颈。在涉及到一些响应系数或者RPA极化率计算
的时候Python用起来就有点慢了，所以干脆也就用Fortran写一个读取Wannier90_hr.dat的程序，方面以后自己使用。</p>

<h1 id="代码">代码</h1>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">numk_bz</span><span class="p">,</span><span class="n">num_wann</span><span class="p">,</span><span class="n">nrpts</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">,</span><span class="n">kn</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">kn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="n">mu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.1415926535897</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">deltaE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.01</span><span class="w">  </span><span class="c1">! 费米面展宽</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w"> </span><span class="c1">!Imagine unit</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">ones_ham</span><span class="p">(:,:)</span><span class="w">  </span><span class="c1">! 为了后续考虑化学势</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">HmnR</span><span class="p">(:,:,:)</span><span class="w">  </span><span class="c1">! hr中的hopping</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">irvec</span><span class="p">(:,:)</span><span class="w">  </span><span class="c1">! hr中的位置矢量</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">indorbit</span><span class="p">(:,:,:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">BZklist</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">FS_points</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">FS_index</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">
    </span><span class="c1">!------------------------------------------</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">FSindex</span><span class="p">(:,:)</span><span class="w">  </span><span class="c1">! 费米点索引指标</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">mpi</span><span class="w"> 
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="n">indcore</span><span class="p">,</span><span class="n">ierr</span><span class="w">
    </span><span class="c1">!-------------------------------------------------</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">code_time_start</span><span class="p">,</span><span class="n">code_time_end</span><span class="p">,</span><span class="n">code_time</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
    </span><span class="kt">character</span><span class="p">(</span><span class="nb">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">20</span><span class="p">)::</span><span class="n">filename</span><span class="p">,</span><span class="n">char1</span><span class="p">,</span><span class="n">char2</span><span class="p">,</span><span class="n">char3</span><span class="p">,</span><span class="n">char4</span><span class="w">
    </span><span class="c1">!-------------------------------------------------------------------</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_INIT</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">     </span><span class="c1">! 初始化进程</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_RANK</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">indcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">! 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该indcore为0到numcore-1间的整数,相当于进程的ID。)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_SIZE</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">!获得进程数量,用numcoer保存</span><span class="w">
    </span><span class="c1">! 循环分拆</span><span class="w">
    </span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
    </span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w"> 
    </span><span class="k">if</span><span class="p">(</span><span class="n">indcore</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="nb">CPU_TIME</span><span class="p">(</span><span class="n">code_time_start</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Start calcation: "</span><span class="p">,</span><span class="n">code_time_start</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Number of CPU = "</span><span class="p">,</span><span class="n">numcore</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Number of nk = "</span><span class="p">,</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">! 输出程序的基本参数信息</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">indcore</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Number of Fermi points = "</span><span class="p">,</span><span class="n">numk_FS</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Number of BZ points = "</span><span class="p">,</span><span class="n">numk_bz</span><span class="w">

        </span><span class="k">call</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">read_hr</span><span class="p">()</span><span class="w">  
        </span><span class="k">call</span><span class="w"> </span><span class="n">fermisurface</span><span class="p">()</span><span class="w">  </span><span class="c1">! 确定体系的费米面,其中会给出所有费米点的位置</span><span class="w">

        </span><span class="k">call</span><span class="w"> </span><span class="nb">CPU_TIME</span><span class="p">(</span><span class="n">code_time_end</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Calcation finished"</span><span class="p">,</span><span class="n">code_time_end</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Code execution time:"</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">code_time_end</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">code_time_start</span><span class="p">),</span><span class="s2">"second"</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Finalize</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">fermisurface</span><span class="p">()</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ibz</span><span class="p">,</span><span class="n">ie</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">mateigval</span><span class="p">(</span><span class="n">num_wann</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham_temp</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">),</span><span class="n">matvec</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">)</span><span class="w">
    </span><span class="c1">! call honeycomyBZ()</span><span class="w">
    </span><span class="k">open</span><span class="p">(</span><span class="mi">13</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"FS.dat"</span><span class="p">)</span><span class="w">
    </span><span class="c1">! numk_FS = 0   ! 全局变量,共计费米点的数量</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ibz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">numk_bz</span><span class="w">
        </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">ibz</span><span class="p">)</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">ibz</span><span class="p">)</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">HamR_to_K</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="mf">0.0</span><span class="p">,</span><span class="n">Ham_temp</span><span class="p">)</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">Ham_temp</span><span class="p">,</span><span class="n">matvec</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ie</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">mateigval</span><span class="p">(</span><span class="n">ie</span><span class="p">))</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">deltaE</span><span class="p">)</span><span class="k">then</span><span class="w">
                </span><span class="k">write</span><span class="p">(</span><span class="mi">13</span><span class="p">,</span><span class="s2">"(3F12.6)"</span><span class="p">)</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="mf">1.0</span><span class="w">
                </span><span class="n">numk_FS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numk_FS</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">  </span><span class="c1">! 统计费米点的数量</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">close</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span><span class="w">
    </span><span class="c1">!--------------------------------------------------------------</span><span class="w">
    </span><span class="c1">!确定费米面点的数量后就可以确定相互作用矩阵的维度</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">numk_FS</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"The Number of Fermi surface points = "</span><span class="p">,</span><span class="n">numk_FS</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"----------------------------------------------"</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"                    Warnning                  "</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"----------------------------------------------"</span><span class="w">
        </span><span class="k">stop</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="k">allocate</span><span class="p">(</span><span class="n">FS_points</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">))</span><span class="w">
        </span><span class="n">FS_points</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">!-----------------------------------------------</span><span class="w">
    </span><span class="c1">!  根据动量坐标记录这是第几个费米点</span><span class="w">
    </span><span class="n">numk_FS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">   
    </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">HamR_to_K</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="mf">0.0</span><span class="p">,</span><span class="n">Ham_temp</span><span class="p">)</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">Ham_temp</span><span class="p">,</span><span class="n">matvec</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">ie</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">mateigval</span><span class="p">(</span><span class="n">ie</span><span class="p">))</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">deltaE</span><span class="p">)</span><span class="k">then</span><span class="w">
                    </span><span class="n">numk_FS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numk_FS</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> 
                    </span><span class="n">FS_index</span><span class="p">(</span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numk_FS</span><span class="w">   
                    </span><span class="n">FS_points</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">kx</span><span class="w">
                    </span><span class="n">FS_points</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ky</span><span class="w">
                </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">

</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">i0</span><span class="w">
    </span><span class="c1">! 对于四方点阵,BZ的点数可以直接确定</span><span class="w">
    </span><span class="n">numk_bz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">   
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">))</span><span class="w">
    </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w"> 
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">return</span><span class="w">  
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">HamR_to_K</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">kz</span><span class="p">,</span><span class="n">Ham_temp</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 将hr变成动量空间</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">kz</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="p">,</span><span class="n">i3</span><span class="p">,</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">,</span><span class="n">r1</span><span class="p">,</span><span class="n">r2</span><span class="p">,</span><span class="n">r3</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham_temp</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">)</span><span class="w">

    </span><span class="n">ones_ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">   </span><span class="c1">! 对于具有allocatable属性的变量,一定要先赋值为零</span><span class="w">
    </span><span class="c1">! 设置单位矩阵</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
        </span><span class="n">ones_ham</span><span class="p">(</span><span class="n">i1</span><span class="p">,</span><span class="n">i1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w"> 


    </span><span class="n">Ham_temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">nrpts</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">i2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">i3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
                </span><span class="n">r1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irvec</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i1</span><span class="p">)</span><span class="w">
                </span><span class="n">r2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irvec</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i1</span><span class="p">)</span><span class="w">
                </span><span class="n">r3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irvec</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="n">i1</span><span class="p">)</span><span class="w">
                </span><span class="n">w1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">indorbit</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="p">,</span><span class="n">i3</span><span class="p">)</span><span class="w">
                </span><span class="n">w2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">indorbit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="p">,</span><span class="n">i3</span><span class="p">)</span><span class="w">
                </span><span class="n">Ham_temp</span><span class="p">(</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham_temp</span><span class="p">(</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">  </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ky</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r3</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ky</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">r3</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">HmnR</span><span class="p">(</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">,</span><span class="n">i1</span><span class="p">)</span><span class="w"> 
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">Ham_temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham_temp</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ones_ham</span><span class="w">   </span><span class="c1">! 在Wannier90_hr的基础上考虑体系的化学势</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">read_hr</span><span class="p">()</span><span class="w">
    </span><span class="c1">! 读取DFT的hr数据,并返回Hr以及</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">r1</span><span class="p">,</span><span class="n">r2</span><span class="p">,</span><span class="n">r3</span><span class="p">,</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">hr</span><span class="p">,</span><span class="n">hi</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">ndegen</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">logical</span><span class="w"> </span><span class="n">stat</span><span class="w">

    </span><span class="k">inquire</span><span class="p">(</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'wannier90_hr.dat'</span><span class="p">,</span><span class="w"> </span><span class="n">exist</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">stat</span><span class="p">)</span><span class="w">  
    </span><span class="k">if</span><span class="p">(</span><span class="n">stat</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'wannier90_hr.dat'</span><span class="p">,</span><span class="n">action</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'read'</span><span class="p">)</span><span class="w">
        </span><span class="k">read</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w">
        </span><span class="k">read</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">num_wann</span><span class="w">  </span><span class="c1">! 轨道数量,也决定了动量空间哈密顿量维度,这是一个全局变量</span><span class="w">
        </span><span class="c1">! read(12,*)r1</span><span class="w">
        </span><span class="k">read</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">nrpts</span><span class="w">
        
        </span><span class="k">allocate</span><span class="p">(</span><span class="n">ndegen</span><span class="p">(</span><span class="n">nrpts</span><span class="p">))</span><span class="w">
        </span><span class="c1">!  全局变量</span><span class="w">
        </span><span class="k">allocate</span><span class="p">(</span><span class="n">HmnR</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">,</span><span class="n">nrpts</span><span class="p">),</span><span class="n">irvec</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="n">nrpts</span><span class="p">))</span><span class="w">
        </span><span class="k">allocate</span><span class="p">(</span><span class="n">indorbit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">nrpts</span><span class="p">,</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">))</span><span class="w">
        </span><span class="k">read</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="n">ndegen</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">nrpts</span><span class="p">)</span><span class="w">
        
        </span><span class="k">do</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">nrpts</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
                </span><span class="k">do</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">num_wann</span><span class="w">
                    </span><span class="k">read</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">r1</span><span class="p">,</span><span class="n">r2</span><span class="p">,</span><span class="n">r3</span><span class="p">,</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">,</span><span class="n">hr</span><span class="p">,</span><span class="n">hi</span><span class="w">
                    </span><span class="n">irvec</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r1</span><span class="w">
                    </span><span class="n">irvec</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r2</span><span class="w">
                    </span><span class="n">irvec</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r3</span><span class="w">
                    </span><span class="n">indorbit</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">w1</span><span class="w">   </span><span class="c1">! 哈密顿量中的轨道索引,后续构建动量空间哈密顿量使用</span><span class="w">
                    </span><span class="n">indorbit</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">w2</span><span class="w">
                    </span><span class="n">HmnR</span><span class="p">(</span><span class="n">w1</span><span class="p">,</span><span class="n">w2</span><span class="p">,</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w">  </span><span class="n">hr</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hi</span><span class="w"> 
                </span><span class="k">enddo</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span><span class="w">
        </span><span class="k">allocate</span><span class="p">(</span><span class="n">ones_ham</span><span class="p">(</span><span class="n">num_wann</span><span class="p">,</span><span class="n">num_wann</span><span class="p">))</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"**************** Error *********************"</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"Tight-binding dat is not exist"</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"**************** Error *********************"</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">read_hr</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">delta</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w">
    </span><span class="c1">!&gt;  Lorentz or gaussian expansion of the Delta function</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="p">,</span><span class="w"> </span><span class="k">only</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">dp</span><span class="p">,</span><span class="w"> </span><span class="n">pi</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="c1">! real(dp), intent(in) :: eta</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">x</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">delta</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">eta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.001</span><span class="w">

    </span><span class="c1">!&gt; Lorentz expansion</span><span class="w">
    </span><span class="c1">!delta= 1d0/pi*eta/(eta*eta+x*x)</span><span class="w">
 
    </span><span class="n">y</span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="p">/</span><span class="n">eta</span><span class="p">/</span><span class="n">eta</span><span class="p">/</span><span class="mf">2d0</span><span class="w">
 
    </span><span class="c1">!&gt; Gaussian broadening</span><span class="w">
    </span><span class="c1">!&gt; exp(-60) = 8.75651076269652e-27</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">y</span><span class="o">&gt;</span><span class="mf">60d0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
       </span><span class="n">delta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0d0</span><span class="w">
    </span><span class="k">else</span><span class="w">
       </span><span class="n">delta</span><span class="o">=</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">y</span><span class="p">)/</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">2d0</span><span class="o">*</span><span class="n">pi</span><span class="p">)/</span><span class="n">eta</span><span class="w">
    </span><span class="k">endif</span><span class="w">
 
    </span><span class="k">return</span><span class="w">
 </span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">delta</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵,这里的本征值是个复数</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">LDA</span><span class="p">,</span><span class="n">LDVL</span><span class="p">,</span><span class="n">LDVR</span><span class="p">,</span><span class="n">LWMAX</span><span class="p">,</span><span class="n">INFO</span><span class="p">,</span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)::</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">RWORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! write(*,*)matin</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">RWORK</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">

    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
       </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="c1">!    STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵求逆 </span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">work2</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">            </span><span class="c1">! work2 array for LAPACK</span><span class="w">
    </span><span class="kt">integer</span><span class="p">::</span><span class="n">ipiv</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">     </span><span class="c1">! pivot indices</span><span class="w">
    </span><span class="c1">! Store matin in matout to prevent it from being overwritten by LAPACK</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! SGETRF computes an LU factorization of a general M - by - N matrix A</span><span class="w">
    </span><span class="c1">! using partial pivoting with row interchanges .</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRF</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix is numerically singular!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w">  </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
    </span><span class="c1">! SGETRI computes the inverse of a matrix using the LU factorization</span><span class="w">
    </span><span class="c1">! computed by SGETRF.</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRI</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">work2</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="n">lwmax0</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="w"> </span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="绘图程序">绘图程序</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">rcParams</span>
<span class="kn">import</span> <span class="nn">matplotlib.cm</span> <span class="k">as</span> <span class="n">cm</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="n">plt</span><span class="p">.</span><span class="n">rc</span><span class="p">(</span><span class="s">'font'</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"font.size"</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
<span class="s">"mathtext.fontset"</span><span class="p">:</span><span class="s">'stix'</span><span class="p">,</span>
<span class="s">"font.serif"</span><span class="p">:</span> <span class="p">[</span><span class="s">'SimSun'</span><span class="p">],</span>
<span class="p">}</span>
<span class="n">rcParams</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">config</span><span class="p">)</span> <span class="c1"># Latex 字体设置
#----------------------------------------------------------------------------
</span><span class="k">def</span> <span class="nf">WannierDETband</span><span class="p">():</span>
    <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">abspath</span><span class="p">(</span><span class="s">'.'</span><span class="p">)</span>
    <span class="n">band_file</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'BAND.dat'</span><span class="p">)</span>
    <span class="n">knode_file</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'KLABELS'</span><span class="p">)</span>
    <span class="n">fermi_file</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'FERMI_ENERGY'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span>

    <span class="c1">#********************      DFT band ************************************************************   
</span>    <span class="n">band_data</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">band_file</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">1</span><span class="p">:],</span><span class="n">color</span> <span class="o">=</span> <span class="s">'b'</span><span class="p">,</span><span class="n">linewidth</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">,</span><span class="n">label</span> <span class="o">=</span> <span class="s">"DFT"</span><span class="p">)</span>
    <span class="n">xmin</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">min</span><span class="p">(</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">xmax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">ymin</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">min</span><span class="p">(</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">1</span><span class="p">:])</span>
    <span class="n">ymax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">band_data</span><span class="p">[:,</span><span class="mi">1</span><span class="p">:])</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xlim</span><span class="p">(</span><span class="n">xmin</span><span class="p">,</span><span class="n">xmax</span><span class="p">)</span>
    <span class="c1"># plt.ylim(ymin,ymax)
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">ylim</span><span class="p">(</span><span class="o">-</span><span class="mi">6</span><span class="p">,</span><span class="mi">6</span><span class="p">)</span>

    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">knode_file</span><span class="p">,</span><span class="s">"r"</span><span class="p">,</span><span class="n">encoding</span> <span class="o">=</span> <span class="s">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
        <span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">readlines</span><span class="p">()</span>
    <span class="n">lines</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span>
    <span class="n">knodes</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)):</span>
        <span class="n">knodes</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
        <span class="n">knodes</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">knodes</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
        <span class="n">plt</span><span class="p">.</span><span class="n">axvline</span><span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="n">knodes</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span><span class="n">linewidth</span> <span class="o">=</span> <span class="mf">1.5</span><span class="p">,</span><span class="n">color</span> <span class="o">=</span> <span class="s">'silver'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">axhline</span><span class="p">(</span><span class="n">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">linewidth</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">,</span><span class="n">color</span> <span class="o">=</span> <span class="s">'b'</span><span class="p">,</span><span class="n">ls</span> <span class="o">=</span> <span class="s">"-."</span><span class="p">)</span>
    <span class="n">knodes</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">knodes</span><span class="p">)))</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xticks</span><span class="p">(</span><span class="n">knodes</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="nb">list</span><span class="p">(</span><span class="n">knodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span><span class="n">fontproperties</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">)</span>


    <span class="c1">#********************      Wannier band  ******************** 
</span>    <span class="n">wannier_bandfile</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'wannier90_band.dat'</span><span class="p">)</span>
    <span class="n">wannier_kptfile</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'wannier90_band.kpt'</span><span class="p">)</span>
    <span class="n">wannier_labkptfile</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'wannier90_band.labelinfo.dat'</span><span class="p">)</span>
    <span class="n">fermi_file</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="s">'FERMI_ENERGY'</span><span class="p">)</span>
    <span class="n">wannier_print</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">exists</span><span class="p">(</span><span class="n">wannier_bandfile</span><span class="p">)</span> <span class="ow">is</span> <span class="bp">True</span> <span class="ow">and</span> <span class="n">wannier_print</span> <span class="ow">is</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">wann_k</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">wannier_kptfile</span><span class="p">,</span><span class="s">"r"</span><span class="p">,</span><span class="n">encoding</span> <span class="o">=</span> <span class="s">"utf-8"</span><span class="p">)</span>
        <span class="n">wann_l</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">wannier_labkptfile</span><span class="p">,</span><span class="s">"r"</span><span class="p">,</span><span class="n">encoding</span> <span class="o">=</span> <span class="s">"utf-8"</span><span class="p">)</span>
        <span class="n">n_k</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">wann_k</span><span class="p">.</span><span class="n">readlines</span><span class="p">()[</span><span class="mi">0</span><span class="p">]))</span>
        <span class="n">lab</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">re</span><span class="p">.</span><span class="n">findall</span><span class="p">(</span><span class="s">'[A-Z]*[A-Z]'</span><span class="p">,</span><span class="n">wann_l</span><span class="p">.</span><span class="n">read</span><span class="p">()))</span>
        <span class="n">fermi_energy</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">fermi_file</span><span class="p">)</span>
        <span class="n">wann_k</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">wann_l</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">wb</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">wannier_bandfile</span><span class="p">)</span>
        <span class="n">wj</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">wb</span><span class="p">)</span><span class="o">/</span><span class="n">n_k</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">wj</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">j</span> <span class="o">==</span> <span class="n">wj</span> <span class="o">-</span> <span class="mi">2</span><span class="p">:</span>
                <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">wb</span><span class="p">[:,</span><span class="mi">0</span><span class="p">][</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="p">:</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="o">+</span><span class="n">n_k</span><span class="p">],</span><span class="n">wb</span><span class="p">[:,</span><span class="mi">1</span><span class="p">][</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="p">:</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="o">+</span><span class="n">n_k</span><span class="p">]</span> <span class="o">-</span> <span class="n">fermi_energy</span><span class="p">,</span><span class="n">color</span> <span class="o">=</span> <span class="s">'r'</span><span class="p">,</span><span class="n">ls</span> <span class="o">=</span> <span class="s">'--'</span><span class="p">,</span><span class="n">linewidth</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">,</span><span class="n">label</span> <span class="o">=</span> <span class="s">"Wannier"</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">wb</span><span class="p">[:,</span><span class="mi">0</span><span class="p">][</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="p">:</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="o">+</span><span class="n">n_k</span><span class="p">],</span><span class="n">wb</span><span class="p">[:,</span><span class="mi">1</span><span class="p">][</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="p">:</span><span class="n">j</span><span class="o">*</span><span class="n">n_k</span><span class="o">+</span><span class="n">n_k</span><span class="p">]</span> <span class="o">-</span> <span class="n">fermi_energy</span><span class="p">,</span><span class="n">color</span> <span class="o">=</span> <span class="s">'r'</span><span class="p">,</span><span class="n">ls</span> <span class="o">=</span> <span class="s">'--'</span><span class="p">,</span><span class="n">linewidth</span> <span class="o">=</span> <span class="mf">2.0</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s">'upper right'</span><span class="p">,</span> <span class="n">shadow</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="n">fancybox</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
    <span class="c1">#********************************************************************************       
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="s">"bandstructure.png"</span><span class="p">,</span><span class="n">dpi</span> <span class="o">=</span> <span class="mi">300</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">,</span><span class="n">transparent</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="c1">#-----------------------------------------------------------------------------------------------------
</span><span class="k">def</span> <span class="nf">plotfs</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="n">numk</span><span class="p">):</span>
    <span class="c1"># 费米面以及极化率绘制
</span>    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"fermi-mu-"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">mu</span><span class="p">)</span> <span class="o">+</span> <span class="s">"-numk-"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">numk</span><span class="p">)</span> <span class="o">+</span> <span class="s">".dat"</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"FS.dat"</span>
    <span class="c1"># dataname = "Honeycomb-fermi-mu-" + str(mu) + ".dat"
</span>    <span class="c1"># dataname = "Square-fermi-mu-" + str(mu) + ".dat"
</span>    <span class="c1"># dataname = "fermi-mu-" + str(mu) + ".dat"
</span>    <span class="c1"># dataname = "Honeycomb-fermivs-" + str(mu) + ".dat"
</span>    <span class="c1"># dataname = "maxvals-chi0-" + str(numk) + ".dat"
</span>    <span class="c1"># picname = os.path.splitext(dataname)[0] + "-" + str(num) + ".png"
</span>    <span class="n">picname</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">dataname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">".png"</span>
    <span class="n">da</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">dataname</span><span class="p">)</span> 
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span>
    <span class="n">sc</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">da</span><span class="p">[:,</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="n">da</span><span class="p">[:,</span><span class="mi">2</span><span class="p">],</span><span class="n">cmap</span> <span class="o">=</span> <span class="s">"jet"</span><span class="p">)</span>
    <span class="c1">#-------------------------------------------------
</span>    <span class="n">r0</span> <span class="o">=</span> <span class="mi">5</span> 
    <span class="nb">hex</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="o">-</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="o">-</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="o">-</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span><span class="p">,</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span> <span class="o">*</span> <span class="n">r0</span><span class="p">]</span>
    <span class="n">hey</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="mi">3</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="mi">3</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="mi">0</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">4</span> <span class="o">*</span> <span class="n">r0</span> <span class="p">,</span><span class="mi">0</span> <span class="o">*</span> <span class="n">r0</span><span class="p">]</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="nb">hex</span><span class="p">,</span><span class="n">hey</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"black"</span><span class="p">,</span><span class="n">lw</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span><span class="n">ls</span> <span class="o">=</span> <span class="s">"--"</span><span class="p">)</span>
    <span class="c1">#-------------------------------------------------
</span>    <span class="n">cb</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">colorbar</span><span class="p">(</span><span class="n">sc</span><span class="p">,</span><span class="n">fraction</span> <span class="o">=</span> <span class="mf">0.1</span><span class="p">,</span><span class="n">ticks</span> <span class="o">=</span> <span class="p">[</span><span class="n">np</span><span class="p">.</span><span class="nb">min</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">2</span><span class="p">]),</span><span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">2</span><span class="p">])])</span>  <span class="c1"># 调整colorbar的大小和图之间的间距
</span>    <span class="c1"># cb.ax.set_yticklabels([r'$d_{3z^2-r^2}$', r'$d_{x^2-y^2}$']) 
</span>    <span class="n">xtic</span> <span class="o">=</span> <span class="p">[</span><span class="o">-</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">]</span>
    <span class="n">xticlab</span> <span class="o">=</span> <span class="p">[</span><span class="s">"$-2\pi$"</span><span class="p">,</span><span class="s">"$0$"</span><span class="p">,</span><span class="s">"$2\pi$"</span><span class="p">]</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xticks</span><span class="p">(</span><span class="n">xtic</span><span class="p">,</span><span class="nb">list</span><span class="p">(</span><span class="n">xticlab</span><span class="p">),</span><span class="n">fontproperties</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">40</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">yticks</span><span class="p">(</span><span class="n">xtic</span><span class="p">,</span><span class="nb">list</span><span class="p">(</span><span class="n">xticlab</span><span class="p">),</span><span class="n">fontproperties</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">40</span><span class="p">)</span>
    <span class="n">xmin</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">min</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">xmax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">ymin</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">min</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">1</span><span class="p">])</span>
    <span class="n">ymax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">1</span><span class="p">])</span>
    <span class="c1"># plt.xlim(xmin,xmax)
</span>    <span class="c1"># plt.ylim(ymin,ymax)
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">xlim</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">,</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylim</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">,</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">300</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">,</span><span class="n">transparent</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>

<span class="c1">#-----------------------------------------------------------------------------------------------------
# WannierDETband()
</span><span class="n">numk</span> <span class="o">=</span> <span class="mi">100</span>
<span class="n">mu</span> <span class="o">=</span> <span class="o">-</span><span class="mf">2.15</span>
<span class="n">plotfs</span><span class="p">(</span><span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">),</span><span class="nb">format</span><span class="p">(</span><span class="n">numk</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span>

</code></pre></div></div>
<p><img src="/assets/images/vasp/FS.png" alt="png" /></p>

<p>上面的所有文件可以<a href="/assets/data/read-hr.zip">点击这里下载</a></p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<table>
  <tr>
    <!-- 图片单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; border: 1px solid #ccc; border-radius: 8px;">
      <img src="/assets/images/qrcode.jpg" alt="QR Code" width="300px" height="300px" style="border-radius: 8px;" />
    </td>
    <!-- 文字单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; padding-left: 20px; border: 1px solid #ccc; border-radius: 8px;">
      <div>
        <h4 style="margin: 0;">Email</h4>
        <p style="margin: 5px 0;">yxli406@gmail.com</p>
      </div>
    </td>
  </tr>
</table>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><summary type="html"><![CDATA[整理用Fortran读取Wannier90拟合的hr数据，后续设计到极化率以及响应之类的计算还是用Fortran的计算速度是最快的。]]></summary></entry><entry><title type="html">Fortran踩坑记录(持续更新中)</title><link href="https://yxli8023.github.io//2024/11/01/Fortran-trick.html" rel="alternate" type="text/html" title="Fortran踩坑记录(持续更新中)" /><published>2024-11-01T00:00:00+08:00</published><updated>2024-11-01T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/11/01/Fortran-trick</id><content type="html" xml:base="https://yxli8023.github.io//2024/11/01/Fortran-trick.html"><![CDATA[<p class="info">最近在用<code class="language-plaintext highlighter-rouge">Fortran</code>写程序的时候，在意想不到的地方踩了坑，这篇Bolg整理一下。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>用<code class="language-plaintext highlighter-rouge">Fortran</code>写程序主打一个方便，只要把公式翻译成代码就行了，但是在码代码的时候还是遇到了一些意想不到的问题，这里整理一下，方便自己查阅闭坑。</p>

<h2 id="费米分布函数">费米分布函数</h2>

<p>在把费米分布转成代码为</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 费米分布函数</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="p">,</span><span class="n">ek</span><span class="p">,</span><span class="n">kbt</span><span class="w">
    </span><span class="n">kbt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.01</span><span class="w">
    </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">/(</span><span class="nb">exp</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">  
    </span><span class="c1">! fermi = ek </span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w">
</span></code></pre></div></div>

<p>但这里有$e^x$指数函数，如果$x$足够大的话，如果是在单精度下面(dp = kind(1.0))，此时分布函数就会溢出。不过就算使用双精度(kind(1.0d0))，还是无法完全避免数据溢出这个问题，所以最好的方式就是给定一个阈值，判断在哪些范围内可以使用费米分布函数，其他范围就是0或者1，取决于该量子态是占据还是非占据</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  万万不能直接用费米分布函数，会存在浮点溢出</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="p">,</span><span class="n">ek</span><span class="p">,</span><span class="n">kbt</span><span class="w">
    </span><span class="n">kbt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.001</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="o">&gt;</span><span class="mi">-40</span><span class="w"> </span><span class="ow">.and.</span><span class="w"> </span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="o">&lt;</span><span class="mi">40</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">/(</span><span class="nb">exp</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> 
    </span><span class="k">if</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="w"> </span><span class="o">&lt;</span><span class="mi">-40</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="w"> </span><span class="o">&gt;</span><span class="mi">40</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> 
</span></code></pre></div></div>
<p>除了上面的截断方式，还可以在能量大于零和小于零的情形下，对费米分布函数做一下变形处理，在数值上避免发散</p>

\[f(E) = 
\begin{cases}
    \frac{e^{-E/(k_B T)}}{1 + e^{-E/(k_B T)}}, &amp; E &gt; 0 \\
    \frac{1}{1 + e^{E/(k_B T)}}, &amp; E \leq 0
\end{cases}\]

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">beta</span><span class="w">
    </span><span class="n">beta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="n">kbt</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ek</span><span class="w"> </span><span class="ow">.le.</span><span class="w"> </span><span class="mf">0.0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="nb">exp</span><span class="p">(</span><span class="n">beta</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ek</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">beta</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ek</span><span class="p">)</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">beta</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ek</span><span class="p">))</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="w">
</span></code></pre></div></div>

<p>如果只是单纯的考虑零温情形，那么就可以使用阶跃函数来代替费米分布</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">fermi</span><span class="p">,</span><span class="n">ek</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">then</span><span class="w">
      </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="k">else</span><span class="w">
      </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> 
</span></code></pre></div></div>

<p>有限温度下，对费米分布的导数为</p>

\[f'(E)=-\frac{1}{4k_BT}sech^2(\frac{E}{2k_BT})\]

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi_derivative</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">beta</span><span class="w">
    </span><span class="n">beta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="n">kbt</span><span class="w">
    </span><span class="n">fermi_derivative</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.25</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">beta</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="nb">cosh</span><span class="p">(</span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">beta</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ek</span><span class="p">))</span><span class="o">**</span><span class="mi">2</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi_derivative</span><span class="w">
</span></code></pre></div></div>

<p>如果是零温极限，此时分布函数是阶跃函数，那么导数就是$\delta$函数的形式，此时在数值上可以利用高斯分布来代替</p>

\[f'(E)\approx-\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{E^2}{2\sigma^2}}\]

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi_derivative_low_temp</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 极低温下费米分布的导数,这里使用高斯展宽代替</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">
    </span><span class="n">fermi_derivative_low_temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-1.0</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">sigma</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">ek</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">sigma</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi_derivative_low_temp</span><span class="w">
</span></code></pre></div></div>
<p>其中的$\sigma$就是展宽，具体这个值取多少需要根据程序计算的曲线平滑程度或者经验进行确定。</p>

<h2 id="动态数组赋值">动态数组赋值</h2>

<p>在<code class="language-plaintext highlighter-rouge">Fortran</code>中经常会用到可变大小的数组，通常会在程序执行过程中来确定数组的大小。但这个时候还是需要对数组进行初始化，但有时候会有错误的初始化，比如</p>

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">ones</span><span class="p">(:,:)</span><span class="w">

</span><span class="k">allocate</span><span class="p">(</span><span class="n">ones</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span><span class="w">

</span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="mi">10</span><span class="w">
    </span><span class="n">ones</span><span class="p">(</span><span class="n">i0</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

</span></code></pre></div></div>
<p>好吧，这是一个错误的示范，因为这里只是对对角元素进行了赋值，但没有对其它位置的元素赋值。所以在后面的程序中如果使用了<code class="language-plaintext highlighter-rouge">ones</code>这个数组，那么必然就会得到错误的结果，因为其它位置的元素在这里没有赋值，但是<code class="language-plaintext highlighter-rouge">Fortran</code>对于这种动态类型的数组，不会默认其初始位置都是零，所以那些没有赋值的地方，数据的指向就是奇奇怪怪的地方，计算结果必然是错的。</p>

<p>正确的做法应该是先对确定大小的动态数组的所有元素进行初始化，然后再填入相对应的值</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">ones</span><span class="p">(:,:)</span><span class="w">

</span><span class="k">allocate</span><span class="p">(</span><span class="n">ones</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span><span class="w">
</span><span class="n">ones</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

</span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="mi">10</span><span class="w">
    </span><span class="n">ones</span><span class="p">(</span><span class="n">i0</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

</span></code></pre></div></div>

<ul>
  <li>并行可变大小数组声明以及初始化</li>
</ul>

<p>在并行计算的时候，声明一个可变大小的数组，在确定其矩阵维度之后要对这个矩阵进行初始化，不然在每个进程中，不计算的部分都具有不同的初始值，最后在收集数据的时候就可能得到错误的数据结果</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">Veff_vec</span><span class="p">(:,:)</span><span class="w">
</span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">Veff_val</span><span class="p">(:)</span><span class="w">
</span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">Veff</span><span class="p">(:,:)</span><span class="w">  </span><span class="c1">! 存储费米面上的相互作用,其维度由费米点的数量决定</span><span class="w">
</span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">Veff_mpi</span><span class="p">(:,:)</span><span class="w">  </span><span class="c1">! 存储费米面上的相互作用,其维度由费米点的数量决定</span><span class="w">

</span><span class="k">if</span><span class="p">(</span><span class="n">numk_FS</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
    </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"The Number of Fermi surface points = "</span><span class="p">,</span><span class="n">numk_FS</span><span class="w">
    </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"----------------------------------------------"</span><span class="w">
    </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"                    Error                     "</span><span class="w">
    </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"----------------------------------------------"</span><span class="w">
</span><span class="k">else</span><span class="w">
    </span><span class="c1">! write(*,"(A30,10F20.8)")"Number of Fermi surface points = ",numk_FS</span><span class="w">

    </span><span class="k">allocate</span><span class="p">(</span><span class="n">Veff_mpi</span><span class="p">(</span><span class="n">numk_FS</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">Veff</span><span class="p">(</span><span class="n">numk_FS</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">Veff_vec</span><span class="p">(</span><span class="n">numk_FS</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">))</span><span class="w">  
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">Veff_val</span><span class="p">(</span><span class="n">numk_FS</span><span class="p">))</span><span class="w">
    </span><span class="n">Veff_mpi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">    </span><span class="c1">! 一定要对这些数据进行初始化</span><span class="w">
    </span><span class="n">Veff</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Veff_vec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Veff_val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

</span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
</span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
</span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w">
</span><span class="c1">!   中间是具体计算过程</span><span class="w">
</span><span class="k">enddo</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

</span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">   
</span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">Veff_mpi</span><span class="p">,</span><span class="w"> </span><span class="n">Veff</span><span class="p">,</span><span class="w"> </span><span class="n">numk_FS</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_REAL</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
</span><span class="k">call</span><span class="w"> </span><span class="n">MPI_BCAST</span><span class="p">(</span><span class="n">Veff</span><span class="p">,</span><span class="w"> </span><span class="n">numk_FS</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_REAL</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> 
</span></code></pre></div></div>

<h1 id="函数声明">函数声明</h1>
<p>一般Fortran默认的都是单精度，可以自行改变成双精度，比如对于零温费米分布函数</p>

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 零温下的分布函数</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">   </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">fermi</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ek</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0.0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="w">
</span></code></pre></div></div>
<p>在主程序或者其他子过程、函数中调用双精度的费米分布函数时，就需要明确声明精度</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">   </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">fermi</span><span class="w">

    </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span></code></pre></div></div>
<p>有时候也会习惯在函数声明的时候就直接确定精度</p>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 零温下的分布函数</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">   </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ek</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0.0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="w">
</span></code></pre></div></div>
<p>需要说明的是，对于后面这种方式定义的费米分布，在双精度情形下使用时是<strong>错误</strong>的方式，因为此时在函数定义的时候声明，控制精度的dp是不明确的，为了保险起见还是采用第一种方式来声明函数精度。</p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><summary type="html"><![CDATA[最近在用Fortran写程序的时候，在意想不到的地方踩了坑，这篇Bolg整理一下。]]></summary></entry><entry><title type="html">正方晶格超导序参量自洽</title><link href="https://yxli8023.github.io//2024/10/31/Square-SC.html" rel="alternate" type="text/html" title="正方晶格超导序参量自洽" /><published>2024-10-31T00:00:00+08:00</published><updated>2024-10-31T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/10/31/Square-SC</id><content type="html" xml:base="https://yxli8023.github.io//2024/10/31/Square-SC.html"><![CDATA[<p class="info">最近在学习计算超导体系的超流权重，其中要涉及到在确定相互作用$U$下自洽出序参量，虽然之前也会，为了保证所有结果的正确性，这里重新将一些过程记录一下，方便后面查阅理解。</p>
<!--more-->
<h1 id="超导序参量自洽">超导序参量自洽</h1>
<p><img src="/assets/images/Note/sc-1.png" alt="png" /></p>

<p><img src="/assets/images/Note/sc-2.png" alt="png" /></p>

<h1 id="代码">代码</h1>
<h2 id="fortran-version">Fortran Version</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="c1">!  计算自由电子的超流权重</span><span class="w">
</span><span class="c1">!  H(k) = t(cos kx + cos ky)  正方晶格最近邻</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">acos</span><span class="p">(</span><span class="mf">-1.0_dp</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w">                 </span><span class="c1">!   Imagine unit  </span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">hn</span><span class="p">,</span><span class="n">hnn</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">,</span><span class="n">kn</span><span class="p">,</span><span class="n">numk_FS</span><span class="p">,</span><span class="n">Un</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kbt</span><span class="p">,</span><span class="n">delta_E</span><span class="p">,</span><span class="n">delta_k</span><span class="p">,</span><span class="n">engcut</span><span class="p">,</span><span class="n">sigma</span><span class="p">,</span><span class="n">Umax</span><span class="w">     
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">t1</span><span class="p">,</span><span class="n">mu</span><span class="w">  </span><span class="c1">! 哈密顿量参数</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">t1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">mu</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="n">hnn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn</span><span class="p">/</span><span class="mi">2</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2e2</span><span class="w"> </span><span class="p">,</span><span class="n">Un</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="n">Umax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="n">kbt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-5</span><span class="p">,</span><span class="n">delta_E</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-5</span><span class="p">,</span><span class="n">engcut</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="n">sigma</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-5</span><span class="p">,</span><span class="n">delta_k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">/</span><span class="n">kn</span><span class="p">)</span><span class="w">  </span><span class="c1">! hn: 哈密顿量维度</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">BZklist</span><span class="p">(:,:)</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">code_param</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">mpi</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="n">indcore</span><span class="p">,</span><span class="n">ierr</span><span class="p">,</span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i0</span><span class="p">,</span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">U0_mpi</span><span class="p">(</span><span class="n">Un</span><span class="p">),</span><span class="n">U0_list</span><span class="p">(</span><span class="n">Un</span><span class="p">),</span><span class="n">U0</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">da_mpi</span><span class="p">(</span><span class="n">Un</span><span class="p">),</span><span class="n">db_mpi</span><span class="p">(</span><span class="n">Un</span><span class="p">),</span><span class="n">da_list</span><span class="p">(</span><span class="n">Un</span><span class="p">),</span><span class="n">db_list</span><span class="p">(</span><span class="n">Un</span><span class="p">)</span><span class="w">
    </span><span class="c1">!-----------------------------------------------------------------------------------------------------------------</span><span class="w">
    </span><span class="c1">!#######################################         并行计算设置      #######################################</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_INIT</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">     </span><span class="c1">! 初始化进程</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_RANK</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">indcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">! 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该indcore为0到numcore-1间的整数,相当于进程的ID。)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_SIZE</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">!获得进程数量,用numcoer保存</span><span class="w">
    </span><span class="c1">! 并行循环分拆</span><span class="w">
    </span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Un</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Un</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w">
    </span><span class="c1">!------------------------------------------------------------------------------------------------------------------</span><span class="w">
    </span><span class="c1">! 预设布里渊区撒点</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">  
    </span><span class="c1">!------------------------------------------------------------------------------------------------------------------</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="n">indcore</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">Fermi_surface</span><span class="p">()</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">!------------------------------------------------------------------------------------------------------------------</span><span class="w">
    </span><span class="c1">! 测试超流权重随相互作用U的变化，同时在每个U下面要自洽超导序参量</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
        </span><span class="n">U0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Umax</span><span class="p">/</span><span class="n">Un</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">   </span><span class="c1">! 改变相互作用强度</span><span class="w">
        </span><span class="n">U0_mpi</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">gap_equation</span><span class="p">(</span><span class="n">U0</span><span class="p">,</span><span class="n">da_mpi</span><span class="p">(</span><span class="n">i0</span><span class="p">))</span><span class="w"> </span><span class="c1">!  自洽序参量</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">   </span><span class="c1">! 等所有核心都计算完成r)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">U0_mpi</span><span class="p">,</span><span class="w"> </span><span class="n">U0_list</span><span class="p">,</span><span class="w"> </span><span class="n">Un</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_REAL</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">da_mpi</span><span class="p">,</span><span class="w"> </span><span class="n">da_list</span><span class="p">,</span><span class="w"> </span><span class="n">Un</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMPLEX</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">

    </span><span class="k">if</span><span class="p">(</span><span class="n">indcore</span><span class="ow">.eq.</span><span class="mi">0</span><span class="p">)</span><span class="k">then</span><span class="w">
        </span><span class="c1">! 数据读写</span><span class="w">

        </span><span class="k">open</span><span class="p">(</span><span class="mi">32</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"fortran-order.dat"</span><span class="p">)</span><span class="w">  </span><span class="c1">! 序参量</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">Un</span><span class="w">
            </span><span class="k">write</span><span class="p">(</span><span class="mi">32</span><span class="p">,</span><span class="s2">"(9F15.8)"</span><span class="p">)</span><span class="n">U0_list</span><span class="p">(</span><span class="n">i0</span><span class="p">),</span><span class="kt">real</span><span class="p">(</span><span class="n">da_list</span><span class="p">(</span><span class="n">i0</span><span class="p">)),</span><span class="nb">aimag</span><span class="p">(</span><span class="n">da_list</span><span class="p">(</span><span class="n">i0</span><span class="p">))</span><span class="w">
        </span><span class="k">enddo</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span><span class="w">
    </span><span class="k">endif</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Finalize</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">

</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">gap_equation</span><span class="p">(</span><span class="n">U0</span><span class="p">,</span><span class="n">delta_A</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  自洽序参量,然后通过参数返回</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">delta_A</span><span class="p">,</span><span class="n">delta_B</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">matvec</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">new_deltaA</span><span class="p">,</span><span class="n">old_deltaA</span><span class="p">,</span><span class="n">new_deltaB</span><span class="p">,</span><span class="n">old_deltaB</span><span class="p">,</span><span class="n">mat_temp</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">matval</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">diff_delta</span><span class="p">,</span><span class="n">diff_A</span><span class="p">,</span><span class="n">diff_B</span><span class="p">,</span><span class="n">ones_mat</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">U0</span><span class="w">   </span><span class="c1">! diff_delta : 控制序参量自洽精度</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ik0</span><span class="p">,</span><span class="n">ie0</span><span class="p">,</span><span class="n">ref</span><span class="p">,</span><span class="n">matdim</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">diff_delta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1e-5</span><span class="p">,</span><span class="n">matdim</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">external</span><span class="p">::</span><span class="n">fermi</span><span class="w">
    </span><span class="c1">! 初猜化学势</span><span class="w">
    </span><span class="n">old_deltaA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.1</span><span class="w">
    </span><span class="n">diff_A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">diff_delta</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1.0</span><span class="w">  </span><span class="c1">! 使循环能进入</span><span class="w">
    </span><span class="c1">! 自洽循环</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">diff_A</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">diff_delta</span><span class="p">)</span><span class="w">
        </span><span class="c1">! open(25,file = "self_loop.dat",access = 'append')</span><span class="w">
        </span><span class="c1">! 下面要重新自洽序参量</span><span class="w">
        </span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ik0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="nb">size</span><span class="p">(</span><span class="n">BZklist</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w">   </span><span class="c1">! 遍历布里渊区点</span><span class="w">
            </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
            </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">matset_BdG_SC</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">old_deltaA</span><span class="p">)</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">matvec</span><span class="p">,</span><span class="n">matval</span><span class="p">)</span><span class="w">

            </span><span class="c1">! Ref: Superconductivity in geometrically and topologically nontrivial lattice models</span><span class="w">
            </span><span class="c1">! 该公式需要 U &gt; 0</span><span class="w">
            </span><span class="n">ones_mat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">ie0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
                </span><span class="n">ones_mat</span><span class="p">(</span><span class="n">ie0</span><span class="p">,</span><span class="n">ie0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">matval</span><span class="p">(</span><span class="n">ie0</span><span class="p">))</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
            </span><span class="n">mat_temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">matmul</span><span class="p">(</span><span class="nb">matmul</span><span class="p">(</span><span class="n">matvec</span><span class="p">,</span><span class="n">ones_mat</span><span class="p">),</span><span class="nb">transpose</span><span class="p">(</span><span class="nb">conjg</span><span class="p">(</span><span class="n">matvec</span><span class="p">)))</span><span class="w">
            </span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">mat_temp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w">

        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="c1">! 自洽得到新的序参(归一化处理)</span><span class="w">
        </span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">U0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">delta_k</span><span class="o">**</span><span class="mi">2</span><span class="w">    </span><span class="c1">! 吸引相互作用才能自洽出超导</span><span class="w">
        </span><span class="c1">! 给定差异来停止自洽过程</span><span class="w">
        </span><span class="n">diff_A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">abs</span><span class="p">(</span><span class="n">new_deltaA</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">old_deltaA</span><span class="p">)</span><span class="w">
        </span><span class="c1">! 重新赋值继续自洽</span><span class="w">
        </span><span class="n">old_deltaA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new_deltaA</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="c1">!  返回自洽收敛后的序参量</span><span class="w">
    </span><span class="n">delta_A</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new_deltaA</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">Fermi_surface</span><span class="p">()</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ik0</span><span class="p">,</span><span class="n">ie</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">mateigval_1</span><span class="p">(</span><span class="n">hnn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham_up</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">hnn</span><span class="p">),</span><span class="n">Ham_down</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">hnn</span><span class="p">),</span><span class="n">mateigvec</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">hnn</span><span class="p">)</span><span class="w">
    </span><span class="k">open</span><span class="p">(</span><span class="mi">31</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"FS.dat"</span><span class="p">)</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ik0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">numk_bz</span><span class="w">
        </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">ik0</span><span class="p">)</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">matset_Normal</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham_up</span><span class="p">,</span><span class="n">Ham_down</span><span class="p">)</span><span class="w">
        </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">Ham_up</span><span class="p">,</span><span class="n">mateigvec</span><span class="p">,</span><span class="n">mateigval_1</span><span class="p">)</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ie</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hnn</span><span class="w">
            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">mateigval_1</span><span class="p">(</span><span class="n">ie</span><span class="p">))</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">1e-2</span><span class="p">)</span><span class="k">then</span><span class="w">  </span><span class="c1">! 给定能量确定费米面</span><span class="w">
                </span><span class="k">write</span><span class="p">(</span><span class="mi">31</span><span class="p">,</span><span class="s2">"(10F20.8)"</span><span class="p">)</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">close</span><span class="p">(</span><span class="mi">31</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset_BdG_SC</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="p">,</span><span class="w"> </span><span class="n">Ham_BdG</span><span class="p">,</span><span class="w"> </span><span class="n">delta_A</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 自由电子气 BdG 哈密顿量</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="w"> </span><span class="n">ky</span><span class="w">  </span><span class="c1">! 最近邻 &amp; 次近邻矢量</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">inout</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">Ham_BdG</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">hn</span><span class="p">),</span><span class="w"> </span><span class="n">delta_A</span><span class="w">

    </span><span class="c1">! Initialize Hamiltonian to zero</span><span class="w">
    </span><span class="n">Ham_BdG</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">

    </span><span class="c1">! Normal part (particle &amp; hole)</span><span class="w">
    </span><span class="n">Ham_BdG</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w">  </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">   </span><span class="c1">! particle</span><span class="w">
    </span><span class="n">Ham_BdG</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="p">(</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="p">)</span><span class="w">  </span><span class="c1">! hole</span><span class="w">

    </span><span class="c1">! Pairing</span><span class="w">
    </span><span class="n">Ham_BdG</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">delta_A</span><span class="w">
    </span><span class="n">Ham_BdG</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">delta_A</span><span class="p">)</span><span class="w">

    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset_BdG_SC</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset_Normal</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham_up</span><span class="p">,</span><span class="n">Ham_down</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  正常态哈密顿量构建</span><span class="w">
    </span><span class="c1">!  矩阵赋值,返回Ham_up &amp; Ham_down</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham_up</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">hnn</span><span class="p">),</span><span class="n">Ham_down</span><span class="p">(</span><span class="n">hnn</span><span class="p">,</span><span class="n">hnn</span><span class="p">)</span><span class="w">
    </span><span class="c1">!--------------------</span><span class="w">
    </span><span class="c1">! Spin-up</span><span class="w">
    </span><span class="n">Ham_up</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="c1">! s_0</span><span class="w">
    </span><span class="n">Ham_up</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w">
    </span><span class="c1">!--------------------</span><span class="w">
    </span><span class="c1">!H_{\ua}(k) = H_{\down}(k)</span><span class="w">
    </span><span class="c1">! Spin-down</span><span class="w">
    </span><span class="n">Ham_down</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham_down</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham_up</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="c1">! function fermi(ek)</span><span class="w">
</span><span class="c1">!     !  万万不能直接用费米分布函数，会存在浮点溢出</span><span class="w">
</span><span class="c1">!     use code_param,only:dp,kbt</span><span class="w">
</span><span class="c1">!     real(dp) fermi,ek</span><span class="w">
</span><span class="c1">!     fermi = 1.0/(exp(ek/kbt) + 1) </span><span class="w">
</span><span class="c1">!     return</span><span class="w">
</span><span class="c1">! end </span><span class="w">
</span><span class="c1">! function fermi(ek)</span><span class="w">
</span><span class="c1">!     !  万万不能直接用费米分布函数，会存在浮点溢出</span><span class="w">
</span><span class="c1">!     use code_param</span><span class="w">
</span><span class="c1">!     real(dp) fermi,ek</span><span class="w">
</span><span class="c1">!     if(ek/kbt &gt; -engcut .and. ek/kbt &lt; engcut) fermi = 1.0/(exp(ek/kbt) + 1) </span><span class="w">
</span><span class="c1">!     if(ek/kbt &lt; -engcut) fermi = 1.0</span><span class="w">
</span><span class="c1">!     if(ek/kbt &gt; engcut) fermi = 0.0</span><span class="w">
</span><span class="c1">!     return</span><span class="w">
</span><span class="c1">! end </span><span class="w">
</span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 零温下的分布函数</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ek</span><span class="w">

    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ek</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0.0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="k">else</span><span class="w">
        </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="w">
</span><span class="c1">!============================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">Gaussian_broadening</span><span class="p">(</span><span class="n">energy</span><span class="p">)</span><span class="w"> 
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">energy</span><span class="w"> 
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Gaussian_broadening</span><span class="w">
    </span><span class="n">Gaussian_broadening</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">energy</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">sigma</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="p">&amp;</span><span class="w">
            </span><span class="p">(</span><span class="n">sigma</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">pi</span><span class="p">))</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">function</span><span class="w"> </span><span class="n">Gaussian_broadening</span><span class="w">
</span><span class="c1">!============================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">squareBZ</span><span class="p">()</span><span class="w">
    </span><span class="c1">! 构建四方BZ</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">code_param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">i0</span><span class="w">
    </span><span class="c1">! 对于四方点阵,BZ的点数可以直接确定</span><span class="w">
    </span><span class="n">numk_bz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">   
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">numk_bz</span><span class="p">))</span><span class="w">
    </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">i0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="w">
            </span><span class="n">BZklist</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">i0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/(</span><span class="mf">1.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="w"> 
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">return</span><span class="w">  
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">

</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="n">lwmax0</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="w"> </span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">


</span></code></pre></div></div>

<blockquote>
  <p>程序运行</p>
  <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mpiifort <span class="nt">-mkl</span>  square-sc-mpi.f90 <span class="nt">-o</span> rpa
mpirun <span class="nt">-np</span> <span class="k">${</span><span class="nv">NUM_MPI</span><span class="k">}</span>  ./rpa
<span class="nb">rm </span>rpa code_param.mod
</code></pre></div>  </div>
</blockquote>

<h2 id="julia-version">Julia Version</h2>

<div class="language-julia highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#  自洽计算配对序参量</span>
<span class="c">#  H(k) = t(cos kx + cos ky)  正方晶格最近邻</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@everywhere</span> <span class="k">using</span> <span class="n">SharedArrays</span><span class="x">,</span><span class="n">LinearAlgebra</span><span class="x">,</span><span class="n">Distributed</span><span class="x">,</span><span class="n">DelimitedFiles</span><span class="x">,</span><span class="n">Printf</span><span class="x">,</span><span class="n">BenchmarkTools</span><span class="x">,</span><span class="n">Arpack</span><span class="x">,</span><span class="n">Dates</span>
<span class="c">#  利用Arpack进行稀疏矩阵对角化,因为只在RPA框架中一般只需要矩阵最大或者最小本征值</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@everywhere</span> <span class="k">function</span><span class="nf"> matset_SC</span><span class="x">(</span><span class="n">kx</span><span class="o">::</span><span class="kt">Float64</span><span class="x">,</span><span class="n">ky</span><span class="o">::</span><span class="kt">Float64</span><span class="x">,</span><span class="n">delta</span><span class="o">::</span><span class="kt">ComplexF64</span><span class="x">)</span>
    <span class="n">t1</span><span class="o">::</span><span class="kt">Float64</span> <span class="o">=</span> <span class="mf">1.0</span>
    <span class="n">mu</span><span class="o">::</span><span class="kt">Float64</span> <span class="o">=</span> <span class="mf">1.0</span>
    <span class="n">Ham</span> <span class="o">=</span> <span class="n">zeros</span><span class="x">(</span><span class="kt">ComplexF64</span><span class="x">,</span><span class="mi">2</span><span class="x">,</span><span class="mi">2</span><span class="x">)</span>
    <span class="n">Ham</span><span class="x">[</span><span class="mi">1</span><span class="x">,</span><span class="mi">1</span><span class="x">]</span> <span class="o">=</span> <span class="n">t1</span> <span class="o">*</span> <span class="x">(</span><span class="n">cos</span><span class="x">(</span><span class="n">kx</span><span class="x">)</span> <span class="o">+</span> <span class="n">cos</span><span class="x">(</span><span class="n">ky</span><span class="x">))</span> <span class="o">-</span> <span class="n">mu</span>
    <span class="n">Ham</span><span class="x">[</span><span class="mi">2</span><span class="x">,</span><span class="mi">2</span><span class="x">]</span> <span class="o">=</span> <span class="o">-</span><span class="n">t1</span> <span class="o">*</span> <span class="x">(</span><span class="n">cos</span><span class="x">(</span><span class="n">kx</span><span class="x">)</span> <span class="o">+</span> <span class="n">cos</span><span class="x">(</span><span class="n">ky</span><span class="x">))</span> <span class="o">+</span> <span class="n">mu</span>
    <span class="n">Ham</span><span class="x">[</span><span class="mi">1</span><span class="x">,</span><span class="mi">2</span><span class="x">]</span> <span class="o">=</span> <span class="n">delta</span>
    <span class="n">Ham</span><span class="x">[</span><span class="mi">2</span><span class="x">,</span><span class="mi">1</span><span class="x">]</span> <span class="o">=</span> <span class="n">conj</span><span class="x">(</span><span class="n">delta</span><span class="x">)</span>
    <span class="k">return</span> <span class="n">Ham</span>
<span class="k">end</span> 
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@everywhere</span> <span class="k">function</span><span class="nf"> BZpoints</span><span class="x">(</span><span class="n">kn</span><span class="o">::</span><span class="kt">Int64</span><span class="x">)</span>
    <span class="n">knn</span><span class="o">::</span><span class="kt">Int64</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">kn</span> <span class="o">+</span> <span class="mi">1</span>
    <span class="n">klist</span> <span class="o">=</span> <span class="n">zeros</span><span class="x">(</span><span class="kt">Float64</span><span class="x">,</span><span class="mi">2</span><span class="x">,</span><span class="n">knn</span><span class="o">^</span><span class="mi">2</span><span class="x">)</span>
    <span class="n">ik0</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">ikx</span> <span class="k">in</span> <span class="o">-</span><span class="n">kn</span><span class="o">:</span><span class="n">kn</span>
    <span class="k">for</span> <span class="n">iky</span> <span class="k">in</span> <span class="o">-</span><span class="n">kn</span><span class="o">:</span><span class="n">kn</span>
        <span class="n">ik0</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="n">klist</span><span class="x">[</span><span class="mi">1</span><span class="x">,</span><span class="n">ik0</span><span class="x">]</span> <span class="o">=</span> <span class="n">ikx</span> <span class="o">*</span> <span class="nb">pi</span><span class="o">/</span><span class="n">kn</span>
        <span class="n">klist</span><span class="x">[</span><span class="mi">2</span><span class="x">,</span><span class="n">ik0</span><span class="x">]</span> <span class="o">=</span> <span class="n">iky</span> <span class="o">*</span> <span class="nb">pi</span><span class="o">/</span><span class="n">kn</span>
    <span class="k">end</span> 
    <span class="k">end</span>
    <span class="k">return</span>  <span class="n">klist</span>
<span class="k">end</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="c"># @everywhere function fermi(ek::Float64)</span>
<span class="c">#     kbt::Float64 = 1E-10</span>
<span class="c">#     return 1.0/(exp(ek/kbt) + 1.0)</span>
<span class="c"># end</span>
<span class="nd">@everywhere</span> <span class="k">function</span><span class="nf"> fermi</span><span class="x">(</span><span class="n">ek</span><span class="o">::</span><span class="kt">Float64</span><span class="x">)</span>
    <span class="k">if</span> <span class="x">(</span><span class="n">ek</span><span class="o">&lt;</span><span class="mi">0</span><span class="x">)</span>
        <span class="k">return</span> <span class="mf">1.0</span>
    <span class="k">else</span>
        <span class="k">return</span> <span class="mf">0.0</span>
    <span class="k">end</span>
<span class="k">end</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@everywhere</span> <span class="k">function</span><span class="nf"> self_delta</span><span class="x">(</span><span class="n">U0</span><span class="o">::</span><span class="kt">Float64</span><span class="x">)</span>
    <span class="c"># 自洽计算配对序参量</span>
    <span class="n">delta</span><span class="o">::</span><span class="kt">ComplexF64</span> <span class="o">=</span> <span class="mf">0.1</span>
    <span class="n">delta_new</span><span class="o">::</span><span class="kt">ComplexF64</span> <span class="o">=</span> <span class="mf">0.1</span>
    <span class="n">diff_delta</span><span class="o">::</span><span class="kt">Float64</span> <span class="o">=</span> <span class="mf">0.1</span>
    <span class="n">diff_eps</span><span class="o">::</span><span class="kt">Float64</span> <span class="o">=</span> <span class="mf">1E-6</span>
    <span class="n">hn</span><span class="o">::</span><span class="kt">Int64</span> <span class="o">=</span> <span class="mi">2</span>   <span class="c"># 哈密顿量维度</span>
    <span class="n">re1</span> <span class="o">=</span> <span class="n">zeros</span><span class="x">(</span><span class="kt">Float64</span><span class="x">,</span><span class="n">hn</span><span class="x">,</span><span class="n">hn</span><span class="x">)</span>
    <span class="n">kn</span><span class="o">::</span><span class="kt">Int64</span> <span class="o">=</span> <span class="mf">2E2</span>
    <span class="n">dk</span><span class="o">::</span><span class="kt">Float64</span> <span class="o">=</span> <span class="mf">1.0</span><span class="o">/</span><span class="n">kn</span>
    <span class="n">klist</span> <span class="o">=</span> <span class="n">BZpoints</span><span class="x">(</span><span class="n">kn</span><span class="x">)</span>  <span class="c"># 布里渊区撒点</span>

    <span class="k">while</span> <span class="n">diff_delta</span> <span class="o">&gt;</span> <span class="n">diff_eps</span> 
        <span class="n">delta_new</span> <span class="o">=</span> <span class="mf">0.0</span>
        <span class="n">ik0</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">ikx</span> <span class="k">in</span> <span class="o">-</span><span class="n">kn</span><span class="o">:</span><span class="n">kn</span>
        <span class="k">for</span> <span class="n">iky</span> <span class="k">in</span> <span class="o">-</span><span class="n">kn</span><span class="o">:</span><span class="n">kn</span>
            <span class="n">ik0</span> <span class="o">+=</span> <span class="mi">1</span>
            <span class="n">kx</span> <span class="o">=</span> <span class="n">klist</span><span class="x">[</span><span class="mi">1</span><span class="x">,</span><span class="n">ik0</span><span class="x">]</span>
            <span class="n">ky</span> <span class="o">=</span> <span class="n">klist</span><span class="x">[</span><span class="mi">2</span><span class="x">,</span><span class="n">ik0</span><span class="x">]</span>
            <span class="n">Ham</span> <span class="o">=</span> <span class="n">matset_SC</span><span class="x">(</span><span class="n">kx</span><span class="x">,</span><span class="n">ky</span><span class="x">,</span><span class="n">delta</span><span class="x">)</span>
            <span class="n">val</span><span class="x">,</span><span class="n">vec</span> <span class="o">=</span> <span class="n">eigen</span><span class="x">(</span><span class="n">Ham</span><span class="x">)</span>
            <span class="k">for</span> <span class="n">ie0</span> <span class="k">in</span> <span class="mi">1</span><span class="o">:</span><span class="n">hn</span>
                <span class="n">re1</span><span class="x">[</span><span class="n">ie0</span><span class="x">,</span><span class="n">ie0</span><span class="x">]</span> <span class="o">=</span> <span class="n">fermi</span><span class="x">(</span><span class="n">real</span><span class="x">(</span><span class="n">val</span><span class="x">[</span><span class="n">ie0</span><span class="x">]))</span>
            <span class="k">end</span>
            <span class="n">temp</span> <span class="o">=</span> <span class="n">vec</span> <span class="o">*</span> <span class="n">re1</span> <span class="o">*</span> <span class="n">vec</span><span class="err">'</span>
            <span class="n">delta_new</span> <span class="o">+=</span> <span class="n">temp</span><span class="x">[</span><span class="mi">1</span><span class="x">,</span><span class="mi">2</span><span class="x">]</span>
        <span class="k">end</span> 
        <span class="k">end</span>
        <span class="n">delta_new</span> <span class="o">=</span> <span class="o">-</span><span class="n">U0</span> <span class="o">*</span> <span class="n">delta_new</span> <span class="o">*</span> <span class="n">dk</span><span class="o">^</span><span class="mi">2</span>
        <span class="n">diff_delta</span> <span class="o">=</span> <span class="n">abs</span><span class="x">(</span><span class="n">delta_new</span> <span class="o">-</span> <span class="n">delta</span><span class="x">)</span>
        <span class="n">delta</span> <span class="o">=</span> <span class="n">delta_new</span>
    <span class="k">end</span> 
    <span class="k">return</span> <span class="n">delta</span>
<span class="k">end</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@everywhere</span> <span class="k">function</span><span class="nf"> main</span><span class="x">()</span>
    <span class="n">Un</span><span class="o">::</span><span class="kt">Int64</span> <span class="o">=</span> <span class="mi">100</span>
    <span class="n">U0list</span> <span class="o">=</span> <span class="n">range</span><span class="x">(</span><span class="mi">0</span><span class="x">,</span><span class="mi">1</span><span class="x">,</span><span class="n">length</span> <span class="o">=</span> <span class="n">Un</span> <span class="o">+</span> <span class="mi">1</span><span class="x">)</span>
    <span class="n">order</span> <span class="o">=</span> <span class="kt">SharedArray</span><span class="x">(</span><span class="n">zeros</span><span class="x">(</span><span class="kt">ComplexF64</span><span class="x">,</span><span class="n">Un</span> <span class="o">+</span> <span class="mi">1</span><span class="x">))</span>
    <span class="nd">@sync</span> <span class="nd">@distributed</span> <span class="k">for</span> <span class="n">iu</span> <span class="k">in</span> <span class="mi">1</span><span class="o">:</span><span class="n">Un</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c"># 并行计算</span>
        <span class="n">order</span><span class="x">[</span><span class="n">iu</span><span class="x">]</span> <span class="o">=</span> <span class="n">self_delta</span><span class="x">(</span><span class="n">U0list</span><span class="x">[</span><span class="n">iu</span><span class="x">])</span>
    <span class="k">end</span>
    <span class="n">fx1</span> <span class="o">=</span><span class="s">"julia-order.dat"</span>
    <span class="n">f1</span> <span class="o">=</span> <span class="n">open</span><span class="x">(</span><span class="n">fx1</span><span class="x">,</span><span class="s">"w"</span><span class="x">)</span>
    <span class="n">x0</span> <span class="o">=</span> <span class="x">(</span><span class="n">a</span><span class="o">-&gt;</span><span class="x">(</span><span class="nd">@sprintf</span> <span class="s">"%15.8f"</span> <span class="n">a</span><span class="x">))</span><span class="o">.</span><span class="x">(</span><span class="n">U0list</span><span class="x">)</span>
    <span class="n">y0</span> <span class="o">=</span> <span class="x">(</span><span class="n">a</span><span class="o">-&gt;</span><span class="x">(</span><span class="nd">@sprintf</span> <span class="s">"%15.8f"</span> <span class="n">a</span><span class="x">))</span><span class="o">.</span><span class="x">(</span><span class="n">real</span><span class="x">(</span><span class="n">order</span><span class="x">))</span>
    <span class="n">z0</span> <span class="o">=</span> <span class="x">(</span><span class="n">a</span><span class="o">-&gt;</span><span class="x">(</span><span class="nd">@sprintf</span> <span class="s">"%15.8f"</span> <span class="n">a</span><span class="x">))</span><span class="o">.</span><span class="x">(</span><span class="n">imag</span><span class="x">(</span><span class="n">order</span><span class="x">))</span>
    <span class="n">writedlm</span><span class="x">(</span><span class="n">f1</span><span class="x">,[</span><span class="n">x0</span> <span class="n">y0</span> <span class="n">z0</span><span class="x">],</span><span class="s">"</span><span class="se">\t</span><span class="s">"</span><span class="x">)</span>
    <span class="n">close</span><span class="x">(</span><span class="n">f1</span><span class="x">)</span>

<span class="k">end</span>
<span class="c">#-------------------------------------------------------------------------------</span>
<span class="nd">@time</span> <span class="n">main</span><span class="x">()</span>
</code></pre></div></div>

<blockquote>
  <p>程序执行</p>
</blockquote>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>julia <span class="nt">-p</span> 10 square-sc.jl  
</code></pre></div></div>

<h2 id="python-version">Python Version</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">rcParams</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">plt</span><span class="p">.</span><span class="n">rc</span><span class="p">(</span><span class="s">'font'</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"font.size"</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
<span class="s">"mathtext.fontset"</span><span class="p">:</span><span class="s">'stix'</span><span class="p">,</span>
<span class="s">"font.serif"</span><span class="p">:</span> <span class="p">[</span><span class="s">'SimSun'</span><span class="p">],</span>
<span class="p">}</span>
<span class="n">rcParams</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">config</span><span class="p">)</span> <span class="c1"># Latex 字体设置
#-------------------------------------------------------
</span><span class="n">t1</span> <span class="o">=</span> <span class="mf">1.0</span> 
<span class="n">mu</span> <span class="o">=</span> <span class="mf">1.0</span>
<span class="n">kn</span> <span class="o">=</span> <span class="mi">100</span>  
<span class="n">T</span> <span class="o">=</span> <span class="mf">1E-10</span>
<span class="n">k1</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="o">-</span><span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">,</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span><span class="p">,</span> <span class="n">kn</span><span class="p">)</span>
<span class="n">Klist</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([</span><span class="n">k1</span><span class="p">,</span> <span class="n">k1</span><span class="p">])</span>
<span class="n">Umax</span> <span class="o">=</span> <span class="mf">1.0</span>
<span class="c1">#-------------------------------------------------------
</span><span class="k">def</span> <span class="nf">SC</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span> <span class="n">ky</span><span class="p">,</span> <span class="n">delta</span><span class="p">):</span>
    <span class="n">Ham</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">zeros</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
    <span class="n">Ham</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">t1</span> <span class="o">*</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span> <span class="o">+</span> <span class="n">np</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span> <span class="o">-</span> <span class="n">mu</span>
    <span class="n">Ham</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="n">t1</span> <span class="o">*</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span> <span class="o">+</span> <span class="n">np</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span> <span class="o">+</span> <span class="n">mu</span>
    <span class="n">Ham</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">delta</span>
    <span class="n">Ham</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">conjugate</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">Ham</span>
<span class="c1">#-------------------------------------------------------
</span><span class="k">def</span> <span class="nf">fermi</span><span class="p">(</span><span class="n">energy</span><span class="p">):</span>
    <span class="k">return</span> <span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">exp</span><span class="p">(</span><span class="n">energy</span> <span class="o">/</span> <span class="n">T</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1">#-------------------------------------------------------
</span><span class="k">def</span> <span class="nf">diagH</span><span class="p">(</span><span class="n">Ham</span><span class="p">):</span>
    <span class="n">eva</span><span class="p">,</span> <span class="n">evc</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="n">eigh</span><span class="p">(</span><span class="n">Ham</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">eva</span><span class="p">,</span> <span class="n">evc</span>
<span class="c1">#-------------------------------------------------------
#无法收敛就直接输出-1
</span><span class="k">def</span> <span class="nf">selfC</span><span class="p">(</span><span class="n">U</span><span class="p">,</span> <span class="n">max_iter</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">):</span>
    <span class="n">delta</span> <span class="o">=</span> <span class="mf">1e-4</span>
    <span class="n">diff</span> <span class="o">=</span> <span class="mf">1e-6</span>
    <span class="n">diff_I</span> <span class="o">=</span> <span class="mf">1.01</span> <span class="o">*</span> <span class="n">diff</span>
    <span class="n">iter_count</span> <span class="o">=</span> <span class="mi">0</span>  

    <span class="k">while</span> <span class="n">diff_I</span> <span class="o">&gt;</span> <span class="n">diff</span><span class="p">:</span>
        <span class="c1"># if iter_count &gt;= max_iter: 
</span>        <span class="c1">#     return -1 
</span>
        <span class="n">new_delta</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">ik0</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">kn</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">ik1</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">kn</span><span class="p">):</span>
                <span class="n">kx</span> <span class="o">=</span> <span class="n">k1</span><span class="p">[</span><span class="n">ik0</span><span class="p">]</span>
                <span class="n">ky</span> <span class="o">=</span> <span class="n">k1</span><span class="p">[</span><span class="n">ik1</span><span class="p">]</span>
                <span class="n">Ham</span> <span class="o">=</span> <span class="n">SC</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span> <span class="n">ky</span><span class="p">,</span> <span class="n">delta</span><span class="p">)</span>
                <span class="n">eva</span><span class="p">,</span> <span class="n">evc</span> <span class="o">=</span> <span class="n">diagH</span><span class="p">(</span><span class="n">Ham</span><span class="p">)</span>
                <span class="n">fermi_vals</span> <span class="o">=</span> <span class="n">fermi</span><span class="p">(</span><span class="n">eva</span><span class="p">)</span>
                <span class="n">MF</span> <span class="o">=</span> <span class="n">evc</span> <span class="o">@</span> <span class="n">np</span><span class="p">.</span><span class="n">diag</span><span class="p">(</span><span class="n">fermi_vals</span><span class="p">)</span> <span class="o">@</span> <span class="n">evc</span><span class="p">.</span><span class="n">conj</span><span class="p">().</span><span class="n">T</span>
                <span class="n">new_delta</span> <span class="o">+=</span> <span class="n">MF</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
        
        <span class="n">new_delta</span> <span class="o">=</span> <span class="o">-</span><span class="n">U</span> <span class="o">*</span> <span class="n">new_delta</span> <span class="o">/</span> <span class="n">kn</span><span class="o">**</span><span class="mi">2</span>
        <span class="n">diff_I</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">abs</span><span class="p">(</span><span class="n">new_delta</span> <span class="o">-</span> <span class="n">delta</span><span class="p">)</span>
        <span class="n">delta</span> <span class="o">=</span> <span class="n">new_delta</span>
        <span class="n">iter_count</span> <span class="o">+=</span> <span class="mi">1</span> 

    <span class="k">return</span> <span class="n">delta</span>
<span class="c1">#-------------------------------------------------------
# selfC(0.5)
</span><span class="n">U_values</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linspace</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span><span class="n">Umax</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">delta_values</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">U</span> <span class="ow">in</span> <span class="n">U_values</span><span class="p">:</span>
    <span class="n">delta_values</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">selfC</span><span class="p">(</span><span class="n">U</span><span class="p">))</span>

<span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
<span class="n">picname</span> <span class="o">=</span> <span class="s">"order-mu-"</span> <span class="o">+</span>  <span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">)</span> <span class="o">+</span> <span class="s">".png"</span>
<span class="c1"># plt.plot(U_values, delta_values, marker='o', color='b',markersize = 4)
</span><span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">U_values</span><span class="p">,</span> <span class="n">delta_values</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"b"</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">20</span><span class="p">)</span>
<span class="c1"># 设置 x 轴刻度在 1 到 10，步长为 2
# plt.xticks(ticks=range(0, Umax, 2))
# plt.hlines(-0.1,xmin=0,xmax = Umax,colors = "black",lw = 2,ls = "-.")
# plt.vlines(1,ymin=0,ymax=Umax/2.0,colors = "b",lw = 4,ls = "-.")
</span><span class="n">plt</span><span class="p">.</span><span class="n">xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">Umax</span><span class="p">)</span>
<span class="c1"># plt.ylim(-0.1,Umax/2.0)
</span><span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$U/t$"</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\Delta$"</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">title</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\mu = $"</span> <span class="o">+</span> <span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
<span class="c1"># 减少 x 和 y 轴上的刻度数量
</span><span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># x 轴最多显示 3 个刻度
</span><span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># y 轴最多显示 3 个刻度
# plt.grid(True)
# plt.show()
</span><span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div></div>

<blockquote>
  <p>Python运算速度太慢了,暂时先这样,并行后面再说</p>
</blockquote>

<h1 id="结果">结果</h1>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">rcParams</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">matplotlib.gridspec</span> <span class="k">as</span> <span class="n">gridspec</span>
<span class="n">plt</span><span class="p">.</span><span class="n">rc</span><span class="p">(</span><span class="s">'font'</span><span class="p">,</span> <span class="n">family</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"font.size"</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span>
<span class="s">"mathtext.fontset"</span><span class="p">:</span><span class="s">'stix'</span><span class="p">,</span>
<span class="s">"font.serif"</span><span class="p">:</span> <span class="p">[</span><span class="s">'SimSun'</span><span class="p">],</span>
<span class="p">}</span>
<span class="n">rcParams</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="n">config</span><span class="p">)</span> <span class="c1"># Latex 字体设置
#----------------------------------------------------------
</span><span class="k">def</span> <span class="nf">plot_fs</span><span class="p">(</span><span class="n">mu</span><span class="p">):</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"FS.dat"</span>
    <span class="c1"># dataname = "julia-order.dat"
</span>    <span class="n">picname</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">dataname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">"-mu-"</span> <span class="o">+</span> <span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">)</span> <span class="o">+</span> <span class="s">".png"</span>
    <span class="n">da</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">dataname</span><span class="p">)</span> 
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
    <span class="n">Umax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">da</span><span class="p">[:,</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"b"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$k_x$"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$k_y$"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">title</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\mu = $"</span> <span class="o">+</span> <span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span>
    <span class="c1"># plt.xlim(0,Umax)
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="c1"># plt.axis('scaled')
</span>    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># x 轴最多显示 3 个刻度
</span>    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># y 轴最多显示 3 个刻度
</span>    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1">#----------------------------------------------------------
</span><span class="k">def</span> <span class="nf">plot_order_compare</span><span class="p">(</span><span class="n">mu</span><span class="p">):</span>
    <span class="n">da1</span> <span class="o">=</span> <span class="s">"fortran-order.dat"</span>
    <span class="n">da2</span> <span class="o">=</span> <span class="s">"julia-order.dat"</span>
    <span class="n">picname</span> <span class="o">=</span> <span class="s">"order-compare"</span>
    <span class="n">da1</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">da1</span><span class="p">)</span> 
    <span class="n">da2</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">da2</span><span class="p">)</span> 
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">))</span>
    <span class="n">Umax</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">da1</span><span class="p">[:,</span><span class="mi">0</span><span class="p">])</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">da1</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">da1</span><span class="p">[:,</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"b"</span><span class="p">,</span><span class="n">label</span> <span class="o">=</span> <span class="s">"Fortran"</span><span class="p">)</span>   <span class="c1"># Fortran
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">da2</span><span class="p">[:,</span><span class="mi">0</span><span class="p">],</span><span class="n">da2</span><span class="p">[:,</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span><span class="n">c</span> <span class="o">=</span> <span class="s">"r"</span><span class="p">,</span><span class="n">label</span> <span class="o">=</span> <span class="s">"Julia"</span><span class="p">)</span>   <span class="c1"># Julia
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$U/t$"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\Delta$"</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">title</span><span class="p">(</span><span class="sa">r</span><span class="s">"$\mu = $"</span> <span class="o">+</span> <span class="nb">format</span><span class="p">(</span><span class="n">mu</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xlim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">Umax</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'x'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">direction</span> <span class="o">=</span> <span class="s">'in'</span> <span class="p">,</span><span class="n">axis</span> <span class="o">=</span> <span class="s">'y'</span><span class="p">,</span><span class="n">width</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span><span class="n">length</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s">'best'</span><span class="p">,</span> <span class="n">fontsize</span> <span class="o">=</span> <span class="mi">25</span><span class="p">,</span> <span class="n">scatterpoints</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">markerscale</span> <span class="o">=</span> <span class="mi">2</span><span class="p">)</span>  <span class="c1"># markerscale 调整点的大小
</span>    <span class="c1"># plt.axis('scaled')
</span>    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'x'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># x 轴最多显示 3 个刻度
</span>    <span class="n">ax</span><span class="p">.</span><span class="n">locator_params</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="s">'y'</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># y 轴最多显示 3 个刻度
</span>    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1">#------------------------------------------------------------
</span><span class="k">if</span> <span class="n">__name__</span><span class="o">==</span><span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">plot_fs</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span>
    <span class="n">plot_order_compare</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="/assets/images/Fortran/order-compare.png" alt="png" /></p>

<p><img src="/assets/images/Fortran/FS-mu-1.00.png" alt="png" /></p>

<p class="warning">在数值计算对动量分布离散之后，再进行求和的时候需要注意动量间隔$\Delta k_i$具体是多少，这个量如果错了是会影响最后的物理结果的。</p>

<p class="info">若有错误，欢迎指出。感谢李公子以及俊熹的帮助。<a href="/assets/data/square-sc.zip">点击下载文件</a></p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<table>
  <tr>
    <!-- 图片单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; border: 1px solid #ccc; border-radius: 8px;">
      <img src="/assets/images/qrcode.jpg" alt="QR Code" width="300px" height="300px" style="border-radius: 8px;" />
    </td>
    <!-- 文字单元格 -->
    <td style="width: 300px; height: 300px; text-align: center; vertical-align: middle; padding-left: 20px; border: 1px solid #ccc; border-radius: 8px;">
      <div>
        <h4 style="margin: 0;">Email</h4>
        <p style="margin: 5px 0;">yxli406@gmail.com</p>
      </div>
    </td>
  </tr>
</table>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><summary type="html"><![CDATA[最近在学习计算超导体系的超流权重，其中要涉及到在确定相互作用$U$下自洽出序参量，虽然之前也会，为了保证所有结果的正确性，这里重新将一些过程记录一下，方便后面查阅理解。]]></summary></entry><entry><title type="html">平带中的紧致局域态(compact localized states in flat band)</title><link href="https://yxli8023.github.io//2024/06/30/Flat-Band.html" rel="alternate" type="text/html" title="平带中的紧致局域态(compact localized states in flat band)" /><published>2024-06-30T00:00:00+08:00</published><updated>2024-06-30T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/06/30/Flat-Band</id><content type="html" xml:base="https://yxli8023.github.io//2024/06/30/Flat-Band.html"><![CDATA[<p class="info">平带最近受到很大的关注，最近正好在研究量子几何，里面涉及到平带相关的内容，这篇笔记整理了一下在学习平带时相关的紧致局域态到底是个什么东西。</p>
<!--more-->
<h1 id="main">Main</h1>
<p><img src="/assets/images/20240630/Flat-band_page-0003.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0004.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0005.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0006.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0007.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0008.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0009.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0010.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0011.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0012.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0013.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0014.jpg" alt="png" /></p>

<p><img src="/assets/images/20240630/Flat-band_page-0015.jpg" alt="png" /></p>

<h1 id="参考文献">参考文献</h1>
<ul>
  <li><a href="https://link.aps.org/doi/10.1103/PhysRevB.104.195128">Designing flat-band tight-binding models with tunable multifold band touching points</a>
= <a href="https://link.aps.org/doi/10.1103/PhysRevB.104.085144">General construction of flat bands with and without band crossings based on wave function singularity</a></li>
</ul>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Topology" /><summary type="html"><![CDATA[平带最近受到很大的关注，最近正好在研究量子几何，里面涉及到平带相关的内容，这篇笔记整理了一下在学习平带时相关的紧致局域态到底是个什么东西。]]></summary></entry><entry><title type="html">Fortran常用对角化函数的封装</title><link href="https://yxli8023.github.io//2024/04/20/Frotran-function.html" rel="alternate" type="text/html" title="Fortran常用对角化函数的封装" /><published>2024-04-20T00:00:00+08:00</published><updated>2024-04-20T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/04/20/Frotran-function</id><content type="html" xml:base="https://yxli8023.github.io//2024/04/20/Frotran-function.html"><![CDATA[<p class="info">这里整理一下在用Fortran编写物理程序的时候经常用的几个函数封装，目前只是简单的几个矩阵对角化函数，后续有新的函数也会继续增加。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>最近因为遇到了计算瓶颈，需要用<code class="language-plaintext highlighter-rouge">Fortran</code>来重写代码，其中就遇到了对矩阵的一些操作，虽然<a href="https://www.netlib.org/lapack/">lapack</a>已经提供了很好的函数，但是在实际程序编写中还是有些麻烦，这里就对目前我用到的函数进行了一些封装，方便调用。</p>

<h2 id="一般方矩阵对角化">一般方矩阵对角化</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_general_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="p">,</span><span class="k">only</span><span class="p">:</span><span class="n">dp</span><span class="p">,</span><span class="n">im</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:),</span><span class="n">VR</span><span class="p">(:,:),</span><span class="n">WR</span><span class="p">(:),</span><span class="n">WI</span><span class="p">(:),</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">VR</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="w">  </span><span class="n">WR</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">WI</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="k">CALL</span><span class="w"> </span><span class="n">SGEEV</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">WR</span><span class="p">,</span><span class="w"> </span><span class="n">WI</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">CALL</span><span class="w"> </span><span class="n">SGEEV</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">WR</span><span class="p">,</span><span class="w"> </span><span class="n">WI</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
        </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">STOP</span><span class="w">
     </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
     </span><span class="k">do</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">mateigval</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">WR</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">WI</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VL</span><span class="w">  </span><span class="c1">! 将左矢量输出</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span></code></pre></div></div>
<h2 id="一般方矩阵对角化双精度">一般方矩阵对角化(双精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_general_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">VL</span><span class="p">(:,:),</span><span class="w"> </span><span class="n">VR</span><span class="p">(:,:),</span><span class="w"> </span><span class="n">WR</span><span class="p">(:),</span><span class="w"> </span><span class="n">WI</span><span class="p">(:),</span><span class="w"> </span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">! 矩阵维度参数设置</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! 分配工作空间</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">WR</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">WI</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="c1">! 初次调用 DGEEV 获取最佳工作空间大小</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">CALL</span><span class="w"> </span><span class="n">DGEEV</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">WR</span><span class="p">,</span><span class="w"> </span><span class="n">WI</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 根据第一次调用的返回值重新调整工作空间大小</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWORK</span><span class="p">))</span><span class="w">
    </span><span class="c1">! 第二次调用 DGEEV 计算特征值和特征向量</span><span class="w">
    </span><span class="k">CALL</span><span class="w"> </span><span class="n">DGEEV</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">WR</span><span class="p">,</span><span class="w"> </span><span class="n">WI</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 检查对角化是否成功</span><span class="w">
    </span><span class="k">IF</span><span class="w"> </span><span class="p">(</span><span class="n">INFO</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
        </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
    </span><span class="c1">! 将实部和虚部合成为复数本征值</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="w">
        </span><span class="n">mateigval</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">WR</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">WI</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="c1">! 将右特征向量存储在 matout 中</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VR</span><span class="w">
    </span><span class="c1">! 释放工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">WR</span><span class="p">,</span><span class="w"> </span><span class="n">WI</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_general_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="复数矩阵对角化单精度">复数矩阵对角化(单精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵,这里的本征值是个复数</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">LDA</span><span class="p">,</span><span class="n">LDVL</span><span class="p">,</span><span class="n">LDVR</span><span class="p">,</span><span class="n">LWMAX</span><span class="p">,</span><span class="n">INFO</span><span class="p">,</span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)::</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">REAL</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">RWORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! write(*,*)matin</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">RWORK</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">

    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
       </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="c1">!    STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VL</span><span class="w">  </span><span class="c1">! 将左矢量输出</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="复数矩阵对角化双精度">复数矩阵对角化(双精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵，这里的本征值是复数(双精度)</span><span class="w">
    </span><span class="c1">! matin 输入矩阵, matout 本征矢量, mateigval 本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">RWORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="c1">! 设置矩阵维度参数</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! 分配工作空间</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">RWORK</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="c1">! 将输入矩阵赋值给 matout</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! 初次调用 ZGEEV 获取最佳工作空间大小</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">ZGEEV</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 根据第一次调用的返回值重新调整工作空间大小</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWORK</span><span class="p">))</span><span class="w">
    </span><span class="c1">! 第二次调用 ZGEEV 计算本征值和本征矢量</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">ZGEEV</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="w"> </span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 检查对角化是否成功</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">INFO</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">! 将右特征向量存储在 matout 中</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VR</span><span class="w">
    </span><span class="c1">! 释放工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">)</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">RWORK</span><span class="p">)</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">VL</span><span class="p">)</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">VR</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="矩阵求逆单精度">矩阵求逆(单精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵求逆 </span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">dp</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">))</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">work2</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">            </span><span class="c1">! work2 array for LAPACK</span><span class="w">
    </span><span class="kt">integer</span><span class="p">::</span><span class="n">ipiv</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">     </span><span class="c1">! pivot indices</span><span class="w">
    </span><span class="c1">! Store matin in matout to prevent it from being overwritten by LAPACK</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! SGETRF computes an LU factorization of a general M - by - N matrix A</span><span class="w">
    </span><span class="c1">! using partial pivoting with row interchanges .</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRF</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix is numerically singular!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w">  </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
    </span><span class="c1">! SGETRI computes the inverse of a matrix using the LU factorization</span><span class="w">
    </span><span class="c1">! computed by SGETRF.</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRI</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">work2</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="w">
</span></code></pre></div></div>
<h2 id="矩阵求逆双精度">矩阵求逆(双精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵求逆(双精度)</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">info</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">work2</span><span class="p">(:)</span><span class="w">       </span><span class="c1">! 工作空间数组</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">ipiv</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">                     </span><span class="c1">! pivot indices</span><span class="w">
    </span><span class="c1">! 将输入矩阵 matin 复制到 matout，防止 LAPACK 函数覆盖 matin</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! 确定工作空间大小</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work2</span><span class="p">(</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="c1">! ZGETRF 用于矩阵 LU 分解</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">ZGETRF</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">ipiv</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="w"> </span><span class="p">/</span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
        </span><span class="k">return</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">! ZGETRI 用于求解逆矩阵</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">ZGETRI</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">ipiv</span><span class="p">,</span><span class="w"> </span><span class="n">work2</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="w"> </span><span class="p">/</span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'Matrix inversion failed!'</span><span class="w">
        </span><span class="k">return</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">! 释放工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">work2</span><span class="p">)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="w">
</span></code></pre></div></div>

<h2 id="厄米矩阵对角化单精度">厄米矩阵对角化(单精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="n">lwmax0</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="w"> </span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span></code></pre></div></div>

<h2 id="厄米矩阵对角化双精度">厄米矩阵对角化(双精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matin</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵, matout 本征矢量, mateigval 本征值</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0d0</span><span class="p">)</span><span class="w">  </span><span class="c1">! 双精度</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">lwmax0</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">allocatable</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">iwork</span><span class="p">(:)</span><span class="w">

    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">

    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">

    </span><span class="c1">! 初次调用 zheevd 获取最佳工作空间大小</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 根据第一次调用的返回值重新调整工作空间大小</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 重新分配工作空间</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">work</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="n">lrwork</span><span class="p">))</span><span class="w">
    </span><span class="k">deallocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">)</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="n">liwork</span><span class="p">))</span><span class="w">

    </span><span class="c1">! 第二次调用 zheevd 计算本征值和本征矢量</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">zheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'U'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">work</span><span class="p">,</span><span class="w"> </span><span class="n">lwork</span><span class="p">,</span><span class="w"> </span><span class="n">rwork</span><span class="p">,</span><span class="w"> </span><span class="n">lrwork</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">,</span><span class="w"> </span><span class="n">liwork</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 错误处理</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">

    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span></code></pre></div></div>
<p><strong>提示</strong></p>

<p class="info">如果使用了双精度，那么在MPI并行的时候，数据收集也需要对应的修改为双精度</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    call MPI_Barrier<span class="o">(</span>MPI_COMM_WORLD,ierr<span class="o">)</span>   <span class="o">!</span> 等所有核心都计算完成
    call MPI_Reduce<span class="o">(</span>U0_mpi, U0_list, Un, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD,ierr<span class="o">)</span>
    call MPI_Reduce<span class="o">(</span>da_mpi, da_list, Un, MPI_DOUBLE_COMPLEX, MPI_SUM, 0, MPI_COMM_WORLD,ierr<span class="o">)</span>
    call MPI_Reduce<span class="o">(</span>Ds_con_mpi, Ds_con_list, 4 <span class="k">*</span> Un, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD,ierr<span class="o">)</span>
</code></pre></div></div>

<h2 id="实数矩阵对角化单精度">实数矩阵对角化(单精度)</h2>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_real_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵,这里的本征值是个复数</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">LDA</span><span class="p">,</span><span class="n">LDVL</span><span class="p">,</span><span class="n">LDVR</span><span class="p">,</span><span class="n">LWMAX</span><span class="p">,</span><span class="n">INFO</span><span class="p">,</span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)::</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">valre</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">valim</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! write(*,*)matin</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">

    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">sgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">valre</span><span class="p">,</span><span class="n">valim</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">sgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">valre</span><span class="p">,</span><span class="n">valim</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
       </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="c1">!    STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">mateigval</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">valre</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">valim</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VL</span><span class="w">  </span><span class="c1">! 将左矢量输出</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_real_matrix</span><span class="w">
</span></code></pre></div></div>
<p>实数矩阵的双精度版本实际上就是一般矩阵对角化</p>

<h1 id="完整代码测试">完整代码&amp;测试</h1>
<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="w"> </span><span class="k">parameter</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">num_wann</span><span class="p">,</span><span class="n">nrpts</span><span class="p">,</span><span class="n">hn</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">ones</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.1415926535897</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w"> </span><span class="c1">!Imagine unit</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">tsig</span><span class="p">,</span><span class="n">tpi</span><span class="p">,</span><span class="n">tsig2</span><span class="p">,</span><span class="n">tpi2</span><span class="p">,</span><span class="n">mu</span><span class="w">  </span><span class="c1">! 哈密顿量参数</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">tsig</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0</span><span class="p">,</span><span class="n">tpi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tsig</span><span class="p">/</span><span class="mf">1.56</span><span class="p">,</span><span class="n">tsig2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tsig</span><span class="p">/</span><span class="mf">7.0</span><span class="p">,</span><span class="n">tpi2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tsig2</span><span class="p">/</span><span class="mf">1.56</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">HmnR</span><span class="p">(:,:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">ndegen</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">allocatable</span><span class="p">::</span><span class="n">irvec</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">BZklist</span><span class="p">(:,:)</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp2</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">A1</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">temp3</span><span class="p">(</span><span class="n">hn</span><span class="p">),</span><span class="n">A0</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">)</span><span class="w">
    </span><span class="kt">character</span><span class="p">(</span><span class="nb">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">20</span><span class="p">)</span><span class="w"> </span><span class="n">char1</span><span class="p">,</span><span class="n">char2</span><span class="p">,</span><span class="n">char3</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="w">

     </span><span class="k">do</span><span class="w"> </span><span class="n">i1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="mi">10</span><span class="w">
         </span><span class="k">do</span><span class="w"> </span><span class="n">i2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="mi">10</span><span class="w">
             </span><span class="n">A0</span><span class="p">(</span><span class="n">i1</span><span class="p">,</span><span class="n">i2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">i2</span><span class="w">
         </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
     </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
     </span><span class="n">char1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"("</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="n">char2</span><span class="p">,</span><span class="s2">"(I4)"</span><span class="p">)</span><span class="mi">10</span><span class="w">
     </span><span class="n">char3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"F8.4)"</span><span class="w">
     </span><span class="n">char2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">trim</span><span class="p">(</span><span class="n">char1</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char2</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char3</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  write(*,*)char2</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="s2">"(10F8.4)"</span><span class="p">)</span><span class="n">A0</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"--------------------------------------"</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="n">char2</span><span class="p">)</span><span class="n">A0</span><span class="w">
    
     </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span><span class="mf">0.2</span><span class="p">,</span><span class="n">Ham</span><span class="p">)</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="n">Ham</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s2">"-----------------------------------------"</span><span class="w">
     </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">temp1</span><span class="p">,</span><span class="n">temp2</span><span class="p">)</span><span class="w">
     </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">temp1</span><span class="p">,</span><span class="n">temp3</span><span class="p">)</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="n">temp2</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="n">temp3</span><span class="w">
     </span><span class="k">call</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">temp1</span><span class="p">)</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="nb">matmul</span><span class="p">(</span><span class="n">Ham</span><span class="p">,</span><span class="n">temp1</span><span class="p">)</span><span class="w">

     </span><span class="k">call</span><span class="w"> </span><span class="n">diagonalize_real_matrix</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="n">A0</span><span class="p">,</span><span class="n">A1</span><span class="p">,</span><span class="n">temp2</span><span class="p">)</span><span class="w">
     </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="n">temp2</span><span class="w">

    </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">,</span><span class="n">Ham</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵赋值,返回Ham</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">k0</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)</span><span class="w"> </span><span class="n">h1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">h2</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">h13</span><span class="p">,</span><span class="n">h14</span><span class="p">,</span><span class="n">h23</span><span class="p">,</span><span class="n">h24</span><span class="p">,</span><span class="n">hn11</span><span class="p">,</span><span class="n">hn22</span><span class="p">,</span><span class="n">hn12</span><span class="w">
    
    </span><span class="n">h13</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">/</span><span class="mi">4</span><span class="o">*</span><span class="p">(</span><span class="n">tpi</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">3.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tsig</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="nb">exp</span><span class="p">(</span><span class="n">im</span><span class="o">*</span><span class="p">(</span><span class="n">ky</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="o">-</span><span class="w"> </span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="n">im</span><span class="o">*</span><span class="p">(</span><span class="n">ky</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="p">))</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">tpi</span><span class="o">*</span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="p">/</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="w">
    </span><span class="n">h14</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)/</span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">tpi</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">tsig</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mi">-1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kx</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="mf">-1.0</span><span class="p">/</span><span class="mf">6.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">3.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kx</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="w"> </span><span class="p">))</span><span class="w">
    </span><span class="n">h23</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h14</span><span class="w">
    </span><span class="n">h24</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="p">/</span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">3.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tpi</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">tsig</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">ky</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">  </span><span class="nb">exp</span><span class="p">(</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">ky</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">tsig</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">exp</span><span class="p">(</span><span class="o">-</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="p">/</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">))</span><span class="w">
    </span><span class="n">hn11</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">3.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tpi2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">tsig2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="p">/</span><span class="mf">2.0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tsig2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">
    </span><span class="n">hn12</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">   </span><span class="p">(</span><span class="n">tpi2</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">tsig2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">sin</span><span class="p">(</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="w"> </span><span class="p">/</span><span class="mf">2.0</span><span class="p">)</span><span class="w">
    </span><span class="n">hn22</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">tpi2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">3.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tsig2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">/</span><span class="mf">2.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="nb">sqrt</span><span class="p">(</span><span class="mf">3.0</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ky</span><span class="w"> </span><span class="p">/</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tpi2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w">

    </span><span class="c1">! 单位矩阵</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">k0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
        </span><span class="n">ones</span><span class="p">(</span><span class="n">k0</span><span class="p">,</span><span class="n">k0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">

    
    
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h13</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="w"> </span><span class="n">H1</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h14</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">H1</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h23</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">H1</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h24</span><span class="w">
    </span><span class="n">H1</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">H1</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span><span class="w">
    </span><span class="c1">!-------------</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn11</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn12</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">H2</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn22</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn11</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn12</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">H2</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span><span class="w">
    </span><span class="n">H2</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn22</span><span class="w">
    </span><span class="c1">!-------------</span><span class="w">
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">H1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">H2</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">mu</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ones</span><span class="w">
    </span><span class="c1">!---------------------------------------------------------------------</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">

</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵,这里的本征值是个复数</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">LDA</span><span class="p">,</span><span class="n">LDVL</span><span class="p">,</span><span class="n">LDVR</span><span class="p">,</span><span class="n">LWMAX</span><span class="p">,</span><span class="n">INFO</span><span class="p">,</span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)::</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">REAL</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">RWORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! write(*,*)matin</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">RWORK</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">

    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">mateigval</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">RWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
       </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="c1">!    STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">VL</span><span class="w">  </span><span class="c1">! 将左矢量输出</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_complex_matrix</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵求逆 </span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">dp</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">kind</span><span class="p">(</span><span class="mf">1.0</span><span class="p">))</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">),</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="kt">real</span><span class="p">(</span><span class="n">dp</span><span class="p">)::</span><span class="w"> </span><span class="n">work2</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">            </span><span class="c1">! work2 array for LAPACK</span><span class="w">
    </span><span class="kt">integer</span><span class="p">::</span><span class="n">ipiv</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">     </span><span class="c1">! pivot indices</span><span class="w">
    </span><span class="c1">! Store matin in matout to prevent it from being overwritten by LAPACK</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! SGETRF computes an LU factorization of a general M - by - N matrix A</span><span class="w">
    </span><span class="c1">! using partial pivoting with row interchanges .</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRF</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix is numerically singular!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w">  </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
    </span><span class="c1">! SGETRI computes the inverse of a matrix using the LU factorization</span><span class="w">
    </span><span class="c1">! computed by SGETRF.</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRI</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">work2</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="c1">! if (info.ne.0) stop 'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">write</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">Matrix_Inv</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">!  厄米矩阵对角化</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lda0</span><span class="p">,</span><span class="n">lwmax0</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">),</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="c1">!-----------------</span><span class="w">
    </span><span class="n">lda0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">lwmax0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax0</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="w"> </span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">matdim</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">lda0</span><span class="p">,</span><span class="n">mateigval</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_Hermitian_matrix</span><span class="w">
</span><span class="c1">!==============================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_real_matrix</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">mateigval</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 对角化一般复数矩阵,这里的本征值是个复数</span><span class="w">
    </span><span class="c1">! matin 输入矩阵   matout 本征矢量    mateigval  本征值</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="n">LDA</span><span class="p">,</span><span class="n">LDVL</span><span class="p">,</span><span class="n">LDVR</span><span class="p">,</span><span class="n">LWMAX</span><span class="p">,</span><span class="n">INFO</span><span class="p">,</span><span class="n">LWORK</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)::</span><span class="n">matin</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">matout</span><span class="p">(</span><span class="n">matdim</span><span class="p">,</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">out</span><span class="p">)::</span><span class="n">mateigval</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">valre</span><span class="p">(</span><span class="n">matdim</span><span class="p">),</span><span class="n">valim</span><span class="p">(</span><span class="n">matdim</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">WORK</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VL</span><span class="p">(:,:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">VR</span><span class="p">(:,:)</span><span class="w">
    </span><span class="n">LDA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LDVR</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matdim</span><span class="w">
    </span><span class="n">LWMAX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">matdim</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">matdim</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="c1">! write(*,*)matin</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VL</span><span class="p">(</span><span class="n">LDVL</span><span class="p">,</span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">VR</span><span class="p">(</span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">WORK</span><span class="p">(</span><span class="n">LWMAX</span><span class="p">))</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">

    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">sgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">valre</span><span class="p">,</span><span class="n">valim</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="n">LWORK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">MIN</span><span class="p">(</span><span class="w"> </span><span class="n">LWMAX</span><span class="p">,</span><span class="w"> </span><span class="nb">INT</span><span class="p">(</span><span class="w"> </span><span class="n">WORK</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">sgeev</span><span class="p">(</span><span class="w"> </span><span class="s1">'V'</span><span class="p">,</span><span class="w"> </span><span class="s1">'N'</span><span class="p">,</span><span class="w"> </span><span class="n">matdim</span><span class="p">,</span><span class="w"> </span><span class="n">matout</span><span class="p">,</span><span class="w"> </span><span class="n">LDA</span><span class="p">,</span><span class="w"> </span><span class="n">valre</span><span class="p">,</span><span class="n">valim</span><span class="p">,</span><span class="w"> </span><span class="n">VL</span><span class="p">,</span><span class="w"> </span><span class="n">LDVL</span><span class="p">,</span><span class="n">VR</span><span class="p">,</span><span class="w"> </span><span class="n">LDVR</span><span class="p">,</span><span class="w"> </span><span class="n">WORK</span><span class="p">,</span><span class="w"> </span><span class="n">LWORK</span><span class="p">,</span><span class="w"> </span><span class="n">INFO</span><span class="p">)</span><span class="w">
    </span><span class="k">IF</span><span class="p">(</span><span class="w"> </span><span class="n">INFO</span><span class="ow">.GT.</span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">THEN</span><span class="w">
       </span><span class="k">WRITE</span><span class="p">(</span><span class="o">*</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
    </span><span class="c1">!    STOP</span><span class="w">
    </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">matdim</span><span class="w">
        </span><span class="n">mateigval</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">valre</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">valim</span><span class="p">(</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">diagonalize_real_matrix</span><span class="w">
</span></code></pre></div></div>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><summary type="html"><![CDATA[这里整理一下在用Fortran编写物理程序的时候经常用的几个函数封装，目前只是简单的几个矩阵对角化函数，后续有新的函数也会继续增加。]]></summary></entry><entry><title type="html">Fortran结合MPI并行</title><link href="https://yxli8023.github.io//2024/04/19/Frotran-MPI-Study.html" rel="alternate" type="text/html" title="Fortran结合MPI并行" /><published>2024-04-19T00:00:00+08:00</published><updated>2024-04-19T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/04/19/Frotran-MPI-Study</id><content type="html" xml:base="https://yxli8023.github.io//2024/04/19/Frotran-MPI-Study.html"><![CDATA[<p class="info">该Bolg整理在<code class="language-plaintext highlighter-rouge">Fortran</code>用<code class="language-plaintext highlighter-rouge">MPI</code>编写并行程序，用在科学计算中速度提升肉眼可见，</p>
<!--more-->
<h1 id="代码解析">代码解析</h1>
<p>先给一个完整的代码，是用来计算自旋极化率的，实际上在<a href="https://yxli8023.github.io/2024/04/19/Frotran-MPI.html">Fortran结合MPI并行计算自旋极化率</a>中已经出现过了，这里就是解读一下其中的并行部分是如何用<code class="language-plaintext highlighter-rouge">MPI</code>写的。</p>

<div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">kn</span><span class="p">,</span><span class="n">hn</span><span class="w">
    </span><span class="k">parameter</span><span class="p">(</span><span class="n">kn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">64</span><span class="p">,</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.1415926535897</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">omega</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.00</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w"> </span><span class="c1">!Imagine unit</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">Umat</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">ones</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w"> </span><span class="c1">! Hamiltonian and interaction Matrix</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">t0</span><span class="p">,</span><span class="n">t1x</span><span class="p">,</span><span class="n">t1z</span><span class="p">,</span><span class="n">t2x</span><span class="p">,</span><span class="n">t2z</span><span class="p">,</span><span class="n">t3xz</span><span class="p">,</span><span class="n">t4xz</span><span class="p">,</span><span class="n">tvx</span><span class="p">,</span><span class="n">tvz</span><span class="p">,</span><span class="n">ex</span><span class="p">,</span><span class="n">ez</span><span class="w">  </span><span class="c1">! 哈密顿量参数</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">U0</span><span class="p">,</span><span class="n">J0</span><span class="w">  </span><span class="c1">! 相互作用参数</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">chi0</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">chi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="c1">! LAPACK PACKAGE PARAM</span><span class="w">
    </span><span class="kt">integer</span><span class="p">::</span><span class="n">lda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">lwmax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="o">*</span><span class="n">hn</span><span class="o">+</span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">val</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lwork</span><span class="w">   </span><span class="c1">! at least 2*hn+N**2</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">lrwork</span><span class="w">    </span><span class="c1">! at least 1 + 5*hn +2*hn**2</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">liwork</span><span class="w">   </span><span class="c1">! at least 3 +5*hn</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">info</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">mpi</span><span class="w"> 
    </span><span class="c1">!------------------------------------</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">temp1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp2</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp3</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">local_rechi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w">
    </span><span class="c1">!---------------------------------</span><span class="w">
    </span><span class="kt">integer</span><span class="w">  </span><span class="n">numcore</span><span class="p">,</span><span class="n">indcore</span><span class="p">,</span><span class="n">ierr</span><span class="w">
    </span><span class="kt">character</span><span class="p">(</span><span class="nb">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">20</span><span class="p">)::</span><span class="n">filename</span><span class="p">,</span><span class="n">char1</span><span class="p">,</span><span class="n">char2</span><span class="w">
    </span><span class="c1">!---------------------------------</span><span class="w">
    </span><span class="k">external</span><span class="p">::</span><span class="n">cheevd</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">val</span><span class="p">(</span><span class="n">hn</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1+5</span><span class="o">*</span><span class="n">hn</span><span class="mi">+2</span><span class="o">*</span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3+5</span><span class="o">*</span><span class="n">hn</span><span class="p">))</span><span class="w">
    </span><span class="c1">!---------------------------------</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_INIT</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">     </span><span class="c1">! 初始化进程</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_RANK</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">indcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">! 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该 rank值为0到p-1间的整数,相当于进程的ID。)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_SIZE</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">!获得进程个数 size, 这里用变量p保存</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
    </span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w"> 
    </span><span class="c1">! 遍历BZ求极化率</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
        </span><span class="n">qy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">qx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">chi0cal</span><span class="p">(</span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">  </span><span class="c1">! 得到裸极化率</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">inv</span><span class="p">(</span><span class="n">ones</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">matmul</span><span class="p">(</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:),</span><span class="n">Umat</span><span class="p">),</span><span class="n">temp2</span><span class="p">)</span><span class="w">  </span><span class="c1">! 矩阵求逆</span><span class="w">
            </span><span class="n">chi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">matmul</span><span class="p">(</span><span class="n">temp2</span><span class="p">,</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">
            </span><span class="n">temp3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">chi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">
            </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">qx</span><span class="w">
            </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">qy</span><span class="w">
            </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">real</span><span class="p">(</span><span class="n">temp3</span><span class="p">)</span><span class="w">
            </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">aimag</span><span class="p">(</span><span class="n">temp3</span><span class="p">)</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="c1">! call MPI_Gather(local_rechi, 2 * kn, MPI_COMPLEX, rechi, 2 * kn, MPI_COMPLEX, 0, MPI_COMM_WORLD,ierr)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">local_rechi</span><span class="p">,</span><span class="w"> </span><span class="n">rechi</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_REAL</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="ow">.eq.</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="n">char1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"fortran-chi-"</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="n">char2</span><span class="p">,</span><span class="s2">"(I3.3)"</span><span class="p">)</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="w">
        </span><span class="n">filename</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">trim</span><span class="p">(</span><span class="n">char1</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char2</span><span class="p">)</span><span class="w">
        </span><span class="n">char1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">".dat"</span><span class="w">
        </span><span class="n">filename</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">trim</span><span class="p">(</span><span class="n">filename</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char1</span><span class="p">)</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">filename</span><span class="p">)</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
                </span><span class="k">write</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="s2">"(4F8.3)"</span><span class="p">)</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Finalize</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">
    </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵赋值</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">k0</span><span class="w">
    </span><span class="n">t0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
    </span><span class="n">t1x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.483</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">t1z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.110</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">t2x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.069</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">t2z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.017</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">t3xz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.239</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">t4xz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.034</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">tvx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.005</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">tvz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.635</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">ex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.776</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    </span><span class="n">ez</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.409</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    
    </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ex</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ez</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ex</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ez</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvx</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvz</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvx</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
    </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvz</span><span class="w">
    </span><span class="c1">!---------------------------------------------------------------------</span><span class="w">
    </span><span class="c1">! 相互作用矩阵赋值</span><span class="w">
    </span><span class="n">U0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.0</span><span class="w">
    </span><span class="n">J0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.4</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
    </span><span class="n">Umat</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
    </span><span class="c1">!---------------------------------------------------------------------</span><span class="w">
    </span><span class="c1">! 单位矩阵</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">k0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
        </span><span class="n">ones</span><span class="p">(</span><span class="n">k0</span><span class="p">,</span><span class="n">k0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">chi0cal</span><span class="p">(</span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">re1</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 计算极化率  返回到re1</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e1</span><span class="p">,</span><span class="n">e2</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
    </span><span class="kt">complex</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
        </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w">
        </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
            </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">

            </span><span class="c1">! k</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">)</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w"> 
            </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">val</span><span class="p">(:)</span><span class="w">
            </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham</span><span class="p">(:,:)</span><span class="w">

            </span><span class="c1">! k + q</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">ky</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">qy</span><span class="p">)</span><span class="w">
            </span><span class="k">call</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w"> 
            </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">val</span><span class="p">(:)</span><span class="w">
            </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham</span><span class="p">(:,:)</span><span class="w">
            
            </span><span class="c1">! 计算极化率</span><span class="w">
            </span><span class="k">do</span><span class="w"> </span><span class="n">l1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">   </span><span class="c1">! orbit ondex</span><span class="w">
                </span><span class="k">do</span><span class="w"> </span><span class="n">l2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
                    </span><span class="k">do</span><span class="w"> </span><span class="n">e1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">  </span><span class="c1">! band index</span><span class="w">
                        </span><span class="k">do</span><span class="w"> </span><span class="n">e2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
                            </span><span class="n">re1</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">fermi</span><span class="p">(</span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e1</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e2</span><span class="p">)))/(</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">omega</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">0.0001</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e2</span><span class="p">))&amp;</span><span class="w">
                                    </span><span class="o">*</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">e2</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e1</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">e1</span><span class="p">)</span><span class="w">
                        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
                    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
                </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
            </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
        </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
    </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">
    </span><span class="k">return</span><span class="w"> 
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 费米分布函数</span><span class="w">
    </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
    </span><span class="kt">real</span><span class="w"> </span><span class="n">fermi</span><span class="p">,</span><span class="n">ek</span><span class="p">,</span><span class="n">kbt</span><span class="w">
    </span><span class="n">kbt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.001</span><span class="w">
    </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">/(</span><span class="nb">exp</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">  
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">equivkpq</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 找到BZ中k+q等价与k的索引</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">equivkpq</span><span class="p">,</span><span class="n">i0</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="w"> </span><span class="ow">.and.</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kn</span><span class="w">
</span><span class="k">end</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w">
    </span><span class="c1">! 对角化得到本征值w和本征矢量Ham</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">integer</span><span class="w"> </span><span class="n">m</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">lda</span><span class="p">,</span><span class="n">val</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">lda</span><span class="p">,</span><span class="n">val</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
        </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
        </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
        </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
    </span><span class="c1">! open(12,file="eigval.dat",status="uknnown")</span><span class="w">
    </span><span class="c1">! do m = 1,N</span><span class="w">
    </span><span class="c1">! 	write(12,*)m,val(m)</span><span class="w">
    </span><span class="c1">! end do</span><span class="w">
    </span><span class="c1">! close(12)</span><span class="w">
    </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">eigSol</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">inv</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">)</span><span class="w">
    </span><span class="c1">! 矩阵求逆</span><span class="w">
    </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
    </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
    </span><span class="kt">complex</span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
    </span><span class="kt">real</span><span class="p">::</span><span class="w"> </span><span class="n">work2</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">            </span><span class="c1">! work2 array for LAPACK</span><span class="w">
    </span><span class="kt">integer</span><span class="p">::</span><span class="n">ipiv</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">     </span><span class="c1">! pivot indices</span><span class="w">
    </span><span class="c1">! Store matin in matout to prevent it from being overwritten by LAPACK</span><span class="w">
    </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
    </span><span class="c1">! SGETRF computes an LU factorization of a general M - by - N matrix A</span><span class="w">
    </span><span class="c1">! using partial pivoting with row interchanges .</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRF</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">stop</span><span class="w"> </span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
    </span><span class="c1">! SGETRI computes the inverse of a matrix using the LU factorization</span><span class="w">
    </span><span class="c1">! computed by SGETRF.</span><span class="w">
    </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRI</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">work2</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">stop</span><span class="w"> </span><span class="s1">'Matrix inversion failed!'</span><span class="w">
    </span><span class="k">return</span><span class="w">
    </span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">inv</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span></code></pre></div></div>
<h1 id="mpi并行解读">MPI并行解读</h1>
<p>首先是要在程序中调用MPI的参数库</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>use mpi
</code></pre></div></div>
<p>我在代码中的并行思想就是将一个$[-kn,kn-1)$，长度为$2*kn$的循环进行分拆。首先是MPI环境的初始化</p>
<div class="language-shell success highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    call MPI_INIT<span class="o">(</span>ierr<span class="o">)</span>     <span class="o">!</span> 初始化进程
    call MPI_COMM_RANK<span class="o">(</span>MPI_COMM_WORLD, indcore, ierr<span class="o">)</span> <span class="o">!</span> 得到本进程在通信空间中的rank值,即在组中的逻辑编号<span class="o">(</span>该 rank值为0到p-1间的整数,相当于进程的ID。<span class="o">)</span>
    call MPI_COMM_SIZE<span class="o">(</span>MPI_COMM_WORLD, numcore, ierr<span class="o">)</span> <span class="o">!</span>获得进程个数 size, 这里用变量p保存
    call MPI_Barrier<span class="o">(</span>MPI_COMM_WORLD,ierr<span class="o">)</span>
    nki <span class="o">=</span> floor<span class="o">(</span>indcore <span class="k">*</span> <span class="o">(</span>2.0 <span class="k">*</span> kn<span class="o">)</span>/numcore<span class="o">)</span> - kn
    nkf <span class="o">=</span> floor<span class="o">((</span>indcore + 1<span class="o">)</span> <span class="k">*</span> <span class="o">(</span>2.0 <span class="k">*</span> kn<span class="o">)</span>/numcore<span class="o">)</span> - kn - 1 
</code></pre></div></div>

<p>并行会同时调用多个CPU进行计算，在调用MPI的时候，每个CPU都会有自己单独的编号，也就是上面的<code class="language-plaintext highlighter-rouge">indcore</code>这个参数来进行标识，而<code class="language-plaintext highlighter-rouge">numcore</code>就是在程序执行的时候调用CPU的总数量。此时可以看到对于每个CPU而言，<code class="language-plaintext highlighter-rouge">nki</code>和<code class="language-plaintext highlighter-rouge">nkf</code>都是不同的，这样就可以在不同的CPU上面执行$[-kn,kn-1)$这个区间的不同子区间。</p>

<p class="warning">这里为了保证并行的效率，需要做到不同的区间之间是没有交叠的，因为后续我们要对不同CPU中计算结果的收集，用的是一个求和的方式，所以如果此时计算区间是有重叠的，那么计算的结果中就会有一部分是重复叠加的，所以一定要保证并行区间是没有重叠，且它们的并集等于$[-kn,kn-1)$.</p>

<p>下面就是分拆之后的循环在不同的CPU上计算不同的区间</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="k">do </span>iky <span class="o">=</span> nki,nkf
        qy <span class="o">=</span> pi <span class="k">*</span> iky/kn
        <span class="k">do </span>ikx <span class="o">=</span> <span class="nt">-kn</span>,kn - 1
            qx <span class="o">=</span> pi <span class="k">*</span> ikx/kn
            call chi0cal<span class="o">(</span>qx,qy,chi0<span class="o">(</span>iky,ikx,:,:<span class="o">))</span>  <span class="o">!</span> 得到裸极化率
            call inv<span class="o">(</span>ones - matmul<span class="o">(</span>chi0<span class="o">(</span>iky,ikx,:,:<span class="o">)</span>,Umat<span class="o">)</span>,temp2<span class="o">)</span>  <span class="o">!</span> 矩阵求逆
            chi<span class="o">(</span>iky,ikx,:,:<span class="o">)</span> <span class="o">=</span> matmul<span class="o">(</span>temp2,chi0<span class="o">(</span>iky,ikx,:,:<span class="o">))</span>
            temp3 <span class="o">=</span> <span class="nb">sum</span><span class="o">(</span>chi<span class="o">(</span>iky,ikx,:,:<span class="o">))</span>
            local_rechi<span class="o">(</span>iky,ikx,1<span class="o">)</span> <span class="o">=</span> qx
            local_rechi<span class="o">(</span>iky,ikx,2<span class="o">)</span> <span class="o">=</span> qy
            local_rechi<span class="o">(</span>iky,ikx,3<span class="o">)</span> <span class="o">=</span> real<span class="o">(</span>temp3<span class="o">)</span>
            local_rechi<span class="o">(</span>iky,ikx,4<span class="o">)</span> <span class="o">=</span> aimag<span class="o">(</span>temp3<span class="o">)</span>
        end <span class="k">do
    </span>end <span class="k">do</span>
</code></pre></div></div>
<p>每个CPU上都会有自己独立的<code class="language-plaintext highlighter-rouge">local_rechi</code>变量，下面就是要等所有的CPU计算结束，将结果收集起来</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    call MPI_Barrier<span class="o">(</span>MPI_COMM_WORLD,ierr<span class="o">)</span>
    call MPI_Reduce<span class="o">(</span>local_rechi, rechi, <span class="o">(</span>2 <span class="k">*</span> kn<span class="o">)</span><span class="k">**</span>2 <span class="k">*</span> 4, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD,ierr<span class="o">)</span>
</code></pre></div></div>
<p>这里调用<code class="language-plaintext highlighter-rouge">call MPI_Barrier(MPI_COMM_WORLD,ierr)</code>的目的就是等所有的CPU都计算结束，如果有一些CPU已经计算完循环了，而有一些并没有计算结束，这个时候就让程序在这里等候所有的CPU计算都接受，然后调用<code class="language-plaintext highlighter-rouge">call MPI_Reduce(local_rechi, rechi, (2 * kn)**2 * 4, MPI_REAL, MPI_SUM, 0, MPI_COMM_WORLD,ierr)</code>来收集数据。其中其中的<code class="language-plaintext highlighter-rouge">rechi</code>是一个维度和<code class="language-plaintext highlighter-rouge">local_rechi</code>都完全相同的变量，第三个参数<code class="language-plaintext highlighter-rouge">(2 * kn)**2 * 4</code>表示要收集的数据量大小。举个例子，你有一个矩阵$A(10,10)$，它一共有100个元素，那么此时需要收集的数据量就是100。第四个参数<code class="language-plaintext highlighter-rouge">MPI_REAL</code>则用来声明收集数据的类型，还有整型<code class="language-plaintext highlighter-rouge">MPI_INTEGER</code>和复数型<code class="language-plaintext highlighter-rouge">MPI_COMPLEX</code>。第五个参数<code class="language-plaintext highlighter-rouge">MPI_SUM</code>就是数据收集的方式。我这里就需要用求和即可，因为程序在设计的时候不同的CPU计算的结果实际上是存储在矩阵不同位置，没有存储的位置自然就是0，所以用求和就能达到收集数据的目的。第六个参数则是申明在哪个CPU核心上来执行数据收集这个操作，我这里就选择了<code class="language-plaintext highlighter-rouge">root</code>核心。剩下的就是一些公共参数了，没什么好解释的了。</p>

<p>计算结束之后总是要进行数据存储的，这个操作需要在一个特定的核心上进行</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="k">if</span> <span class="o">(</span>indcore .eq. 0<span class="o">)</span> <span class="k">then
        </span>char1 <span class="o">=</span> <span class="s2">"fortran-chi-"</span>
        write<span class="o">(</span>char2,<span class="s2">"(I3.3)"</span><span class="o">)</span>2 <span class="k">*</span> kn
        filename <span class="o">=</span> trim<span class="o">(</span>char1<span class="o">)</span>//trim<span class="o">(</span>char2<span class="o">)</span>
        char1 <span class="o">=</span> <span class="s2">".dat"</span>
        filename <span class="o">=</span> trim<span class="o">(</span>filename<span class="o">)</span>//trim<span class="o">(</span>char1<span class="o">)</span>
        open<span class="o">(</span>12,file <span class="o">=</span> filename<span class="o">)</span>
        <span class="k">do </span>iky <span class="o">=</span> <span class="nt">-kn</span>,kn - 1
            <span class="k">do </span>ikx <span class="o">=</span> <span class="nt">-kn</span>,kn - 1
                write<span class="o">(</span>12,<span class="s2">"(4F8.3)"</span><span class="o">)</span>rechi<span class="o">(</span>iky,ikx,1<span class="o">)</span>,rechi<span class="o">(</span>iky,ikx,2<span class="o">)</span>,rechi<span class="o">(</span>iky,ikx,3<span class="o">)</span>,rechi<span class="o">(</span>iky,ikx,4<span class="o">)</span>
            end <span class="k">do
        </span>end <span class="k">do
        </span>close<span class="o">(</span>12<span class="o">)</span>
    end <span class="k">if</span>
</code></pre></div></div>
<p>程序执行结束之后还申明结束<code class="language-plaintext highlighter-rouge">MPI</code>并行</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    call MPI_Finalize<span class="o">(</span>ierr<span class="o">)</span>
</code></pre></div></div>

<p>上面实际上只完成了对一个循环的并行，实际情况可以更加丰富。比如我需要用到前面并行得到的结果进行后续计算，而且后续的计算也需要并行，此时就需要对计算得到的变量进行数据广播，然后再进行并行计算，这个方法在后续会继续更新，目前的代码还没有涉及到这个问题。</p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><category term="MPI" /><summary type="html"><![CDATA[该Bolg整理在Fortran用MPI编写并行程序，用在科学计算中速度提升肉眼可见，]]></summary></entry><entry><title type="html">Fortran结合MPI并行计算自旋极化率</title><link href="https://yxli8023.github.io//2024/04/19/Frotran-MPI.html" rel="alternate" type="text/html" title="Fortran结合MPI并行计算自旋极化率" /><published>2024-04-19T00:00:00+08:00</published><updated>2024-04-19T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/04/19/Frotran-MPI</id><content type="html" xml:base="https://yxli8023.github.io//2024/04/19/Frotran-MPI.html"><![CDATA[<p class="info">在之前的博客<a href="https://yxli8023.github.io/2024/03/24/chi0-mpi.md.html">Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)</a>利用<code class="language-plaintext highlighter-rouge">Julia</code>计算了一个模型的极化率，但是在撒点数量增加的时候计算速度还是堪忧。这里就返祖利用<code class="language-plaintext highlighter-rouge">Fortran</code>语言再结合<code class="language-plaintext highlighter-rouge">MPI</code>并行来重写code。根据测试发现计算速度显著提升。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>虽然使用<code class="language-plaintext highlighter-rouge">Julia</code>在计算的时候速度已经相当快了，但是如果涉及到计算极化率这种需要在布里渊区撒点很多才能精确计算的量，<code class="language-plaintext highlighter-rouge">Julia</code>在计算的时候需要的时间还是有点久。况且想要速度更快，就需要仔细的去对代码进行优化，想想还是挺复杂的。最后考虑直接返祖，就用<code class="language-plaintext highlighter-rouge">Fortran</code>(公式翻译器)来计算极化率。</p>

<p>关于公式具体的内容可以参考<a href="https://yxli8023.github.io/2024/03/24/chi0-mpi.md.html">Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)</a>这篇Blog，或者去查看原文<a href="https://link.aps.org/doi/10.1103/PhysRevLett.131.126001">Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure</a>，下面直接上代码。</p>

<h1 id="代码">代码</h1>
<p>这里在写的时候偷懒了，将哈密顿量设置为全局变量了，而且对角化厄米矩阵的函数并没有进行封装，调用之后就是直接对角化哈密顿量。实际上正确且安全的写法就是通过子过程返回哈密顿量，并将其传递给对角化函数计算本征值和本征矢量，这样才能让程序具有通用性。不过事情我是知道的，但这个程序很简单，就先不做这样做了，后续写大程序的时候就会规范了。</p>

<ul>
  <li>计算耗时
这里撒点数量为 256 * 256，调用了64个核，计算时间如下
    <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">========</span> Job starts at 2024-04-15 15:25:16 on n26 <span class="o">========</span> 
Start Fortran code
<span class="o">========</span> Job ends at 2024-04-15 15:25:37 on n26 <span class="o">========</span> 
</code></pre></div>    </div>
    <p>下面就是完整的代码了</p>
    <div class="language-fortran highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">kn</span><span class="p">,</span><span class="n">hn</span><span class="w">
  </span><span class="k">parameter</span><span class="p">(</span><span class="n">kn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">64</span><span class="p">,</span><span class="n">hn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w">
  </span><span class="kt">real</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.1415926535897</span><span class="w">
  </span><span class="kt">real</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">omega</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.00</span><span class="w">
  </span><span class="kt">complex</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">im</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="mf">0.</span><span class="p">,</span><span class="mf">1.</span><span class="p">)</span><span class="w"> </span><span class="c1">!Imagine unit</span><span class="w">
  </span><span class="kt">complex</span><span class="w"> </span><span class="n">Ham</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">Umat</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">ones</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w"> </span><span class="c1">! Hamiltonian and interaction Matrix</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">t0</span><span class="p">,</span><span class="n">t1x</span><span class="p">,</span><span class="n">t1z</span><span class="p">,</span><span class="n">t2x</span><span class="p">,</span><span class="n">t2z</span><span class="p">,</span><span class="n">t3xz</span><span class="p">,</span><span class="n">t4xz</span><span class="p">,</span><span class="n">tvx</span><span class="p">,</span><span class="n">tvz</span><span class="p">,</span><span class="n">ex</span><span class="p">,</span><span class="n">ez</span><span class="w">  </span><span class="c1">! 哈密顿量参数</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">U0</span><span class="p">,</span><span class="n">J0</span><span class="w">  </span><span class="c1">! 相互作用参数</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
  </span><span class="kt">complex</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
  </span><span class="kt">complex</span><span class="w"> </span><span class="n">chi0</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">chi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
  </span><span class="c1">! LAPACK PACKAGE PARAM</span><span class="w">
  </span><span class="kt">integer</span><span class="p">::</span><span class="n">lda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hn</span><span class="w">
  </span><span class="kt">integer</span><span class="p">,</span><span class="k">parameter</span><span class="p">::</span><span class="n">lwmax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="o">*</span><span class="n">hn</span><span class="o">+</span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="w">
  </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">val</span><span class="p">(:)</span><span class="w">
  </span><span class="kt">complex</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">work</span><span class="p">(:)</span><span class="w">
  </span><span class="kt">real</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">rwork</span><span class="p">(:)</span><span class="w">
  </span><span class="kt">integer</span><span class="p">,</span><span class="k">allocatable</span><span class="p">::</span><span class="n">iwork</span><span class="p">(:)</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">lwork</span><span class="w">   </span><span class="c1">! at least 2*hn+N**2</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">lrwork</span><span class="w">    </span><span class="c1">! at least 1 + 5*hn +2*hn**2</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">liwork</span><span class="w">   </span><span class="c1">! at least 3 +5*hn</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">info</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="n">param</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">mpi</span><span class="w"> 
  </span><span class="c1">!------------------------------------</span><span class="w">
  </span><span class="kt">complex</span><span class="w"> </span><span class="n">temp1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp2</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">),</span><span class="n">temp3</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">local_rechi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="o">-</span><span class="n">kn</span><span class="p">:</span><span class="n">kn</span><span class="mi">-1</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w">
  </span><span class="c1">!---------------------------------</span><span class="w">
  </span><span class="kt">integer</span><span class="w">  </span><span class="n">numcore</span><span class="p">,</span><span class="n">indcore</span><span class="p">,</span><span class="n">ierr</span><span class="w">
  </span><span class="kt">character</span><span class="p">(</span><span class="nb">len</span><span class="o">=</span><span class="mi">20</span><span class="p">)::</span><span class="n">filename</span><span class="p">,</span><span class="n">char1</span><span class="p">,</span><span class="n">char2</span><span class="w">
  </span><span class="c1">!---------------------------------</span><span class="w">
  </span><span class="k">external</span><span class="p">::</span><span class="n">cheevd</span><span class="w">
  </span><span class="k">allocate</span><span class="p">(</span><span class="n">val</span><span class="p">(</span><span class="n">hn</span><span class="p">))</span><span class="w">
  </span><span class="k">allocate</span><span class="p">(</span><span class="n">work</span><span class="p">(</span><span class="n">lwmax</span><span class="p">))</span><span class="w">
  </span><span class="k">allocate</span><span class="p">(</span><span class="n">rwork</span><span class="p">(</span><span class="mi">1+5</span><span class="o">*</span><span class="n">hn</span><span class="mi">+2</span><span class="o">*</span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span><span class="w">
  </span><span class="k">allocate</span><span class="p">(</span><span class="n">iwork</span><span class="p">(</span><span class="mi">3+5</span><span class="o">*</span><span class="n">hn</span><span class="p">))</span><span class="w">
  </span><span class="c1">!---------------------------------</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_INIT</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">     </span><span class="c1">! 初始化进程</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_RANK</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">indcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">! 得到本进程在通信空间中的rank值,即在组中的逻辑编号(该 rank值为0到p-1间的整数,相当于进程的ID。)</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_COMM_SIZE</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="w"> </span><span class="n">numcore</span><span class="p">,</span><span class="w"> </span><span class="n">ierr</span><span class="p">)</span><span class="w"> </span><span class="c1">!获得进程个数 size, 这里用变量p保存</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
  </span><span class="n">nki</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
  </span><span class="n">nkf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">floor</span><span class="p">((</span><span class="n">indcore</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mf">2.0</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)/</span><span class="n">numcore</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w"> 
  </span><span class="c1">! 遍历BZ求极化率</span><span class="w">
  </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nki</span><span class="p">,</span><span class="n">nkf</span><span class="w">
      </span><span class="n">qy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w">
      </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
          </span><span class="n">qx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">chi0cal</span><span class="p">(</span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">  </span><span class="c1">! 得到裸极化率</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">inv</span><span class="p">(</span><span class="n">ones</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">matmul</span><span class="p">(</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:),</span><span class="n">Umat</span><span class="p">),</span><span class="n">temp2</span><span class="p">)</span><span class="w">  </span><span class="c1">! 矩阵求逆</span><span class="w">
          </span><span class="n">chi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">matmul</span><span class="p">(</span><span class="n">temp2</span><span class="p">,</span><span class="n">chi0</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">
          </span><span class="n">temp3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">sum</span><span class="p">(</span><span class="n">chi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:))</span><span class="w">
          </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">qx</span><span class="w">
          </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">qy</span><span class="w">
          </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">real</span><span class="p">(</span><span class="n">temp3</span><span class="p">)</span><span class="w">
          </span><span class="n">local_rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">aimag</span><span class="p">(</span><span class="n">temp3</span><span class="p">)</span><span class="w">
      </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Barrier</span><span class="p">(</span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
  </span><span class="c1">! call MPI_Gather(local_rechi, 2 * kn, MPI_COMPLEX, rechi, 2 * kn, MPI_COMPLEX, 0, MPI_COMM_WORLD,ierr)</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Reduce</span><span class="p">(</span><span class="n">local_rechi</span><span class="p">,</span><span class="w"> </span><span class="n">rechi</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_REAL</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_SUM</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">MPI_COMM_WORLD</span><span class="p">,</span><span class="n">ierr</span><span class="p">)</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">indcore</span><span class="w"> </span><span class="ow">.eq.</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
      </span><span class="n">char1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"fortran-chi-"</span><span class="w">
      </span><span class="k">write</span><span class="p">(</span><span class="n">char2</span><span class="p">,</span><span class="s2">"(I3.3)"</span><span class="p">)</span><span class="n">kn</span><span class="w">
      </span><span class="n">filename</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">trim</span><span class="p">(</span><span class="n">char1</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char2</span><span class="p">)</span><span class="w">
      </span><span class="n">char1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">".dat"</span><span class="w">
      </span><span class="n">filename</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">trim</span><span class="p">(</span><span class="n">filename</span><span class="p">)//</span><span class="nb">trim</span><span class="p">(</span><span class="n">char1</span><span class="p">)</span><span class="w">
      </span><span class="k">open</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">filename</span><span class="p">)</span><span class="w">
      </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
          </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
              </span><span class="k">write</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="s2">"(4F5.3)"</span><span class="p">)</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span><span class="nb">abs</span><span class="p">(</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">3</span><span class="p">)),</span><span class="nb">abs</span><span class="p">(</span><span class="n">rechi</span><span class="p">(</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="mi">4</span><span class="p">))</span><span class="w">
          </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
      </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
      </span><span class="k">close</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">MPI_Finalize</span><span class="p">(</span><span class="n">ierr</span><span class="p">)</span><span class="w">
  </span><span class="k">stop</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">program</span><span class="w"> </span><span class="n">main</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">)</span><span class="w">
  </span><span class="c1">! 矩阵赋值</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">k0</span><span class="w">
  </span><span class="n">t0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1.0</span><span class="w">
  </span><span class="n">t1x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.483</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">t1z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.110</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">t2x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.069</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">t2z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.017</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">t3xz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.239</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">t4xz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.034</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">tvx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.005</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">tvz</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">-0.635</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">ex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.776</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
  </span><span class="n">ez</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.409</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t0</span><span class="w">
    
  </span><span class="n">Ham</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.0</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ex</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ez</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ex</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t1z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t2z</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ez</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t3xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvx</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvz</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvx</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">t4xz</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">cos</span><span class="p">(</span><span class="n">kx</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">cos</span><span class="p">(</span><span class="n">ky</span><span class="p">))</span><span class="w">
  </span><span class="n">Ham</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tvz</span><span class="w">
  </span><span class="c1">!---------------------------------------------------------------------</span><span class="w">
  </span><span class="c1">! 相互作用矩阵赋值</span><span class="w">
  </span><span class="n">U0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3.0</span><span class="w">
  </span><span class="n">J0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.4</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">U0</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
  </span><span class="n">Umat</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">J0</span><span class="p">/</span><span class="mi">2</span><span class="w">
  </span><span class="c1">!---------------------------------------------------------------------</span><span class="w">
  </span><span class="c1">! 单位矩阵</span><span class="w">
  </span><span class="k">do</span><span class="w"> </span><span class="n">k0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
      </span><span class="n">ones</span><span class="p">(</span><span class="n">k0</span><span class="p">,</span><span class="n">k0</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
  </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">chi0cal</span><span class="p">(</span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">re1</span><span class="p">)</span><span class="w">
  </span><span class="c1">! 计算极化率  返回到re1</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">ikx</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e1</span><span class="p">,</span><span class="n">e2</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">qy</span><span class="p">,</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="w">
  </span><span class="kt">complex</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
  </span><span class="k">do</span><span class="w"> </span><span class="n">iky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
      </span><span class="n">ky</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">iky</span><span class="p">/</span><span class="n">kn</span><span class="w">
      </span><span class="k">do</span><span class="w"> </span><span class="n">ikx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">,</span><span class="n">kn</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w">
          </span><span class="n">kx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pi</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ikx</span><span class="p">/</span><span class="n">kn</span><span class="w">

          </span><span class="c1">! k</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="p">,</span><span class="n">ky</span><span class="p">)</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w"> 
          </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">val</span><span class="p">(:)</span><span class="w">
          </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham</span><span class="p">(:,:)</span><span class="w">

          </span><span class="c1">! k + q</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">matset</span><span class="p">(</span><span class="n">kx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">qx</span><span class="p">,</span><span class="n">ky</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">qy</span><span class="p">)</span><span class="w">
          </span><span class="k">call</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w"> 
          </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">val</span><span class="p">(:)</span><span class="w">
          </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,:,:)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Ham</span><span class="p">(:,:)</span><span class="w">
            
          </span><span class="c1">! 计算极化率</span><span class="w">
          </span><span class="k">do</span><span class="w"> </span><span class="n">l1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">   </span><span class="c1">! orbit ondex</span><span class="w">
              </span><span class="k">do</span><span class="w"> </span><span class="n">l2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
                  </span><span class="k">do</span><span class="w"> </span><span class="n">e1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">  </span><span class="c1">! band index</span><span class="w">
                      </span><span class="k">do</span><span class="w"> </span><span class="n">e2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="n">hn</span><span class="w">
                          </span><span class="n">re1</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">(</span><span class="n">l1</span><span class="p">,</span><span class="n">l2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">fermi</span><span class="p">(</span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e1</span><span class="p">))</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e2</span><span class="p">)))/(</span><span class="n">im</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">omega</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">0.0001</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">valmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">e2</span><span class="p">))&amp;</span><span class="w">
                                  </span><span class="o">*</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">e2</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">conjg</span><span class="p">(</span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l2</span><span class="p">,</span><span class="n">e1</span><span class="p">))</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">vecmesh</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">iky</span><span class="p">,</span><span class="n">ikx</span><span class="p">,</span><span class="n">l1</span><span class="p">,</span><span class="n">e1</span><span class="p">)</span><span class="w">
                      </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
                  </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
              </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
          </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
      </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">do</span><span class="w">
  </span><span class="n">re1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">re1</span><span class="p">/(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">kn</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="w">
  </span><span class="k">return</span><span class="w"> 
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">fermi</span><span class="p">(</span><span class="n">ek</span><span class="p">)</span><span class="w">
  </span><span class="c1">! 费米分布函数</span><span class="w">
  </span><span class="k">implicit</span><span class="w"> </span><span class="k">none</span><span class="w">
  </span><span class="kt">real</span><span class="w"> </span><span class="n">fermi</span><span class="p">,</span><span class="n">ek</span><span class="p">,</span><span class="n">kbt</span><span class="w">
  </span><span class="n">kbt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.001</span><span class="w">
  </span><span class="n">fermi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">/(</span><span class="nb">exp</span><span class="p">(</span><span class="n">ek</span><span class="p">/</span><span class="n">kbt</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">  
  </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">function</span><span class="w"> </span><span class="n">equivkpq</span><span class="p">(</span><span class="n">i0</span><span class="p">)</span><span class="w">
  </span><span class="c1">! 找到BZ中k+q等价与k的索引</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">equivkpq</span><span class="p">,</span><span class="n">i0</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="w"> </span><span class="ow">.and.</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">kn</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i0</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="o">-</span><span class="n">kn</span><span class="p">/</span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="n">equivkpq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i0</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">kn</span><span class="w">
</span><span class="k">end</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">eigSol</span><span class="p">()</span><span class="w">
  </span><span class="c1">! 对角化得到本征值w和本征矢量Ham</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="kt">integer</span><span class="w"> </span><span class="n">m</span><span class="w">
  </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
  </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
  </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">lda</span><span class="p">,</span><span class="n">val</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
  </span><span class="n">lwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">work</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
  </span><span class="n">lrwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="nb">int</span><span class="p">(</span><span class="w"> </span><span class="n">rwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
  </span><span class="n">liwork</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="mi">3</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">hn</span><span class="p">,</span><span class="w"> </span><span class="n">iwork</span><span class="p">(</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">)</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">cheevd</span><span class="p">(</span><span class="s1">'V'</span><span class="p">,</span><span class="s1">'U'</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">Ham</span><span class="p">,</span><span class="n">lda</span><span class="p">,</span><span class="n">val</span><span class="p">,</span><span class="n">work</span><span class="p">,</span><span class="n">lwork</span><span class="p">,</span><span class="n">rwork</span><span class="p">,</span><span class="n">lrwork</span><span class="p">,</span><span class="n">iwork</span><span class="p">,</span><span class="n">liwork</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
  </span><span class="k">if</span><span class="p">(</span><span class="w"> </span><span class="n">info</span><span class="w"> </span><span class="ow">.GT.</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">then</span><span class="w">
      </span><span class="k">open</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mes.dat"</span><span class="p">,</span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"unknown"</span><span class="p">)</span><span class="w">
      </span><span class="k">write</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span><span class="o">*</span><span class="p">)</span><span class="s1">'The algorithm failed to compute eigenvalues.'</span><span class="w">
      </span><span class="k">close</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="w">
  </span><span class="c1">! open(12,file="eigval.dat",status="uknnown")</span><span class="w">
  </span><span class="c1">! do m = 1,N</span><span class="w">
  </span><span class="c1">! 	write(12,*)m,val(m)</span><span class="w">
  </span><span class="c1">! end do</span><span class="w">
  </span><span class="c1">! close(12)</span><span class="w">
  </span><span class="k">return</span><span class="w">
</span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">eigSol</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span><span class="k">subroutine</span><span class="w"> </span><span class="n">inv</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="n">matout</span><span class="p">)</span><span class="w">
  </span><span class="c1">! 矩阵求逆</span><span class="w">
  </span><span class="k">use</span><span class="w"> </span><span class="n">param</span><span class="w">
  </span><span class="kt">complex</span><span class="p">,</span><span class="k">intent</span><span class="p">(</span><span class="k">in</span><span class="p">)</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">matin</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">)</span><span class="w">
  </span><span class="kt">complex</span><span class="p">::</span><span class="w"> </span><span class="n">matout</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span><span class="w">
  </span><span class="kt">real</span><span class="p">::</span><span class="w"> </span><span class="n">work2</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">            </span><span class="c1">! work2 array for LAPACK</span><span class="w">
  </span><span class="kt">integer</span><span class="p">::</span><span class="n">ipiv</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">matin</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="w">     </span><span class="c1">! pivot indices</span><span class="w">
  </span><span class="c1">! Store matin in matout to prevent it from being overwritten by LAPACK</span><span class="w">
  </span><span class="n">matout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">matin</span><span class="w">
  </span><span class="c1">! SGETRF computes an LU factorization of a general M - by - N matrix A</span><span class="w">
  </span><span class="c1">! using partial pivoting with row interchanges .</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRF</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">stop</span><span class="w"> </span><span class="s1">'Matrix is numerically singular!'</span><span class="w">
  </span><span class="c1">! SGETRI computes the inverse of a matrix using the LU factorization</span><span class="w">
  </span><span class="c1">! computed by SGETRF.</span><span class="w">
  </span><span class="k">call</span><span class="w"> </span><span class="n">CGETRI</span><span class="p">(</span><span class="n">hn</span><span class="p">,</span><span class="n">matout</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">ipiv</span><span class="p">,</span><span class="n">work2</span><span class="p">,</span><span class="n">hn</span><span class="p">,</span><span class="n">info</span><span class="p">)</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">info</span><span class="ow">.ne.</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="k">stop</span><span class="w"> </span><span class="s1">'Matrix inversion failed!'</span><span class="w">
  </span><span class="k">return</span><span class="w">
  </span><span class="k">end</span><span class="w"> </span><span class="k">subroutine</span><span class="w"> </span><span class="n">inv</span><span class="w">
</span><span class="c1">!================================================================================================================================================================================================</span><span class="w">
</span></code></pre></div>    </div>
    <p>计算结果</p>
  </li>
</ul>

<p><img src="/assets/images/Fortran/fortran-chi-128.png" alt="png" /></p>

<h1 id="绘图程序">绘图程序</h1>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">plotchi</span><span class="p">(</span><span class="n">numk</span><span class="p">):</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"chi-nk-"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">format</span><span class="p">(</span><span class="n">numk</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span> <span class="o">+</span> <span class="s">".dat"</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"julia-chi-nk-"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">format</span><span class="p">(</span><span class="n">numk</span><span class="p">,</span><span class="s">".2f"</span><span class="p">))</span> <span class="o">+</span> <span class="s">".dat"</span>
    <span class="n">dataname</span> <span class="o">=</span> <span class="s">"fortran-chi-"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">format</span><span class="p">(</span><span class="n">numk</span><span class="p">,</span><span class="s">"0&gt;3d"</span><span class="p">))</span> <span class="o">+</span> <span class="s">".dat"</span>  <span class="c1"># 补足整数
</span>    <span class="n">picname</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">dataname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">".png"</span>
    <span class="n">da</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">dataname</span><span class="p">)</span> 
    <span class="n">x0</span> <span class="o">=</span> <span class="n">da</span><span class="p">[:,</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">z0</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">da</span><span class="p">[:,</span><span class="mi">2</span><span class="p">])</span>
    <span class="n">xn</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">x0</span><span class="p">)))</span>
    <span class="n">z0</span> <span class="o">=</span> <span class="n">z0</span><span class="p">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">xn</span><span class="p">,</span><span class="n">xn</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span> <span class="o">=</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
    <span class="c1"># sc = plt.imshow(z0,interpolation='bilinear', cmap = cm.RdYlGn,origin='lower',vmax = abs(z0).max(), vmin = 0)
</span>    <span class="c1"># sc = plt.imshow(z0,interpolation='bilinear', cmap = "jet",origin='lower', extent=[1, 30, 1, 30],vmax = abs(z0).max(), vmin = 0)
</span>    <span class="n">sc</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">imshow</span><span class="p">(</span><span class="n">z0</span><span class="p">,</span><span class="n">interpolation</span><span class="o">=</span><span class="s">'bilinear'</span><span class="p">,</span> <span class="n">cmap</span> <span class="o">=</span> <span class="s">"jet_r"</span><span class="p">,</span><span class="n">origin</span><span class="o">=</span><span class="s">'lower'</span><span class="p">)</span>
    <span class="n">cb</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">colorbar</span><span class="p">(</span><span class="n">sc</span><span class="p">,</span><span class="n">fraction</span> <span class="o">=</span> <span class="mf">0.045</span><span class="p">)</span>  <span class="c1"># 调整colorbar的大小和图之间的间距
</span>    <span class="n">cb</span><span class="p">.</span><span class="n">ax</span><span class="p">.</span><span class="n">tick_params</span><span class="p">(</span><span class="n">labelsize</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
    <span class="n">font2</span> <span class="o">=</span> <span class="p">{</span><span class="s">'family'</span><span class="p">:</span> <span class="s">'Times New Roman'</span><span class="p">,</span><span class="s">'weight'</span><span class="p">:</span> <span class="s">'normal'</span><span class="p">,</span><span class="s">'size'</span><span class="p">:</span> <span class="mi">40</span><span class="p">}</span>
    <span class="c1"># cb.set_label('ldos',fontdict=font2) #设置colorbar的标签字体及其大小
</span>    <span class="c1"># plt.scatter(x0, y0, s = 5, color='blue',edgecolor="blue")
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">axis</span><span class="p">(</span><span class="s">'scaled'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$q_x$"</span><span class="p">,</span><span class="n">font2</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="sa">r</span><span class="s">"$q_y$"</span><span class="p">,</span><span class="n">font2</span><span class="p">)</span>
    <span class="c1"># tit = "$J_x= " + str(cont) + "$"
</span>    <span class="c1"># plt.title(tit,font2)
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">yticks</span><span class="p">([],</span><span class="n">fontproperties</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">40</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">xticks</span><span class="p">([],</span><span class="n">fontproperties</span><span class="o">=</span><span class="s">'Times New Roman'</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">40</span><span class="p">)</span>
    <span class="c1"># plt.tick_params(axis='x',width = 2,length = 10)
</span>    <span class="c1"># plt.tick_params(axis='y',width = 2,length = 10)
</span>    <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">gca</span><span class="p">()</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"bottom"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"left"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> 
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"right"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">spines</span><span class="p">[</span><span class="s">"top"</span><span class="p">].</span><span class="n">set_linewidth</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span>
    <span class="c1"># plt.show()
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">picname</span><span class="p">,</span> <span class="n">dpi</span> <span class="o">=</span> <span class="mi">300</span><span class="p">,</span><span class="n">bbox_inches</span> <span class="o">=</span> <span class="s">'tight'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1">#------------------------------------------------------------
</span><span class="k">if</span> <span class="n">__name__</span><span class="o">==</span><span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">plotchi</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span>
</code></pre></div></div>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Fortran" /><category term="Code" /><category term="MPI" /><category term="Superconductor" /><category term="Python" /><summary type="html"><![CDATA[在之前的博客Julia的MPI并行计算极化率(重复Bilayer Two-Orbital Model of La$_3$Ni$_2$O$_7$ under Pressure)利用Julia计算了一个模型的极化率，但是在撒点数量增加的时候计算速度还是堪忧。这里就返祖利用Fortran语言再结合MPI并行来重写code。根据测试发现计算速度显著提升。]]></summary></entry><entry><title type="html">使用Latex进行文档对比并自动标记修改的内容</title><link href="https://yxli8023.github.io//2024/03/31/latexdiff.html" rel="alternate" type="text/html" title="使用Latex进行文档对比并自动标记修改的内容" /><published>2024-03-31T00:00:00+08:00</published><updated>2024-03-31T00:00:00+08:00</updated><id>https://yxli8023.github.io//2024/03/31/latexdiff</id><content type="html" xml:base="https://yxli8023.github.io//2024/03/31/latexdiff.html"><![CDATA[<p class="info">这里整理一下如何使用Latex自动整理出文档改动内容并进行标记，这个功能在我们给审稿人回复意见的时候非常有用。</p>
<!--more-->
<h1 id="前言">前言</h1>
<p>通常在文章审稿的过程中，都需要根据审稿人的要求和问题对文章内容进行修改，常用的方法就是将修改的部分用颜色标记出来，但是这样就将原来的内容删除掉了，审稿人再次看到的时候只能看到我们修改文章的结果，但具体修改了什么，修改到了什么程度就不是很显而易见了。当然，如果有精力也可以用下划线以及删除线等标记自己手动将原本的内容与修改之后的内容分别进行标记，但这种手动的方式操作起来还是挺累的，毕竟<code class="language-plaintext highlighter-rouge">Latex</code>本身虽然排本能力很强，但是在写的时候可读性就不是很好了，内容多了就会眼花缭乱。</p>

<h1 id="解决方法">解决方法</h1>
<p>实际上在安装了<code class="language-plaintext highlighter-rouge">TexLive</code>之后，本身就会自带一个文档比对的功能，与<code class="language-plaintext highlighter-rouge">Linux</code>系统里面的<code class="language-plaintext highlighter-rouge">diff</code>的功能是相似的，使用</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>latexdiff file-1.tex file-2.tex <span class="o">&gt;</span> diff.tex
</code></pre></div></div>
<p>这个命令之后，就可以自动生成一个对比之后的文件<code class="language-plaintext highlighter-rouge">diff.tex</code>，当然，这里的名字都是自己起的。在产生的<code class="language-plaintext highlighter-rouge">diff.tex</code>文件中就会将两个文件的比对结果存储，删除以及修改的内容都会用各种标记方式给出。再对<code class="language-plaintext highlighter-rouge">diff.tex</code>文件编译之后就可以得到一个内容修改对比的结果了，示例如下</p>

<ul>
  <li>原版(file-1.tex)</li>
</ul>

<p><img src="/assets/images/latex/f-1.png" alt="png" /></p>

<ul>
  <li>修改版(file-2.tex)</li>
</ul>

<p><img src="/assets/images/latex/f-2.png" alt="png" /></p>

<ul>
  <li>对比版(diff.tex)</li>
</ul>

<p><img src="/assets/images/latex/f-3.png" alt="png" /></p>

<p class="info">这样就可以让审稿人一目了然的看清楚我们对正文的修改以及修改程度，对文章审稿意见的仔细回复也能体现出对审稿人的尊重</p>

<p>上面给出的只是<code class="language-plaintext highlighter-rouge">latexdiff</code>的默认参数选择，更加丰富的选项可以移步官网查看，但是以我现在的需要，看起来默认的选项就已经足够了。</p>

<h1 id="提示">提示</h1>
<p>前面只是给出了一个很简单的示例，实际上文档中包含的并不仅仅是文字，还会有公式和图片，这些都是可以识别修改前后的差别。</p>

<p class="warning">但有一点很重要，在修改之后的<em>file-2.tex</em>中，尽量要保证它与<em>file-1.tex</em>的结构是一致的。比如说你有一张图片本来在Latex中在<em>Section I</em>里面的，但是在修改过程中将这个图片的插入移动到了<em>Section II</em>中，此时再利用上面的方法进行文档差异识别的时候，就会将<em>file-2.tex</em>中的这张图片插入与<em>file-1.tex</em>中处于相同文本位置的文字进行对比，给出的结果自然是有问题的。因此在修改的时候，若非文章进行的改动非常大，尽量不要去改变原本的架构。</p>

<h1 id="公众号">公众号</h1>
<p class="info">相关内容均会在公众号进行同步，若对该Blog感兴趣，欢迎关注微信公众号。</p>

<p><img src="/assets/images/qrcode.jpg" alt="png" class="border rounded" width="300px" height="300px" /></p>
<div class="card">
  <div class="card__content">
    <div class="card__header">
      <h4>Email</h4>
    </div>
    <p>yxli406@gmail.com</p>
  </div>
</div>]]></content><author><name>YuXuan</name><email>yxli406@163.com</email></author><category term="Latex" /><summary type="html"><![CDATA[这里整理一下如何使用Latex自动整理出文档改动内容并进行标记，这个功能在我们给审稿人回复意见的时候非常有用。]]></summary></entry></feed>