zoukankan      html  css  js  c++  java
  • 闪电动画模拟(Dielectric Breakdown Model)附源码

      当两个物体之间存在较大的电势差时会出现放电现象,比如生活中常见的闪电现象,闪电形成的条件就是云层积累了大量负电荷之后与地面之间形成了强大的电势差。目前关于闪电建模的方法比较少,下面介绍一种利用电介击穿模型来模拟闪电的方法电介击穿模型可以模拟自然界许多现象该方法通过迭代求解Laplace方程得到放电过程的中间状态。

      初始电位结构如下图所示,首先在2维栅格正中心的单元放置一个负电荷Ф = 0(灰色),然后在其周围放置一圈正电荷Ф = 1(黑色),而其他栅格单元可以通过求解Laplace方程得到:

      Laplace方程求解完之后,我们构建一个列表记录负电荷(Ф = 0)周围的栅格单元,并随机选取其中一个单元作为下一个被击穿的单元,被选中的栅格单元设置Ф = 0,同时把它作为下一步迭代计算时的边界条件。

      相邻栅格单元被击穿的概率与其计算得到的电势相关,其概率如下:

    式中i代表第i个与负电荷相邻的栅格单元,n代表与负电荷相邻的栅格单元个数,而η是一个用户设定的参数,通过实验表明η值可以控制电弧的分叉密度,当η = 1时,分叉密集,当η逐渐增大时,分叉密度慢慢减小。

    图:不同结构的初始电位,其中灰色点代表负电荷Ф = 0,黑色点代表正电荷Ф = 1

    图:初始电位为(b)结构时的模拟结果

    左:η = 1,中:η = 2,右:η = 3

    % Laplacian Growth Model
    clc
    clear all
    close all
    
    w = 256; % width
    h = 256; % height
    eta = 3;
    
    % 指定正负电荷
    ni = floor(w/2)*h + (1:2)'; % negative charge
    pi = ((1:w)' - 1)*h + h; % positive charge
    
    % 构建laplace矩阵
    S1 = bsxfun(@plus, ((1:(w-1)) - 1)*h, (1:h)');
    D1 = bsxfun(@plus, ((2:w) - 1)*h, (1:h)');
    S2 = bsxfun(@plus, ((1:w) - 1)*h, (1:(h-1))');
    D2 = bsxfun(@plus, ((1:w) - 1)*h, (2:h)');
    
    S = [S1(:); S2(:)];
    D = [D1(:); D2(:)];
    A = sparse([S D], [D S], 1);
    n = size(A,1);
    % Lp = speye(h*w) - bsxfun(@rdivide, A, sum(A,2));
    Lp = spdiags(sum(A,2), 0, n, n) - A;
    rhs = zeros(n, 1);
    
    % 循环计算下一步状态
    [X0, Y0] = ind2sub([h,w], (1:h*w)');
    im = zeros(h,w);
    iter = 1;
    i = 1;
    while ~any(ismember(ni, pi))
        phi = solve_equation(Lp, rhs, [ni;pi], [zeros(size(ni));ones(size(pi))]);
        
        [~, adj] = find(A(ni,:));
        adj = unique(adj);
        adj = adj(~ismember(adj, ni));
    
        k = randsample(adj, 1, true, phi(adj).^eta/sum(phi(adj).^eta));
        ni = [ni; k];
    
        if mod(iter,10) == 1
            [X, Y] = ind2sub([h,w], ni);
            [~, dis] = knnsearch([X,Y], [X0,Y0]);
            im = reshape(1-dis/3, [h,w]);
    
            imshow(im, 'Border','tight');
            drawnow;
    
            Frame(i) = getframe(gcf);
            i = i + 1;
        end
        fprintf('iteration: %d ...
    ', iter);
        iter = iter + 1;
    end

    本文为原创,转载请注明出处:http://www.cnblogs.com/shushen

     

     

    参考文献:

    [1] Theodore Kim and Ming C. Lin. 2007. Fast Animation of Lightning Using an Adaptive Mesh. IEEE Transactions on Visualization and Computer Graphics 13, 2 (March 2007), 390-402.

  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/shushen/p/5779596.html
Copyright © 2011-2022 走看看