首页/文章/ 详情

PVOX-自定义函数readoutput分析

3年前浏览1698

image.png

 过冷水诚挚邀请你加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载,群号:927550334 

QQ图片20210424105303.png

“庖丁为文惠君解牛,手之所触,肩之所倚,足之所履,膝之所踦,砉然向然,奏刀騞然,莫不中音。合于《桑林》之舞,乃中《经首》之会”。

    牛虽难解,十载不费一刀,徒心中有牛。复杂工程不要慌,看过冷水带你一步一步解析PVOX工具包,本期先看看自定义函数readoutput函数的构建。

[data, wfn, D_valid, W_valid] = readOutput(outName, datName)



  (1)自定义函数readOutput()的作用是读取后缀为*.out*.dat的两个文件,输出data、wfn、D_valid、W_valid对象;

    (2)Data:的作用是提取*.out中的一些变量和对应的数据,重新储存在data对象中。

  (3)wfn:是提取后缀为*.dat的文件中的数据,储存在wfn中。表征波函数

    (4)D_valid、W_valid这两个量是用于监控Data、wfn过程环节是否出错而设置的。假设wfn计算没有问题则W_valid赋值为1,否则为0

outName='parsec_grid0_4.out'

datName='parsec_grid0_4.dat'

D_valid = false;

W_valid = [0,0,0,0,0];

data = [];

wfn = [];

该步骤为导入两个文件。定义输出对象。需要注意的是:D_valid为单值,W_valid为多值,这是因为存储wfn数据过程中有多个子环节需要判断。

接下是try-catch-end结构

try

   Statements1

catch 

   Statements2

end

该结构的含义是尝试执行命令。先执行try层下的语句命令sta1,若是正常执行,则该结构功能结束,若是try层语句命令不能正常执行,则执行catch 层下的语句命令sta2,如果sta1、sta2皆不能正常执行,则跳过该结构代码,执行后续命令,不报错。这样来配合变量监控就可以从整体来把控代码有几处问题了,而不是代码以有错,就停止判断,无法了解后续代码情况。


h = waitbar(0,'Opening parsec.out');

[str,maxsize,endian] = computer;

fName = fopen('pTemp/fname.dat','wt');

fName = fopen('pTemp/fname.dat','wt');

fwrite(fName,datName);

fclose(fName);

waitbar(0.1,h);

该部分的语句的含义是新建一个文件,将后缀为*.out*.dat的两个文件的路径写入该文件中,以便后续使用。

原始代码的第一个错误就在这里出现了。我们以截图的形式比较两段代码的差别。

图片

过冷水的修改代码中多了两行命令,

fprintf(fName,'\n');

fwrite(fName,datName);

What you want do!过冷水总会为自己擅自修改代码编造出合理的理由,我们结合这两段代码来看另一段代码。

图片

如果不对matlab中fname.dat写入文件时进行适当修改,下图的代码2就会报错。代码1、2是python码,不了解python的加入我们python课程,懂一点python让我们的距离更加近一点!在此说明一下:

fname = file('./pTemp/fname.dat', 'r')

fileName = fname.readline()

   目的为打开fname.dat文件,并读取第一行的内容。我们们将*.out文件路径写入fname.dat中,让其读取,没毛病!

  • fname = file('./pTemp/fname.dat', 'r')

  • fileName = fname.readline()

  • fileName = fname.readline()

  • switchEndian = fname.readline()

  • inFile = file(fileName, 'rb')

目的为打开fname.dat文件,并读取第二行、第三行的内容。什么时候往fname.dat文件中第二行和第三行写入数据了?能不报错吗?这就是为什么添加写入内容的原因。这里改写需要注意一下各种error!


图片


图片

图片

图片

想要给读者展示错误代码报错,容易的很,在此过冷水只展示了几种没有明显错误,但实际是错的案例。过冷水只是想往文本里多添一条绝对路径,需要注意的点就有这么多,可见代码的编写细节很多,不断学习才能够完善编程知识。需要你精通matlab的跟着过冷水一行一行看代码!


if strncmp(str,'PCWIN',5)

        try   % Parsec Abridged Output

            [s,w] = dos('del /Q pTemp\main.dat');

            !"./pTools/PARSEC_PARSER_ABRIDGED.py"

        catch % Parsec Un-Abridged Output

            !"./pTools/PARSEC_PARSER.py"

        end  

else:

   [s,w] = unix('rm -f pTemp/main.dat');


新知识[!"fName"]该格式是在matlab中打开文件的命令。

该段代码是判断我们运行matlab的系统是什么,不同的系统用不同的方式打开*.py文件。继续接着走:

  • inMain = load('pTemp/main.dat');

  •    data.timeDiag = inMain(:,1);

  •     data.FermiLevel = inMain(:,2);

  •     data.timeHart = inMain(:,3);

  •     data.ChargeDmin = inMain(:,4);

  •     data.ChargeDmax = inMain(:,5);

  •     data.Eig_Energy = inMain(:,6);

  •     data.H_Energy = inMain(:,7);

  •     data.Int_Vxc_rho = inMain(:,8);

  •     data.Exc = inMain(:,9);

  •     data.E_I_Energy = inMain(:,10);

  •     data.I_I_Energy = inMain(:,11);

  •     data.Enew_Eold = inMain(:,12);

  •      data.Tot_Energy = inMain(:,13);

  •     data.Energy_atom = inMain(:,14);

  •     data.SREpot = inMain(:,15);

  • data.ChrgWghtPot = inMain(:,16);

这段代码的目的为从main.dat(运行*.py文件得到)中导入数据,储存到data对象中。这里再次get一个新知识点。以前过冷水就只知道:

data.timeDiag = inMain(:,1)

data= inMain(:,1)

现在变了一种赋值形式:

  • >>  inMain = load('pTemp/main.dat');

  •     data.timeDiag = inMain(:,1)

  • data = 

  •     timeDiag: [9x1 double]

    Dat.char这种赋值方式很有用的,可以让我们很容易储存不同类型的数据到一个对象中,直接表示数据类型,不需要做其它操作,类似于元包组。

fOptions = fopen('pTemp/misc.dat');

opt = fgetl(fOptions);

data.num_states = str2num(strtok(opt));

    opt = fgetl(fOptions);

    data.num_atoms = str2num(strtok(opt));

    iter = size(data.timeDiag);

    data.num_iterations = iter(1);

这段代码有三个新函数:fgetl()、str2num();

 fgetl():该函数的目的是每次运行从misc.dat文件中获取一行内容。fgetl()有记忆功能。这里要注意运行次数,稍微运行次数出错会导致写入的数据对不上号,其实这里如果可以用正则匹配或者关键字定位行就不容易出错了;

strtok():函数的含义是从字符串中找出数值字符串;

str2num:函数的目的是将字符串转化为数值。

inEigs = load('pTemp/eigenvalues.dat');

    m = data.num_states;

    n = size(inEigs(:,1));

    n = n(1);

    n = n/m;

    data.State = reshape(inEigs(:,1),m,n);

    data.EigenvalueRY = reshape(inEigs(:,2),m,n);

    data.EigenvalueEV = reshape(inEigs(:,3),m,n);

    data.Occup = reshape(inEigs(:,4),m,n);

    data.Repr = reshape(inEigs(:,5),m,n)

这段代码就没有什么新意了,打开一个文件读取文件内容,并用一定规则重构元素排列。Reshape()、size()都是常用命令。

 inForces = load('pTemp/forces.dat');

    forceIon = reshape(inForces(1,:),3,data.num_atoms);

    data.forceIon = transpose(forceIon);

    forceSelfC = reshape(inForces(2,:),3,data.num_atoms);

    data.forceSelfC = transpose(forceSelfC);

    forceCoreC = reshape(inForces(3,:),3,data.num_atoms);

    data.forceCoreC = transpose(forceCoreC);

代码调试不通,困扰过冷水的第二处错误就此出现。load()加载文件、reshape重构数据结构、transpose()函数没见过?调用出错?

函数transpose():看上去定义又长,好像很重要的样子,过冷水一查:

B=transpose(A)=A’结束!

既然语句看上去没有问题,那么会有什么问题呢?这里过冷水怎么都没有想到这个坑,逻辑错误!什么意思呢?你要加载这个文件,首先的有这个文件吧!没有文件怎么加载。如果没有这个文件那就是error呗!

解释的有点费劲。*.out生成文件一般默认不包含forceIon、 forceSelfC、forceCoreC数据。然而这里的程序包默认*.out含有相应数据,不做有无的判断!这是程序设计的漏洞,因为这个原因,*.py程序编写的也有问题。过冷水的解决办法是用NaN 填充相应数据。这里可以让程序运行正确,我们不考虑科学合理性的问题。

inForces2 = load('pTemp/forces2.dat');

    forceLocal = reshape(inForces2(1,:),6,data.num_atoms);

    data.forceLocal = transpose(forceLocal);

    forceNonLcl = reshape(inForces2(2,:),6,data.num_atoms);

    data.forceNonLcl = transpose(forceNonLcl);

    forceTotal = reshape(inForces2(3,:),6,data.num_atoms);

    data.forceTotal = transpose(forceTotal);

    forceTotal2 = reshape(inForces2(4,:),6,data.num_atoms);

    data.forceTotal2 = transpose(forceTotal2);


    inForces3 = load('pTemp/forces3.dat');

    data.dipole = reshape(inForces3(1,:),1,3);

    data.netForce = reshape(inForces3(2,:),1,3);

    data.netTorque = reshape(inForces3(3,:),1,3);

D_valid = true;

data数据写入完毕!该段代码没有什么好讲的,和前面的功能相似,注意D_valid = true命令!这里就相当于在做是否有完整执行data数据写入的代码。该段代码让过冷水的涨见识了,简单的写数据的操作就几百行代码,可唬人了。经过冷水一番解刨,不过如此!

接下来回是wfn数据的写入,这里有涉及一个新自定义函数

[wfn, pot, rho, wavedata, XYZ] = wfnread(datName, h)

这真他*的是一个牵一发,动全身的工程。该完整函数程序比较复杂,初次学习涉及到的新函数比较多,需讲解内容较多,本期只讲data数据的提取。欲学后情,且下次再讲。图片

过冷水发表于 仿真秀 平台原创文章,未经授权禁止私自转载,如需转载请需要和作者沟通表明授权声明,未授权文章皆视为侵权行为,必将追责。如果您希望加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载均可加群:927550334。

精品回顾

 matlab绘制农夫过河动态图

分子动力学的原子空间运动轨迹演示编程

过冷水带你用matlab制作演示动画

python批量移动文件&重命名代码分享

过冷水和你分享 matlab读取存储各种文件的方法 文末有独家金曲分享

image.png


理论科普代码&命令MATLAB
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2021-04-25
最近编辑:3年前
过冷水
博士 | 讲师 讨论号:927550334
获赞 358粉丝 180文章 107课程 11
点赞
收藏
作者推荐

¥5 5.0
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈