@su
2014-06-22T01:51:10.000000Z
字数 5408
阅读 3957
matlab 偏微分 Freefem++ 计算
求解 Helmholtz 方程的边值问题:
利用虚功原理求解 Helmholtz 方程的变分形式
使用 Freefem++ 编写程序实现使用有限元算法计算 Helmholtz 方程的边值问题,代码如下:
func z=0;border a0(t=0,1){x=1; y=t;}border a1(t=0,1){x=1-t;y=1;}border a2(t=0,1){x=0; y=1-t;}border a3(t=0,1){x=t;y=0;}mesh Th = buildmesh(a0(150)+a1(150)+a2(150)+a3(150));fespace Vh(Th,P2);Vh phi,w,f=x*y;solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))- int2d(Th)(f*w)+on(a1,phi=z)+on(a2,phi=z) ;plot(phi,wait=true,ps="phi.eps");plot(Th,wait=true, ps="membraneTh.eps");savemesh(Th,"trace.msh");
绘制的图形如下:

用差分法求解如下 Laplace 方程
主函数 main
function [] = main()N = input('lxease Input N:');[value, cow, row, b]=getmatrix(N);% for m=1:(N+1)^2% fprintf('\n')% for n = 1:(N+1)^2% %fprintf('%f',m)% temp = getvalue(m,n,value,cow,row);% fprintf('%f\t',temp)% end% end% b;%% 使用基本迭代法求解方程组,( E+ T)x = b. then x = b-t*xres = solve_equation(value,cow,row,b);%% now plot the shape[y,x]=meshgrid(1:-1/N:0);Z =flipud( reshape(res,N+1,N+1));mesh(x,y,Z);end
getmatrix 函数 主要用来获得系数矩阵的压缩行存储格式
function [value, cow, row,b] = getmatrix(N)%% 使用addm 差值节点的地址信息。[xsta, xend, ysta, yend] = deal(0, 1, 0, 1);%多变量同时赋值xh = (xend-xsta)/N;yh = (yend-ysta)/N;addm = {};for m = 1:N+1for n = 1:N+1xtemp = xsta + (m-1)*xh;ytemp = ysta + (n-1)*yh;addm(m,n) = {[xtemp, ytemp, xtemp*ytemp ],};endend%disp(addm);%% 使用crs存储方法记录系数矩阵Avaluelen = (N*3-2)*N + N*(N-1)*2;value = ones(valuelen,1);cow = ones(N*N,1);row = ones(valuelen,1);tempadr = 1;%利用 tempadr 记录 value 数值变化的位置;cowadr = 1;%利用 cowadr 记录 cow 列号变化的位置;rowadr = 1 ;%利用 row 记录行变化的位置b = zeros(N*N+2*N+1,1);badr = 1;%% 从第一行开始逐个记录系数矩阵每行的for t = 1:N+1if t==1for n = 1:N+1value(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N-1)+n;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;endelseif t<=Nvalue(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N+1)+1;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;for n=2:Nvalue(tempadr:tempadr+4) = [-1/4 -1/4 1 -1/4 -1/4];tempadr = tempadr +5;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr:rowadr+4) = [(t-2)*(N+1)+n, (t-1)*(N+1)+n-1, (t-1)*(N+1)+n, (t-1)*(N+1)+n+1, t*(N+1)+n];rowadr = rowadr + 5;b(badr) = xh*xh*addm{t,n}(3);badr = badr + 1;endvalue(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = t*(N+1);rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;elsefor n = 1:N+1value(tempadr) = 1;tempadr = tempadr + 1;cow(cowadr) = tempadr;cowadr = cowadr +1;row(rowadr) = (t-1)*(N+1)+n;rowadr = rowadr + 1;b(badr) = 0;badr = badr + 1;endendendendend
solve_equation 主要使用基本迭代法求解方程组
function [ x ] = solve_equation( value, cow, row, b )%This function is used to solve equation%% get size of x;lenth = length(b);x0 = ones(lenth,1);x = x0;error = 1;%% 方程的解为xwhile error>=1e-5for m=1:lenthtemp = 0;if m == 1for t = 1:(cow(m)-1)if row(t) ~= mn = row(t);temp = temp + x0(n)*value(t);endendelsefor t = cow(m-1):(cow(m)-1)if row(t) ~= mn = row(t);temp = temp + x0(n)*value(t);endendendtemp = b(m)- temp;x(m) = temp;enderror = norm(x0-x,2);x0 = x;endend
getvalue 函数 检查系数矩阵是否正确
function[val] = getvalue(m,n,value,cow,row)% 这个函数通过 crs 存储的 value , cow ,row 计算出矩阵第m行 n列的元素的值并返回%%lenth = length(cow);if m>lenth || m<=0fprintf('Larger than the matrix')elseval = 0;if m==1for t=1:(cow(m)-1)if n == row(t)val =value(t);return;endendelseval = 0;for t=cow(m-1):(cow(m)-1)if n == row(t)val =value(t);return;endendendend
使用 freefem++ 通过变分法计算,代码如下:
real theta=4.*pi/3;real a=2. ,b=1.;func z=0;border a0(t=0,1){x=1; y=t;}border a1(t=0,1){x=1-t;y=1;}border a2(t=0,1){x=0; y=1-t;}border a3(t=0,1){x=t;y=0;}mesh Th = buildmesh(a0(50)+a1(50)+a2(50)+a3(50));fespace Vh(Th,P2);Vh phi,w,f=x*y;solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))- int2d(Th)(f*w)+on(a0,phi=z)+on(a1,phi=z)+on(a2,phi=z)+on(a3,phi=z) ;plot(phi,wait=true);plot(Th,wait=true, ps="membraneTh.eps");savemesh(Th,"trace.msh");



