Skip to content

Commit

Permalink
Metodo iteración del subespacio listo
Browse files Browse the repository at this point in the history
  • Loading branch information
ppizarror committed May 10, 2019
1 parent 2b5af36 commit 69e5f6d
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 23 deletions.
37 changes: 24 additions & 13 deletions tefame/analisis/ModalEspectral.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
% Methods:
% analisisObj = ModalEspectral(modeloObjeto)
% definirNumeracionGDL(analisisObj)
% analizar(analisisObj)
% analizar(analisisObj,varargin)
% numeroEcuaciones = obtenerNumeroEcuaciones(analisisObj)
% M_Modelo = obtenerMatrizMasa(analisisObj)
% C_Modelo = obtenerMatrizAmortiguamiento(analisisObj,rayleigh)
Expand Down Expand Up @@ -151,7 +151,7 @@ function analizar(analisisObj, varargin)
% set de cargas, requiere el numero de modos para realizar el
% analisis y de los modos conocidos con sus beta
%
% analizar(analisisObj,betacR,betacP,maxcond,varargin)
% analizar(analisisObj,varargin)
%
% Parametros:
% 'nModos' Numero de modos de analisis (obligatorio)
Expand All @@ -161,7 +161,7 @@ function analizar(analisisObj, varargin)
% 'cpenzienBeta' Vector amortiguamiento Cpenzien
% 'toleranciaMasa' Tolerancia de la masa para la condensacion
% 'condensar' Aplica condensacion (true por defecto)
% 'valvecAlgoritmo' 'eigvc','iterDir','matBarr','itInvDesp','itSubesp'
% 'valvecAlgoritmo' 'eigvc','itDir','matBarr','itInv','itInvDesp','itSubesp'
% 'valvecTolerancia' Tolerancia calculo valores y vectores propios

% Define parametros
Expand Down Expand Up @@ -193,18 +193,22 @@ function analizar(analisisObj, varargin)
if isempty(r.rayleighBeta)
error('Vector amortiguamiento de Rayleigh no puede ser nulo');
end

if isempty(r.rayleighModo)
error('Vector modo Rayleigh no puede ser nulo');
end

for i = 1:length(r.rayleighModo)
if r.rayleighModo(i) <= 0
error('Vector Rayleigh modo mal definido');
end
end % for i

if length(r.rayleighBeta) ~= length(r.rayleighModo) || ...
length(r.rayleighBeta) ~= length(r.rayleighDir)
error('Vectores parametros Rayleigh deben tener igual dimension');
end

for i = 1:length(r.rayleighDir)
if ~(r.rayleighDir(i) == 'h' || r.rayleighDir(i) == 'v')
error('Direccion amortiguamiento Rayleigh solo puede ser (h) horizonal o (v) vertical');
Expand Down Expand Up @@ -1868,7 +1872,6 @@ function disp(analisisObj)
end
end % for i

fprintf('-------------------------------------------------\n');
fprintf('\n');

end % disp function
Expand Down Expand Up @@ -1971,7 +1974,7 @@ function calcularModalEspectral(analisisObj, nModos, betacR, modocR, ...
% betacP,maxcond,valvecAlgoritmo,valvecTolerancia)

% Calcula tiempo inicio
fprintf('\tCalculando metodo modal espectral\n');
fprintf('\tCalculando metodo modal espectral:\n');
tInicio = cputime;

% Obtiene matriz de masa
Expand Down Expand Up @@ -2114,32 +2117,40 @@ function calcularModalEspectral(analisisObj, nModos, betacR, modocR, ...
fprintf('\t\tCalculo valores y vectores propios con metodo eigs\n');
[modalPhin, modalWn] = calculoEigEigs(Meq, Keq, nModos);

elseif strcmp(valvecAlgoritmo, 'iterDir')
elseif strcmp(valvecAlgoritmo, 'itDir')

fprintf('\tCalculo valores y vectores con algoritmo iteracion directa\n');
fprintf('\t\tCalculo valores y vectores con algoritmo iteracion directa\n');
fprintf('\t\t\tTolerancia: %.4f\n', valvecTolerancia);
[modalPhin, modalWn] = calculoEigIterDirecta(Meq, Keq, valvecTolerancia);
nModos = length(modalWn);

elseif strcmp(valvecAlgoritmo, 'matBarr')

fprintf('\tCalculo valores y vectores propios con algoritmo matriz de barrido\n');
fprintf('\t\tCalculo valores y vectores propios con algoritmo matriz de barrido\n');
fprintf('\t\t\tTolerancia: %.4f\n', valvecTolerancia);
[modalPhin, modalWn] = calculoEigDirectaBarrido(Meq, Keq, nModos, valvecTolerancia);

elseif strcmp(valvecAlgoritmo, 'itInv')

fprintf('\t\tCalculo valores y vectores propios con metodo iteracion inversa\n');

elseif strcmp(valvecAlgoritmo, 'itInvDesp')

fprintf('\tCalculo valores y vectores propios con metodo iteracion inversa con desplazamientos\n');
fprintf('\t\tCalculo valores y vectores propios con metodo iteracion inversa con desplazamientos\n');

elseif strcmp(valvecAlgoritmo, 'itSubesp')

fprintf('\tCalculo valores y vectores propios con metodo iteracion del subespacio\n');
fprintf('\t\tCalculo valores y vectores propios con metodo iteracion del subespacio\n');
fprintf('\t\t\tTolerancia: %.4f\n', valvecTolerancia);
[modalPhin, modalWn] = calculoEigItSubespacio(Meq, Keq, nModos, valvecTolerancia);

else

error('Algoritmo valvec:%s incorrecto, valores posibles: eigvc,iterDir,matBarr,itInvDesp,itSubesp', ...
error('Algoritmo valvec:%s incorrecto, valores posibles: eigvc,itDir,matBarr,itInv,itInvDesp,itSubesp', ...
valvecAlgoritmo);

end
fprintf('\t\tFinalizado en %.3f segundos\n', cputime-eigCalcT);
fprintf('\t\t\tFinalizado en %.3f segundos\n', cputime-eigCalcT);
analisisObj.numModos = nModos;

% Se recuperan los grados de libertad condensados y se
Expand Down Expand Up @@ -2299,7 +2310,7 @@ function calcularModalEspectral(analisisObj, nModos, betacR, modocR, ...
analisisObj.analisisFinalizado = true;
analisisObj.numDG = ndg;
analisisObj.numDGReal = analisisObj.modeloObj.obtenerNumerosGDL();
fprintf('\tSe completo el analisis en %.3f segundos\n', cputime-tInicio);
fprintf('\tSe completo el analisis en %.3f segundos\n\n', cputime-tInicio);

end % calcularModalEspectral function

Expand Down
37 changes: 37 additions & 0 deletions tefame/analisis/eig/GSM.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function [V] = GSM(V, M, V_b)
% GSM: Gram - Shmidt Modificado
% Esta funcion deja normalizados y ortogonales entre si (en base a la
% matriz M) los vectores de entrada, mediante el metodo de Gram-Schmidt
% modificado, sistema mas estabe que Gram-Schmidt clasico dado que itera
% por bloques.
%
% [V] = GSM(V,M,V_b)
%
% Input:
% V Matriz cuyas columnas corresponden a los vectores a ortonormalizar
% M Matriz de base para ortonormalizacion
% V_b Matriz cuyas columnas ya estan ortonormalizadas en M

% En una primera etapa, si se tiene la matriz V_b se ortogonalizan todos
% los vectores en V a los vectores en esta matriz
if nargin == 3
[~, n1] = size(V_b);
for k = 1:n1
alpha = V_b(:, k)' * M * V;
V = V - V_b(:, k) * alpha;
end % for k
end
[~, n1] = size(V);

% El metodo de Gram-Schmidt modificado consiste en, asumiendo en cada
% iteracion que el vector considerado ya es ortogonal a los procesados
% anteriormente, se normaliza el vector y ortogonalizan a este con todos
% los vectores posteriores
for k = 1:n1 - 1
V(:, k) = V(:, k) / (V(:, k)' * M * V(:, k))^0.5;
alpha = V(:, k)' * M * V(:, (k + 1):n1);
V(:, (k + 1):n1) = V(:, (k + 1):n1) - V(:, k) * alpha;
end % for k
V(:, n1) = V(:, n1) / (V(:, n1)' * M * V(:, n1))^0.5;

end
6 changes: 3 additions & 3 deletions tefame/analisis/eig/calculoEigDirectaBarrido.m
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
function [v, w, error] = calculoEigDirectaBarrido(M, K, nModos, tol)
% calculoEigIterDirecta: Calcula los valores y vectores propios del sistema
% usando el algoritmo de iteracion directo
% usando el algoritmo de matriz de barrido
%
% [w,v,error] = calculoEigIterDirecta(M,K,tol)
% [w,v,error] = calculoEigDirectaBarrido(M,K,nModos,tol)
%
% Parametros:
% M, K Matriz masa y rigidez
Expand Down Expand Up @@ -42,7 +42,7 @@
while err >= tol

% Vector de iteracion
vTemp = modonorm(D*v0Temp);
vTemp = modonorm(D*v0Temp, M, 4);

% Aproximacion al valor propio
wTemp = sqrt((vTemp' * K * vTemp)/(vTemp' * M * vTemp));
Expand Down
86 changes: 86 additions & 0 deletions tefame/analisis/eig/calculoEigItSubespacio.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
function [v, w] = calculoEigItSubespacio(M, K, nModos, tol)
% calculoEigItSubespacio: Calcula los valores y vectores propios del sistema
% usando el algoritmo de iteracion del subespacio
%
% [w,v] = calculoEigItSubespacio(M,K,nModos,tol)
%
% Parametros:
% M, K Matriz masa y rigidez
% nModos Numero de modos del analisis
% tol Tolerancia del calculo
%
% Salida:
% w Matriz vectores propios
% v Valores propios

if nargin < 4 || isempty(tol)
tol = 0.001;
end

% Calculos iniciales
ngdl = length(K);

% Calcula matriz de rigidez triangular LU
[L, U] = lu(K);
U = U';
L = L';

% Genera vector v a partir de numeros aleatorios
Vsize = min(6, ngdl);
X = (rand(ngdl, Vsize));

phi = X; % Matriz que contendra los vectores finales
wfinal = zeros(nModos, 1); % Contendra las frecuencias

% Primera estimacion de la frecuencia
wo = sqrt(X(:, 1)'*K*X(:, 1)) / (X(:, 1)' * X(:, 1));

% Genera los vectores propios iterando
for i = 1:nModos

err = 1000; % Reinicializa error
temp = []; %#ok<NASGU>

while err > tol

% Resuelve el sistema de ecuaciones en dos etapas
% L*D*y=b y
% L'*u=y
% donde L*D=U' (U de la descomposicion LU)
y1 = U \ (M * X);
X = L \ y1;

% Genera bloque de vectores u_s, rigidez y masa ortogonal
M_b = X' * M * X;
K_b = X' * K * X;
[Z] = eig(K_b, M_b);
X = X * Z; % Vectores ortogonales

% Calcula Gram-Schmidt para hacer X ortogonal a todos los
% demas vectores
if i ~= 1
X = GSM(X, M, phi(:, 1:i-1));
end
X = modonorm(X, M); % Normalizacion modal

% Verifio tolerancia con valores propios
Xo = X(:, 1);
w = sqrt(Xo'*K*Xo) / (Xo' * M * Xo);
err = abs((wo - w)/wo);
if err <= tol
wfinal(i) = w;
phi(:, i) = X(:, 1);
X = [X(:, 2:end), (rand(ngdl, 1))];
else
wo = w;
end

end

end % for i

% Guarda valores
v = phi;
w = wfinal;

end
4 changes: 2 additions & 2 deletions tefame/analisis/eig/calculoEigIterDirecta.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
% v Valores propios
% error Vector error de iteraciones

if nargin < 4 || isempty(tol)
if nargin < 3 || isempty(tol)
tol = 0.001;
end

Expand All @@ -35,7 +35,7 @@
while err >= tol

% Vector de iteracion
vTemp = modonorm(D*v0Temp);
vTemp = modonorm(D*v0Temp, M, 4);

% Aproximacion al valor propio
wTemp = sqrt((vTemp' * K * vTemp)/(vTemp' * M * vTemp));
Expand Down
45 changes: 41 additions & 4 deletions tefame/analisis/eig/modonorm.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
function w = modonorm(v)
% modonorm: Normaliza un modo
function [phi] = modonorm(phi, M, opt)
% modonorm: Normaliza formas modales
%
% w = modonorm(phi,M,opt)

vn = norm(v);
w = v ./ vn;
if nargin < 2
opt = 1;
end

if nargin < 3 || isempty(opt)
opt = 2;
end

% Para caso general
if opt == 0
end

% Normaliza con primera linea
if opt == 1
aux = (phi(1, :));
if min(abs(aux)) <= eps
opt = 3;
warning('No se puede dividir debido a un valor nulo, se usa opt=3');
else
phi = phi * diag(1./aux);
end
end

if opt == 2
Mn = sqrt(diag(conj(phi)'*M*phi));
phi = phi * diag(Mn^-1);
end

if opt == 3
aux = max(phi);
phi = phi * diag(1./aux);
end

% Simplemente normaliza por el valor absoluto
if opt == 4
phi = phi ./ norm(phi);
end

end
2 changes: 1 addition & 1 deletion test/modal/Modelo_DinamicaAvanzada.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
%% Analiza el sistema
analisisObj.analizar('nModos', 41, 'rayleighBeta', [0.02, 0.02], 'rayleighModo', [1, 8], ...
'rayleighDir', ['h', 'h'], 'cpenzienBeta', [0.02, 0.02, 0], 'condensar', true, ...
'valvecAlgoritmo', 'matBarr');
'valvecAlgoritmo', 'itSubesp', 'valvecTolerancia', 0.0001);
analisisObj.disp();
cargaEstatica = analisisObj.obtenerCargaEstatica();
% plt = analisisObj.plot('modo', 8, 'factor', 20, 'cuadros', 25, 'gif', ...
Expand Down

0 comments on commit 69e5f6d

Please sign in to comment.