%
%                     PGD Code for parametrized force
%                    D. González, I. Alfaro, E. Cueto
%                        Universidad de Zaragoza
%                          AMB-I3A Dec 2015
%
clear all; close all; clc;
%
% VARIABLES
%
global coords triangles E nu behaviour % Global variables.
E = 1000; nu = 0.3; % Material (Young Modulus and Poisson Coef)
Modulus = 1; % Force Modulus.
behaviour = 1; % Plane Stress(1), Plane Strain(2).
TOL = 1.0E-03; % Tolerance.
num_max_iter = 11; % Max. # of functional pairs for the approximation.
%
% GEOMETRY
%
X0 = 0; Xf = 3; Y0 = 0; Yf = 1.0; % The beam dimensions, [0,3]x[0,1]
tamx = 0.1; tamy = 0.1; %  mesh size along each direction
nenY = numel(Y0:tamx:Yf); % # of elements in vertical direction
[X,Y] = meshgrid(X0:tamx:Xf,Y0:tamy:Yf); 
coords = [X(:),Y(:)];
force = X0:tamx:Xf; force = force'; % force positions and 1D coordinates.
triangles = delaunayTriangulation(coords(:,1),coords(:,2)); % Mesh data.
%
% ALLOCATION OF MATRICES AND VECTORS
%
F = zeros(numel(coords),1); % Nodal values of spatial function F
G = zeros(numel(force),1); % Nodal values of force function G
FR1 = zeros(numel(coords),numel(force)); % Nodal values for force space term
FR2 = eye(numel(force)); % Nodal values for force force term
%
% COMPUTING STIFFNESS AND MASS MATRIX FOR SPACE, ONLY MASS MATRIX FOR force
%
[K1,M2] = elemstiff(force);
%
% SOURCE (FORCE) TERM IN SEPARATED FORM
%
DOFforceed = 2*nenY:2*nenY:numel(coords); % force on vertical d.o.f. on top.
for i1=1:numel(DOFforceed)
    FR1(DOFforceed(i1),i1) = -Modulus;
end
V1 = FR1; % Take into account that integration is done only in S direction
V2 = M2*FR2; % Mass matrix by nodal value of the source. R.H.S. of Eq.(3.9)
%
% BOUNDARY CONDITIONS
%
CC = 1:2*(nenY); % Left side of the beam fixed.
%
% ENRICHMENT OF THE APPROXIMATION, LOOKING FOR R AND S
%
num_iter = 0; iter = zeros(1); Aprt = 0; Error_iter = 1.0;
while Error_iter>TOL && num_iter<num_max_iter
    num_iter = num_iter + 1; 
    S0 = rand(numel(force),1); % Initial guess for S.
    %
    % ENRICHMENT STEP
    %
    [R,S,iter(num_iter)] = enrichment(K1,M2,V1,V2,S0,F,G,num_iter,TOL,CC);
    F(:,num_iter) = R; G(:,num_iter) = S; % R and S are valid, new summand.
    %
    % STOPPING CRITERION
    %
    Error_iter = norm(F(:,num_iter)*G(:,num_iter)');
    Aprt = max(Aprt,sqrt(Error_iter));
    Error_iter = sqrt(Error_iter)/Aprt;
    fprintf(1,'%dst summand in %d iterations with a weight of %f\n',...
        num_iter,iter(num_iter),Error_iter);
end
num_iter = num_iter - 1; % The last sum was negligible, we discard it.
fprintf(1,'PGD off-line Process exited normally\n\n');
save('WorkSpacePGD_Parametricedforce.mat');
%
% POST-PROCESSING
%
fprintf(1,'Please select force position');
fprintf(1,'on the figure or pick out of the beam to exit');
h1 = figure(1); triplot(triangles); 
axis equal;
[Cx,Cy] = ginput(1); % Waiting for a mouse click on the figure.
lim = 0.2/(Xf-X0); % Establishes an exit zone on the figure.
while X0-lim<=Cx && Cx<=Xf+lim && Y0-lim<=Cy && Cy<=Yf+lim 
    h1 = figure(1); triplot(triangles);
    axis equal;
    Posforce = find(force<Cx,1,'last'); % Look for the closest 'forceed'node.
    %
    % EVALUATING THE SOLUTION CHOOSING THE PICKED NODE IN G VECTOR
    %
    desp = zeros(numel(coords),1);
    for i1=1:num_iter
        desp = desp + F(:,i1).*G(Posforce,i1); % Obtain the solution
    end
    %
    % PLOTTING THE SOLUTION
    %
    cdx = coords(:,1) + desp(1:2:end); % New X coordinates.
    cdy = coords(:,2) + desp(2:2:end); % New Y coordinates.    
    trisurf(triangles.ConnectivityList,cdx,cdy,desp(2:2:end));
    title('Vertical Displacement'); view(2); colorbar;
    figure(1); axis equal; [Cx,Cy] = ginput(1); % Wait for a new force.
    
end
fprintf(1,'\n\n########## End of simulation ##########\n\n');
