二阶偏微分方程组 龙格库塔法_有限单元法(Finite Element Method)实现声波方程模拟(Part 2)...

b194c25e8a5d4e407323aa9e2d31b1ac.png

2.1 前言

承接上一篇文章,前面我们已经介绍了一维声波方程有限元求解:

蓝不是蓝:有限单元法(Finite Element Method)实现声波方程模拟(Part 1)​zhuanlan.zhihu.com
c7417855aedd0c3a950e80020bef72a2.png

这一部分将一维问题提升到二维问题。不知道大家有没有发现,在一维问题中,我们是通过矩阵相乘的方式来求解,得到的解

是一个关于节点编号的向量,即对于一个研究区域,将该研究区域划分为有限个单元,两个单元间有共用的节点,假设一共有
个节点并编号为
,那么我们实际上求解得到的是向量
。在二维问题中,也是同样的求解方法,只不过这里的节点编号不再是按照单方向编号(如一维中沿着
方向),而是按照一定规律编号(如按列或按行),编号规则可人为设定。那么这样得到的一个向量
就会在空间上出现跳跃,但是这并不会影响我们的求解。如果这里没有理解,先继续往后面看。

2.2 二维声波方程有限元求解

2.2.1 算法推导

对于二维声波方程,我们先写成一个简写形式:

9cb43241696abf8124a9f04f5980e6e0.png

我们同样使用伽辽金(Galerkin )方法将该微分方程变成弱形式。并引入一个二维基函数

,来实现对解的插值近似。这里我们假设

60a6c02374f9d4d7c04db2ca48e5b2af.png

对上式关于空间项的积分使用分部积分法则:

f056d4146623a7905a6bd556309d6b5d.png

将上式代入公式(14)后得到:

3de8c653e2cf001701bf1fc38931c425.png

这里我们仍然使用一维情况下类似的边界条件:

a14bf4f51536530a47c5c5c196561492.png

消掉边界条件这一项后,再利用基函数插值近似我们的解(

代表节点数
):

0e60a73eec99b7e74645ad4ac30af720.png

最终得到的公式为:

c135b5e5cc6e97dd9fa8fd56ea236276.png

时间项我们采用二阶差分格式,则上式的隐式差分格式为:

286a475de021f9c72e06bc720505db23.png

简写成矩阵形式:

85df21998a1c372729b757fc06cfa6fa.png

同样的,简写成矩阵形式的显式差分格式为:

02571b9d4b6ca7cab71b0ea008f715b2.png

其中的质量矩阵

和刚度矩阵
为:

58c4f9824344d14b3761c4835ae900f8.png

那么,我们先利用公式(21)和(22)求出

之后,在利用公式(20.1)或(20.2)就可以得到计算域中每一个节点的值。

2.2.2 网格剖面

在这里我们使用三角形单元构建一个非结构化网格,事实上如果让我们自己来构建一个很复杂的非结构化网格是比较费力的,我们可以使用MATLAB自带的网格生成函数来帮助我们完成网格生成。

这部分代码为:

function [p,e,t] = unstructured()[p, e, t] = initmesh('squareg', 'hmax', 0.08);%单元初始化[p,e,t] = refinemesh('squareg',p,e,t);%单元加密
end

其中

完成网格初始化,0.08衡量网格疏密程度,越小网格越密。
完成网格的加密。函数返回值
的含义见下表:
返回值含义
p在点矩阵p中,第一行和第二行包含网格中节点编号对应的x和y坐标。
e在边界矩阵e中,第一行和第二行包含每一段边界起始点和结束点的索引,第三和第四行包含起始和结束参数值,第五行包含边界段编号,第六和第七行包含左侧和右侧子域编号。
t在三角形单元矩阵t中,前三行包含三角形三个角点的索引,按逆时针顺序给出,第四行包含子域编号。

上述代码生成的网格为:

a0e783445e6638c380cba92c466bce1d.png
非结构化网格示意图

这样一个网格包含了4465个节点和8728个单元,已经很密集了,再大一些计算起来就会很吃力,如果本身计算机内存不大,算力不够的话,可以减少单元数。

使用下面的代码可以查看网格及节点、单元编号,这里先把网格调稀疏点:

expand = 1000;
p = expand*p;
%'NodeLabels','on'——可以显示节点编号,'ElementLabels','on'——显示单元编号
pdemesh(p, e, t,'NodeLabels','on','ElementLabels','on');

这里对p乘上expand是因为MATLAB生成的网格范围默认是

的,我们需要乘上一个系数把网格范围调大。最终得到的图:

78f143f1965fdf5d1ac439353a680bcf.png
网格节点及单元编号分布情况

到这里大家应该就明白了,为什么向量

会出现跳跃了,我们是
按照节点编号顺序求解的,得到的值自然会在计算域内出现跳跃。但是我们会找到一个正确的对应关系,来保证我们计算的每一个值是和节点一一对应的

2.2.3 求解质量矩阵和刚度矩阵

我们已经得到了这样一个非结构化网络,并且每一个节点和单元的编号我们也有,接下来就是求质量矩阵和刚度矩阵了。

首先我们求解质量矩阵和刚度矩阵并不是一个节点一个节点的求,而是一个单元一个单元的求,在一个单元里面包含三个节点,三个节点两两组合后构成一个

的矩阵,然后在根据这三个节点对应的编号组装到整体的
的矩阵中。这是什么意思呢?给大家一个直观的例子,例如我求一个由编号
这三个节点构成的三角形单元
的质量矩阵(参照上图:
网格节点及单元编号分布情况左下角单元),这个矩阵长这样:

06e91d093face5a0c19b26efb7c13627.png
单元[7]的质量矩阵

可以看到这个矩阵其实是对称的。之后将这个小矩阵组装进大矩阵,即总质量矩阵,得到大矩阵长这个样子的:

b043dbe7afabe6044510c183de77954d.png
单元[7]组装进总质量矩阵

不知道大家有没有注意到,我们之前提到过单元与单元之间存在节点的重叠,这种重叠就体现在组装矩阵的时候,不同单元节点值的叠加,例如上面的例子中,节点

同时被单元
六个单元所共享,最终得到的矩阵
这个元素是这六个单元的贡献值之和。而这种
叠加现象只出现在对角元素上

那么这个小质量矩阵或刚度矩阵怎么求呢?这里我推荐使用参考单元的方法来求解,因为好理解而且也很好计算。

我们发现,对于上面的非结构化网络,三角单元的节点坐标值不具有规律性,我们如果能用一种规则的、好计算的三角形来求解,例如等腰直角三角形,那我们就好求出每一个小矩阵。将

组成的单元映射到
参考单元:

0dcf97b9e49bc8686617b01b31a94fea.png
参考单元及坐标映射

这其实就相当于一种坐标映射,将不规则的三角形映射为规则的三角形,这种映射关系为:

45cce347a9a8ac0a3e84e2702c52de3e.png

其中的

为坐标映射系数:

383fa9691e274a00d528815dfcc55703.png

,则参考单元中三个节点对应的插值基函数为:

9c0587dad809a8ec94866478c6e33cfa.png

有了插值基函数表达式后还没完,我们还要进行积分算子

的坐标转换,对于一个通用的坐标转换例子:

a81876a73ffaff769dd81c97be052f42.png

我们从

域变换到
域,使用微分的链式法则:

2b9d383b11679a1196565aab8acfddf2.png

则有如下关系:

4498b9371f8252a5f6996fc8dd1d09a7.png

式中的

代表雅可比矩阵行列式,其数值与参与变换的三角形节点坐标有关:

87996fb9a696ed6c1a1aba86350cf0ed.png

可以发现,通过上面的参考单元,我们就能够找到一种通用的方法来计算每个单元的质量矩阵和刚度矩阵,并且积分区域都统一变成了一样的。

(1)质量矩阵

首先,对于每个单元的质量矩阵,其中的元素计算公式变换为:

a7b15727ce7f8174b0eab7322dccfcc5.png

这里由于我们已经知道了参考单元每一个节点的基函数表达式,我们可以把雅克比行列式从积分中提出来,将关于基函数的积分计算出来,即:

e97659b49fe207a5738c7a38896dbafd.png

这个公式说明什么,说明经过参考单元变换后,我们刚刚提到的质量矩阵其实计算起来只需要求

就可以了,形象一点就是:

b747e37e80d5cce9823b38bf05e4e685.png
参考单元下计算单元质量矩阵

细心的你可能会注意到,这里的编号统一都是

,和前面的单元
对应关系为:
,按照逆时针方向一一对应。

(2)刚度矩阵

刚度矩阵要稍微复杂一点点,因为这里面涉及到对基函数的偏导,将这个偏导写成向量形式:

bb0975398924a619fcc59e0cca445b8d.png

使用偏微分的链式法则:

27640f6a66bec81b77a9b1128c1eff9f.png

将公式(31)代入(30)中,则有:

cea1ebe13b2782c7bff2ada9e0fac052.png

058e9edd919b2ef715a2f0bcd3131839.png

其中的矩阵

代表雅克比矩阵的逆。对参考单元的基函数求导:

94a4e190b3be8ec365e42ac5c1b6ff84.png

最终得到单元每一个元素的刚度矩阵计算公式为:

661f9f40d9f7c2d5de4ea3014cfb72ad.png

为了简化计算,我们发现积分公式里面没有任何一项和

有关,即:

39f53d755dc04af06600d4a550e6d281.png

这相当于告诉我们:

10f45e7a6b74be6239e49a1a85c58e8f.png

用这个公式就好计算多了。

2.3 算法实现

(1)首先生成网格,这里封装为函数create_grid():

function GRID = create_grid()
% This function is used to generate  structured and unstructured mesh
GRID = struct('unstructured',@unstructured,...'structured',@structured,...'connect_mat',@connect_mat);function [p,e,t] = unstructured()[p, e, t] = initmesh('squareg', 'hmax', 1);%单元初始化[p,e,t] = refinemesh('squareg',p,e,t);%单元加密endfunction [p,e,t] = structured()%% 参数设置Lx = 1000; %定义单元右边界(左边界为0,如果不是,可以平移为0)Ly = 1000;%定义单元上边界N = 60;%分割的一个方向的单元数目numelx = N;%定义分割的x方向单元数目(按矩形计算)numely = N;%定义分割的y方向单元数目(按矩形计算)numnodx = numelx + 1; % x方向节点个数比单元个数多1numnody = numely + 1; % y方向节点个数比单元个数多1nel = 3;%每个单元的节点数目,即每个单元上有几个形函数参与作用,单元自由度coordx = linspace(0,Lx,numnodx)'; %等分节点的坐标(为了方便,我这里采用等分的方式,事实上单元长度可以不一致,非均匀网格)coordy = linspace(0,Ly,numnody)'; %等分节点的坐标(为了方便,我这里采用等分的方式,事实上单元长度可以不一致)[X, Y] = meshgrid(coordx,coordy);%张成网格,X和Y分别表示对应位置的横纵坐标X = X';Y = Y';p = [X(:) Y(:)];%把网格一行一行扯开,coord的每一行是对应节点的坐标,按顺序排p = p';connect = connect_mat(numnodx,numnody,nel);%连接矩阵,表示每个单元周围的节点编号,也就是涉及的形函数编号t = connect';e = [1:numnodx numnodx*numely+1:numnodx*numely+numnodx ...numnodx+1:numnodx:numnodx*(numely-1)+1 2*numnodx:numnodx:numely*numnodx]; % 强制性边界点的编号,本例子中是四条边,下上左右边endfunction connect_mat = connect_mat( numnodx,numnody,nel)%输入横纵坐标的节点数目,和单元自由度%输出连接矩阵,每个单元涉及的节点的编号xn = 1:(numnodx*numnody);%拉成一条编号A = reshape(xn,numnodx,numnody);%同形状编号for i = 1:(numnodx-1)*(numnody-1)xg = rem(i,numnodx-1);%xg表示单元为左边界数起第几个if xg == 0xg = numnodx-1;endyg = ceil(i/(numnodx-1));%下边界其数第几个a = A(xg:xg+1,yg:yg+1);%这个小矩阵,拉直了就是连接矩阵a_vec = a(:);connect_mat(2*i-1:2*i,1:nel) = [a_vec([1 4 3])';a_vec([4 1 2])'];endend
end

函数里面除了可以实现非结构化网格,还提供了了等腰直角三角形形式的结构化网络可选。

(2)接着编写计算质量矩阵和刚度矩阵的函数FEM_2D_func():

function FEM_2D_function = FEM_2D_func()%设置所有需要的函数FEM_2D_function = struct('assemble_matrix_2D',@assemble_matrix_2D,...%组装刚度矩阵方法一'assemble_matrix_2D2',@assemble_matrix_2D2,...%组装刚度矩阵方法二'assemble_vector_2D',@assemble_vector_2D,...%组装右端向量'treat_boundary_condition',@treat_boundary_condition);%处理边界条件%% 实现——组装刚度矩阵方法一function A = assemble_matrix_2D(p, t)fprintf('组装刚度矩阵:n');%获取单元个数和节点个数number_of_elements = length(t);number_of_nodes = length(p);%初始化总刚度矩阵A = zeros(number_of_nodes, number_of_nodes);for n = 1: number_of_elements% 获取单元局部编号到全局编号之间的对应关系local2global = t(1: 3, n);vertices = p(:, local2global);x = vertices(1, :);y = vertices(2, :);a = 0.5*((x(2)*y(3)-x(3)*y(2))-(y(3)-y(2))*x(1)+y(1)*(x(3)-x(2)));%三角形单元面积a = abs(a);a = 1/(2*a);A_local = zeros(3,3);ph = [1,0;0,1;-1,-1];detJ = (x(3)-x(1))*(y(2)-y(3))-(y(3)-y(1))*(x(2)-x(3));J_inv = a*[y(2)-y(3) , x(3)-x(2);y(3)-y(1) , x(1)-x(3)];for i = 1: 3for j = 1: 3A_local(i, j) = -0.5*detJ.*(ph(i,:)*J_inv*(J_inv'*ph(j,:)'));endendA(local2global, local2global) = A(local2global, local2global) + A_local;if(mod(n,100)==0)fprintf('number of  elements:%d/%dn',n,number_of_elements)endendfprintf('刚度矩阵组装完成n')end
%% 组装刚度矩阵方法二——参考单元function A = assemble_matrix_2D2(p, t)fprintf('组装刚度矩阵:n');%获取单元个数和节点个数number_of_elements = length(t);number_of_nodes = length(p);%初始化总刚度矩阵A = zeros(number_of_nodes, number_of_nodes);N{1} = @(xi, eta) 1 - xi - eta; N_xi{1} = -1; N_eta{1} = -1;N{2} = @(xi, eta) xi; N_xi{2} = 1; N_eta{2} = 0;N{3} = @(xi, eta) eta; N_xi{3} = 0; N_eta{3} = 1;ymax = @(xi) 1 - xi;for n = 1: number_of_elements% 获取单元局部编号到全局编号之间的对应关系local2global = t(1: 3, n);vertices = p(:, local2global);xx = vertices(1, :); yy = vertices(2, :);J = [xx(1) * N_xi{1} + xx(2) * N_xi{2} + xx(3) * N_xi{3}, xx(1) * N_eta{1} + xx(2) * N_eta{2} + xx(3) * N_eta{3};yy(1) * N_xi{1} + yy(2) * N_xi{2} + yy(3) * N_xi{3}, yy(1) * N_eta{1} + yy(2) * N_eta{2} + yy(3) * N_eta{3}];detJ = abs(det(J));J_inv_T = inv(J);A_local = zeros(3, 3);for i = 1: 3for j = 1: 3fun = (N_xi{i} * J_inv_T(1, 1) + N_eta{i} * J_inv_T(2, 1))...* (N_xi{j} * J_inv_T(1, 1) + N_eta{j} * J_inv_T(2, 1))...+ (N_xi{i} * J_inv_T(1, 2) + N_eta{i} * J_inv_T(2, 2))...* (N_xi{j} * J_inv_T(1, 2) + N_eta{j} * J_inv_T(2, 2));A_local(i, j) = integral2(@(xi, eta) fun .* eta ./ eta, 0, 1, 0, ymax) * detJ;endendA(local2global, local2global) = A(local2global, local2global) + A_local;if(mod(n,100)==0)fprintf('number of  elements:%d/%dn',n,number_of_elements)endendfprintf('刚度矩阵组装完成n')end
%% 组装质量矩阵M和右端向量Ffunction [M,F] = assemble_vector_2D(p, t)fprintf('组装质量矩阵:n');number_of_elements = length(t);number_of_nodes = length(p);M = zeros(number_of_nodes, number_of_nodes); % 总质量矩阵Me = zeros(3, 3);F = zeros(number_of_nodes, 1);            % 初始化右端向量Fe = zeros(3, 1);                         % 初始单元右端向量% 单元质量矩阵N{1} = @(xi, eta) 1 - xi - eta; N_xi{1} = -1; N_eta{1} = -1;N{2} = @(xi, eta) xi; N_xi{2} = 1; N_eta{2} = 0;N{3} = @(xi, eta) eta; N_xi{3} = 0; N_eta{3} = 1;ymax = @(xi) 1 - xi;for i = 1: number_of_elementslocal2global = t(1: 3, i);%获取当前单元包含的节点编号vertices = p(:, local2global);%获取当前单元所有节点的x,y坐标% 从参考单元到物理单元的映射%     x = @(xi, eta) xx(1) * N{1}(xi, eta) + xx(2) * N{2}(xi, eta) + xx(3) * N{3}(xi, eta);%     y = @(xi, eta) yy(1) * N{1}(xi, eta) + yy(2) * N{2}(xi, eta) + yy(3) * N{3}(xi, eta);xx = vertices(1, :); yy = vertices(2, :);J = [xx(1) * N_xi{1} + xx(2) * N_xi{2} + xx(3) * N_xi{3}, xx(1) * N_eta{1} + xx(2) * N_eta{2} + xx(3) * N_eta{3};yy(1) * N_xi{1} + yy(2) * N_xi{2} + yy(3) * N_xi{3}, yy(1) * N_eta{1} + yy(2) * N_eta{2} + yy(3) * N_eta{3}];detJ = abs(det(J));%积分太慢了
%             for m=1:3
%                 for n=1:3
%                     Me(m,n) = integral2(@(xi,eta)N{m}(xi,eta).*N{n}(xi,eta),0,1,0,ymax)*detJ;
%                 end
%                 Fe(m,1) = integral2(@(xi,eta) N{m}(xi,eta), 0, 1,0,ymax) * detJ;
%             endMe(1,1) = 1/12*detJ;Me(1,2) = 1/24*detJ;Me(1,3) = 1/24*detJ;Me(2,1) = 1/24*detJ;Me(2,2) = 1/12*detJ;Me(2,3) = 1/24*detJ;Me(3,1) = 1/24*detJ;Me(3,2) = 1/24*detJ;Me(3,3) = 1/12*detJ;Fe(:,1) = 1/6*detJ;M(local2global, local2global) = M(local2global, local2global) + Me;F(local2global, 1) = F(local2global, 1) + Fe;if(mod(i,100)==0)fprintf('number of  elements:%d/%dn',i,number_of_elements)endendfprintf('质量矩阵组装完成n')end
%% 边界条件的处理function [M,S,F] = treat_boundary_condition(M,S,F, p, boundarynodes, e)p = p';number_of_boundarynodes = length(boundarynodes);for i = 1: length(e)if p(e(1, i), 1) == -1 && p(e(2, i), 1) == -1f1 = @(x) (p(e(2, i), 2) - x) ./ (p(e(2, i), 2) - p(e(1, i), 2));f2 = @(x) (x - p(e(1, i), 2)) ./ (p(e(2, i), 2) - p(e(1, i), 2));F(e(1, i)) = F(e(1, i)) + integral(f1, p(e(1, i), 2), p(e(2, i), 2));F(e(2, i)) = F(e(2, i)) + integral(f2, p(e(1, i), 2), p(e(2, i), 2));endendfor i = 1: number_of_boundarynodesif p(boundarynodes(i), 2) == -1 || p(boundarynodes(i), 2) == 1M(boundarynodes(i), :) = 0;M(boundarynodes(i), boundarynodes(i)) = 1;F(boundarynodes(i)) = 0;S(boundarynodes(i), :) = 0;S(boundarynodes(i), boundarynodes(i)) = 1;endendendend

这个函数里面还提供了另外一种求解刚度矩阵的方法可选(没有使用到参考单元),并求解右端向量F、设置边界条件(可选)。

(3)接着编写主函数FEM_2D_main():

clear;clc
t_pre = clock;
t_start = clock;
%% 生成单元
GRID = create_grid();
[p,e,t] = GRID.unstructured();
expand = 1000;
p = expand*p;
%'NodeLabels','on'——可以显示节点编号,'ElementLabels','on'——显示单元编号
pdemesh(p, e, t,'NodeLabels','on','ElementLabels','on');%生成结构化三角网格
% GRID = create_grid();
% [p,e,t] = GRID.structured();num_nodes = length(p);
num_elements = length(t);
t_s = sprintf('nodes=%d  elements=%d',num_nodes,num_elements);
title(t_s)
% 在点矩阵p中,第一行和第二行包含网格中点的x和y坐标。
% 在边矩阵e中,第一行和第二行包含起始点和结束点的索引,第三和第四行包含起始和结束参数值,
%第五行包含边缘段编号,第六和第七行包含左侧和右侧子域编号。
% 在三角形矩阵t中,前三行包含角点的索引,按逆时针顺序给出,第四行包含子域编号。%% 参数设置
nt = 150; dt = 0.003;
v = 1500; 
T = (1:nt)*dt;
number_of_notes = length(p);
fmain = 40;%% 设置震源
s_t = (1-2*pi^2*fmain*(T-0.2).^2).*exp(-fmain*pi^2*(T-0.2).^2);%雷克子波%% 调用函数计算矩阵
FEM = FEM_2D_func();
S = FEM.assemble_matrix_2D(p, t);%刚度矩阵
[M,F]= FEM.assemble_vector_2D(p, t);%质量矩阵和右端向量
boundarynodes = unique([e(1, :) e(2, :)]);
U = zeros(number_of_notes,nt);
[m,source_x] = find(abs(p(1,:))>=0&abs(p(1,:))<=50&abs(p(2,:))>=0&abs(p(2,:))<=50);%% 利用递推关系求波场值
for i = 2:nt-1U(source_x(1),i) = s_t(i);%隐式
%     U(:,i+1) = (M+v^2*dt^2*S)(M*(2*U(:,i)-U(:,i-1)));
%     %显式right_vector = v^2*dt^2*S*U(:,i);U(:,i+1) = 2*U(:,i)-U(:,i-1)-Mright_vector;U(boundarynodes,i+1) = 0;if(mod(i,10)==0)fprintf('time step=%d total=%dsn',i,nt);end
end
fprintf('time step=%d total=%dsn',nt,nt);
total_time = etime(clock,t_start)/60;
fprintf('total runtime %.2fminutes',total_time)%% 绘图
filename = sprintf('FEM-2D dt=%.3f fm=%.1f v=%d explicit.gif',dt,fmain,v);
pic_num = 1;
for i=5:5:nttrisurf(t(1: 3, :)', p(1, :)', p(2, :)', U(:,i))str = sprintf('time step=%dndt=%.3f fm=%.1f v=%d',i,dt,fmain,v);title(str)colorbarshading interpview([90,90])F = getframe(gcf);I = frame2im(F,256);[I,map]=rgb2ind(I,256);if pic_num == 1imwrite(I,map,filename,'gif','Loopcount',inf,'DelayTime',0.2);elseimwrite(I,map,filename,'gif','WriteMode','append','DelayTime',0.2);endpic_num = pic_num + 1;
end
%% 获取波场快照
trisurf(t(1: 3, :)', p(1, :)', p(2, :)', U(:,150))
str = sprintf('FEM-2D-hemogenous t=%d ms',150*3);
title(str)
shading interp
view([90,90])
colormap('gray')
saveas(gcf, 'FEM-2D-unstructued.png', 'png')

主函数里面可选这使用非结构化和结构化网格,并有隐式差分格式和显式差分格式可选。

2.4 模拟结果

b88afe57493d468a4174de5b44301d74.gif
隐式差分格式模拟结果

ddff11732984b359bf8388e4224a5cfa.gif
显式差分格式模拟结果

两种都存在一定的数值耗散和色散现象。

3 声波方程有限单元法数值模拟总结

通过这两篇文章,相信大家对于有限单元法都有了一定的了解,我本来还想向大家介绍一下有关有限元法稳定性分析的,但是本来篇幅就太长了,以后如果感兴趣的人比较多,我再更新这一块吧!

另外,我之前都没有在文章中求赞求关注啥的,不过这次我还是厚脸皮一下,如果你喜欢这篇文章,觉得对你有用的话,请点击一下喜欢,欢迎你关注我,我会在后续继续分享有限体积法以及我所做过的一些比较有意思的数值模拟

ps:文章中如有纰漏,欢迎在评论区指出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python图片转文字_【收藏】图片转成文字的方法总结,python批量图片转文字信息参考源码...

在日常办公或者学习中&#xff0c;往往存在这样一个工作场景&#xff0c;比如&#xff0c;“老王&#xff0c;我这里有一张图片&#xff0c;你把里面的文字信息给我整理出来”&#xff0c;都2021年了&#xff0c;你真的还在手敲图片文字信息么&#xff1f;那么还不赶紧收藏这篇…

qpsk 锁相环_本科毕业设计课题—QPSK相干解调的MATLAB仿真(4)

继续看参考资料&#xff01;现在常用的数字调制方式有二相移相键控(BPSK)、正交移相键控(QPSK)、偏移四项移相键控(OQPSK)、最小移频键控(MSK)等。它们具有相同的功率效率。BPSK 频谱利用率差&#xff0c;抗非线性能力差&#xff0c;实现简单&#xff1b;QPSK频谱利用率好&…

postgresql是如何求年龄的_Postgresql 通过出生日期获取年龄的操作

三个基础的时间表示函数 current_date/current_time/now()select current_date ;返回当前日期以 年-月-日(yyyy-mm-dd)的形式&#xff1a;2019-01-10select current_time;返回当日时间以 时:分:秒时区(hh:mm:ss )的形式&#xff1a;17:49:11.58530808select now();返回当前时间…

python关闭浏览器删除session_Django操作session 的方法

session是存放在服务端的&#xff0c;在django中使用session必须要先在数据库中创建django_session表&#xff0c;session相关信息都要依赖此表获取sessionrequest.session[status]request.session.get(status)#一般用get&#xff0c;无此键返回None不报错设置session#在使用se…

python网页保存为图片_使用Python保存网页上的图片或者保存页面为截图

Python保存网页图片这个是个比较简单的例子&#xff0c;网页中的图片地址都是使用http://。。。。.jpg这种方式直接定义的。使用前&#xff0c;可以先建立好一个文件夹用于保存图片&#xff0c;本例子中使用的文件夹是 d:\\pythonPath这个文件夹代码如下&#xff1a;# -*- codi…

ioc框架 java_从零开始实现一个简易的Java MVC框架(三)--实现IOC

Spring中的IOCIoC全称是Inversion of Control&#xff0c;就是控制反转&#xff0c;他其实不是spring独有的特性或者说也不是java的特性&#xff0c;他是一种设计思想。而DI(Dependency Injection)&#xff0c;即依赖注入就是Ioc的一种实现方式。关于Ioc和DI的具体定义和优缺点…

b树索引 java_B树索引最通俗易懂的介绍

先来一段有莫的对话&#xff1a;前几天下班回到家后正在处理一个白天没解决的bug&#xff0c;厕所突然传来对象的声音&#xff1a;对象&#xff1a;xx&#xff0c;你有《时间简史》吗&#xff1f;我&#xff1a;我去&#xff01;妹子&#xff0c;你这啥癖好啊&#xff0c;我有时…

jython mysql_Jython

gomysql###介绍gomysql是基于go-sql-driver基础上开发的orm&#xff0c;这是一个轻量级的库。它会使数据库的增删改查变得非常容易。当然也是测试开发版&#xff0c;会一直优化和更新&#xff01;请时刻关注我们###安装go get github.com/go-sql-driver/mysqlgo get github.com…

java人种_Java面向对象练习题继承之人种

//People类package 继承;public class People {private String name;private double height;private double weight;public String getName() {return name;}public void setName(String name) {this.name name;}public double getHeight() {return height;}public void setHe…

java高校职工工资管理论文_毕业设计论文java大学工资管理系统

毕业设计论文java大学工资管理系统 本 科 生 毕 业 论 文(设 计)题 目&#xff1a;大学工资管理系统 学 号&#xff1a; _________姓 名&#xff1a; ____ ___年 级&#xff1a; ___________学 院&#xff1a; ____ ___系 别&#xff1a; ___ ____专 业&#xff1a; ___ __完成…

mysql 冷热表_Redis+MySQL冷热数据交换

场景&#xff1a;某网站需要对其项目做一个投票系统&#xff0c;投票项目上线后一小时之内预计有100万用户进行投票&#xff0c;希望用户投票完就能看到实时的投票情况这个场景可以使用redismysql冷热数据交换来解决。何为冷热数据交换&#xff1f;冷数据&#xff1a;之前使用的…

关于包装java_[java初探09]__关于java的包装类

前言在Java语言的学习过程中,我们逐渐的理解了Java面向对象的思想,与类和对象的应用.但是在基本数据类型的使用上,我们无法将其定义为一个对象,通过使用对象的方法来使用它们,但是Java语言的思想又是面向对象的.那么在Java语言中,是否能够解决这个问题,使基本数据类型能够以对象…

能跑java的服务器_一台java服务器可以跑多少个线程?

一台java服务器能跑多少个线程&#xff1f;这个问题来自一次线上报警如下图&#xff0c;超过了我们的配置阈值。京东自研UMP监控分析打出jstack文件&#xff0c;通过IBM Thread and Monitor Dump Analyzer for Java工具查看如下&#xff1a;IBM Thread and Monitor Dump Analyz…

php取json子对象属性,php中输出json对象的值(实现方法)

实例如下所示&#xff1a;$json {"report":{"date":"2012-04-10","content":"abcdefght"}};$arr (array) json_decode($json,true);echo 当前日期是&#xff1a;. $arr[report][date];echo "";echo ;print_r($a…

php mysql 表关联,mysql的多表关联_MySQL

bitsCN.commysql的多表关联数据库中经常要用到多个表的关联。mysql的关联主要包括inner join&#xff0c;left join&#xff0c;right join三种&#xff0c;下面分别加以介绍&#xff0c;并举例说明。顾名思义&#xff0c;inner join集合了两个表的信息&#xff0c;只有都包含的…

ulink php,【转载】15款USB数字界面横向评测(对比顶级CD转盘)!多看点!

还有一则有趣的回帖&#xff0c;一位纽约的烧友认为作者没有尝试何庆华最新的数字界面非常可惜&#xff0c;他认为何先生自主开发的DI-V3电源套件非常之牛&#xff0c;甚至超过了AP1PP的水准(不少人认为这个组合有一点点过于分析&#xff0c;不如何先生的作品水润)。他认为以他…

php取掉字符串第一位支付,php怎样去掉字符串中的第一个字符

php去掉字符串中的第一个字符的方法&#xff1a;可以利用substr()函数来实现。substr()函数可以返回字符串的提取部分&#xff0c;如果失败则返回false&#xff0c;或者返回一个空字符串。substr() 函数返回字符串的提取部分&#xff0c;如果失败则返回 FALSE&#xff0c;或者返…

matlab求距离判别函数,求MATLAB的逐步判别程序 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...

somomo91你不觉得信息量太少了么&#xff1f;摸不着头脑&#xff0c;zhouxiaobo是啊&#xff0c;信息量太少&#xff0c;LZ能详细描述一下你的问题吗或者直接给出你的数据和要求2012jxyl引用回帖:zhouxiaobo at 2013-06-06 09:44:49是啊&#xff0c;信息量太少&#xff0c;LZ能…

php验证码背景图是数字,ThinkPHP5.0.20验证码背景图片

tp5配置验证码相关问题一、验证码背景图片及tp中文验证码5.0.1及以上支持者在应用配置目录(application)下面 extra 子目录内配置captcha.php文件&#xff1b;配置参数如下&#xff1a;2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY,// 验证码字体大小(px)fontSize &g…

c mysql安装教程,Mysql安装教程_完成版(吐血式安装)

每次在不同操作系统中安装oracle和mysql这些常规数据库&#xff0c;步骤就那么点儿&#xff0c;但是遇见的错误却是千差万别。。记一次耗时两天的mysql数据库安装新得&#xff0c;有耐心&#xff0c;有毅力&#xff0c;憋生气。1.官网上下载免安装的版本(也就是下载下来直接解压…