!+ ! Subroutine bmad_create_element (ix_lat, c_ele, has_twiss, file_name, c_err) ! ! Lattice creation routine to add a non-bend element to the lattice. ! Use bmad_create_bend for creating bends. ! ! If file_name is blank, the element prototype is given by c_ele. ! ! If file_name is not blank, The element prototype is read in from the file. ! In this case, the following properties from c_ele are used: ! c_ele.name ! c_ele.s ! ! Input: ! ix_lat -- Integer: Index of lattice to place the element in. ! has_twiss -- Integer: Has twiss paramters ! file_name -- Character(200): If not blank, name of file which defines the element. ! ! Output: ! c_err -- C_logical: Set True if there is an error. False otherwise. !- subroutine bmad_create_element (ix_lat, c_ele, has_twiss, file_name, c_err) use bmad_common_mod use superimpose_mod implicit none type (c_ptr), value :: c_ele type (ele_struct), target :: ele type (ele_struct), pointer :: super_ele, ele2 type (lat_struct), pointer :: lat, lat2 type (bmad_doocs_common_struct), save, target :: lat_save(20) integer i, has_twiss, ix_lat logical(c_bool) c_err integer stat_b(24), stat, ierr logical err_flag, does_exist, parsing_needed, err character(1) file_name(*) character(200) f_name character(20), parameter :: r_name = 'bmad_create_element' ! c_err = c_logic(.true.) call ele_to_f(c_ele, c_loc(ele)) if (lat_status(ix_lat) /= in_init$) then call out_io (s_error$, r_name, & 'Element creation attempted outside of init stage for lat \i0\ for element: ' // & trim(ele%name), ix_lat) call deallocate_ele_pointers (ele) return endif lat => bd_com(ix_lat)%lat lat%param%bookkeeping_state%s_position = stale$ call s_calc(lat) if (isnan(ele%s)) then call out_io (s_error$, r_name, 'Bad ele%s input.') call bmad_remove_lat(ix_lat) return end if ! Read in the element from a file. call remove_null_in_string (file_name, f_name) if (f_name /= '') then inquire (file = f_name, exist = does_exist) if (.not. does_exist) then call out_io (s_error$, r_name, 'FILE DOES NOT EXIST: ' // f_name) return endif ierr = stat(f_name, stat_b) ! Find a free lat parsing_needed = .false. do i = 1, size(lat_save) lat2 => lat_save(i)%lat if (lat2%input_file_name == f_name) exit enddo ! Found a match. Now look at the creation date if (i <= size(lat_save)) then if (stat_b(10) /= lat_save(i)%status) then call deallocate_lat_pointers (lat2) parsing_needed = .true. endif ! Else look for an empty slot. If there is none just use the last one. else do i = 1, size(lat_save) lat2 => lat_save(i)%lat if (lat_save(i)%status == no_init$) exit if (i == size(lat_save)) then call deallocate_lat_pointers (lat2) exit endif enddo parsing_needed = .true. endif ! parse if (parsing_needed) then call bmad_parser (f_name, lat2, make_mats6 = .false., err_flag = err) if (err) then return endif lat2%input_file_name = f_name lat_save(i)%status = stat_b(10) endif ! Now transfer the info to ele ele2 => lat2%ele(1) ele2%name = ele%name ele2%s = ele%s ele2%value = ele%value ele = ele2 endif ! Error check: if (ele%key == marker$ .and. ele%value(l$) /= 0) then call out_io (s_error$, r_name, 'Marker does not have zero length: ' // ele%name) return endif ! E_gun uses ele%value(scratch1$) for grid offset. if (ele%key == e_gun$ .and. associated(ele%grid_field)) then ele%grid_field(1)%r0(2) = -ele%value(scratch1$) endif ! Now superimpose element on the lattice call add_superimpose (lat, ele, 0, err_flag, super_ele) if (err_flag) then return endif if (f_logic(has_twiss)) super_ele%logic = .true. call deallocate_ele_pointers (ele) c_err = c_logic(.false.) end subroutine