%**************************************************************************
%ppm_und_sim
%This program simulates the magnetic field in a pure permanent magnet
%undulator.  Magnet block parameters are entered.  Equivalent charges are
%calculated to replace the magnet blocks.  The field from each charge is
%calculated and added to the field from the other charges.
%
%The following structures are used.
%
%param, structure containing program parameters
%   output_file_dir %Directory for output files
%   num_block_xdiv  %Number of divisions in x for charge calculation
%   num_block_ydiv  %Number of divisions in y for charge calculation
%   num_block_zdiv  %Number of divisions in z for charge calculation
%   und_gap         %Undulator gap height (m)
%   period          %Undulator period (m)
%   num_ctr_period  %Number of periods in the undulator, excluding the ends
%   br              %Permanent magnet remnant field (T)
%   block_x_width   %Magnet block width in x direction (m)
%   block_y_width   %Magnet block width in y direction (m)
%   block_z_width   %Magnet block width in z direction (m)
%   block_end_mag_1_z_width 	%Width of end magnet block (m)
%   block_end_space_2_z_width	%Width of space between 1 and 2 end blocks (m)
%   block_end_mag_2_z_width 	%Width of block second from the end (m)
%   block_end_space_3_z_width	%Width of space between 2 and 3 end blocks (m)
%   block_end_mag_3_z_width     %Width of block third from the end (m)
%   x_field_pts     %X positions where field is calculated (m)
%   y_field_pts     %Y positions where field is calculated (m)
%   z_field_pts     %Z positions where field is calculated (m)
%
%block, structure containing the permanent magnet block information
%   num_block       %Number of blocks
%   mx              %X component of the magnetic moment density (A/m)
%   my              %Y component of the magnetic moment density (A/m)
%   mz              %Z component of the magnetic moment density (A/m)
%   x_center        %X position of the block center (m)
%   y_center        %Y position of the block center (m)
%   z_center        %Z position of the block center (m)
%   x_width         %Block width in the x direction (m)
%   y_width         %Block width in the y direction (m)
%   z_width         %Block width in the z direction (m)
%
%charge, structure containing the charge information
%   num_charge      %Number of charges
%   q               %Magnetic charge, M.n dA (Am)
%   x               %X position of charge (m)
%   y               %Y position of charge (m)
%   z               %Z position of charge (m)
%   block_num       %Block number the charge came from
%
%field_pos, structure giving the positions at which to calculate the field
%   x               %X position of the field point (m)
%   y               %Y position of the field point (m)
%   z               %Z position of the field point (m)
%
%mag_field, structure containing the calculated magnetic field
%   x               %X position of the field point (m)
%   y               %Y position of the field point (m)
%   z               %Z position of the field point (m)
%   bx              %Bx magnetic field component at (x, y, z) (T)
%   by              %By magnetic field component at (x, y, z) (T)
%   bz              %Bz magnetic field component at (x, y, z) (T)
%
%Zachary Wolf, 3/31/08

%Clear all variables
clear;

%Set the working directory
cd('c:\Simulation\PPM Und Sim');

%Global
global mu_0;
mu_0 = 4 * pi * 10^-7;  %(Tm/A)

%Program parameters
[param] = ppm_und_sim_get_param();

%Initialize output files
[dat_file, plt_file] = ppm_und_sim_file_init(param);

%Initialize the permanent magnet blocks
disp('Initializing blocks...');
[block] = ppm_und_sim_block_init(param);

%Move blocks 29 and 30, get slope sensitivity, V blocks
%block.y_center(29) = block.y_center(29) + -100.e-6;
%block.y_center(30) = block.y_center(30) - -100.e-6;

%Shift blocks 29 and 30 horizontally, produce Bx, V blocks
block.x_center(29) = block.x_center(29) + 1.e-3;
block.x_center(30) = block.x_center(30) + 1.e-3;

%Calculate charges on blocks
disp('Calculating charges...');
[charge] = ppm_calc_charge(param, block);

%Rotate block 29
% index_array = find(charge.block_num == 29);
% r_charge.num_charge = charge.num_charge;
% r_charge.q = charge.q(index_array);
% r_charge.x = charge.x(index_array);
% r_charge.y = charge.y(index_array);
% r_charge.z = charge.z(index_array);
% r_charge.block_num = charge.block_num(index_array);
% [rotz_charge] = ppm_calc_rotz_charge(r_charge, block.x_center(29), block.y_center(29) - block.y_width(29) / 2, .001);
% charge.q(index_array) = rotz_charge.q;
% charge.x(index_array) = rotz_charge.x;
% charge.y(index_array) = rotz_charge.y;
% charge.z(index_array) = rotz_charge.z;
% charge.block_num(index_array) = rotz_charge.block_num;

%Rotate block 30
% index_array = find(charge.block_num == 30);
% r_charge.num_charge = charge.num_charge;
% r_charge.q = charge.q(index_array);
% r_charge.x = charge.x(index_array);
% r_charge.y = charge.y(index_array);
% r_charge.z = charge.z(index_array);
% r_charge.block_num = charge.block_num(index_array);
% %[rotz_charge] = ppm_calc_rotz_charge(r_charge, block.x_center(30), block.y_center(30) + block.y_width(30) / 2, .001);  %for Bx
% [rotz_charge] = ppm_calc_rotz_charge(r_charge, block.x_center(30), block.y_center(30) + block.y_width(30) / 2, -.001);  %for cant angle
% charge.q(index_array) = rotz_charge.q;
% charge.x(index_array) = rotz_charge.x;
% charge.y(index_array) = rotz_charge.y;
% charge.z(index_array) = rotz_charge.z;
% charge.block_num(index_array) = rotz_charge.block_num;

%Calculate fields from the charges
disp('Calculating fields...');
[mag_field] = ppm_calc_mag_field(param, charge);

%Plot the field
ppm_plot_block_charge_yz(plt_file, block, charge);
%ppm_plot_b_on_ctr_z_line(plt_file, block, charge, mag_field);
ppm_plot_b_on_z_line(plt_file, block, charge, mag_field, 0, 0);
%ppm_plot_b_on_x_slice(plt_file, block, charge, mag_field, 0);
ppm_plot_by_vs_z(plt_file, block, charge, mag_field, 0, 0);
%ppm_plot_bz_vs_z(plt_file, block, charge, mag_field, 0, .005);
ppm_plot_bx_vs_z(plt_file, block, charge, mag_field, 0, 0);
%ppm_plot_bx_vs_x(plt_file, block, charge, mag_field, 0, block.z_center(39));
%ppm_plot_by_vs_x(plt_file, block, charge, mag_field, 0, block.z_center(39));

%Write the results to a data file
%ppm_dat_byx_vs_z(dat_file, mag_field, 0, 0);
ppm_dat_byx_vs_z(dat_file, mag_field, .001, 0);

%Output the results to the output file directory
mat_file = strcat(lower(param.output_file_dir), 'ppm_und_sim.mat');
save(mat_file, 'param', 'block', 'charge', 'mag_field');

%Done
disp('Done');
