%**************************************************************************
%ppm_und_sim_block_init
%This file initializes the simulation program.
%
%Input:
%param, parameter structure
%
%Output:
%block, structure containing permanent magnet block information
%
%Zachary Wolf, 3/31/08

function [block] = ppm_und_sim_block_init(param)

%Global
global mu_0;

%Undulator parameters
und_gap = param.und_gap;
period = param.period;
num_ctr_period = param.num_ctr_period;
br = param.br;
block_x_width = param.block_x_width;
block_y_width = param.block_y_width;
block_z_width = param.block_z_width;
block_z_space = param.block_z_space;
block_end_mag_1_z_width = param.block_end_mag_1_z_width;
block_end_space_2_z_width = param.block_end_space_2_z_width;
block_end_mag_2_z_width = param.block_end_mag_2_z_width;
block_end_space_3_z_width = param.block_end_space_3_z_width;
block_end_mag_3_z_width = param.block_end_mag_3_z_width;

%Initialization
num_block = 0;

%Entrance end -----

%Set the undulator entrance end start z position
z_und_enter_start = 0;

%Upper block #1
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = -br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_1_z_width;

%Lower block #1
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = -br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_1_z_width;

%Upper block #2
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = -br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width + block_end_space_2_z_width + block_end_mag_2_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_2_z_width;

%Lower block #2
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width + block_end_space_2_z_width + block_end_mag_2_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_2_z_width;

%Upper block #3
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width + block_end_space_2_z_width + block_end_mag_2_z_width + block_end_space_3_z_width + block_end_mag_3_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_3_z_width;

%Lower block #3
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_enter_start + block_end_mag_1_z_width + block_end_space_2_z_width + block_end_mag_2_z_width + block_end_space_3_z_width + block_end_mag_3_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_3_z_width;

%Undulator center -----
%After the center there is an extra block, treat it later

%Set the undulator center start z position
z_und_ctr_start = block.z_center(num_block) + block_end_mag_3_z_width / 2 + block_z_space;

%Loop over the undulator center blocks
for iperiod = 1 : num_ctr_period
    
    %Note that the period length includes the spacer after the fourth block in the period

    %Upper block #1 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = 0;
    block.mz(num_block) = br / mu_0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Lower block #1 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = 0;
    block.mz(num_block) = -br / mu_0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Upper block #2 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = -br / mu_0;
    block.mz(num_block) = 0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + block_z_width + block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Lower block #2 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = -br / mu_0;
    block.mz(num_block) = 0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + block_z_width + block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Upper block #3 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = 0;
    block.mz(num_block) = -br / mu_0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + 2 * block_z_width + 2 * block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Lower block #3 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = 0;
    block.mz(num_block) = br / mu_0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + 2 * block_z_width + 2 * block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Upper block #4 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = br / mu_0;
    block.mz(num_block) = 0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + 3 * block_z_width + 3 * block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;

    %Lower block #4 in period
    num_block = num_block + 1;
    block.mx(num_block) = 0;  %(T/Tm/A = A/m)
    block.my(num_block) = br / mu_0;
    block.mz(num_block) = 0;
    block.x_center(num_block) = 0;
    block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
    block.z_center(num_block) = z_und_ctr_start + block_z_width / 2 + 3 * block_z_width + 3 * block_z_space + (iperiod - 1) * period;
    block.x_width(num_block) = block_x_width;
    block.y_width(num_block) = block_y_width;
    block.z_width(num_block) = block_z_width;
    
%End loop over undulator center
end

%Extra block after undulator center -----

%Set the start z position
z_und_ctr_start = block.z_center(num_block) + block_z_width / 2 + block_z_space;

%Upper block #1 in period
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_ctr_start + block_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_z_width;

%Lower block #1 in period
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = -br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_ctr_start + block_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_z_width;

%Exit end -----

%Set the undulator exit end start z position
z_und_exit_start = block.z_center(num_block) + block_z_width / 2 + block_z_space;

%Upper block #3
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = -br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_3_z_width;

%Lower block #3
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = - br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_3_z_width;

%Upper block #2
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = - br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width + block_end_space_3_z_width + block_end_mag_2_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_2_z_width;

%Lower block #2
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = 0;
block.mz(num_block) = br / mu_0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width + block_end_space_3_z_width + block_end_mag_2_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_2_z_width;

%Upper block #1
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = und_gap / 2 + block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width + block_end_space_3_z_width + block_end_mag_2_z_width + block_end_space_2_z_width + block_end_mag_1_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_1_z_width;

%Lower block #1
num_block = num_block + 1;
block.mx(num_block) = 0;  %(T/Tm/A = A/m)
block.my(num_block) = br / mu_0;
block.mz(num_block) = 0;
block.x_center(num_block) = 0;
block.y_center(num_block) = - und_gap / 2 - block_y_width / 2;
block.z_center(num_block) = z_und_exit_start + block_end_mag_3_z_width + block_end_space_3_z_width + block_end_mag_2_z_width + block_end_space_2_z_width + block_end_mag_1_z_width / 2;
block.x_width(num_block) = block_x_width;
block.y_width(num_block) = block_y_width;
block.z_width(num_block) = block_end_mag_1_z_width;

%Add the number of blocks to the structure
block.num_block = num_block;

%Done
