/*+ precompute_subquery */子查询中的提示

本文通过具体示例展示了如何使用Oracle SQL提示precompute_subquery优化含有IN子查询的SQL语句执行效率,对比了不同情况下的执行计划及成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QUOTE:
--------------------------------------------------------------------------------
select * from tab1 where tab1.object_name in(select /*+ precompute_subquery */ object_name from tab2 where owner='SYS');

/*+ precompute_subquery */子查询中的提示

就是把子查询中in的多个值改写成多个OR条件
--------------------------------------------------------------------------------


SCOTT@ncdb>select count(*) from dba_objects;

  COUNT(*)
----------
     62493

Elapsed: 00:00:00.84
SCOTT@ncdb>create table dba_objects_20090210 as select * from dba_objects;

Table created.

Elapsed: 00:00:01.56

SCOTT@ncdb>create table dba_objects2 as select * from dba_objects;

Table created.

Elapsed: 00:00:01.48

SCOTT@ncdb>select owner, count(*) from dba_objects2 group by owner;

OWNER        COUNT(*)
---------- ----------
PUBLIC          20084
SYSTEM            454
XDB               680
OLAPSYS           720
IUFOV31           366
YONGYOU          1573
SYS             23257
TSMSYS              3
MDSYS             936
SHUIBO           1562
JV                 50
NCTOCC              7
SYSMAN           1346
HAIFENG          1561
EXFSYS            282
SI_INFORMT          8
N_SCHEMA
BI_DATA            18
NCV31            4798
WMSYS             315
ORDSYS           1721
SCOTT              17
NCTOPSI           220
NFD               191
ORACLE_OCM          8
BI_REP            111
CTXSYS            313
ORDPLUGINS         10
OUTLN               9
DBSNMP             46
DMSYS             189
OULONG           1503
RMAN              128
OA                  8

33 rows selected.

Elapsed: 00:00:00.82
SCOTT@ncdb>create index idx_dba_objects_name on dba_objects_20090210(object_name);

Index created.

Elapsed: 00:00:00.43
SCOTT@ncdb>explain plan for
  2  select * from dba_objects_20090210 where object_name in
  3  (select object_name from dba_objects2 where owner='NCTOCC');

Explained.

Elapsed: 00:00:00.06
SCOTT@ncdb>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
Plan hash value: 2716592996

-----------------------------------------------------------------------------------------------------
| Id  | Operation                                   | Name                                 | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                                           |    94 | 24440 |   114   (6)| 00:00:01 |
|   1 |  NESTED LOOPS                           |                                           |    94 | 24440 |   114   (6)| 00:00:01 |
|   2 |   SORT UNIQUE                             |                                          |    10 |   830 |   103   (5)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL                 | DBA_OBJECTS2                 |    10 |   830 |   103   (5)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DBA_OBJECTS_20090210 |    10 |  1770 |     2   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN                  | IDX_DBA_OBJECTS_NAME |    10 |           |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("OWNER"='NCTOCC')
   5 - access("OBJECT_NAME"="OBJECT_NAME")

Note
-----
   - dynamic sampling used for this statement

22 rows selected.

Elapsed: 00:00:00.06
SCOTT@ncdb>explain plan for
  2  select * from dba_objects_20090210 where object_name in
  3  (select object_name from dba_objects2 where owner='SYS');

Explained.

Elapsed: 00:00:00.06
SCOTT@ncdb>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
Plan hash value: 3391626064

-----------------------------------------------------------------------------------------------------
| Id  | Operation            | Name                 | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                      | 68173 |    16M|       |   560   (5)| 00:00:04 |
|*  1 |  HASH JOIN RIGHT SEMI|                      | 68173 |    16M|  2352K|   560   (5)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL  | DBA_OBJECTS2         | 25340 |  2053K|       |   104   (6)| 00:00:01 |
|   3 |   TABLE ACCESS FULL  | DBA_OBJECTS_20090210 | 77278 |    13M|       |   108  (10)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("OBJECT_NAME"="OBJECT_NAME")
   2 - filter("OWNER"='SYS')

Note
-----
   - dynamic sampling used for this statement

20 rows selected.

Elapsed: 00:00:00.04
SCOTT@ncdb>explain plan for
  2  select * from dba_objects_20090210 where object_name in
  3  (select /*+ precompute_subquery */object_name from dba_objects2 where owner='SYS');

Explained.

Elapsed: 00:00:00.34
SCOTT@ncdb>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
Plan hash value: 3391626064

-----------------------------------------------------------------------------------------------------
| Id  | Operation            | Name                 | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                      | 68173 |    16M|       |   560   (5)| 00:00:04 |
|*  1 |  HASH JOIN RIGHT SEMI|                      | 68173 |    16M|  2352K|   560   (5)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL  | DBA_OBJECTS2         | 25340 |  2053K|       |   104   (6)| 00:00:01 |
|   3 |   TABLE ACCESS FULL  | DBA_OBJECTS_20090210 | 77278 |    13M|       |   108  (10)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("OBJECT_NAME"="OBJECT_NAME")
   2 - filter("OWNER"='SYS')

Note
-----
   - dynamic sampling used for this statement

20 rows selected.

Elapsed: 00:00:00.04
SCOTT@ncdb>explain plan for
  2  select /*+ precompute_subquery */ * from dba_objects_20090210 where object_name in
  3  (select object_name from dba_objects2 where owner='SYS');

Explained.

Elapsed: 00:00:00.04
SCOTT@ncdb>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------
Plan hash value: 3391626064

-----------------------------------------------------------------------------------------------------
| Id  | Operation            | Name                 | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                      | 68173 |    16M|       |   560   (5)| 00:00:04 |
|*  1 |  HASH JOIN RIGHT SEMI|                      | 68173 |    16M|  2352K|   560   (5)| 00:00:04 |
|*  2 |   TABLE ACCESS FULL  | DBA_OBJECTS2         | 25340 |  2053K|       |   104   (6)| 00:00:01 |
|   3 |   TABLE ACCESS FULL  | DBA_OBJECTS_20090210 | 77278 |    13M|       |   108  (10)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("OBJECT_NAME"="OBJECT_NAME")
   2 - filter("OWNER"='SYS')

Note
-----
   - dynamic sampling used for this statement

20 rows selected.

Elapsed: 00:00:00.04
SCOTT@ncdb>

=======================================================================================================

SQL> create table test_1 as select * from dba_objects;

表已创建。


SQL> create table test2 as select rownum id  from dual connect by rownum<10;

表已创建。

SQL> create index i_test_1 on test_1(object_id);

索引已创建。

SQL> set autot trace exp
SQL> select * from test_1 where object_id in (select /*+ precompute_subquery */ id from test2);

执行计划
----------------------------------------------------------
Plan hash value: 3907423376

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |     8 |  1416 |    12   (0)| 00:00:01 |
|   1 |  INLIST ITERATOR             |          |       |       |            |        |
|   2 |   TABLE ACCESS BY INDEX ROWID| TEST_1   |     8 |  1416 |    12   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | I_TEST_1 |   207 |       |     9   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("OBJECT_ID"=1 OR "OBJECT_ID"=2 OR "OBJECT_ID"=3 OR "OBJECT_ID"=4
              OR "OBJECT_ID"=5 OR "OBJECT_ID"=6 OR "OBJECT_ID"=7 OR "OBJECT_ID"=
8 OR

              "OBJECT_ID"=9)

Note
-----
   - dynamic sampling used for this statement

==================================================================================================

SCOTT@ncdb>explain plan for
  2  select * from dba_objects_20090210 where object_name in
  3  (select /*+ precompute_subquery */ object_name from dba_objects2 where owner='NCTOCC');

Explained.

Elapsed: 00:00:00.18
SCOTT@ncdb>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2232840152

-----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                      |    69 | 12213 |    59   (0)| 00:00:01 |
|   1 |  INLIST ITERATOR             |                      |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| DBA_OBJECTS_20090210 |    69 | 12213 |    59   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | IDX_DBA_OBJECTS_NAME |   309 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("OBJECT_NAME"='V_COINFO' OR "OBJECT_NAME"='V_CUSTINFO' OR
              "OBJECT_NAME"='V_RETURNBILL_STATUS' OR "OBJECT_NAME"='V_SALEORDER_STATUS' OR
              "OBJECT_NAME"='V_SALEOUT_STATUS' OR "OBJECT_NAME"='V_SALERET_STATUS' OR
              "OBJECT_NAME"='V_USERINFO')

Note
-----
   - dynamic sampling used for this statement

22 rows selected.

clc; n = 40; % number of elements finalT = 0.2; % final time %boundary = 1; % switch between Dirichlet conditions (1) and Absorbing (0) k = 6; % polynomial degree gamma=1.4; % 比热比 %Cr = 0.2; % Courant number -> sets time step size in dt = Cr * h / a CFL=0.2; %flux = 1; % flux type, 0 = LF, 1 = HDG nc = k+1; % number of quadrature points left = -0.5; % left end of the domain right = 0.5; % right end of the domain %plot_accurate = 1; % plot only on nodes (0) or with more resolution (1) %% set quadrature formula and quadrature nodes for integration [xg,wg] = legendre_gauss(nc); % set the node points for the Lagrange polynomials [xunit,w] = legendre_gauss_lobatto(k+1); %% START THE SIMULATION % create mesh y and compute mesh size h kp1 = length(xunit); y = zeros(2*n,1); h = zeros(n,1); for e=1:n y(2*e-1) = left + (right-left)*(e-1)/n; y(2*e) = left + (right-left)*e/n; h(e) = y(2*e)-y(2*e-1); end dx=(right-left)/n; % create the grid of all node points for interpolation x=zeros(kp1,n); for e=1:n for i=1:kp1 x(i,e) = y(2*e-1)+(y(2*e)-y(2*e-1))*(0.5+0.5*xunit(i)); end end % compute time step from Cr number, adjust to hit the desired final time dt=CFL*dx; % evaluate reference cell polynomials %[values,derivatives] = evaluate_lagrange_basis(xunit, pg); %% MASS MATRIX [psi,dpsi] = lagrange_basis3(k+1,nc,xunit, xg); Me = psi * diag(wg) * psi'; m1=inv(Me); % De = dpsi * diag(wg) * psi'; %M1inv = sparse(kp1*n,kp1*n); %for e=1:n % M1inv((kp1*e-k):kp1*e,(kp1*e-k):kp1*e) = inv(0.5*dx*Me); % De((kp1*e-k):kp1*e,(kp1*e-k):kp1*e) = 0.5*dx*De; %end %M=M1inv; % D=De; %% 初始条件 - Sod激波管问题 rho = zeros(kp1,n); u = zeros(kp1,n); p = zeros(kp1,n); for e=1:n for j = 1:kp1 x_pos = x(j,e); if x_pos < 0.0 rho(j,e) = 1.0; u(j,e) = 0.0; p(j,e) = 1.0; else rho(j,e) = 0.125; u(j,e) = 0.0; p(j,e) = 0.1; end end end %% 计算初始条件下的守恒变量 E = p/(gamma-1) + 0.5*rho.*u.^2; % 总能量 U = zeros(3,kp1,n); U(1,:,:) = rho; U(2,:,:) = rho.*u; U(3,:,:) = E; %% run time loop t=0; %step_count=0; %output_interval=100; %输出时间间隔 while t<finalT if t+dt>finalT dt=finalT-t; end % Runge-Kutta 3 U1 = U+dt*rhs1(U,dx,gamma,xunit,psi,dpsi,wg); U2 = 0.75*U + 0.25*(U1 + dt*rhs1(U1,dx,gamma,xunit,psi,dpsi,wg)); U = 1/3*U + 2/3*(U2 + dt*rhs1(U2,dx,gamma,xunit,psi,dpsi,wg)); t=t+dt; end %% 结果可视化 figure; x_plot = reshape(x,kp1*n, 1); rho_plot = reshape(U(1,:,:), kp1*n, 1); u_plot = reshape(U(2,:,:)./U(1,:,:), kp1*n, 1); p_plot = reshape((gamma-1)*(U(3,:,:)-0.5*U(2,:,:).^2./U(1,:,:)), kp1*n, 1); % 绘制图形 subplot(3,1,1); plot(x_plot, rho_plot, 'b-', 'LineWidth', 1.5); title('密度分布'); xlabel('x'); ylabel('\rho'); grid on; subplot(3,1,2); plot(x_plot, u_plot, 'r-', 'LineWidth', 1.5); title('速度分布'); xlabel('x'); ylabel('u'); grid on; subplot(3,1,3); plot(x_plot, p_plot, 'g-', 'LineWidth', 1.5); title('压力分布'); xlabel('x'); ylabel('p'); grid on; %% %---------------------------------------------------------------------% %This code computes the Legendre-Gauss points and weights %which are the roots of the Legendre Polynomials. %Written by F.X. Giraldo on 4/2008 % Department of Applied Mathematics % Naval Postgraduate School % Monterey, CA 93943-5216 %---------------------------------------------------------------------% function [xgl,wgl] = legendre_gauss(P) xgl=zeros(P,1); wgl=zeros(P,1); p=P-1; %Order of Polynomials (P is the number of points: p+1) ph=floor( (p+1)/2 ); for i=1:ph x=cos( (2*i-1)*pi/(2*p+1) ); for k=1:20 [L0,L0_1,L0_2]=legendre_poly(p+1,x); %Compute the N+1 Legendre Polys %Get new Newton Iteration dx=-L0/L0_1; x=x+dx; if (abs(dx) < 1.0e-20) break end end xgl(p+2-i)=x; wgl(p+2-i)=2/( (1-x^2)*L0_1^2 ); end %Check for Zero Root if (p+1 ~= 2*ph) x=0; [L0,L0_1,L0_2]=legendre_poly(p+1,x); xgl(ph+1)=x; wgl(ph+1)=2/( (1-x^2)*L0_1^2 ); end %Find remainder of roots via symmetry for i=1:ph xgl(i)=-xgl(p+2-i); wgl(i)=+wgl(p+2-i); end end %% %---------------------------------------------------------------------% %This code computes the Legendre-Gauss-Lobatto points and weights %which are the roots of the Lobatto Polynomials. %Written by F.X. Giraldo on 4/2000 % Department of Applied Mathematics % Naval Postgraduate School % Monterey, CA 93943-5216 %---------------------------------------------------------------------% function [xgl,wgl] = legendre_gauss_lobatto(P) xgl=zeros(P,1); wgl=zeros(P,1); p=P-1; ph=floor( (p+1)/2 ); for i=1:ph x=cos( (2*i-1)*pi/(2*p+1) ); for k=1:20 [L0,L0_1,L0_2]=legendre_poly(p,x); %Get new Newton Iteration dx=-(1-x^2)*L0_1/(-2*x*L0_1 + (1-x^2)*L0_2); x=x+dx; if (abs(dx) < 1.0e-20) break end end xgl(p+2-i)=x; wgl(p+2-i)=2/(p*(p+1)*L0^2); end %Check for Zero Root if (p+1 ~= 2*ph) x=0; [L0,L0_1,L0_2]=legendre_poly(p,x); xgl(ph+1)=x; wgl(ph+1)=2/(p*(p+1)*L0^2); end %Find remainder of roots via symmetry for i=1:ph xgl(i)=-xgl(p+2-i); wgl(i)=+wgl(p+2-i); end end %% %---------------------------------------------------------------------% %This code computes the Legendre Polynomials and its 1st and 2nd derivatives %Written by F.X. Giraldo on 4/2000 % Department of Applied Mathematics % Naval Postgraduate School % Monterey, CA 93943-5216 %---------------------------------------------------------------------% function [L0,L0_1,L0_2] = legendre_poly(p,x) L1=0;L1_1=0;L1_2=0; L0=1;L0_1=0;L0_2=0; for i=1:p L2=L1;L2_1=L1_1;L2_2=L1_2; L1=L0;L1_1=L0_1;L1_2=L0_2; a=(2*i-1)/i; b=(i-1)/i; L0=a*x*L1 - b*L2; L0_1=a*(L1 + x*L1_1) - b*L2_1; L0_2=a*(2*L1_1 + x*L1_2) - b*L2_2; end end %% %% 函数:计算右侧项 function rhs11=rhs1(U,dx,gamma,xunit,psi,dpsi,weights) [~,kp1,n]=size(U); rhs11=zeros(size(U)); rho=U(1,:,:); u=U(2,:,:)./rho; E=U(3,:,:); p=(gamma-1)*(E-0.5*rho.*u.^2); rhs11_1=zeros(kp1,n); rhs11_2=zeros(kp1,n); rhs11_3=zeros(kp1,n); rho_1=zeros(kp1,1); u_1 =zeros(kp1,1); E_1 =zeros(kp1,1); %% 计算刚度部分 de=0.5*dx*dpsi*diag(weights)*(psi)'; for e=1:n rho_1(:,1)=rho(:,e); u_1(:,1) =u(:,e); E_1(:,1) =E(:,e); rhs11_1(:,e)=de*rho_1; rhs11_2(:,e)=de*u_1; rhs11_3(:,e)=de*E_1; rhs11(1,:,e)=rhs11_1(:,e); rhs11(2,:,e)=rhs11_2(:,e); rhs11(3,:,e)=rhs11_3(:,e); end %% 边界通量计算(数值通量) for e = 1:n %% 左边界 if e == 1 % 流入边界条件 rho_L = 1.0; u_L = 0.0; p_L = 1.0; E_L = p_L/(gamma-1) + 0.5*rho_L*u_L^2; U_L = [rho_L; rho_L*u_L; E_L]; % 单元内左端点状态 rho_R = U(1,1,e); u_R = U(2,1,e)/rho_R; E_R = U(3,1,e); p_R = (gamma-1)*(E_R - 0.5*rho_R*u_R^2); U_R = [rho_R; rho_R*u_R; E_R]; % 计算Roe平均 U_roe = roe_average(U_L, U_R, gamma); rho_roe = U_roe(1); u_roe = U_roe(2)/rho_roe; E_roe = U_roe(3); p_roe = (gamma-1)*(E_roe - 0.5*rho_roe*u_roe^2); a_roe = sqrt(gamma*p_roe/rho_roe); % 计算特征值 lambda1 = u_roe - a_roe; lambda2 = u_roe; lambda3 = u_roe + a_roe; lambda_max = max(abs([lambda1, lambda2, lambda3])); % 使用更强的Lax-Friedrichs通量 F_L = euler_flux(U_L, gamma); F_R = euler_flux(U_R, gamma); F_num = 0.5*(F_L + F_R - 1.5*lambda_max*(U_R - U_L)); % 增加系数提高耗散 % 应用数值通量 rhs11(:,1,e)=rhs11(:,1,e)-F_num; else % 内部边界 - 与左侧单元交互 % 当前单元左端点状态 rho_R = U(1,1,e); u_R = U(2,1,e)/rho_R; E_R = U(3,1,e); p_R = (gamma-1)*(E_R - 0.5*rho_R*u_R^2); U_R = [rho_R; rho_R*u_R; E_R]; % 左侧单元右端点状态 rho_L = U(1,kp1,e-1); u_L = U(2,kp1,e-1)/rho_L; E_L = U(3,kp1,e-1); p_L = (gamma-1)*(E_L - 0.5*rho_L*u_L^2); U_L = [rho_L; rho_L*u_L; E_L]; % 计算Roe平均 U_roe = roe_average(U_L, U_R, gamma); rho_roe = U_roe(1); u_roe = U_roe(2)/rho_roe; E_roe = U_roe(3); p_roe = (gamma-1)*(E_roe - 0.5*rho_roe*u_roe^2); a_roe = sqrt(gamma*p_roe/rho_roe); % 计算特征值 lambda1 = u_roe - a_roe; lambda2 = u_roe; lambda3 = u_roe + a_roe; lambda_max = max(abs([lambda1, lambda2, lambda3])); % 使用更强的Lax-Friedrichs通量 F_L = euler_flux(U_L, gamma); F_R = euler_flux(U_R, gamma); F_num = 0.5*(F_L + F_R - 1.5*lambda_max*(U_R - U_L)); % 增加系数提高耗散 % 应用数值通量 rhs11(:,1,e)=rhs11(:,1,e)-F_num; end %% 右边界 if e == n % 改进的流出边界条件 rho_R = 0.125; u_R = 0.0; p_R = 0.1; E_R = p_R/(gamma-1) + 0.5*rho_R*u_R^2; U_R = [rho_R; rho_R*u_R; E_R]; % 使用前一个单元的状态作为外部状态 rho_L = U(1,kp1,e); u_L = U(2,kp1,e)/rho_L; E_L = U(3,kp1,e); p_L = (gamma-1)*(E_L - 0.5*rho_L*u_L^2); U_L = [rho_L; rho_L*u_L; E_L]; % 计算Roe平均 U_roe = roe_average(U_L, U_R, gamma); rho_roe = U_roe(1); u_roe = U_roe(2)/rho_roe; E_roe = U_roe(3); p_roe = (gamma-1)*(E_roe - 0.5*rho_roe*u_roe^2); a_roe = sqrt(gamma*p_roe/rho_roe); % 计算特征值 lambda1 = u_roe - a_roe; lambda2 = u_roe; lambda3 = u_roe + a_roe; lambda_max = max(abs([lambda1, lambda2, lambda3])); % 使用更强的Lax-Friedrichs通量 F_L = euler_flux(U_L, gamma); F_R = euler_flux(U_R, gamma); F_num = 0.5*(F_L + F_R - 1.5*lambda_max*(U_R - U_L)); % 增加系数提高耗散 % 应用数值通量 rhs11(:,kp1,e)=rhs11(:,kp1,e)-F_num; else % 内部边界 - 与右侧单元交互 % 当前单元右端点状态 rho_L = U(1,kp1,e); u_L = U(2,kp1,e)/rho_L; E_L = U(3,kp1,e); p_L = (gamma-1)*(E_L - 0.5*rho_L*u_L^2); U_L = [rho_L; rho_L*u_L; E_L]; % 右侧单元左端点状态 rho_R = U(1,1,e+1); u_R = U(2,1,e+1)/rho_R; E_R = U(3,1,e+1); p_R = (gamma-1)*(E_R - 0.5*rho_R*u_R^2); U_R = [rho_R; rho_R*u_R; E_R]; % 计算Roe平均 U_roe = roe_average(U_L, U_R, gamma); rho_roe = U_roe(1); u_roe = U_roe(2)/rho_roe; E_roe = U_roe(3); p_roe = (gamma-1)*(E_roe - 0.5*rho_roe*u_roe^2); a_roe = sqrt(gamma*p_roe/rho_roe); % 计算特征值 lambda1 = u_roe - a_roe; lambda2 = u_roe; lambda3 = u_roe + a_roe; lambda_max = max(abs([lambda1, lambda2, lambda3])); % 使用更强的Lax-Friedrichs通量 F_L = euler_flux(U_L, gamma); F_R = euler_flux(U_R, gamma); F_num = 0.5*(F_L + F_R - 1.5*lambda_max*(U_R - U_L)); % 增加系数提高耗散 % 应用数值通量 rhs11(:,1,e+1)=rhs11(:,1,e+1)-F_num; end end %% 质量矩阵的逆乘右端项:inv(M)*rhs mass=0.5*dx*psi*diag(weights)*(psi)'; rhs11_11=zeros(kp1,1); rhs11_22=zeros(kp1,1); rhs11_33=zeros(kp1,1); rho_11=zeros(kp1,1); u_11 =zeros(kp1,1); E_11 =zeros(kp1,1); for e=1:n rho_11(:,1)=rhs11(1,:,e); u_11(:,1) =rhs11(2,:,e); E_11(:,1) =rhs11(3,:,e); rhs11_11(:,e)=mass\rho_1; rhs11_22(:,e)=mass\u_1; rhs11_33(:,e)=mass\E_1; rhs11(1,:,e)=rhs11_11(:,e); rhs11(2,:,e)=rhs11_22(:,e); rhs11(3,:,e)=rhs11_33(:,e); end end %% 函数:计算Roe平均 function U_roe = roe_average(U_L, U_R, gamma) rho_L = U_L(1); u_L = U_L(2)/rho_L; E_L = U_L(3); p_L = (gamma-1)*(E_L - 0.5*rho_L*u_L^2); rho_R = U_R(1); u_R = U_R(2)/rho_R; E_R = U_R(3); p_R = (gamma-1)*(E_R - 0.5*rho_R*u_R^2); % Roe平均 sqrt_rho_L = sqrt(rho_L); sqrt_rho_R = sqrt(rho_R); rho_roe = sqrt_rho_L * sqrt_rho_R; u_roe = (sqrt_rho_L*u_L + sqrt_rho_R*u_R) / (sqrt_rho_L + sqrt_rho_R); H_L = (E_L + p_L) / rho_L; H_R = (E_R + p_R) / rho_R; H_roe = (sqrt_rho_L*H_L + sqrt_rho_R*H_R) / (sqrt_rho_L + sqrt_rho_R); E_roe = rho_roe * (H_roe - 0.5*u_roe^2); U_roe = [rho_roe; rho_roe*u_roe; E_roe]; end %% 函数:计算Euler方程通量 function F = euler_flux(U, gamma) rho = U(1); u = U(2)/rho; E = U(3); p = (gamma-1)*(E - 0.5*rho*u^2); F = zeros(3,1); F(1) = rho*u; F(2) = rho*u^2 + p; F(3) = u*(E + p); end 对上述代码分析,给出出现错误的原因和地方,并给出修正后完整的代码
最新发布
07-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值