@@ -27,29 +27,52 @@ bool is_root()
2727
2828void bcast_double_vector (std::vector<double >& values)
2929{
30+ #ifdef __MPI
3031 if (!values.empty ())
3132 {
3233 Parallel_Common::bcast_double (values.data (), static_cast <int >(values.size ()));
3334 }
35+ #else
36+ (void )values;
37+ #endif
38+ }
39+
40+ void bcast_socket_int (int & value)
41+ {
42+ #ifdef __MPI
43+ Parallel_Common::bcast_int (value);
44+ #else
45+ (void )value;
46+ #endif
47+ }
48+
49+ void bcast_socket_chars (char * value, const int size)
50+ {
51+ #ifdef __MPI
52+ Parallel_Common::bcast_char (value, size);
53+ #else
54+ (void )value;
55+ (void )size;
56+ #endif
3457}
3558
3659void bcast_socket_string (std::string& value)
3760{
3861 int size = static_cast <int >(value.size ());
39- Parallel_Common::bcast_int (size);
62+ bcast_socket_int (size);
4063 if (!is_root ())
4164 {
4265 value.resize (static_cast <std::size_t >(size));
4366 }
4467 if (size > 0 )
4568 {
46- Parallel_Common::bcast_char (&value[0 ], size);
69+ bcast_socket_chars (&value[0 ], size);
4770 }
4871}
4972
5073void quit_if_root_io_failed (int root_failed, std::string root_message)
5174{
52- Parallel_Common::bcast_int (root_failed);
75+ bcast_socket_int (root_failed);
5376 bcast_socket_string (root_message);
5477 if (root_failed != 0 )
5578 {
@@ -85,6 +108,58 @@ std::vector<double> ipi_cell_bohr_from_unitcell(const UnitCell& ucell)
85108 };
86109}
87110
111+ double max_wrapped_direct_delta_from_unitcell (const UnitCell& ucell, const std::vector<double >& positions_bohr)
112+ {
113+ if (positions_bohr.size () != static_cast <std::size_t >(3 * ucell.nat ))
114+ {
115+ return 1.0e99 ;
116+ }
117+
118+ double out = 0.0 ;
119+ int iat = 0 ;
120+ for (int it = 0 ; it < ucell.ntype ; ++it)
121+ {
122+ const Atom* atom = &ucell.atoms [it];
123+ for (int ia = 0 ; ia < atom->na ; ++ia)
124+ {
125+ const double tau_x = positions_bohr[3 * iat + 0 ] / ucell.lat0 ;
126+ const double tau_y = positions_bohr[3 * iat + 1 ] / ucell.lat0 ;
127+ const double tau_z = positions_bohr[3 * iat + 2 ] / ucell.lat0 ;
128+
129+ double dx = 0.0 ;
130+ double dy = 0.0 ;
131+ double dz = 0.0 ;
132+ ModuleBase::Mathzone::Cartesian_to_Direct (tau_x,
133+ tau_y,
134+ tau_z,
135+ ucell.latvec .e11 ,
136+ ucell.latvec .e12 ,
137+ ucell.latvec .e13 ,
138+ ucell.latvec .e21 ,
139+ ucell.latvec .e22 ,
140+ ucell.latvec .e23 ,
141+ ucell.latvec .e31 ,
142+ ucell.latvec .e32 ,
143+ ucell.latvec .e33 ,
144+ dx,
145+ dy,
146+ dz);
147+
148+ double ddx = dx - atom->taud [ia].x ;
149+ double ddy = dy - atom->taud [ia].y ;
150+ double ddz = dz - atom->taud [ia].z ;
151+ ddx -= std::round (ddx);
152+ ddy -= std::round (ddy);
153+ ddz -= std::round (ddz);
154+ out = std::max (out, std::abs (ddx));
155+ out = std::max (out, std::abs (ddy));
156+ out = std::max (out, std::abs (ddz));
157+ ++iat;
158+ }
159+ }
160+ return out;
161+ }
162+
88163double max_abs_delta (const std::vector<double >& a, const std::vector<double >& b)
89164{
90165 if (a.size () != b.size ())
@@ -214,6 +289,7 @@ void Socket_Driver::socket_driver(ModuleESolver::ESolver* p_esolver,
214289 std::vector<double > virial_hartree (9 , 0.0 );
215290
216291 const std::vector<double > reference_cell = ipi_cell_bohr_from_unitcell (ucell);
292+ bool checked_initial_positions = false ;
217293
218294 while (true )
219295 {
@@ -306,8 +382,8 @@ void Socket_Driver::socket_driver(ModuleESolver::ESolver* p_esolver,
306382 }
307383 }
308384 quit_if_root_io_failed (io_failed, io_message);
309- Parallel_Common::bcast_int (rid);
310- Parallel_Common::bcast_int (nbytes);
385+ bcast_socket_int (rid);
386+ bcast_socket_int (nbytes);
311387 if (nbytes > 0 && is_root ())
312388 {
313389 ofs_running << " ABACUS socket INIT params bytes " << nbytes << std::endl;
@@ -352,7 +428,7 @@ void Socket_Driver::socket_driver(ModuleESolver::ESolver* p_esolver,
352428 quit_if_root_io_failed (io_failed, io_message);
353429 bcast_double_vector (cell);
354430 bcast_double_vector (inv_cell);
355- Parallel_Common::bcast_int (nat_socket);
431+ bcast_socket_int (nat_socket);
356432 if (!is_root ())
357433 {
358434 positions.assign (static_cast <std::size_t >(3 * nat_socket), 0.0 );
@@ -368,6 +444,17 @@ void Socket_Driver::socket_driver(ModuleESolver::ESolver* p_esolver,
368444 {
369445 ModuleBase::WARNING_QUIT (" ABACUS socket" , " variable-cell socket updates are not supported yet." );
370446 }
447+ if (!checked_initial_positions)
448+ {
449+ checked_initial_positions = true ;
450+ if (max_wrapped_direct_delta_from_unitcell (ucell, positions) > 1.0e-5 && is_root ())
451+ {
452+ ModuleBase::WARNING (
453+ " ABACUS socket" ,
454+ " first POSDATA positions are not PBC-equivalent to STRU atom order; "
455+ " i-PI POSDATA carries no species, so the client atoms should use the same atom order as STRU." );
456+ }
457+ }
371458
372459 set_positions_from_ipi_bohr (ucell, positions);
373460 p_esolver->runner (ucell, istep);
0 commit comments