MATLAB做晶体结构图(固体物理)

MATLAB做晶体结构图(固体物理).md

写在前面

最近在复习考研复试《固体物理》这一门课,去年学的内容已经忘干净了,所以就翻开前几页。突然看到了面心立方和体心立方结构图,想到了去年室友用Mathematica做了晶胞的结构图,于是就手痒痒自己也想来做一个。

具体物理内容不会涉及到多少,但还是要求大家能对“简单立方结构”、“体心立方结构”、“面心立方结构”有一个简单的理解,因为我比较懒,所以我就不放这些基础内容凑字数了。

用MATLAB跑出来的效果图为

面心立方-MATLAB跑出来的图

我的所有程序都放在我的Github: https://github.com/HanpuLiang/Something-Small中,点击即可查看。

基本的思考

如果我们想要做一个类似于这样子的结构图的话,我们需要知道些什么?

想要达成的效果(图源百度)

如果我们想要做成这么大个超胞的话,又需要在上面的基础上怎么做?

超胞示意图(图源我自己)

有过做计算的同学已经想到了,需要计算物理中,描述晶胞中原子位置的文件POSCAR,然后把POSCAR拖到VESTA中就可以上面这幅图了。

所以我们这里模拟POSCAR来输入参数:

  • 晶胞参数:描述晶胞大小的参数。
  • 超胞大小:当晶胞数量大于1个并且周期性变化时,用三个数字描述其在三个方向上的晶胞叠加数目。
  • 各个原子的坐标:没有这个还怎么画出来原子啊。

基本参数

晶胞参数

晶胞参数包括6个值:三条边a1, a2, a3和三个角\alpha, \beta, \gamma,如下图所示

晶胞参数

因为编写程序的复杂程度问题,我们这里只考虑\alpha\neq 90^o, \beta=\gamma=90^o这样的情况。如果不这样的话,那就有点难了,需要考虑这个晶胞斜向的角度。

超胞大小

超胞大小是用来形容我们这个超胞到底由几个晶胞组成,以及他们的排列方式是怎么样子的。就比如下图中,沿着a1方向的层数为1个,沿着a2方向的层数为3,沿着a3方向的层数为2.所以我们就可以设定为[1, 3, 2]

值得注意的是,这里我用的并不是x, y, z轴的方向!!!因为如果\alpha\neq 90^o的话,那么a2方向就不和y轴平齐了,所以为了保证两个晶胞相连,就必须要沿着晶轴方向拓展。

超胞大小

原子位置

这个没什么好说的,如果我们建立好了超胞,那么直接在对应的坐标画上原子就好。

开始写程序

设定参数

首先我们来设定好上面的参数

%% 参数设定
global cell_size a1 a2 a3 alpha beta gamma
% 晶胞参数
a = [1, 1, 1];
% 三个角度
angle = [pi/2, pi/2, pi/2];
% 超胞大小
cell_size = [2, 2, 2];
% 简单立方
position1 = [0, 0, 0; ...
           1, 1, 0; ...
           1, 0, 0; ...
           0, 1, 0; ...
           0, 0, 1; ...
           1, 1, 1; ...
           1, 0, 1; ...
           0, 1, 1];
% 体心
position2 = [0.5, 0.5, 0.5];
% 面心
position3 = [0, 0.5, 0.5; ...
             0.5, 0, 0.5; ...
             0.5, 0.5, 0; ...
             1, 0.5, 0.5; ...
             0.5, 1, 0.5; ...
             0.5, 0.5, 1];

[a1, a2, a3] = deal(a(1), a(2), a(3));
[alpha, beta, gamma] = deal(angle(1), angle(2), angle(3));

这里将体心和面心的原子分别提取出来,作图的时候再放上去和简单立方的一起做就好了。

作图

我们为了图像美观就得做一些处理坐标轴的事情

%% 作图
figure
% 作图设置
hold on, axis equal
axis image off
view(-37.5, 30)

然后我们就可以愉快的画超胞的框架和各个原子啦,下面的两个函数是我自定义的两个函数

% 做超胞框架
plotBox();
% 做各个原子
plotAtoms(position2, [244, 13, 100]/255, 40);
plotAtoms(position1, [29, 191, 151]/255, 50);   %简单立方的一定要放在最后面

简单立方因为最大,所以我在里面设定了一些自动变坐标轴大小的内容,所以要放在最后面。

这样子主程序就完成了。后面详细解释这两个函数的内容。

做超胞的框架plotBox

我们需要定出立方体的8个顶点,然后做出12条边,这一部分很简单,根据简单的数学就可以推导出公式,然后写出程序来。

function plotBox()
% 做边框
    global a1 a2 a3 alpha beta gamma cell_size 
    % 超胞的边长
    [A1, A2, A3] = deal(a1*cell_size(1), a2*cell_size(2), a3*cell_size(3));
    % 8个顶点
    vertex = [0, 0, 0;...
              A1, 0, 0;...
              A2*cos(alpha), A2*sin(alpha), 0;...
              A2*cos(alpha)+A1, A2*sin(alpha), 0;...
              0, 0, A3;...
              A1, 0, A3;...
              A2*cos(alpha), A2*sin(alpha), A3;...
              A2*cos(alpha)+A1, A2*sin(alpha), A3];
    % 12个边
    plotLine(vertex(1,:), vertex(2,:))
    plotLine(vertex(1,:), vertex(3,:))
    plotLine(vertex(2,:), vertex(4,:))
    plotLine(vertex(3,:), vertex(4,:))
    plotLine(vertex(5,:), vertex(6,:))
    plotLine(vertex(5,:), vertex(7,:))
    plotLine(vertex(6,:), vertex(8,:))
    plotLine(vertex(7,:), vertex(8,:))
    plotLine(vertex(1,:), vertex(5,:))
    plotLine(vertex(2,:), vertex(6,:))
    plotLine(vertex(3,:), vertex(7,:))
    plotLine(vertex(4,:), vertex(8,:))
end

function plotLine(x1, x2)
% 做两个点之间的框架线
    plot3([x1(1) x2(1)], [x1(2), x2(2)], [x1(3), x2(3)], 'k', 'linewidth', 1.3)
end

做各个原子的图

这个才是重头戏。

我们首先要确定出在超胞内,一共有多少个原子。我们之前设置的超胞大小就派上用场了,我们通过三个循环嵌套在一起,遍历出超胞内的所有晶胞,然后将其原子位置加到矩阵中,最后统一作图。

function plotAtoms(position, markercolor, markersize)
% 做各原子图像
    global cell_size a1 a2 a3 alpha beta gamma
    % 原始晶胞
    % plot3(position(:,1), position(:,2), position(:,3), 'ok', 'linewidth', 1.5, 'markersize', 50, 'markerfacecolor', [29,191,151]/255)
    % 超胞
    % 遍历得到超胞所有原子
    cur_point = position;
    for i1 = 1:cell_size(1)
        for i2=1:cell_size(2)
            for i3=1:cell_size(3)
                x_plus = a1*(i1-1) + a2*cos(alpha)*(i1-1);
                y_plus = a2*sin(alpha)*(i2-1);
                z_plus = a3*(i3-1);
                cur_point = [cur_point; [position(:,1)+x_plus position(:,2)+y_plus position(:,3)+z_plus]];
            end
        end
    end
    plot3(cur_point(:,1), cur_point(:,2), cur_point(:,3), 'ok', 'linewidth', 1.5, 'markersize', markersize, 'markerfacecolor', markercolor)
    % 设置坐标轴大小
    [x_min, x_max, y_min, y_max, z_min, z_max] = deal(min(cur_point(:,1)), max(cur_point(:,1)), ...
                                                      min(cur_point(:,2)), max(cur_point(:,2)), ...
                                                      min(cur_point(:,3)), max(cur_point(:,3)));
    x_len = (x_max - x_min)/6;
    y_len = (y_max - y_min)/6;
    z_len = (z_max - z_min)/6;
    axis([x_min-x_len x_max+x_len y_min-y_len y_max+y_len z_min-z_len z_max+z_len])
end

然后这样就完事了。是不是很简单的。

写在后面

以上所有代码我都放在了我的Github中,可以通过点击我的Github: https://github.com/HanpuLiang/Something-Small去查看。代码下载后可直接运行。

如果喜欢的话,麻烦点个关注,给个赞,加个收藏噢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 本文转载自博主一个人就是一个叠加态,有部分删减修改,文中对相关概念方法做了详细的总结,留坑待填... 1. 第一原...
    chempeng阅读 42,813评论 1 33
  • ****1、****做 ****XRD ****有什么用途啊,能看出其纯度****?****还是能看出其中含有某种...
    鸭梨山大哎阅读 12,061评论 0 5
  • I'm so angry at Bob for buying a new bike.我因鲍勃买了一辆新自行车而对他...
    bayue_9阅读 104评论 0 0
  • 来平遥之前二哥说“去看又见平遥” 山西人就是这么简单 直 直的让你无话可说 同行的老锅在大街上歇斯底里的和我大声说...
    哈哈同学阅读 1,994评论 0 0
  • 小城楼外相思雨。风满相思,雨满相思。翠壶银盘冷荔枝。 觑得浮云分半日。柳也入诗,人也入诗。古巷...
    麦片加冰阅读 322评论 0 0