XIAN-FEM-2026June/三维matlab代码/2023-2-端口激励问题(四面体网格)/exportAbMatrixFem2.m

92 lines
3.2 KiB
Matlab

function exportAbMatrixFem2(outDir)
%EXPORTABMATRIXFEM2 Export reduced A/b (after PEC, before symrcm) for MainFem2 / MeshData2
rootDir = fileparts(mfilename('fullpath'));
if nargin < 1 || isempty(outDir)
outDir = fullfile(rootDir, 'OutFile_fem2_ab');
end
if ~exist(outDir, 'dir')
mkdir(outDir);
end
exportDir = fullfile(rootDir, '..', 'matlab 3D一阶基+散射边界条件');
addpath(rootDir, exportDir);
meshFile = fullfile(rootDir, 'MeshData2.mat');
S = load(meshFile);
Mesh = S.Mesh;
[Physic, Material, Port1Solver, Port2Solver] = configPhysicMaterialFem4();
if ~isfield(Mesh, 'NbrNodes')
Mesh.NbrNodes = length(Mesh.Nodes);
Mesh.NbrElements = length(Mesh.Elements);
end
fprintf('Port eigenmode solve (MainFem2 / MeshData2)...\n');
Port1Mesh = GetBMesh(Mesh.Nodes, Mesh.Faces, Mesh.FacesIndex, Physic.Port1);
[Port1Solver, Port1Mesh] = BoundaryEigenMode(Port1Mesh, Physic, Material, Port1Solver);
Port1Solver = GetPowerCoef(Port1Solver, Port1Mesh, Material.murF, 1);
Port1Mesh.normal = [0; 0; -1];
Port2Mesh = GetBMesh(Mesh.Nodes, Mesh.Faces, Mesh.FacesIndex, Physic.Port2);
[Port2Solver, Port2Mesh] = BoundaryEigenMode(Port2Mesh, Physic, Material, Port2Solver);
Port2Mesh.normal = [0; 0; 1];
fprintf('Global matrix assembly (wave + ports + PEC reduce)...\n');
epsilonr = Material.epsilonr - 1i * Material.sigma * Material.temp;
[A, Mesh.Edges, Mesh.EdgesOfElements, Dof] = PhysicMatrixAssembly( ...
Mesh.Nodes, Mesh.Elements, Mesh.Domains, Physic.lam0, epsilonr, Material.mur);
b = complex(zeros(Dof, 1));
el2no = Mesh.Elements';
f1 = el2no([1 1 1 2], :);
f2 = el2no([2 2 3 3], :);
f3 = el2no([3 4 4 4], :);
f_array = [f1(:) f2(:) f3(:)];
[Faces, ~, FacesOfElements] = unique(f_array, 'rows');
Mesh.AllFaces = Faces;
Mesh.FacesOfElements = FacesOfElements;
addDof = 0;
Port1Mesh.FacesConn = GetBFacesConn(Port1Mesh.OldFaces, Faces, FacesOfElements);
[A, b, addDof] = PortBCMatrixAssembly(A, b, Mesh.Nodes, Mesh.Elements, Mesh.EdgesOfElements, ...
Mesh.Domains, Material.mur, Port1Mesh, Port1Solver, Dof, addDof);
Port2Mesh.FacesConn = GetBFacesConn(Port2Mesh.OldFaces, Faces, FacesOfElements);
[A, b, addDof] = PortBCMatrixAssembly(A, b, Mesh.Nodes, Mesh.Elements, Mesh.EdgesOfElements, ...
Mesh.Domains, Material.mur, Port2Mesh, Port2Solver, Dof, addDof);
addDof(1) = [];
[PECFaces, ~] = GetBFaces(Mesh.Faces, Mesh.FacesIndex, Physic.PEC);
fl2no = PECFaces';
n1 = fl2no([1 1 2], :);
n2 = fl2no([2 3 3], :);
fl_fd2no_array = [n1(:) n2(:)];
PECEdges = unique(fl_fd2no_array, 'rows');
PECInd = find(ismember(Mesh.Edges, PECEdges, 'rows'));
Free_ind = 1:(Dof + sum(addDof));
Free_ind(PECInd) = [];
A = A(Free_ind, Free_ind);
b = b(Free_ind);
fprintf('Reduced system: size=%d, nnz=%d, |b|=%g\n', ...
size(A, 1), nnz(A), norm(b));
export_ab_matrix(A, b, outDir);
metaFile = fullfile(outDir, 'meta.txt');
fid = fopen(metaFile, 'w');
fprintf(fid, 'source=MATLAB exportAbMatrixFem2\n');
fprintf(fid, 'mesh=MeshData2.mat\n');
fprintf(fid, 'stage=after_PEC_before_symrcm\n');
fprintf(fid, 'n=%d\n', size(A, 1));
fprintf(fid, 'nnz=%d\n', nnz(A));
fprintf(fid, 'nPEC=%d\n', numel(PECInd));
fprintf(fid, 'Dof=%d\n', Dof);
fprintf(fid, 'addDof=%d\n', sum(addDof));
fprintf(fid, 'powerCoef=%.15g\n', Port1Solver.powerCoef);
fclose(fid);
fprintf('Done. MATLAB A/b -> %s\n', outDir);
end