@@ -547,6 +547,10 @@ void fix_field_phase(void)
547547/* Functions to return epsilon, fields, energies, etcetera, at a specified
548548 point, linearly interpolating if necessary. */
549549
550+ /* get_val returns process-specific output for HAVE_MPI: if the "point" (ix, iy, iz; stride)
551+ is on the local process, the value of data at that point is returned returned; otherwise
552+ (i.e. point is not on local process) 0.0 is returned: calls to get_val should therefore
553+ be followed by sum-reduction via mpi_allreduce_1(..) in the caller (as in interp_val) */
550554static real get_val (int ix , int iy , int iz ,
551555 int nx , int ny , int nz , int last_dim_size ,
552556 real * data , int stride , int conjugate )
@@ -569,20 +573,33 @@ static real get_val(int ix, int iy, int iz,
569573#endif
570574
571575#ifdef HAVE_MPI
572- CHECK (0 , "get-*-point not yet implemented for MPI!" );
573- #else
574- if (conjugate )
575- return - data [(((ix * ny ) + iy ) * nz + iz ) * stride ];
576- else
577- return data [(((ix * ny ) + iy ) * nz + iz ) * stride ];
576+ /* due to real-space xy=>yx transposition in MPI configuration, we need to
577+ do a little extra work here; see details e.g. in XYZ_LOOP macro */
578+ int local_ny = mdata -> local_ny ; /* dim of local process over y-indices */
579+ int local_y_start = mdata -> local_y_start ;
580+ int local_iy = iy - local_y_start ;
581+ real val = 0 ; /* reduce local processes over this variable later */
582+
583+ /* check if local_iy is in the current process' data block */
584+ if (local_iy >= 0 && local_iy < local_ny ) {
585+ val = data [(((local_iy * nx ) + ix ) * nz + iz ) * stride ]; /* note transposition in x and y indices */
586+ }
587+
588+ #else /* no MPI */
589+ real val = data [(((ix * ny ) + iy ) * nz + iz ) * stride ];
578590#endif
591+
592+ if (conjugate )
593+ return - val ;
594+ else
595+ return val ;
579596}
580597
581598static real interp_val (vector3 p , int nx , int ny , int nz , int last_dim_size ,
582599 real * data , int stride , int conjugate )
583600{
584601 double ipart ;
585- real rx , ry , rz , dx , dy , dz ;
602+ real rx , ry , rz , dx , dy , dz , v ;
586603 int x , y , z , x2 , y2 , z2 ;
587604
588605 rx = modf (p .x /geometry_lattice .size .x + 0.5 , & ipart ); if (rx < 0 ) rx += 1 ;
@@ -611,10 +628,13 @@ static real interp_val(vector3 p, int nx, int ny, int nz, int last_dim_size,
611628
612629#define D (x ,y ,z ) (get_val(x,y,z,nx,ny,nz,last_dim_size, data,stride,conjugate))
613630
614- return (((D (x ,y ,z )* (1.0 - dx ) + D (x2 ,y ,z )* dx ) * (1.0 - dy ) +
615- (D (x ,y2 ,z )* (1.0 - dx ) + D (x2 ,y2 ,z )* dx ) * dy ) * (1.0 - dz ) +
616- ((D (x ,y ,z2 )* (1.0 - dx ) + D (x2 ,y ,z2 )* dx ) * (1.0 - dy ) +
617- (D (x ,y2 ,z2 )* (1.0 - dx ) + D (x2 ,y2 ,z2 )* dx ) * dy ) * dz );
631+ v = (((D (x ,y ,z ) * (1.0 - dx ) + D (x2 ,y ,z ) * dx ) * (1.0 - dy ) +
632+ (D (x ,y2 ,z ) * (1.0 - dx ) + D (x2 ,y2 ,z ) * dx ) * dy ) * (1.0 - dz ) +
633+ ((D (x ,y ,z2 ) * (1.0 - dx ) + D (x2 ,y ,z2 ) * dx ) * (1.0 - dy ) +
634+ (D (x ,y2 ,z2 ) * (1.0 - dx ) + D (x2 ,y2 ,z2 ) * dx ) * dy ) * dz );
635+
636+ mpi_allreduce_1 (& v , real , SCALAR_MPI_TYPE , MPI_SUM , mpb_comm );
637+ return v ;
618638
619639#undef D
620640}
0 commit comments