function Heat_Conduction_T3_XY (nbc, mixed)
%..................................................................
% Planar heat conduction with internal source, T3 triangle
%             XY COORDINATES CLOSED FORM INTEGRALS
%..................................................................
if ( nargin == 1 )     ;  % check for optional BC flags
  mixed = 0            ;  % default to no mixed (Robin) BC
elseif ( nargin == 0 ) ; 
  mixed = 0 ; nbc = 0  ;  % default to no mixed or Neumann BC
end % if from argument count
if ( mixed > 0 )       ;  % not done yet
  error('Sorry, mixed bc data not yet installed')
end % if lazy author

%            Set given constants 
n_g = 1                 ;  % number of DOF per node
n_n = 3                 ;  % number of nodes per element
n_i = n_n*n_g           ;  % number of DOF per element

% MODEL input file controls (for various data generators)
pre_e = 0 ; % Dummy items before el_type & connectivity
pre_p = 0 ; % Dummy items before BC_flag % coordinates

%       READ MESH AND EBC INPUT DATA
% specific problem data from MODEL data files (sequential)
load msh_bc_xyz.tmp       ; % bc_flag, x_coord, y_coord 
n_m = size (msh_bc_xyz,1) ; % number of nodal points in mesh
n_d = n_g*n_m             ; % system degrees of freedom (DOF)
if ( n_m == 0 )           ; % data missing !
  error ('Error missing file msh_bc_xyz.tmp')
end % if error
fprintf ('Read %g mesh coordinate pairs \n', n_m)
P = msh_bc_xyz (1:n_m, (pre_p+1)) ; % extract integer Packed BC flag
x = msh_bc_xyz (1:n_m, (pre_p+2)) ; % extract x column 
y = msh_bc_xyz (1:n_m, (pre_p+3)) ; % extract y column 
 
load  msh_typ_nodes.tmp        ; % el_type, connectivity list (3)
n_e = size (msh_typ_nodes,1)   ; % number of elements
if ( n_e == 0 )                ; % data file missing
  error ('Error missing file msh_typ_nodes.tmp')
end % if error
nod_per_el = size (msh_typ_nodes,2) - pre_e - 1 ; % data checking 
fprintf ('Read %g elements with %g nodes each \n', n_e, nod_per_el)
if ( nod_per_el ~= n_n )
  error (['Mesh requires %g nodes per element. \n', n_n])
  %b error ('Mesh requires 3 nodes per element')
end % if
el_type = msh_typ_nodes(:, pre_e+1) ; % element type number >= 1
n_t     = max(el_type)              ; % number of element types

%       BOOKKEEPING FOR BC FLAGS AND VALUES
%   Allocate for BC flags and values
EBC_flag  = zeros(n_m, n_g) ;     NBC_flag  = zeros(n_m, n_g) ; 
EBC_value = zeros(n_m, n_g) ;     NBC_value = zeros(n_m, n_g) ;

%   Extract EBC flags from packed integer flag P 
if ( n_g == 1 )     % following is not general enough
  EBC_flag (1:n_m, 1) = P (1:n_m)          ; % insert first flag
else
  error('Current EBC limited to 1 DOF per node')
end % if more than 1 DOF packed into EBC flag.
EBC_count = sum( P == 1)      ; % number of EBC values expected
 
%  Read EBC values
if ( EBC_count > 0 )          ; % read EBC data
  load msh_ebc.tmp            ; % node, DOF, value (eq. number)
  n_c = size(msh_ebc, 1)      ; % number of constraints
  if ( EBC_count ~= n_c )     ; % probable user error
    fprintf ('WARNING: mismatch in bc_flag count & msh_ebc.tmp')
  end % if user error
  for j = 1:n_c                    ; % loop over ebc inputs
    node  = msh_ebc (j, 1)         ; DOF = msh_ebc (j, 2) ;
    value = msh_ebc (j, 3)         ; % EBC value   
    Eq    = n_g * (node - 1) + DOF ; % row in system matrix
    EBC_value (Eq) = value         ; % should check EBC_flag
  end % for each EBC
end % if any EBC data expected
 
%  Read Neumann point data
if ( nbc > 0 )                ; % read NBC data
  load msh_nbc.tmp            ; % node, DOF, value (eq. number)
  n_u = size(msh_nbc, 1)      ; % number of point sources
  if ( n_u < 1 )              ; % missing data
    error ('No nbc data in msh_nbc.tmp')
  end % if user error
  for j = 1:n_u                    ; % non-zero Neumann pts
    node  = msh_nbc (j, 1)         ; DOF = msh_nbc (j, 2) ;
    value = msh_nbc (j, 3)         ; % NBC value
    Eq    = n_g * (node - 1) + DOF ; % row in system matrix
    NBC_flag  (Eq) = 1             ; % set NBC_flag
    NBC_value (Eq) = value         ; % insert value          
  end % for each EBC
end % if any NBC data expected

%  Reorder and count BC flags and values                        
if ( n_g > 1 )
  EBC_flag  = reshape (EBC_flag',  n_d, 1)    ; % change to vector 
  NBC_flag  = reshape (NBC_flag',  n_d, 1)    ; % change to vector 
  EBC_value = reshape (EBC_value', n_d, 1)    ; % change to vector 
  NBC_value = reshape (NBC_value', n_d, 1)    ; % change to vector 
end % if

% Optional storage allocation for reaction recovery
EBC_count = sum(EBC_flag)                   ; % number of EBC's
NBC_count = sum(NBC_flag)                   ; % number of NBC's
EBC_row   = zeros(EBC_count, n_d) ; EBC_col = zeros(EBC_count, 1) ;
EBC_react = zeros(EBC_count, 1)             ; % reaction allocation

%          SET ELEMENT PROPERTIES and internal source
% Manually set constant element properties (Fig 11.9 text)
t   = 1.0                               ; % default thickness
Kx = 8. ; Ky = 8. ; Kxy = 0.            ; % thermal conductivity
E_e = zeros (2, 2)                      ; % constitutive matrix
E_e (1, 1) = Kx   ; E_e (1, 2) = Kxy    ; % non-zero term
E_e (2, 1) = Kxy  ; E_e (2, 2) = Ky     ; % non-zero term
has_source = 1                          ; % internal source on
Q_e = 6                                 ; % component

%    GENERATE ELEMENT MATRICES AND ASSYMBLE INTO SYSTEM
%         Assemble n_d by n_d square matrix terms
S_e = zeros (n_i, n_i) ; C_e = zeros (n_i, 1) ; % initalize values
S   = zeros (n_d, n_d) ; C   = zeros (n_d, 1) ; % initalize sums

for j = 1:n_e                              ; % loop over elements
  thick   = t * el_type (j)                ; % integer multiple 
  e_nodes = msh_typ_nodes (j, (pre_e+2):(pre_e+4)); % connectivity
  
%  define nodal coordinates, ccw: i, j, k
  x_e = x(e_nodes) ; y_e = y(e_nodes)        ; % coord at el nodes
  x_i = x_e(1) ; x_j = x_e(2) ; x_k = x_e(3) ; % change notation
  y_i = y_e(1) ; y_j = y_e(2) ; y_k = y_e(3) ; % change notation

%  define centroid coordinates (quadrature point)
  x_cg = (x_i + x_j + x_k)/3 ;  y_cg = (y_i + y_j + y_k)/3 ;

%  geometric parameters: H_i (x,y) = (a_i + b_i*x + c_i*y)/two_a
  a_i = x_j * y_k - x_k * y_j ; b_i = y_j - y_k ; c_i = x_k - x_j ;
  a_j = x_k * y_i - x_i * y_k ; b_j = y_k - y_i ; c_j = x_i - x_k ;
  a_k = x_i * y_j - x_j * y_i ; b_k = y_i - y_j ; c_k = x_j - x_i ;

%  calculate twice element area
  two_a = a_i + a_j + a_k            ; % = b_j*c_k - b_k*c_j also

%  define 2 by 3 gradient matrix, B_e
  B_e (1, 1:3) = [ b_i,  b_j,  b_k ] / two_a ;
  B_e (2, 1:3) = [ c_i,  c_j,  c_k ] / two_a ;

%          ELEMENT MATRICES 
%  stiffness matrix, with constant jacobian 
  S_e = ( B_e' * E_e * B_e ) * thick * two_a / 2  ; % conduction

%  internal heat generation unit volume, Q_e
  if ( has_source ) % then form forcing vector            
    X_x = Q_e * thick * two_a / 6.0   ; %  resultant
    C_e (1:3) = [ X_x, X_x, X_x ]     ; % vector result 
  end % if or set up properties for body force

%         SCATTER TO SYSTEM ARRAYS
% Insert completed element matrices into system matrices
  rows (1:3) = n_g*(e_nodes(1:3) - 1) + 1 ; % element DOF numbers
  S (rows, rows) = S (rows, rows) + S_e   ; % add to system sq
  C (rows) = C (rows) + C_e               ; % add to sys column
end % for each j element in mesh

%         INSERT EBC AND NBC (if any)
kount = 0                                 ; % initialize counter
for j = 1:n_d       % check all DOF for displacement BC or pt force
  if ( NBC_flag(j) )                      ; % then NBC here
    C (j) = C (j) + NBC_value (j)         ; % add force value
  end % if NBC for this DOF

%         ENFORCE ESSENTIAL BOUNDARY CONDITIONS
  if ( EBC_flag(j) )                         % then EBC here
    if ( EBC_flag(j) == NBC_flag(j) )        % warning both here
      fprintf ('Usually an error: EBC and NBC at same DOF \n')
    end % if fatal BC data

%   Save reaction data to be destroyed by EBC solver trick
    kount = kount + 1                      ; % copy counter
    EBC_row(kount, 1:n_d) = S (j, 1:n_d)   ; % copy reaction data
    EBC_col(kount)        = C (j)          ; % copy reaction data

%   Insert EBC identity to avoid matrix partition accounting
    EBC = EBC_value(j)                ; % recover EBC value
    C (:) = C (:) - EBC * S (:, j)    ; % carry known column to RHS
    S (:, j) = 0 ; S (j, :) = 0       ; % clear, restore symmetry
    S (j, j) = 1 ; C (j) = EBC        ; % insert identity into row
  end % if EBC for this DOF
end % for over all j-th DOF

%             DISPLACEMENT SOLUTION & SAVE
T = S \ C                                ; % Compute displacements
fprintf ('\n')                             ; % blank
fprintf('Temperature at %g nodes \n', n_m) ; % header
if ( n_g > 1 )
  disp (reshape(T, n_g, n_m)')               % to look pretty
end % if
% save results (displacements) to MODEL file: node_results.tmp
fid = fopen('node_results.tmp', 'w')       ; % open for writing
for j = 1:n_g:n_d                          ; % save displacements
  fprintf ( fid, '%g \n', T (j))           ; % print
  fprintf (' %g %g \n', j, T (j))          ; % sequential save
end % for j DOF

%                REACTION RECOVERY & SAVE
if ( EBC_count > 0 )                    ; % reactions exist ?
  EBC_react = EBC_row * T - EBC_col     ; % matrix reactions (+-)
  % save reactions (forces) to MODEL file: node_reaction.tmp
  fprintf ('\n')                        ; % Skip a line
  fprintf ('Node, DOF, Value, Eq. for %g Heat Flow Reactions \n', ...
            EBC_count)                  ; % header
  fid = fopen('node_reaction.tmp', 'w') ; % open for writing
  kount = 0                             ; % initialize counter
  for j = 1:n_d                         ; % extract all EBC reactions
    if ( EBC_flag(j) )                      ; % then EBC here
  %   Output node_number, component_number, value, equation_number 
      kount = kount + 1                     ; % copy counter
      node  = ceil(j/n_g)                   ; % node at DOF j
      j_g   = j - (node - 1)*n_g            ; % 1 <= j_g <= n_g
      React = EBC_react (kount, 1)          ; % reaction value
      fprintf ( fid, '%g %g %g %g \n', node, j_g, React, j);% save
      fprintf ('%g %g %g %g \n', node, j_g, React, j);     % print
    end % if EBC for this DOF
  end % for over all j-th DOF
end % if EBC exist

%                 HEAT FLUX RECOVERY & SAVE
fid = fopen('el_qp_xyz_fluxes.tmp', 'w')    ; % open for writing
fprintf ('\n')                              ; % blank line
fprintf('Elem, X_qp, Y_qp, HeatFlux_x, HeatFlux_y \n');% header
for j = 1:n_e                              ; % loop over elements
  thick   = t * el_type (j)                ; % integer multiple 
  e_nodes = msh_typ_nodes (j, (pre_e+2):(pre_e+4)); % connectivity
  
%  define nodal coordinates, ccw: i, j, k
  x_e = x(e_nodes) ; y_e = y(e_nodes)        ; % coord at el nodes
  x_i = x_e(1) ; x_j = x_e(2) ; x_k = x_e(3) ; % change notation
  y_i = y_e(1) ; y_j = y_e(2) ; y_k = y_e(3) ; % change notation

%  geometric parameters: H_i (x,y) = (a_i + b_i*x + c_i*y)/two_a
  a_i = x_j * y_k - x_k * y_j ; b_i = y_j - y_k ; c_i = x_k - x_j ;
  a_j = x_k * y_i - x_i * y_k ; b_j = y_k - y_i ; c_j = x_i - x_k ;
  a_k = x_i * y_j - x_j * y_i ; b_k = y_i - y_j ; c_k = x_j - x_i ;

%  calculate twice element area
  two_a = a_i + a_j + a_k            ; % = b_j*c_k - b_k*c_j also

%          RECOVER B MATRIX & ITS LOCATION & ELEMENT DOF
%  define centroid coordinates (quadrature point)
  x_cg = (x_i + x_j + x_k)/3 ;  y_cg = (y_i + y_j + y_k)/3 ;

%  define 2 by 3 Gradient matrix, B_e
  B_e (1, 1:3) = [ b_i,  b_j,  b_k ] / two_a ;
  B_e (2, 1:3) = [ c_i,  c_j,  c_k ] / two_a ;

%  get DOF numbers for this element, gather solution
  rows (1:3) = n_g*(e_nodes(1:3) - 1) + 1 ; % element DOF numbers
  T_e = T (rows)                          ; % gather element DOF

%  COMPUTE GRADIENT & HEAT FLUX, SAVE LOCATION AND VALUES
  Strain = B_e * T_e                        ; % gradient vector
  Stress = E_e * Strain                     ; % heat flux vector
  fprintf (fid, '%g %g %g %g \n',  x_cg, y_cg, Stress(1:2));% save
  fprintf ('%g %g %g %g %g \n', j, x_cg, y_cg, Stress(1:2));% prt
end % for each j element in mesh

% End finite element calculations. 
% See /home/mech517/public_html/Matlab_Plots for graphic options
% http://www.owlnet.rice.edu/~mech517/help_plot.html for help

% end of Heat_Conduction_T3_XY            
