计算化学公社
标题:
cp2k计算平面平均LDOS的后处理脚本
[打印本页]
作者Author:
Stardust0831
时间:
2025-4-1 00:55
标题:
cp2k计算平面平均LDOS的后处理脚本
本帖最后由 Stardust0831 于 2025-4-1 00:58 编辑
几个月前,我在文献里看到了这样的图
(, 下载次数 Times of downloads: 48)
上传 Uploaded
点击下载Click to download
。图中通过平面平均的LDOS来展现异质结界面的能带弯曲。在尝试用cp2k+multiwfn重复的时候,发现multiwfn只能计算某条线上的LDOS,由于修改multiwfn源代码遇到了环境问题,我基于multiwfn现有的计算某条线的LDOS的功能写了个批处理脚本,可以批量计算上不同(X,Y)坐标对应的垂直于Z平面的线上的LDOS,对这些不同的(X,Y)坐标下得到的值取平均,取的点足够密时也就实现了平面平均。此脚本
避免了反复读取molden文件而增加耗时
。该脚本需要使用
powershell7
运行。由于是依赖于multiwfn的已有功能完成的计算,这个LDOS的结果是gamma点而非考虑了不同k点。考虑特定k点的这一部分我暂时没有想到很好的解决策略,就用这个脚本抛砖引玉一下,看看各位大佬有没有更好的思路。
以下为脚本本体,部分内容根据备注自行修改:
#!/usr/bin/pwsh
# ./auto.ps1 -OutputFolder /opt/example/output
param(
[string] $OutputFolder = $PSScriptRoot
)
function Start-Multiwfn
{
param(
[string] $MultiwfnPath,
[string] $MoldenFile,
[System.IntPtr] $Affinity
)
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.RedirectStandardInput = $true
$startInfo.RedirectStandardOutput = $true
$startInfo.StandardInputEncoding = [System.Text.Encoding]::UTF8
$startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
$startInfo.FileName = $MultiwfnPath
$startInfo.Arguments = "$MoldenFile -slient"
$process = [System.Diagnostics.Process]::Start($startInfo)
$process.PriorityClass = [System.Diagnostics.ProcessPriorityClass]::RealTime
$process.ProcessorAffinity = $Affinity
$process.Refresh()
return $process
}
function Push-Data
{
param(
[string] $StartPoint,
[string] $EndPoint,
[int] $Number
)
# Wait input until specific output
while ($true)
{
if ($Reader.Peek() -le 0)
{
Start-Sleep -Seconds 1
Write-Host $s
++$s
continue
}
$line = $Reader.ReadLine()
Write-Host $line
if ($line.Contains('========== Plot density-of-states (DOS) =========='))
{
break
}
}
$Writer.WriteLine("11")
Start-Sleep -Seconds 1
$Writer.WriteLine($StartPoint)
Start-Sleep -Seconds 1
$Writer.WriteLine($EndPoint)
Start-Sleep -Seconds 1
$Writer.WriteLine($Number)
$s = 0
while ($true)
{
if ($Reader.Peek() -le 0)
{
Start-Sleep -Seconds 1
Write-Host $s
++$s
continue
}
$line = $Reader.ReadLine()
Write-Host $line
if ($line.Contains('-------- Post-processing menu --------'))
{
break
}
}
$Writer.WriteLine("3")
while ($true)
{
if ($Reader.Peek() -le 0)
{
Start-Sleep -Seconds 1
Write-Host $s
++$s
continue
}
$line = $Reader.ReadLine()
Write-Host $line
if ($line.Contains('-------- Post-processing menu --------'))
{
break
}
}
$timestamp = Get-Date -Format "yyyyMMddHHmmss"
$filename = "LDOS" + "_" + $StartPoint + "_" + $EndPoint + "_" + $Number + "_$timestamp.txt"
# !!!IMPORTANT!!! Move and rename output file
Move-Item -Path "$PSScriptRoot/LDOS.txt" -Destination "$OutputFolder/$filename"
$Writer.WriteLine("0")
}
# Script Entry
try
{
$timestamp = Get-Date -Format "yyyyMMddHHmmss"
$OutputFolder = [System.IO.Path]::Combine($OutputFolder, $timestamp)
[System.IO.Directory]::CreateDirectory($OutputFolder)
# !!!IMPORTANT!!! Start Multiiwfn process
$process = Start-Multiwfn -MultiwfnPath "$PSScriptRoot/Multiwfn.exe" -MoldenFile "$PSScriptRoot/test1/FAPbI3-ch3opeai-sp-MOS-1_0.molden" -Affinity 0xfff
$Reader = $process.StandardOutput
$Writer = $process.StandardInput
$s = 0
while ($true)
{
if ($Reader.Peek() -le 0)
{
Start-Sleep -Seconds 1
Write-Host $s
++$s
continue
}
$line = $Reader.ReadLine()
Write-Host $line
if ($line.Contains('************ Main function menu ************'))
{
break
}
}
$Writer.WriteLine("\r\n")
# Add additional option, $Writer.WriteLine("10")
$Writer.WriteLine("10")
Start-Sleep -Seconds 1
$Writer.WriteLine("8")
Start-Sleep -Seconds 1
$Writer.WriteLine("2")
Start-Sleep -Seconds 1
$Writer.WriteLine("-10,2,2")
Start-Sleep -Seconds 1
$Writer.WriteLine("3")
Start-Sleep -Seconds 1
#$Writer.WriteLine("0.4")
Start-Sleep -Seconds 1
for ($i = 0; $i -lt 5; ++$i)
{
Push-Data -StartPoint "$i,0,0" -EndPoint "$i,0,30" -Number 20
}
$process.Close()
return
}
catch
{
Write-Error $_.Exception
}
finally
{
if (-not $process.HasExited){
$process.Close()
}
}
复制代码
该脚本会把计算得到的不同线段的LDOS输出到特定文件夹,可以通过这个C#程序来完成对这些数据取平均,从而实现平面平均的效果:
using System.Text;
using System.Text.RegularExpressions;
var dictionary = new Dictionary<(double, double), double>();
var files = Directory.GetFiles(Environment.CurrentDirectory, "*.txt", SearchOption.AllDirectories);
foreach (var file in files)
{
using var reader = new StreamReader(file);
while (!reader.EndOfStream)
{
var line = reader.ReadLine()?.Trim();
if (string.IsNullOrEmpty(line))
{
continue;
}
line = Regex.Replace(line, "( ){2,}", " ");
var values = line.Split(' ');
var key = (double.Parse(values[0]), double.Parse(values[1]));
var value = double.Parse(values[2]);
dictionary[key] = value;
}
}
if (File.Exists("result.txt")) File.Move("result.txt", [ DISCUZ_CODE_1 ]quot;result_{DateTime.Now:yyyyMMddHHmmss}).txt");
using var writer = new StreamWriter("result.txt", false, Encoding.UTF8);
foreach (var (key, value) in dictionary)
{
writer.WriteLine([ DISCUZ_CODE_1 ]quot;{key.Item1} {key.Item2} {value}");
}
复制代码
作者Author:
berserker.npc
时间:
2025-7-4 19:09
你好,我试着运行这个脚本,结果导入文件成功后就一直输出数字,是哪一部分的原因呢?
P1是运行脚本后的输出,P2是正常使用multiwfn导入文件后的结果,P3是我修改过的部分代码
作者Author:
Stardust0831
时间:
2025-7-9 01:45
berserker.npc 发表于 2025-7-4 19:09
你好,我试着运行这个脚本,结果导入文件成功后就一直输出数字,是哪一部分的原因呢?
P1是运行脚本后的输 ...
可能是由于体系特殊,multiwfn输出变了,脚本没有捕获到预期的输出。
提供具体结构的cif文件以及molden文件,我这边帮你试一下。
欢迎光临 计算化学公社 (http://ccc.keinsci.com/)
Powered by Discuz! X3.3