Worker for distributed Hessian calculation Requests displacement indices, computes gradients, and sends results back
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(comm_t), | intent(in) | :: | world_comm | |||
| type(system_geometry_t), | intent(in) | :: | sys_geom | |||
| type(driver_config_t), | intent(in) | :: | config |
Driver configuration |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | atom_idx | ||||
| class(qc_method_t), | private, | allocatable | :: | calculator |
Polymorphic calculator |
||
| integer, | private | :: | coord | ||||
| integer, | private | :: | disp_idx | ||||
| type(physical_fragment_t), | private | :: | displaced_geom | ||||
| integer, | private | :: | dummy_msg | ||||
| type(physical_fragment_t), | private | :: | full_system | ||||
| type(calculation_result_t), | private | :: | grad_result | ||||
| integer, | private | :: | gradient_type | ||||
| type(method_config_t), | private | :: | local_config |
Local copy for verbose override |
|||
| integer, | private | :: | n_atoms | ||||
| type(request_t), | private | :: | req | ||||
| type(MPI_Status), | private | :: | status |
module subroutine hessian_worker(world_comm, sys_geom, config) !! Worker for distributed Hessian calculation !! Requests displacement indices, computes gradients, and sends results back use mqc_finite_differences, only: copy_and_displace_geometry use mqc_method_base, only: qc_method_t use mqc_method_factory, only: create_method type(comm_t), intent(in) :: world_comm type(system_geometry_t), intent(in) :: sys_geom type(driver_config_t), intent(in) :: config !! Driver configuration type(physical_fragment_t) :: full_system, displaced_geom type(calculation_result_t) :: grad_result integer :: n_atoms, disp_idx, atom_idx, coord, gradient_type, dummy_msg type(MPI_Status) :: status type(request_t) :: req class(qc_method_t), allocatable :: calculator !! Polymorphic calculator type(method_config_t) :: local_config !! Local copy for verbose override n_atoms = sys_geom%total_atoms ! Build full system geometry full_system%n_atoms = n_atoms full_system%n_caps = 0 allocate (full_system%element_numbers(n_atoms)) allocate (full_system%coordinates(3, n_atoms)) full_system%element_numbers = sys_geom%element_numbers full_system%coordinates = sys_geom%coordinates full_system%charge = sys_geom%charge full_system%multiplicity = sys_geom%multiplicity call full_system%compute_nelec() ! Create calculator using factory local_config = config%method_config local_config%verbose = .false. calculator = create_method(local_config) dummy_msg = 0 do ! Request work from coordinator call isend(world_comm, dummy_msg, 0, TAG_WORKER_REQUEST, req) call wait(req) call irecv(world_comm, disp_idx, 0, MPI_ANY_TAG, req) call wait(req, status) if (status%MPI_TAG == TAG_WORKER_FINISH) exit ! Compute displacement index to atom and coordinate atom_idx = (disp_idx - 1)/3 + 1 coord = mod(disp_idx - 1, 3) + 1 ! Compute FORWARD gradient call copy_and_displace_geometry(full_system, atom_idx, coord, config%hessian%displacement, displaced_geom) call calculator%calc_gradient(displaced_geom, grad_result) if (grad_result%has_error) then call logger%error("Worker gradient calculation error for forward displacement "// & to_char(disp_idx)//": "//grad_result%error%get_message()) call abort_comm(world_comm, 1) end if if (.not. grad_result%has_gradient) then call logger%error("Worker failed gradient for forward displacement "//to_char(disp_idx)) call abort_comm(world_comm, 1) end if ! Send: displacement index, gradient type (1=forward), gradient data, dipole flag, dipole gradient_type = 1 call isend(world_comm, disp_idx, 0, TAG_WORKER_SCALAR_RESULT, req) call wait(req) call isend(world_comm, gradient_type, 0, TAG_WORKER_SCALAR_RESULT, req) call wait(req) call send(world_comm, grad_result%gradient, 0, TAG_WORKER_SCALAR_RESULT) call send(world_comm, grad_result%has_dipole, 0, TAG_WORKER_SCALAR_RESULT) if (grad_result%has_dipole) then call send(world_comm, grad_result%dipole, 0, TAG_WORKER_SCALAR_RESULT) end if call grad_result%destroy() call displaced_geom%destroy() ! Compute BACKWARD gradient call copy_and_displace_geometry(full_system, atom_idx, coord, -config%hessian%displacement, displaced_geom) call calculator%calc_gradient(displaced_geom, grad_result) if (grad_result%has_error) then call logger%error("Worker gradient calculation error for backward displacement "// & to_char(disp_idx)//": "//grad_result%error%get_message()) call abort_comm(world_comm, 1) end if if (.not. grad_result%has_gradient) then call logger%error("Worker failed gradient for backward displacement "//to_char(disp_idx)) call abort_comm(world_comm, 1) end if ! Send: displacement index, gradient type (2=backward), gradient data, dipole flag, dipole gradient_type = 2 call isend(world_comm, disp_idx, 0, TAG_WORKER_SCALAR_RESULT, req) call wait(req) call isend(world_comm, gradient_type, 0, TAG_WORKER_SCALAR_RESULT, req) call wait(req) call send(world_comm, grad_result%gradient, 0, TAG_WORKER_SCALAR_RESULT) call send(world_comm, grad_result%has_dipole, 0, TAG_WORKER_SCALAR_RESULT) if (grad_result%has_dipole) then call send(world_comm, grad_result%dipole, 0, TAG_WORKER_SCALAR_RESULT) end if call grad_result%destroy() call displaced_geom%destroy() end do ! Cleanup deallocate (calculator) end subroutine hessian_worker