subroutine load_steerings (u, frac, load_golden) use cesrv_struct use cesrv_interface implicit none type (universe_struct), target :: u type (var_struct), pointer :: var integer, parameter :: MAX_CHANGE=4095 integer i, n, ix1, ix, jj integer dcu_dipole, dcu_horz(120), dcu_mag(120), cu_dipole integer cu0_csr_horz_cur(98), delt_csr_horz_cur(98), load_csr_horz_cur(98) integer cu0_csr_hbnd_cur(n_hbnd_maxx), delt_csr_hbnd_cur(n_hbnd_maxx), load_csr_hbnd_cur(n_hbnd_maxx) integer cu0_csr_vert_cur(98), delt_csr_vert_cur(98), load_csr_vert_cur(98) integer cu0_und_vert_cur(n_und_vert_maxx), delt_und_vert_cur(n_und_vert_maxx), load_und_vert_cur(n_und_vert_maxx) integer cu0_und_cntg_cur(1), delt_und_cntg_cur(1), load_und_cntg_cur(1) integer cu0_und_cntgtrim(1), delt_und_cntgtrim(1), load_und_cntgtrim(1) integer largest_change, steps real(rp) frac, merit, dE, part real(rp), save :: old_frac character(80) string logical, optional :: load_golden logical zero_all, limited, zero_hsep ! Golden orbit if (logic_option(.false., load_golden)) then if (all(u%var%cu_golden == 0)) then print *, 'YOU MUST DO "SAVE GOLDEN" BEFORE LOADING!' return endif do i = lbound(u%hsteer_kick%v, 1), ubound(u%hsteer_kick%v, 1) var => u%hsteer_kick%v(i) if (var%dvar_dcu == 0) cycle var%model = (var%cu_saved - var%cu_golden) * var%dvar_dcu + var%design enddo do i = lbound(u%vsteer_kick%v, 1), ubound(u%vsteer_kick%v, 1) var => u%vsteer_kick%v(i) if (var%dvar_dcu == 0) cycle var%model = (var%cu_saved - var%cu_golden) * var%dvar_dcu + var%design enddo endif ! check that we have resonable saved values if (all(u%hsteer_kick%v(:)%saved == 0) .and. & all(u%hsteer_kick%v(:)%saved == 0)) then print *, 'ERROR: ALL SAVED VALUES ARE 0!' print *, ' I CONCLUDE THAT YOU HAVE NOT READ IN DATA OR A CSR_SAVE_SET.' print *, ' NOTHING LOADED.' return endif ! check for steering out-of-range call limit_calc (limited) ! find cu values if (limited) then print *, 'ERROR: THE STEERING STRENGTH HAS SHIFTED BY THE LIMIT_CALC.' print *, ' NOTHING WILL BE DONE' return endif ! If model is still zeroed then we are continuing from the last load. ! If so then transfer old -> model. ! The exception is If we are trying to load after reading in a data set. ! In this case we are trying to restore the saved ! values and logic%use_old_in_loading = F zero_all = .true. do i = lbound(u%hsteer_kick%v, 1), ubound(u%hsteer_kick%v, 1) if (u%hsteer_kick%v(i)%good_var .and. u%hsteer_kick%v(i)%model /= 0) then zero_all = .false. exit endif enddo do i = lbound(u%vsteer_kick%v, 1), ubound(u%vsteer_kick%v, 1) if (u%vsteer_kick%v(i)%good_var .and. u%vsteer_kick%v(i)%model /= 0) then zero_all = .false. exit endif enddo zero_hsep = .true. do i = lbound(u%hsep_kick%v, 1), ubound(u%hsep_kick%v, 1) if (u%hsep_kick%v(i)%good_var .and. abs(u%hsep_kick%v(i)%model) > 1e-6) then zero_all = .false. zero_hsep = .false. exit endif enddo if (zero_all .and. logic%use_old_in_loading .and. .not. load_golden) then print *, 'Note: Looks like you are doing a second load...' print *, ' Reinstating model' call do_var_transfer (u%hsteer_kick, 1.0_rp, 'OLD', u, .false.) call do_var_transfer (u%vsteer_kick, 1.0_rp, 'OLD', u, .false.) call do_var_transfer (u%hsep_kick, 1.0_rp, 'OLD', u, .false.) else old_frac = 0 endif ! Query for load if (.not. logic%gui .and. .not. logic%auto_measurement) then call get_input_string ('Load steerings: Are you sure? :', string) call str_upcase (string, string) call string_trim(string, string, ix1) if (string(1:1) /= 'Y') then print *, 'NOTHING LOADED' return endif endif dE = 1000 * u%energy_data%d1%d(1)%model * (u%ring%ele(0)%value(E_TOT$) / 1e9) if (abs(dE) > 0.1_rp) then print *, 'The energy change is greater than 0.1 MeV !!!' if (.not. logic%auto_measurement) then call showit ('ENERGY', u) call get_input_string ('Load steerings? Are you VERY sure? : ', string) call str_upcase (string, string) call string_trim(string, string, ix1) if (ix1 == 0 .or. index('YES', string(1:ix1)) /= 1) then print *, 'NOTHING LOADED' return endif endif endif ! Calculate changes ! Remember: Separator saved values are from the voltage readbacks ! which are not completely accurate. ! Therefore we only load if there are changes to be made. call cu_target_calc (u%hsteer_kick%v, u, frac+old_frac) call cu_target_calc (u%vsteer_kick%v, u, frac+old_frac) call cu_target_calc (u%hsteer_kick%v, u, frac+old_frac) call cu_target_calc (u%vsteer_kick%v, u, frac+old_frac) do i = lbound(u%hsteer_kick%v, 1), ubound(u%hsteer_kick%v, 1) if (u%hsteer_kick%v(i)%good_var) then u%hsteer_kick%v(i)%old = u%hsteer_kick%v(i)%model u%hsteer_kick%v(i)%model = 0 call var_bookkeeper(u%hsteer_kick%v(i), u%ring, u%orb) endif enddo do i = lbound(u%vsteer_kick%v, 1), ubound(u%vsteer_kick%v, 1) if (u%vsteer_kick%v(i)%good_var) then u%vsteer_kick%v(i)%old = u%vsteer_kick%v(i)%model u%vsteer_kick%v(i)%model = 0 call var_bookkeeper(u%vsteer_kick%v(i), u%ring, u%orb) endif enddo if (.not. zero_hsep) then do i = lbound(u%hsep_kick%v, 1), ubound(u%hsep_kick%v, 1) if (u%hsep_kick%v(i)%good_var) then u%hsep_kick%v(i)%old = u%hsep_kick%v(i)%model u%hsep_kick%v(i)%model = 0 call var_bookkeeper(u%hsep_kick%v(i), u%ring, u%orb) endif enddo endif ! check for horizontal dipole too large wrt the dipole setting call vxgetn ('CSR BEND CUR', 1, 1, cu_dipole) call horz_dipole_limits (cu_dipole, u%hsteer_kick%v(1:120)%cu_target, & dcu_dipole, dcu_horz, dcu_mag) do i = 1, 120 if (u%hsteer_kick%v(i)%ix_ele == 0) cycle if (dcu_horz(i) > 0) then print *, 'UGH! Horizontal Steering wrong for hysteresis loop!' print *, ' For steering: ', u%hsteer_kick%v(i)%name print *, ' Setting steering to limit.' u%hsteer_kick%v(i)%model = u%hsteer_kick%v(i)%model + & 1.01 * dcu_horz(i) * u%hsteer_kick%v(i)%dvar_dcu u%hsteer_kick%v(i)%good_user = .false. endif enddo if (dcu_dipole > 0) then call set_var_useit (u) print *, 'NOTHING LOADED!' return endif ! load changes do i = 1, size(u%db%csr_horz_cur, 1) ix = u%db%csr_horz_cur(i)%ix_cesrv if (ix < 0) cycle u%db%csr_horz_cur(i)%cu_now = u%hsteer_kick%v(ix)%cu_target enddo do i = 1, size(u%db%csr_hbnd_cur, 1) ix = u%db%csr_hbnd_cur(i)%ix_cesrv if (ix < 0) cycle u%db%csr_hbnd_cur(i)%cu_now = u%hsteer_kick%v(ix)%cu_target enddo do i = 1, size(u%db%csr_vert_cur, 1) ix = u%db%csr_vert_cur(i)%ix_cesrv if (ix < 0) cycle u%db%csr_vert_cur(i)%cu_now = u%vsteer_kick%v(ix)%cu_target enddo do i = 1, size(u%db%und_vert_cur, 1) ix = u%db%und_vert_cur(i)%ix_cesrv if (ix < 0) cycle u%db%und_vert_cur(i)%cu_now = u%vsteer_kick%v(ix)%cu_target enddo do i = 1, size(u%db%und_cntg_cur, 1) ix = u%db%und_cntg_cur(i)%ix_cesrv if (ix < 0) cycle u%db%und_cntg_cur(i)%cu_now = u%vsteer_kick%v(ix)%cu_target enddo do i = 1, size(u%db%und_cntgtrim, 1) ix = u%db%und_cntgtrim(i)%ix_cesrv if (ix < 0) cycle u%db%und_cntgtrim(i)%cu_now = u%vsteer_kick%v(ix)%cu_target enddo if (.not. zero_hsep) then n = size(u%db%csr_hsp_volt, 1) do i = 1, n ix = u%db%csr_hsp_volt(i)%ix_cesrv if (ix < 0) cycle u%db%csr_hsp_volt(i)%cu_now = u%hsep_kick%v(ix)%cu_target enddo if (any(u%hsep_kick%v%old /= 0)) call vxputn ('CSR HSP VOLT', 1, n, u%db%csr_hsp_volt(:)%cu_now) print *, 'Note: Separator changes loaded.' endif ! get current values from database call vxgetn ('CSR HORZ CUR', 1, 98, cu0_csr_horz_cur) call vxgetn ('CSR HBND CUR', 1, n_hbnd_maxx, cu0_csr_hbnd_cur) call vxgetn ('CSR VERT CUR', 1, 98, cu0_csr_vert_cur) call vxgetn ('UND VERT CUR', 1, n_und_vert_maxx, cu0_und_vert_cur) call vxgetn ('UND CNTG CUR', 1, 1, cu0_und_cntg_cur) call vxgetn ('UND CNTGTRIM', 1, 1, cu0_und_cntgtrim) ! calculate total change delt_csr_horz_cur = u%db%csr_horz_cur(:)%cu_now - cu0_csr_horz_cur delt_csr_hbnd_cur = u%db%csr_hbnd_cur(:)%cu_now - cu0_csr_hbnd_cur delt_csr_vert_cur = u%db%csr_vert_cur(:)%cu_now - cu0_csr_vert_cur delt_und_vert_cur = u%db%und_vert_cur(:)%cu_now - cu0_und_vert_cur delt_und_cntg_cur = u%db%und_cntg_cur(:)%cu_now - cu0_und_cntg_cur delt_und_cntgtrim = u%db%und_cntgtrim(:)%cu_now - cu0_und_cntgtrim ! find largest change largest_change = 0 largest_change = max(maxval(abs(delt_csr_horz_cur)), largest_change) largest_change = max(maxval(abs(delt_csr_hbnd_cur)), largest_change) largest_change = max(maxval(abs(delt_csr_vert_cur)), largest_change) largest_change = max(maxval(abs(delt_und_vert_cur)), largest_change) largest_change = max(maxval(abs(delt_und_cntg_cur)), largest_change) largest_change = max(maxval(abs(delt_und_cntgtrim)), largest_change) steps = ceiling(float(largest_change) / MAX_CHANGE) ! make sure scaler values match commands call set_sca_to_cmd ! put in changes print *, 'NOTE: UND_VERT_CUR AND UND_CNTG CHANGES DISABLED UNTIL TESTING IS COMPLETE!' call vcmode ('shortd') do jj=1,steps part = float(jj) / steps load_csr_horz_cur = nint(cu0_csr_horz_cur + part*delt_csr_horz_cur) load_csr_hbnd_cur = nint(cu0_csr_hbnd_cur + part*delt_csr_hbnd_cur) load_csr_vert_cur = nint(cu0_csr_vert_cur + part*delt_csr_vert_cur) load_und_vert_cur = nint(cu0_und_vert_cur + part*delt_und_vert_cur) load_und_cntg_cur = nint(cu0_und_cntg_cur + part*delt_und_cntg_cur) load_und_cntgtrim = nint(cu0_und_cntgtrim + part*delt_und_cntgtrim) if (logic%debug) then print *, "Fake Loading: STEERINGS" else call vxputn ('CSR HORZ CUR', 1, size(u%db%csr_horz_cur, 1), load_csr_horz_cur) call vxputn ('CSR HBND CUR', 1, size(u%db%csr_hbnd_cur, 1), load_csr_hbnd_cur) call vxputn ('CSR VERT CUR', 1, size(u%db%csr_vert_cur, 1), load_csr_vert_cur) !!! call vxputn ('UND VERT CUR', 1, size(u%db%und_vert_cur, 1), load_und_vert_cur) !!! call vxputn ('UND CNTG CUR', 1, size(u%db%und_cntg_cur, 1), load_und_cntg_cur) !!! call vxputn ('UND CNTGTRIM', 1, size(u%db%und_cntgtrim, 1), load_und_cntgtrim) call vclogo endif enddo call vcfree ! vclogo does not unlock clock semaphore when done call vcmode ('') ! Put back to immediate mode. ! logic%use_old_in_loading = .true. call merit_calc(merit) !!call read_steerings (u) print '(a, f8.2)', 'Steerings loaded. Total fraction loaded:', frac+old_frac old_frac = frac + old_frac end subroutine